我不知道我应该如何进行。
我有一堆 div 相对于 document.body 绝对定位的情况。我知道每个 div 的大小和位置。我也有爆炸原点的位置。
我想做的目标 是在爆炸原点模拟爆炸,让所有的 div 飞离爆炸但最终停下来。即模拟爆炸。
他们是那里的任何物理公式专家,可以告诉我我需要使用哪些公式吗?我的猜测类似于给爆炸点某种质量并使用它来计算 div 的速度。
我想把这件事做好,所以我对任何会产生不太现实效果的捷径公式并不感兴趣。
如果有任何高效、轻量级的 JavaScript 物理库可以让这项任务变得更容易,那就太好了。虽然不想要任何基于 jQuery 的东西,因为我需要尽可能地保持轻量级。并且没有库具有完整的代码库来处理 canvas 元素,因为这只会添加大量不需要的代码。
提前感谢,阿里。
背景故事,与上述问题无关,请随意忽略 我实现此功能的原因,因为我认为这对于一些史诗般的页面过渡效果会很好。所以我想通过爆炸所有主要的可见 div 来进行过渡。
到目前为止,我已经实现了一些代码,用一堆准备爆炸的小 div 替换视口中的大 div。
到目前为止,这是我的实现。您将看到对非 JavaScript 原生函数的引用,这是因为我使用的是 Closure 库,所以要显示所有内容就太过分了。
/**
* @constructor
*/
pwd.fx.Explode = function (div) {
this.element_ = div;
}
/**
* @public
*/
pwd.fx.Explode.prototype.play = function () {
this.viewportOffset = goog.style.getViewportPageOffset(document);
this.size = goog.style.getBounds(this.element_);
this.position = goog.style.getClientPosition(this.element_);
this.backgroundColour = goog.style.getBackgroundColor(this.element_);
// Set the explosion centre
// relative to the viewport
this.explosionEpicentre = new goog.math.Coordinate(
this.position.x + Math.floor(this.size.width / 2),
this.position.y + Math.floor(this.size.height / 2)
);
this.seperate();
}
/**
* @private
* Seperates the current div into loads of little divs
*/
pwd.fx.Explode.prototype.seperate = function () {
var idealSize = new goog.math.Size(35, 35);
var widths = pwd.math.algorithms.getExactFit(idealSize.width, this.size.width);
var heights = pwd.math.algorithms.getExactFit(idealSize.height, this.size.height);
// Remove the node as it will be replaced by blocks
goog.dom.removeNode(this.element_);
var cumulativeHeight = 0;
for (var i = 0; i < heights.length; i++) {
var cumulativeWidth = 0;
for (var j = 0; j < widths.length; j++) {
var blockSize = new goog.math.Size(widths[j], heights[i]);
var blockRelativePosition = new goog.math.Coordinate(cumulativeWidth, cumulativeHeight);
cumulativeWidth += widths[j];
var blockPosition = new goog.math.Coordinate.sum(this.position, blockRelativePosition);
// Add the block
this.addBlock(blockSize, blockPosition, this.backgroundColour);
}
cumulativeHeight += heights[i];
}
}
/**
* Add a block
* All positions are relative to the viewport
* @private
*/
pwd.fx.Explode.prototype.addBlock = function (blockSize, blockPosition, backgroundColour) {
var block = document.createElement("div");
// Height and width
block.style.width = blockSize.width + "px";
block.style.height = blockSize.height + "px";
// Positioning
block.style.position = "absolute";
block.style.left = this.viewportOffset.x + blockPosition.x + "px";
block.style.top = this.viewportOffset.y + blockPosition.y + "px";
// Styling
block.style.backgroundColor = backgroundColour;
// Add to document relative to viewport
document.body.appendChild(block);
// Explode block
// TODO...?
}