canvas实现彩色线条绘制屏保动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas实现彩色线条绘制屏保动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
:root {
background: black;
color: white;
}
</style>
</head>
<body translate="no">
<script >
const particles = 4;
const minD = 0.05; // min/max distance
const maxD = 1;
const maxV = 20; // max velocity
const maxF = 10; // max force
const F = 0.0186125; // attraction force
const G = 0.003; // gravity
const canvas = document.createElement("canvas");
canvas.style.position = "absolute";
canvas.style.top = canvas.style.left = 0;
document.body.appendChild(canvas);
const buffer = document.createElement("canvas");
const bufferCtx = buffer.getContext("2d");
const ctx = canvas.getContext("2d");
let w, h, hw, hh;
const PI2 = Math.PI * 2;
const random = (min = -1, max = 1) => Math.random() * (max - min) + min;
const resize = () => {
w = Math.max(innerWidth, 1) - innerWidth % 2;
h = Math.max(innerHeight, 1) - innerHeight % 2;
hw = w / 2;
hh = h / 2;
canvas.width = buffer.width = w;
canvas.height = buffer.height = h;
initContext();
};
const initContext = () => {
ctx.translate(hw, hh);
ctx.fillStyle = "white";
ctx.strokeStyle = "white";
ctx.lineWidth = 1.3;
ctx.fillRect(-hw, -hh, w, h);
bufferCtx.fillStyle = "black";
bufferCtx.fillRect(0, 0, w, h);
};
resize(false);
const debounce = (fn, delay) => {
let timeout;
return () => {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => fn(), delay);
};
};
const debouncedResize = debounce(resize, 100);
addEventListener("resize", () => debouncedResize());
const createPoints = (count, source, phase = Math.random() * PI2) =>
Array.from({ length: count }, (_, i) => {
const x = source?.x ?? Math.sin(phase + i / count * PI2) * .9;
const y = source?.y ?? Math.cos(phase + i / count * PI2) * .9;
const dx = source?.dx ?? -x / 4;
const dy = source?.dy ?? -y / 4;
return { x, y, dx, dy, closest: null };
});
const project2d = ({ x, y }) => {
return {
x: Math.round(x * hw),
y: Math.round(y * hh) };
};
const distance = (p1, p2) =>
Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
const map = (value, min = 0, max = 1, targetMin = 0, targetMax = 1) =>
targetMin + (value - min) * (targetMax - targetMin) / (max - min);
let firstHit = false;
const updatePoint = dt => (p, i, points) => {
p.dy += G * dt;
p.closest = getClosestPoints(points, p);
const [cdx, cdy] = p.closest.reduce((sum, cp) => {
const dx = cp.x - p.x;
const dy = cp.y - p.y;
const d = distance(cp, p);
if (d > maxD) return sum;
if (d < minD) {
const rStr = .5 * (1 - d / minD);
sum[0] -= dx / d * rStr;
sum[1] -= dy / d * rStr;
return sum;
}
const mag = Math.min(maxF, (1 - d / maxD) / (d * d));
const force = mag; // p.closest.length;
sum[0] += dx / d * force;
sum[1] += dy / d * force;
return sum;
}, [0, 0]);
const .........完整代码请登录后点击上方下载按钮下载查看
网友评论0