前端开发 之 12个鼠标交互特效上【附完整源码】

前端开发 之 12个鼠标交互特效上【附完整源码】

文章目录

一:彩色空心爱心滑动特效

1.效果展示
2.HTML完整代码
html 复制代码
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>超级炫酷的爱心滑动特效</title>
  <style>
    body {
      overflow: hidden;
      margin: 0;
      background: #222;
    }

    canvas {
      display: block;
    }
  </style>
</head>

<body>
  <canvas></canvas>
  <script>
    var canvas = document.querySelector("canvas"),
      ctx = canvas.getContext("2d");

    var ww, wh;

    function onResize() {
      ww = canvas.width = window.innerWidth;
      wh = canvas.height = window.innerHeight;
    }

    function randomColor() {
      return `hsla(${Math.random() * 360}, 100%, 60%, 1)`;
    }

    var precision = 100;
    var hearts = [];
    var mouseMoved = false;

    function onMove(e) {
      mouseMoved = true;
      for (let i = 0; i < 5; i++) { // 生成更多的爱心
        let x, y;
        if (e.type === "touchmove") {
          x = e.touches[0].clientX;
          y = e.touches[0].clientY;
        } else {
          x = e.clientX;
          y = e.clientY;
        }
        hearts.push(new Heart(x, y));
      }
    }

    var Heart = function (x, y) {
      this.x = x || Math.random() * ww;
      this.y = y || Math.random() * wh;
      this.size = Math.random() * 4 + 1;
      this.shadowBlur = Math.random() * 20;
      this.speedX = (Math.random() - 0.5) * 10;
      this.speedY = (Math.random() - 0.5) * 10;
      this.speedSize = Math.random() * 0.05 + 0.01;
      this.opacity = 1;
      this.color = randomColor();
      this.vertices = [];
      for (var i = 0; i < precision; i++) {
        var step = (i / precision - 0.5) * (Math.PI * 2);
        var vector = {
          x: (15 * Math.pow(Math.sin(step), 3)),
          y: -(13 * Math.cos(step) - 5 * Math.cos(2 * step) - 2 * Math.cos(3 * step) - Math.cos(4 * step))
        }
        this.vertices.push(vector);
      }
    }

    Heart.prototype.draw = function () {
      this.size -= this.speedSize;
      this.x += this.speedX;
      this.y += this.speedY;
      ctx.save();
      ctx.translate(this.x, this.y);
      ctx.scale(this.size, this.size);
      ctx.beginPath();
      ctx.strokeStyle = this.color;
      ctx.shadowBlur = this.shadowBlur;
      ctx.shadowColor = this.color;
      for (var i = 0; i < precision; i++) {
        var vector = this.vertices[i];
        ctx.lineTo(vector.x, vector.y);
      }
      ctx.globalAlpha = this.size;
      ctx.closePath();
      ctx.stroke();
      ctx.restore();
    };

    function render(a) {
      requestAnimationFrame(render);
      ctx.clearRect(0, 0, ww, wh);
      for (var i = 0; i < hearts.length; i++) {
        hearts[i].draw();
        if (hearts[i].size <= 0) {
          hearts.splice(i, 1);
          i--;
        }
      }
    }

    onResize();
    window.addEventListener("mousemove", onMove);
    window.addEventListener("touchmove", onMove);
    window.addEventListener("resize", onResize);
    requestAnimationFrame(render);
  </script>
</body>
</html>

二:彩色实心爱心滑动特效

