激光绘制爱心代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>激光汇聚成爱心</title>
<style>
canvas {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.2);
}
</style>
</head>
<body>
<canvas id="heart"></canvas>
<script>
window.requestAnimationFrame =
window.__requestAnimationFrame ||
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
(function () {
return function (callback, element) {
var lastTime = element.__lastTime;
if (lastTime === undefined) {
lastTime = 0;
}
var currTime = Date.now();
var timeToCall = Math.max(1, 33 - (currTime - lastTime));
window.setTimeout(callback, timeToCall);
element.__lastTime = currTime + timeToCall;
};
})();
window.isDevice =
/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(
(
navigator.userAgent ||
navigator.vendor ||
window.opera
).toLowerCase()
);
var loaded = false;
var init = function () {
if (loaded) return;
loaded = true;
var mobile = window.isDevice;
var koef = mobile ? 1.5 : 1;
var canvas = document.getElementById('heart');
var ctx = canvas.getContext('2d');
var width = (canvas.width = koef * innerWidth);
var height = (canvas.height = koef * innerHeight);
var rand = Math.random;
ctx.fillStyle = 'rgba(0,0,0,1)';
ctx.fillRect(0, 0, width, height);
var heartPosition = function (rad) {
return [
Math.pow(Math.sin(rad), 3),
-(
15 * Math.cos(rad) -
5 * Math.cos(2 * rad) -
2 * Math.cos(3 * rad) -
Math.cos(4 * rad)
),
];
};
var scaleAndTranslate = function (pos, sx, sy, dx, dy) {
return [dx + pos[0] * sx, dy + pos[1] * sy];
};
window.addEventListener('resize', function () {
width = canvas.width = koef * innerWidth;
height = canvas.height = koef * innerHeight;
ctx.fillStyle = 'rgba(0,0,0,1)';
ctx.fillRect(0, 0, width, height);
});
var traceCount = 50;
var pointsOrigin = [];
var i;
var dr = 0.1;
for (i = 0; i < Math.PI * 2; i += dr)
pointsOrigin.push(
scaleAndTranslate(heartPosition(i), 105, 6.5, 0, 0)
); // 修改比例参数
for (i = 0; i < Math.PI * 2; i += dr)
pointsOrigin.push(scaleAndTranslate(heartPosition(i), 75, 4.5, 0, 0)); // 修改比例参数
for (i = 0; i < Math.PI * 2; i += dr)
pointsOrigin.push(scaleAndTranslate(heartPosition(i), 45, 2.5, 0, 0)); // 修改比例参数
var heartPointsCount = pointsOrigin.length;
var targetPoints = [];
var pulse = function (kx, ky) {
for (i = 0; i < pointsOrigin.length; i++) {
targetPoints[i] = [];
targetPoints[i][0] = kx * pointsOrigin[i][0] + width / 2;
targetPoints[i][1] = ky * pointsOrigin[i][1] + height / 2;
}
};
var e = [];
for (i = 0; i < heartPointsCount; i++) {
var x = rand() * width;
var y = rand() * height;
e[i] = {
vx: 0,
vy: 0,
R: 2,
speed: rand() + 5,
q: ~~(rand() * heartPointsCount),
D: 2 * (i % 2) - 1,
force: 0.2 * rand() + 0.7,
f:
'hsla(0,' +
~~(40 * rand() + 60) +
'%,' +
~~(60 * rand() + 20) +
'%,.3)',
trace: [],
};
for (var k = 0; k < traceCount; k++) e[i].trace[k] = { x: x, y: y };
}
var config = {
traceK: 0.4,
timeDelta: 0.01,
};
var time = 0;
var loop = function () {
var n = -Math.cos(time);
pulse((1 + n) * 0.5, (1 + n) * 0.5);
time +=
(Math.sin(time) < 0 ? 9 : n > 0.8 ? 0.2 : 1) * config.timeDelta;
ctx.fillStyle = 'rgba(0,0,0,.1)';
ctx.fillRect(0, 0, width, height);
for (i = e.length; i--; ) {
var u = e[i];
var q = targetPoints[u.q];
var dx = u.trace[0].x - q[0];
var dy = u.trace[0].y - q[1];
var length = Math.sqrt(dx * dx + dy * dy);
if (10 > length) {
if (0.95 < rand()) {
u.q = ~~(rand() * heartPointsCount);
} else {
if (0.99 < rand()) {
u.D *= -1;
}
u
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。