canvas_31 动画-星空连线_数组

<template>
    <view class="zcvs">
        <canvas canvas-id="cvs" id="cvs" :style="setCanvasStyle" />
    </view>
</template>

<script>
    export default {
        data() {
            return {};
        },
        onReady() {
            this.drawCvs();
        },
        computed: {
            setCanvasStyle() {
                let retStyle = "background: #000;"
                const info = uni.getSystemInfoSync();
                retStyle += "width:" + info.windowWidth + "px;"
                retStyle += "height:" + info.windowHeight + "px;"
                return retStyle;
            }
        },
        methods: {
            drawCvs() {
                const ctx = uni.createCanvasContext('cvs');
                const info = uni.getSystemInfoSync();
                const canvas = {
                    width: info.windowWidth,
                    height: info.windowHeight
                };

                let warea = {
                    x: null,
                    y: null,
                    max: 20000
                };

                window.onmousemove = e => {
                    warea.x = e.clientX;
                    warea.y = e.clientY;
                };

                window.onmouseout = e => { //鼠标移出界面时清空
                    warea.x = null;
                    warea.y = null;
                };

                let dots = []; // 所有粒子`
                for (var i = 0; i < 500; i++) {
                    dots.push({
                        x: Math.random() * canvas.width, // x  , y  为 粒子坐标
                        y: Math.random() * canvas.height,
                        xa: Math.random() * 2 - 1, // xa , ya 为 粒子 xy 轴加速度
                        ya: Math.random() * 2 - 1,
                        max: 6000 //max为 连线的最大距离
                    });
                };

                var animate = () => {
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                    var ndots = [warea].concat(dots); // 数组合并
                    dots.forEach(dot => { // 粒子位移
                        dot.x += dot.xa
                        dot.y += dot.ya
                        // 遇到边界将加速度反向
                        dot.xa *= dot.x > canvas.width || dot.x < 0 ? -1 : 1
                        dot.ya *= dot.y > canvas.height || dot.y < 0 ? -1 : 1
                        // 绘制点
                        ctx.fillRect(dot.x - 1, dot.y - 1, 2, 2)
                        ctx.setFillStyle("#d6b816");
                        // 循环比对粒子间的距离
                        for (var i = 0; i < ndots.length; i++) {
                            var d2 = ndots[i]
                            if (dot === d2 || d2.x === null || d2.y === null) continue
                            let [xc, yc, dis, ratio] = [dot.x - d2.x, dot.y - d2.y, '', '']
                            // 两个粒子之间的距离
                            dis = xc * xc + yc * yc
                            // 如果两个粒子之间的距离小于粒子对象的max值
                            //则在两个粒子间画线
                            if (dis < d2.max) {
                                // 如果是鼠标,则让粒子向鼠标的位置移动
                                if (d2 === warea && dis > d2.max / 2) {
                                    dot.x -= xc * 0.03
                                    dot.y -= yc * 0.03
                                }
                                // 计算距离比
                                ratio = (d2.max - dis) / d2.max
                                // 画线
                                ctx.beginPath()
                                ctx.setLineWidth(ratio / 2);
                                ctx.setStrokeStyle("#d6b816");
                                ctx.moveTo(dot.x, dot.y)
                                ctx.lineTo(d2.x, d2.y)
                                ctx.stroke();

                                ctx.draw(true);
                            }
                        }
                        ndots.splice(ndots.indexOf(dot), 1) // 从数组中删除已经计算过的粒子
                    })
                    window.requestAnimationFrame(animate);
                };
                animate();
            },
        }
    }
</script>

<style lang="scss" scoped>
    .zcvs {
        flex: 1;
        background: "#000";
    }
</style>