1.效果展示
2.HTML完整代码
html 复制代码
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>滑动爱心</title>
  <style>
    body {
      overflow: hidden;
      margin: 0;
      background: linear-gradient(to right, #ff9a9e, #fad0c4);
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    canvas {
      position: absolute;
      top: 0;
      left: 0;
    }
  </style>
</head>
<body>
  <canvas></canvas>
  <script>
    var canvas = document.querySelector("canvas"),
      ctx = canvas.getContext("2d");

    var ww, wh;

    function onResize() {
      ww = canvas.width = window.innerWidth;
      wh = canvas.height = window.innerHeight;
    }

    var precision = 50;
    var hearts = [];
    var mouseMoved = false;

    function onMove(e) {
      mouseMoved = true;
      var x, y;
      if (e.type === "touchmove") {
        x = e.touches[0].clientX;
        y = e.touches[0].clientY;
      } else {
        x = e.clientX;
        y = e.clientY;
      }
      hearts.push(new Heart(x, y));
    }

    var Heart = function (x, y) {
      this.x = x || Math.random() * ww;
      this.y = y || Math.random() * wh;
      this.size = Math.random() * 2 + 1;
      this.maxSize = this.size * 1.5;
      this.shadowBlur = Math.random() * 15;
      this.speedX = (Math.random() - 0.5) * 4;
      this.speedY = (Math.random() - 0.5) * 4;
      this.alpha = 1;
      this.fadeSpeed = Math.random() * 0.02 + 0.02;
      this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
      this.vertices = [];
      for (var i = 0; i < precision; i++) {
        var step = (i / precision - 0.5) * (Math.PI * 2);
        var vector = {
          x: (15 * Math.pow(Math.sin(step), 3)),
          y: -(13 * Math.cos(step) - 5 * Math.cos(2 * step) - 2 * Math.cos(3 * step) - Math.cos(4 * step))
        }
        this.vertices.push(vector);
      }
    }

    Heart.prototype.draw = function () {
      this.x += this.speedX;
      this.y += this.speedY;
      this.size += (this.maxSize - this.size) * 0.1;
      this.alpha -= this.fadeSpeed;

      ctx.save();
      ctx.translate(this.x, this.y);
      ctx.scale(this.size, this.size);
      ctx.beginPath();
      ctx.moveTo(0, 0);
      for (var i = 0; i < precision; i++) {
        var vector = this.vertices[i];
        ctx.lineTo(vector.x, vector.y);
      }
      ctx.closePath();
      ctx.fillStyle = this.color;
      ctx.globalAlpha = this.alpha;
      ctx.shadowBlur = this.shadowBlur;
      ctx.shadowColor = this.color;
      ctx.fill();
      ctx.restore();
    };

    function render(a) {
      requestAnimationFrame(render);
      ctx.clearRect(0, 0, ww, wh);
      for (var i = 0; i < hearts.length; i++) {
        hearts[i].draw();
        if (hearts[i].alpha <= 0) {
          hearts.splice(i, 1);
          i--;
        }
      }
    }

    onResize();
    window.addEventListener("mousemove", onMove);
    window.addEventListener("touchmove", onMove);
    window.addEventListener("resize", onResize);
    requestAnimationFrame(render);
  </script>
</body>
</html>

三:粒子连结特效

1.效果展示
2.HTML完整代码
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Enhanced Particle System with Cool Effects</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: linear-gradient(45deg, #000, #333);
            animation: bgGradient 10s ease infinite;
        }

        @keyframes bgGradient {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }

        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <canvas id="particleCanvas"></canvas>
</body>
<script>
const canvas = document.getElementById('particleCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

let particlesArray = [];
const numberOfParticles = 50;
const mouse = {
    x: undefined,
    y: undefined,
};
const maxParticleLifeTime = 1; 

class Particle {
    constructor(x, y, initialLife = 1) {
        this.x = x || Math.random() * canvas.width;
        this.y = y || Math.random() * canvas.height;
        this.size = Math.random() * 2 + 1;
        this.speedX = (Math.random() - 0.5) * 2;
        this.speedY = (Math.random() - 0.5) * 2;
        this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
        this.alpha = 1;
        this.decay = Math.random() * 0.01 + 0.01;
        this.life = initialLife;
        this.trail = [];
        this.lifeTime = 0; 
    }

    update() {
        this.x += this.speedX;
        this.y += this.speedY;

        if (this.x > canvas.width || this.x < 0) this.speedX *= -1;
        if (this.y > canvas.height || this.y < 0) this.speedY *= -1;

        if (mouse.x && mouse.y) {
            const dx = mouse.x - this.x;
            const dy = mouse.y - this.y;
            const distance = Math.sqrt(dx * dx + dy * dy);
            const force = 1 / distance * 20;
            this.speedX += (dx / distance) * force;
            this.speedY += (dy / distance) * force;
        }

        this.life -= this.decay;
        this.alpha = this.life;
        this.color = `hsl(${(1 - this.life) * 360}, 100%, 50%)`;
        this.lifeTime += 1 / 60; 
        if (this.life <= 0 || this.lifeTime >= maxParticleLifeTime) {
            this.reset();
        }
        this.trail.push({ x: this.x, y: this.y });
        if (this.trail.length > 15) this.trail.shift();

        for (let otherParticle of particlesArray) {
            if (otherParticle !== this) {
                const dx = this.x - otherParticle.x;
                const dy = this.y - otherParticle.y;
                const distance = Math.sqrt(dx * dx + dy * dy);
                if (distance < 50) {
                    const repelForce = 0.1 / distance;
                    this.speedX -= (dx / distance) * repelForce;
                    this.speedY -= (dy / distance) * repelForce;
                }
            }
        }
    }

    draw() {
        ctx.globalAlpha = this.alpha;
        ctx.fillStyle = this.color;

        ctx.beginPath();
        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
        ctx.closePath();
        ctx.fill();

        ctx.globalAlpha = 0.7 * this.alpha;
        ctx.beginPath();
        for (let i = 0; i < this.trail.length; i++) {
            ctx.lineTo(this.trail[i].x, this.trail[i].y);
        }
        ctx.strokeStyle = this.color;
        ctx.lineWidth = 0.5;
        ctx.stroke();
        ctx.closePath();
    }

    reset() {
        this.x = Math.random() * canvas.width;
        this.y = Math.random() * canvas.height;
        this.size = Math.random() * 2 + 1;
        this.speedX = (Math.random() - 0.5) * 4;
        this.speedY = (Math.random() - 0.5) * 4;
        this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
        this.alpha = 1;
        this.life = 1;
        this.decay = Math.random() * 0.01 + 0.01;
        this.trail = [];
        this.lifeTime = 0;
    }
}

function init() {
    particlesArray = [];
    for (let i = 0; i < numberOfParticles; i++) {
        particlesArray.push(new Particle());
    }
}

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    for (let particle of particlesArray) {
        particle.update();
        particle.draw();
    }

    requestAnimationFrame(animate);
}

window.addEventListener('resize', function() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    init();
});

window.addEventListener('mousemove', function(event) {
    mouse.x = event.x;
    mouse.y = event.y;
});

window.addEventListener('mouseout', function() {
    mouse.x = undefined;
    mouse.y = undefined;
});

window.addEventListener('click', function(event) {
    for (let i = 0; i < 30; i++) {
        const angle = Math.random() * 2 * Math.PI;
        const distance = Math.random() * 50;
        const x = event.x + Math.cos(angle) * distance;
        const y = event.y + Math.sin(angle) * distance;
        particlesArray.push(new Particle(x, y, 1));
    }
});

init();
animate();
</script>
</html>

四:彩色拖尾特效

1.效果展示
2.HTML完整代码
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1234</title>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
            background-color: #000;
        }

        #trail-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
        }

        .particle {
            position: absolute;
            width: 3px; /* 减小粒子大小 */
            height: 3px;
            background-color: #fff;
            border-radius: 50%;
            opacity: 1;
            transform: translate(-50%, -50%);
            pointer-events: none;
            mix-blend-mode: screen;
        }

        /* 为粒子添加一个更快的淡出动画 */
        @keyframes fadeOut {
            0% { opacity: 1; }
            100% { opacity: 0; }
        }

        .particle.fade {
            animation: fadeOut 0.5s ease-out forwards; /* 缩短动画持续时间 */
        }
    </style>
