js canvas实现“倒8”形状loading动画

179 阅读1分钟
<body>
	 <canvas id="canvas"></canvas>
</body>
 <script src="./handle.js"> </script>

handle.js:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const W = window.innerWidth;
const H = window.innerHeight;
canvas.width = W;
canvas.height = H;
let particles = []; //每段线条的总和
const maxLife = 40; //线条的个数
const lineColor = 'rgb(220,220,220)'; //线的颜色
const backgroundColor = '#38f'; //背景色
const lineWidth = 8; //线条宽度
const loadingSize = 2; //loading的大小
let distanceBase = 0; //起步位置
const tIncrement = 0.1; //换算倍数
/* 画背景 */
const drawBackground = () => {
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, W, H);
    ctx.stroke();
}
/* 连点成线,将所有点存进数组,点的信息:x,y,color */
const addParticlesAtPoint = (x, y) => {
    if (particles.length > maxLife) {
        particles = particles.slice(0, maxLife)
    }
    particles.unshift({
        x,
        y,
        lineColor
    })
    particles.forEach((item, index) => {
        const endP = particles[index + 1]
        if (endP) {
            ctx.save();
            ctx.beginPath();
            ctx.moveTo(item.x, item.y);
            ctx.lineTo(endP.x, endP.y);
            ctx.lineWidth = lineWidth; //设置线宽状态
            ctx.lineCap = 'round';
            ctx.strokeStyle = item.lineColor; //设置线的颜色状态
            ctx.stroke();
        }
    })

};
/* 坐标移动到中间 */
const getPositionOnCanvas = (x, y) => ({
    x: x + W / 2,
    y: y + H / 2
});
/* 开始处理线以及画出来 */
const addParticlesOnAxis = (x, y) => {
    const {
        x: realX,
        y: realY
    } = getPositionOnCanvas(x, y);
    ctx.clearRect(0, 0, W, H);
    drawBackground();
    addParticlesAtPoint(+realX.toFixed(2), +realY.toFixed(2));
};
/* 窗口大小换算 */
const getScreenScale = Math.min(W, H) / 8;
/* 产生每段线首尾坐标x,y */
const addParticlesAtNextPoint = () => {
    const scale = loadingSize / (3 - Math.cos(2 * distanceBase)) * getScreenScale;
    const x = scale * Math.cos(distanceBase);
    const y = scale * Math.sin(2 * distanceBase) / 2;
    distanceBase += tIncrement;
    addParticlesOnAxis(x, y);
    window.beforeEnterLoadingId = window.requestAnimationFrame(addParticlesAtNextPoint);
};
addParticlesAtNextPoint();