鼠标移动生出四散图形的效果

本文介绍了一种利用JavaScript技术,在鼠标移动时产生四散图形的动态效果。通过解析提供的源码,读者可以了解到如何在网页中实现这种交互式图形动画,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>spread</title>
    <style type="text/css">
        body {
            overflow: hidden;
            background: #eee;
        }
    </style>
</head>
<body>
<canvas id="canvas" width="100" height="100"></canvas>
<script type="text/javascript">
    'use strict';

    function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) {
            throw new TypeError("Cannot call a class as a function");
        }
    }

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var width = undefined,
            height = undefined;
    var forces = [],
            particles = [];
    var nParticles = 250;
    var p = 0;

    var V2 = function () {
        function V2(x, y) {
            _classCallCheck(this, V2);

            this.x = x || 0;
            this.y = y || 0;
        }

        V2.prototype.add = function add(vector) {
            this.x += vector.x;
            this.y += vector.y;
        };

        V2.prototype.reset = function reset(x, y) {
            this.x = x;
            this.y = y;
        };

        V2.prototype.lerp = function lerp(vector, n) {
            this.x += (vector.x - this.x) * n;
            this.y += (vector.y - this.y) * n;
        };

        return V2;
    }();

    var Particle = function () {
        function Particle() {
            _classCallCheck(this, Particle);

            this.position = new V2(-100, -100);
            this.velocity = new V2();
            this.acceleration = new V2();
            this.alpha = 0;
            this.color = '#000000';
            this.points = [new V2(-10 + Math.random() * 20, -10 + Math.random() * 20),
                new V2(-10 + Math.random() * 25, -10 + Math.random() * 25),
                new V2(-10 + Math.random() * 25, -10 + Math.random() * 25),
                new V2(-10 + Math.random() * 25, -10 + Math.random() * 25),
                new V2(-10 + Math.random() * 25, -10 + Math.random() * 25),
                new V2(-10 + Math.random() * 25, -10 + Math.random() * 25),
                new V2(-10 + Math.random() * 25, -10 + Math.random() * 25)];
        }

        Particle.prototype.update = function update() {
            this.velocity.add(this.acceleration);
            this.position.add(this.velocity);
            this.acceleration.reset(0, 0);
            this.alpha -= 0.008;
            if (this.alpha < 0) this.alpha = 0;
        };

        Particle.prototype.follow = function follow() {
            var x = Math.floor(this.position.x / 20);
            var y = Math.floor(this.position.y / 20);
            var index = x * Math.floor(height / 20) + y;
            var force = forces[index];
            if (force) this.applyForce(force);
        };

        Particle.prototype.applyForce = function applyForce(force) {
            this.acceleration.add(force);
        };

        Particle.prototype.draw = function draw() {
            ctx.globalAlpha = this.alpha;
            ctx.beginPath();
            ctx.moveTo(this.position.x + this.points[0].x, this.position.y + this.points[0].y);
            ctx.lineTo(this.position.x + this.points[1].x, this.position.y + this.points[1].y);
            ctx.lineTo(this.position.x + this.points[2].x, this.position.y + this.points[2].y);
            ctx.lineTo(this.position.x + this.points[3].x, this.position.y + this.points[3].y);
            ctx.lineTo(this.position.x + this.points[4].x, this.position.y + this.points[4].y);
            ctx.lineTo(this.position.x + this.points[5].x, this.position.y + this.points[5].y);
            ctx.lineTo(this.position.x + this.points[6].x, this.position.y + this.points[6].y);
            ctx.closePath();
            ctx.fillStyle = this.color;
            ctx.fill();
        };

        return Particle;
    }();

    var resize = function resize() {
        width = window.innerWidth;
        height = window.innerHeight;
        canvas.width = width;
        canvas.height = height;
        initForces();
    };

    var initForces = function initForces() {
        var i = 0;
        for (var x = 0; x < width; x += 20) {
            for (var y = 0; y < height; y += 20) {
                if (!forces[i]) forces[i] = new V2();
                i++;
            }
        }

        if (i < forces.length) {
            forces.splice(i + 1);
        }
    };

    var updateForces = function updateForces(t) {
        var i = 0;
        var xOff = 0,
                yOff = 0;
        for (var x = 0; x < width; x += 20) {
            xOff += 0.1;
            for (var y = 0; y < height; y += 20) {
                yOff += 0.1;
               // var a = noise.perlin3(xOff, yOff, t * 0.00005) * Math.PI * 4;
                var a = Math.PI *2*Math.random();
                if (forces[i]) forces[i].reset(Math.cos(a) * 0.1, Math.sin(a) * 0.1);
                i++;
            }
        }
    };

    var initParticles = function initParticles() {
        for (var i = 0; i < nParticles; i++) {
            particles.push(new Particle(Math.random() * width, Math.random() * height));
            particles[i].velocity.y = 0.1;
        }
    };

    var drawParticles = function drawParticles() {
        for (var i = 0; i < nParticles; i++) {
            particles[i].update();
            particles[i].follow();
            particles[i].draw();
        }
    };

    var launchParticle = function launchParticle() {
        particles[p].position.reset(emitter.x, emitter.y);
        particles[p].velocity.reset(-1 + Math.random() * 2, -1 + Math.random() * 2);
        particles[p].color = 'hsl(' + Math.floor(emitter.x / width * 256) + ',40%,' + (60 + Math.random() * 20) + '%)';
        particles[p].alpha = 1;
        p++;
        if (p === nParticles) p = 0;
    };

    var updateEmitter = function updateEmitter() {
        emitter.lerp(mouse, 0.2);
    };

    var animate = function animate(t) {
        ctx.clearRect(0, 0, width, height);
        updateEmitter();
        launchParticle();
        updateForces(t);
        drawParticles();
        requestAnimationFrame(animate);
    };

    var pointerMove = function pointerMove(e) {
        mouse.x = e.touches ? e.touches[0].pageX : e.pageX;
        mouse.y = e.touches ? e.touches[0].pageY : e.pageY;
    };

    var mouse = new V2(window.innerWidth / 2, window.innerHeight / 2);
    var emitter = new V2(window.innerWidth / 2, window.innerHeight / 2);
    resize();
    initParticles();
    requestAnimationFrame(animate);

    window.addEventListener('resize', resize);
    window.addEventListener('mousemove', pointerMove);
    window.addEventListener('touchmove', pointerMove);
</script>
</body>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值