</head>
<body>
    <div id="trail-container"></div>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const trailContainer = document.getElementById('trail-container');
            const particles = [];

            // 监听鼠标移动事件
            document.addEventListener('mousemove', (e) => {
                // 在鼠标位置创建粒子
                createParticle(e.clientX, e.clientY);
            });

            // 创建粒子
            function createParticle(x, y) {
                const particle = document.createElement('div');
                particle.classList.add('particle');
                particle.style.left = `${x}px`;
                particle.style.top = `${y}px`;
                // 使用随机颜色或固定颜色
                particle.style.backgroundColor = getRandomColor();
                trailContainer.appendChild(particle);
                particles.push(particle);

                // 几乎立即给粒子添加淡出动画
                setTimeout(() => {
                    particle.classList.add('fade');
                    // 动画结束后移除粒子
                    particle.addEventListener('animationend', () => {
                        particle.remove();
                        particles.splice(particles.indexOf(particle), 1);
                    });
                }, 100); // 非常短的延迟,几乎立即开始淡出
            }

            // 获取随机颜色
            function getRandomColor() {
                const letters = '0123456789ABCDEF';
                let color = '#';
                for (let i = 0; i < 6; i++) {
                    color += letters[Math.floor(Math.random() * 16)];
                }
                return color;
            }

            // 定期清理,动画结束后粒子会自动移除
            setInterval(() => {
                particles.forEach(particle => {
                    if (particle.classList.contains('fade')) {
                        particle.remove();
                        particles.splice(particles.indexOf(particle), 1);
                    }
                });
            }, 1000);
        });
    </script>
