html5 树开花效果,HTML5 Bluebird.js树木生长花开花落动画

JavaScript

语言:

JaveScriptBabelCoffeeScript

确定

"use strict";

var SVG_NS = "http://www.w3.org/2000/svg";

var MAX_FLOWER_AGE = 50;

var MAX_GROWTH_TICKS = 15;

var BRANCH_COLOR = "rgb(101, 67, 33)";

// from http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors

function shadeRGBColor(color, percent) {

var f = color.split(","),

t = percent < 0 ? 0 : 255,

p = percent < 0 ? percent * -1 : percent,

R = parseInt(f[0].slice(4)),

G = parseInt(f[1]),

B = parseInt(f[2]);

return "rgb(" + (Math.round((t - R) * p) + R) + "," + (Math.round((t - G) * p) + G) + "," + (Math.round((t - B) * p) + B) + ")";

}

(function() {

var maxDepth = 11,

trunkWidth = 12;

var branchShrinkage = 0.8;

var maxAngleDelta = Math.PI / 2;

var delay = 100;

var svg = document.getElementById("svg");

var scaleIncrement = 0.1;

var flowerSize = 10.0;

var dropIncrement = 2.0;

var rotateIncrement = Math.PI * 2;

var wind = 0;

var windIncrement = 1;

var maxWind = 2.0;

var createFlower = function createFlower(_ref) {

var x = _ref.x;

var y = _ref.y;

var idx = _ref.idx;

var telomeres = MAX_FLOWER_AGE;

var growthPhase = 0;

var attached = true;

var hangPhase = 1;

var scale = 0.5;

var rotation = 0;

var element = document.createElementNS(SVG_NS, "use");

element.setAttribute("href", "#flower");

element.setAttribute("style", "z-index: -1");

var flower = {

idx: idx,

grow: function grow() {

growthPhase += 1;

scale += scaleIncrement * Math.random();

},

drop: function drop() {

y += dropIncrement * Math.random();

x += dropIncrement * (Math.random() - 0.5) + wind;

rotation += rotateIncrement * (Math.random() - 0.5);

},

transform: function transform() {

var radius = scale * flowerSize / 2;

element.setAttribute("transform", "translate(" + (x - radius) + "," + (y - radius) + ") scale(" + scale + ") rotate(" + rotation + ")");

},

step: function step() {

if (y >= window.innerHeight - 2 * flowerSize) {

telomeres -= 1;

} else if (growthPhase >= MAX_GROWTH_TICKS) {

if (attached) {

attached = Math.random() < Math.pow(0.9999, hangPhase);

hangPhase += 0.00001;

} else {

this.drop();

}

} else {

this.grow();

}

this.transform();

return telomeres;

},

delete: function _delete() {

svg.removeChild(element);

}

};

flower.transform();

// pick a random branch so it looks like the flowers are falling through them

var childNodes = svg.childNodes;

var randomBranch = childNodes[Math.floor(Math.random() * childNodes.length)];

svg.insertBefore(element, randomBranch);

return flower;

};

var animateFlowers = function animateFlowers(branchEndings) {

var branchesInUse = {};

var flowers = [];

var findFreeBranchIdx = function findFreeBranchIdx() {

for (var i = 0; i < branchEndings.length; i++) {

var idx = Math.floor(Math.random() * branchEndings.length);

if (!branchesInUse[idx]) {

branchesInUse[idx] = true;

return idx;

}

}

return -1;

};

var attachFlower = function attachFlower() {

var idx = findFreeBranchIdx();

if (idx >= 0) {

var branch = branchEndings[idx];

flowers.push(createFlower(Object.assign({}, branch, {

idx: idx

})));

}

};

var tick = function tick() {

flowers = flowers.reduce(function(acc, flower) {

if (flower.step() > 0) {

return acc.concat([flower]);

} else {

console.log("deleting flower", flower.idx);

flower.delete();

delete branchesInUse[flower.idx];

return acc;

}

}, []);

Array(5).fill().forEach(function() {

if (Math.random() < 0.02) {

attachFlower();

}

});

if (Math.random() < 0.02) {

wind = Math.min(maxWind, wind + (Math.random() * 2 - 1) * windIncrement);

wind = Math.max(-maxWind, wind);

}

requestAnimationFrame(tick);

};

requestAnimationFrame(tick);

};

var wrap = function wrap(a) {

return Array.isArray(a) ? a : [a];

};

var flatten = function flatten(a) {

if (!Array.isArray(a)) {

return a;

}

var left = a[0];

var right = a[1];

return wrap(left).concat(wrap(right));

};

var drawBranch = function drawBranch(x1, y1, length, angle, depth, branchWidth, branchColor) {

var x2 = x1 + length * Math.cos(angle);

var y2 = y1 + length * Math.sin(angle);

var line = document.createElementNS(SVG_NS, "line");

var style = "stroke:" + branchColor + ";stroke-width:" + branchWidth + ";z-index:1;";

line.setAttribute("x1", x1);

line.setAttribute("x2", x2);

line.setAttribute("y1", y1);

line.setAttribute("y2", y2);

line.setAttribute("style", style);

svg.appendChild(line);

var newDepth = depth - 1;

if (newDepth <= 0) {

return Promise.resolve({

x: x2,

y: y2

});

}

var newBranchWidth = branchWidth * branchShrinkage;

var newBranchColor = shadeRGBColor(branchColor, 0.1);

return Promise.map([-1, 1], function(direction) {

var newAngle = angle + maxAngleDelta * (Math.random() * 0.5 * direction);

var newLength = length * (branchShrinkage + Math.random() * (1.0 - branchShrinkage));

return new Promise(function(resolve) {

setTimeout(function() {

return resolve(drawBranch(x2, y2, newLength, newAngle, newDepth, newBranchWidth, newBranchColor));

}, delay);

});

}).then(flatten);

};

// returns a promise that resolves to an array of the positions of the branches

var drawTree = function drawTree(maxDepth, trunkWidth) {

return drawBranch(Math.floor(window.innerWidth / 2), Math.floor(window.innerHeight / 1.02), 60, -Math.PI / 2, maxDepth, trunkWidth, BRANCH_COLOR);

};

var init = function init() {

svg.setAttribute("width", window.innerWidth);

svg.setAttribute("height", window.innerHeight);

drawTree(maxDepth, trunkWidth).then(animateFlowers);

};

init();

})();

