查看效果:http://keleyi.com/keleyi/phtml/html5/33.htm
.NET版本:http://keleyi.com/a/bjac/66mql4bc.htm
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>使用javascript生成的植物显示过程特效 - 柯乐义</title><base target="_blank" /> <style>html, body {background: black;}a{color:white;text-decoration:none} .hovertreefrme{height:700px;width:760px;border:solid 1px red; } </style> </head> <body> <div class="hovertreefrme"><div><a href="http://keleyi.com">首页</a> <a href="http://keleyi.com/a/bjae/4d3jagcj.htm">原文</a> <a href="http://keleyi.com/keleyi/phtml/">特效库</a> <a href="http://hovertree.com">HoverTree</a> <a href="http://keleyi.com/a/bjac/66mql4bc.htm">参考</a></div> <canvas id="hovertree"></canvas> </div> <script> (function () { var H, W, animationCurve, keleyicanvas, colorStops, getColors, i, k, lut, maxDraws, numDraws, pMax, rand, render, row, speed, step, styles, transformations, v, xRange, xSpan, yRange, ySpan, _i, _len, _ref; speed = 1; W = 350; H = 500; transformations = [ [ (function (x, y) { return 0; }), (function (x, y) { return 0.16 * y; }), 1 ], [ (function (x, y) { return 0.2 * x - 0.26 * y; }), (function (x, y) { return 0.23 * x + 0.22 * y + 1.6; }), 7 ], [ (function (x, y) { return -0.15 * x + 0.28 * y; }), (function (x, y) { return 0.26 * x + 0.24 * y + 0.44; }), 7 ], [ (function (x, y) { return 0.85 * x + 0.04 * y; }), (function (x, y) { return -0.04 * x + 0.85 * y + 1.6; }), 85 ] ]; maxDraws = 200000; xRange = [-2.182, 2.6558]; yRange = [0, 9.9983]; keleyicanvas = document.getElementById("hover"+"tree"); keleyicanvas.width = W; keleyicanvas.height = H; styles = { position: "absolute", top: "400px", left: "300px", margin: "-" + (~~(H / 2)) + "px 0 0 -" + (~~(W / 2)) + "px" }; colorStops = [[0, "rgba(255,255,255,1)"], [1000, "rgba(253,253,52,0.6)"], [5000, "rgba(0,171,56,0.7)"], [10000, "rgba(168,210,110,0.7)"], [20000, "rgba(246,243,27,0.6)"], [40000, "rgba(138,215,39,0.7)"], [65000, "rgba(243,205,8,0.5)"], [90000, "rgba(150,204,104,0.4)"], [125000, "rgba(137,230,101,0.5)"], [150000, "rgba(246,243,27,0.5)"], [190000, "rgba(255,255,255,0.8)"]]; animationCurve = function (frame) { if (frame < 1000) return 25; if (frame < 5000) return 50; if (frame < 10000) return 75; if (frame < 20000) return 100; if (frame < 40000) return 150; if (frame < 65000) return 250; if (frame < 90000) return 400; if (frame < 150000) return 600; if (frame < 190000) return 400; if (frame < 200000) return 100; }; lut = {}; numDraws = 0; pMax = 0; for (_i = 0, _len = transformations.length; _i < _len; _i++) { row = transformations[_i]; for (i = pMax, _ref = row[2] + pMax - 1; pMax <= _ref ? i <= _ref : i >= _ref; pMax <= _ref ? i++ : i--) { lut[i] = [row[0], row[1]]; } pMax += row[2]; } getColors = function () { var colors; colors = colorStops.slice(); return function () { var colorStop; if (!(colors[0] && numDraws >= colors[0][0])) return; colorStop = colors.shift(); return ctx.fillStyle = colorStop[1]; }; }; for (k in styles) { v = styles[k]; keleyicanvas.style[k] = v; } window.ctx = keleyicanvas.getContext("2d"); xSpan = xRange[1] - xRange[0]; ySpan = yRange[1] - yRange[0]; window.updateColor = getColors(); render = function () { var drawsPerFrame, f, i, iter, x, y, _ref2, _ref3; if (numDraws > maxDraws) return; updateColor(); drawsPerFrame = speed * animationCurve(numDraws); for (i = 0; 0 <= drawsPerFrame ? i <= drawsPerFrame : i >= drawsPerFrame; 0 <= drawsPerFrame ? i++ : i--) { iter = 0; _ref2 = [rand(xRange[0], xRange[1]), rand(yRange[0], yRange[1])], x = _ref2[0], y = _ref2[1]; while (iter++ < 50) { f = lut[~~rand(0, pMax)]; _ref3 = [f[0](x, y), f[1](x, y)], x = _ref3[0], y = _ref3[1]; } x = W * (x - xRange[0]) / xSpan; y = H * (1 - y / ySpan); ctx.fillRect(x, y, 1, 1); } return numDraws += drawsPerFrame; }; window.onclick = function () { numDraws = 0; window.updateColor = getColors(); return ctx.clearRect(0, 0, W, H); }; rand = function (a, b) { return (b - a) * Math.random() + a; }; window.requestAnimationFrame || (window.requestAnimationFrame = (function () { var prefix, r, _j, _len2, _ref2; _ref2 = ['webkit', 'moz', 'ms', 'o']; for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { prefix = _ref2[_j]; if (r = window["" + prefix + "RequestAnimationFrame"]) return r; } return function (callback) { return window.setTimeout(callback, 1000 / 60); }; })()); (step = function () { return requestAnimationFrame(step) && render(); })(); }).call(this); </script> </body> </html>