</body>
</html>

五:彩色粒子收回特效

1.效果展示
2.HTML完整代码
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Enhanced Particle System with Gravity and Wind</title>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        #particleCanvas {
            display: block;
            width: 100%;
            height: 100%;
            background: linear-gradient(to bottom, #000000, #111111);
        }
    </style>
</head>
<body>
    <canvas id="particleCanvas"></canvas>
    <script>
        const canvas = document.getElementById('particleCanvas');
        const ctx = canvas.getContext('2d');

        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        const particlesArray = [];
        const numberOfParticles = 500; 
        const mouse = {
            x: undefined,
            y: undefined,
        };

        const gravity = 0.05; 
        const wind = {
            x: 0.01, 
            y: 0,
        };

        class Particle {
            constructor() {
                this.x = Math.random() * canvas.width;
                this.y = Math.random() * canvas.height;
                this.size = Math.random() * 5 + 1; 
                this.speedX = (Math.random() - 0.5) * 4; 
                this.speedY = (Math.random() - 0.5) * 4;
                this.color = 'hsl(' + Math.floor(Math.random() * 360) + ', 100%, 50%)';
                this.alpha = 1; 
                this.targetX = this.x;
                this.targetY = this.y;
                this.ease = 0.05;
            }

            update() {
                if (mouse.x !== undefined && mouse.y !== undefined) {
                    this.targetX = mouse.x;
                    this.targetY = mouse.y;
                }
                this.x += (this.targetX - this.x) * this.ease;
                this.y += (this.targetY - this.y) * this.ease;

                this.speedY += gravity;
                this.speedX += wind.x;

                if (this.x > canvas.width || this.x < 0) this.speedX *= -1;
                if (this.y > canvas.height) this.y = canvas.height, this.speedY *= -0.7; 
                this.alpha -= 0.01; 
                if (this.alpha < 0) this.alpha = 0;

                this.draw();
            }

            draw() {
                ctx.globalAlpha = this.alpha;
                ctx.fillStyle = this.color;
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                ctx.closePath();
                ctx.fill();
            }
        }

        function init() {
            for (let i = 0; i < numberOfParticles; i++) {
                particlesArray.push(new Particle());
            }
        }

        function animate() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            for (let particle of particlesArray) {
                particle.update();
            }

            requestAnimationFrame(animate);
        }

        window.addEventListener('resize', function() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        });

        window.addEventListener('mousemove', function(event) {
            mouse.x = event.x;
            mouse.y = event.y;
        });

        window.addEventListener('mouseout', function() {
            mouse.x = undefined;
            mouse.y = undefined;
        });

        window.addEventListener('click', function() {
            for (let i = 0; i < 20; i++) {
                particlesArray.push(new Particle());
            }
        });

        init();
        animate();
    </script>
</body>
</html>

六:彩色粒子交互特效