可以使用 JavaScript 的 Canvas API 来实现一棵开花动画特效。 首先,需要绘制出的结构。可以使用 Canvas 的路径(Path)来绘制出干和枝。接着,在每个枝的末端绘制出花朵。 在动画效果上,可以通过改变花朵的位置、大小、颜色等属性来模拟花朵的生长过程。可以使用 Canvas 的动画函数 requestAnimationFrame() 来实现动画效果。 以下是一个简单的示例代码: ```html <!DOCTYPE html> <html> <head> <title>Tree Animation</title> <style> canvas { border: 1px solid #000; } </style> </head> <body> <canvas id="canvas"></canvas> <script> // 获取 Canvas 元素 var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); // 定义的结构 function drawTree(x, y, len, angle, branchWidth) { ctx.beginPath(); ctx.save(); ctx.strokeStyle = 'brown'; ctx.lineWidth = branchWidth; ctx.translate(x, y); ctx.rotate(angle * Math.PI / 180); ctx.moveTo(0, 0); ctx.lineTo(0, -len); ctx.stroke(); if (len < 20) { ctx.beginPath(); ctx.arc(0, -len, 10, 0, Math.PI * 2); ctx.fillStyle = 'pink'; ctx.fill(); ctx.restore(); return; } drawTree(0, -len, len * 0.8, angle + 30, branchWidth * 0.7); drawTree(0, -len, len * 0.8, angle - 30, branchWidth * 0.7); ctx.restore(); } // 定义动画函数 var flowerSize = 0; var flowerColor = 'pink'; function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawTree(canvas.width / 2, canvas.height, 120, -90, 10); // 绘制花朵 ctx.beginPath(); ctx.arc(canvas.width / 2, canvas.height - 120, flowerSize, 0, Math.PI * 2); ctx.fillStyle = flowerColor; ctx.fill(); // 改变花朵属性 flowerSize += 0.5; if (flowerSize > 20) { flowerColor = 'red'; } requestAnimationFrame(animate); } // 启动动画 animate(); </script> </body> </html> ``` 在上面的代码中,我们定义了一个 drawTree() 函数来绘制的结构,使用 Canvas 的 arc() 方法来绘制花朵。在 animate() 函数中,我们通过改变花朵的大小和颜色来模拟花朵的生长过程。最后,我们使用 requestAnimationFrame() 函数来启动动画
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值