これをどのように進めればよいかわかりません。
document.body に対して絶対的に配置された div の束がある状況。各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...?
}