1.效果展示
2.HTML完整代码
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>彩色粒子交互特效</title>
</head>
<body>
<script>
    !(function () {
      function n(n, e, t) {
        return n.getAttribute(e) || t;
      }
      function e(n) {
        return document.getElementsByTagName(n);
      }
      function t() {
        var t = e("script"),
          o = t.length,
          i = t[o - 1];
        return {
          l: o,
          z: n(i, "zIndex", -1),
          o: n(i, "opacity", 0.6),
          c: n(i, "color", "0,255,0"), 
          n: n(i, "count", 400), // 粒子的数量
        };
      }

      function o() {
        (a = m.width =
          window.innerWidth ||
          document.documentElement.clientWidth ||
          document.body.clientWidth),
          (c = m.height =
            window.innerHeight ||
            document.documentElement.clientHeight ||
            document.body.clientHeight);
      }
      function i() {
        r.clearRect(0, 0, a, c);
        var n, e, t, o, m, l;
        s.forEach(function (particle, index) {
          for (
            particle.x += particle.xa,
            particle.y += particle.ya,
            particle.xa *= particle.x > a || particle.x < 0 ? -1 : 1,
            particle.ya *= particle.y > c || particle.y < 0 ? -1 : 1,
            // 使用粒子的颜色属性进行绘制
            r.fillStyle = particle.color,
            r.fillRect(particle.x - 0.5, particle.y - 0.5, 1, 1),
            e = index + 1;
            e < u.length;
            e++
          ) {
            (n = u[e]),
              null !== n.x &&
              null !== n.y &&
              ((o = particle.x - n.x),
                (m = particle.y - n.y),
                (l = o * o + m * m),
                l < n.max &&
                (n === y &&
                  l >= n.max / 2 &&
                  ((particle.x -= 0.03 * o), (particle.y -= 0.03 * m)),
                  (t = (n.max - l) / n.max),
                  r.beginPath(),
                  (r.lineWidth = t / 2),
                  // 连线颜色和粒子颜色一致
                  r.strokeStyle = particle.color,
                  r.moveTo(particle.x, particle.y),
                  r.lineTo(n.x, n.y),
                  r.stroke()));
          }
        }),
          x(i);
      }
      var fixedColors = [
        "rgba(255, 0, 0, 1.0)",   // 红色
        "rgba(0, 255, 0, 1.0)",   // 绿色
        "rgba(0, 0, 255, 1.0)",   // 蓝色
        "rgba(255, 255, 0, 1.0)", // 黄色
        "rgba(0, 255, 255, 0.8)", // 青色
        "rgba(255, 0, 255, 0.8)", // 紫色
        "rgba(255, 165, 0, 0.8)", // 橙色
        "rgba(127, 255, 212, 1.0)",
          "rgba(0, 255, 127, 1.0)"
      ];
      var a,
        c,
        u,
        m = document.createElement("canvas"),
        d = t(),
        l = "c_n" + d.l,
        r = m.getContext("2d"),
        x =
          window.requestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame ||
          window.oRequestAnimationFrame ||
          window.msRequestAnimationFrame ||
          function (n) {
            window.setTimeout(n, 1e3 / 45);
          },
        w = Math.random,
        y = { x: null, y: null, max: 2e4 };
      (m.id = l),
        (m.style.cssText =
          "position:fixed;top:0;left:0;z-index:" + d.z + ";opacity:" + d.o),
        e("body")[0].appendChild(m),
        o(),
        (window.onresize = o),
        (window.onmousemove = function (n) {
          (n = n || window.event), (y.x = n.clientX), (y.y = n.clientY);
        }),
        (window.onmouseout = function () {
          (y.x = null), (y.y = null);
        });

        //固定颜色
        for (var s = [], f = 0; d.n > f; f++) {
        var h = w() * a,
          g = w() * c,
          v = 2 * w() - 1,
          p = 2 * w() - 1,
          // 从固定颜色数组中随机选择一个颜色
          color = fixedColors[Math.floor(Math.random() * fixedColors.length)];
        s.push({ x: h, y: g, xa: v, ya: p, max: 6e3, color: color }); // 使用选定的固定颜色
      }

      (u = s.concat([y])),
        setTimeout(function () {
          i();
        }, 100);
    })();
  </script>
</body>
</html>
相关推荐
正小安5 分钟前
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
前端·vite
向宇it9 分钟前
【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么、主流的游戏引擎、为什么选择Unity
开发语言·unity·c#·游戏引擎
是娜个二叉树!26 分钟前
图像处理基础 | 格式转换.rgb转.jpg 灰度图 python
开发语言·python
Schwertlilien29 分钟前
图像处理-Ch5-图像复原与重建
c语言·开发语言·机器学习
liuyunshengsir33 分钟前
Squid代理服务器的安装使用
开发语言·php
暴富的Tdy33 分钟前
【CryptoJS库AES加密】
前端·javascript·vue.js
neeef_se33 分钟前
Vue中使用a标签下载静态资源文件(比如excel、pdf等),纯前端操作
前端·vue.js·excel
m0_7482356139 分钟前
web 渗透学习指南——初学者防入狱篇
前端
℘团子এ40 分钟前
js和html中,将Excel文件渲染在页面上
javascript·html·excel
只做开心事41 分钟前
C++之红黑树模拟实现
开发语言·c++