【发布时间】:2020-12-26 15:45:36
【问题描述】:
纯js里有树叶飞舞的动画。问题是它需要优化以获得最佳性能,因为页面上会有更多此类动画。除了优化原始 SVG 图像和减少传单的数量之外,您还可以提供哪些提示来提高代码的性能?
var LeafScene = function(el) {
this.viewport = el;
this.world = document.createElement('div');
this.leaves = [];
this.options = {
numLeaves: 6,
wind: {
magnitude: 0,
maxSpeed: 12,
duration: 300,
start: 0,
speed: 10
},
};
this.width = this.viewport.offsetWidth;
this.height = this.viewport.offsetHeight;
this.timer = 0;
this._resetLeaf = function(leaf) {
leaf.x = this.width * 2 - Math.random()*this.width*1.75;
leaf.y = -10;
leaf.z = Math.random()*200;
if (leaf.x > this.width) {
leaf.x = this.width + 10;
leaf.y = Math.random()*this.height/2;
}
if (this.timer == 0) {
leaf.y = Math.random()*this.height;
}
leaf.rotation.speed = Math.random()*10;
var randomAxis = Math.random();
if (randomAxis > 0.5) {
leaf.rotation.axis = 'X';
} else if (randomAxis > 0.25) {
leaf.rotation.axis = 'Y';
leaf.rotation.x = Math.random()*180 + 90;
} else {
leaf.rotation.axis = 'Z';
leaf.rotation.x = Math.random()*360 - 180;
leaf.rotation.speed = Math.random()*3;
}
leaf.xSpeedVariation = Math.random() * 0.8 - 0.4;
leaf.ySpeed = Math.random() + 1.5;
return leaf;
}
this._updateLeaf = function(leaf) {
var leafWindSpeed = this.options.wind.speed(this.timer - this.options.wind.start, leaf.y);
var xSpeed = leafWindSpeed + leaf.xSpeedVariation;
leaf.x -= xSpeed;
leaf.y += leaf.ySpeed;
leaf.rotation.value += leaf.rotation.speed;
var t = 'translateX( ' + leaf.x + 'px ) translateY( ' + leaf.y + 'px ) translateZ( ' + leaf.z + 'px ) rotate' + leaf.rotation.axis + '( ' + leaf.rotation.value + 'deg )';
if (leaf.rotation.axis !== 'X') {
t += ' rotateX(' + leaf.rotation.x + 'deg)';
}
leaf.el.style.webkitTransform = t;
leaf.el.style.MozTransform = t;
leaf.el.style.oTransform = t;
leaf.el.style.transform = t;
if (leaf.x < -10 || leaf.y > this.height + 10) {
this._resetLeaf(leaf);
}
}
this._updateWind = function() {
if (this.timer === 0 || this.timer > (this.options.wind.start + this.options.wind.duration)) {
this.options.wind.magnitude = Math.random() * this.options.wind.maxSpeed;
this.options.wind.duration = this.options.wind.magnitude * 50 + (Math.random() * 20 - 10);
this.options.wind.start = this.timer;
var screenHeight = this.height;
this.options.wind.speed = function(t, y) {
var a = this.magnitude/2 * (screenHeight - 2*y/3)/screenHeight;
return a * Math.sin(2*Math.PI/this.duration * t + (3 * Math.PI/2)) + a;
}
}
}
}
LeafScene.prototype.init = function() {
for (var i = 0; i < this.options.numLeaves; i++) {
var leaf = {
el: document.createElement('div'),
x: 0,
y: 0,
z: 0,
rotation: {
axis: 'X',
value: 0,
speed: 0,
x: 0
},
xSpeedVariation: 0,
ySpeed: 0,
path: {
type: 1,
start: 0,
},
image: 1
};
this._resetLeaf(leaf);
this.leaves.push(leaf);
this.world.appendChild(leaf.el);
}
this.world.className = 'leaf-scene';
this.viewport.appendChild(this.world);
this.world.style.webkitPerspective = "400px";
this.world.style.MozPerspective = "400px";
this.world.style.oPerspective = "400px";
this.world.style.perspective = "400px";
var self = this;
window.onresize = function(event) {
self.width = self.viewport.offsetWidth;
self.height = self.viewport.offsetHeight;
};
}
LeafScene.prototype.render = function() {
this._updateWind();
for (var i = 0; i < this.leaves.length; i++) {
this._updateLeaf(this.leaves[i]);
}
this.timer++;
requestAnimationFrame(this.render.bind(this));
}
var leafContainer = document.querySelector('.falling-leaves'),
leaves = new LeafScene(leafContainer);
leaves.init();
leaves.render();
body, html {
height: 100%;
}
.falling-leaves {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 100%;
max-width: 880px;
max-height: 880px;
transform: translate(-50%, 0);
border: 20px solid #fff;
border-radius: 50px;
background-size: cover;
overflow: hidden;
}
.leaf-scene {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
transform-style: preserve-3d;
}
.leaf-scene div {
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
background: url(https://www.flaticon.com/svg/static/icons/svg/892/892881.svg) no-repeat;
background-size: 100%;
transform-style: preserve-3d;
-webkit-backface-visibility: visible;
backface-visibility: visible;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<div class="falling-leaves"></div>
【问题讨论】:
标签: javascript css animation optimization mathematical-optimization