canvas小练习之鼠标粒子特效

2023-11-18

<!DOCTYPE html>
<html lang="en">
<style>
    body {
        overflow: hidden;
        margin: 0px;
    }
</style>

<body>
    <canvas id="canvas"></canvas>
    <script type="text/javascript">
        // 动画兼容函数
        window.requestAnimFrame = (function () {
            return (
                window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame ||
                window.msRequestAnimationFrame ||
                function (callback) {
                    window.setTimeout(callback, 1000 / 60)      //延迟一帧执行一次绘制,每秒60帧
                }
            )
        })()

        const canvas = document.getElementById('canvas')
        canvas.height = window.innerHeight      //根据屏幕显示canvas大小
        canvas.width = window.innerWidth
        const context = canvas.getContext('2d')
        window.addEventListener('resize', resizeCanvas)

        function resizeCanvas() {       //实时调整canvas大小
            canvas.height = window.innerHeight
            canvas.width = window.innerWidth
        }

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

        // 鼠标粒子
        let warea = {
            x: null,
            y: null,
            max: 200 // 鼠标位置 和点的连线
        }
        //获取鼠标活动时的鼠标坐标
        canvas.onmousemove = (e) => {
            warea.x = e.clientX
            warea.y = e.clientY
        }
        //鼠标移出界面时清空
        canvas.onmouseout = (e) => {
            warea.x = null
            warea.y = null
        }

        // 绘制粒子
        function drawDots() {
            // 先清空
            context.clearRect(0, 0, canvas.width, canvas.height)
            context.fillStyle = 'rgba(0,43,54,1)'
            context.fillRect(0, 0, canvas.width, canvas.height)

            // 循环加载粒子
            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

                // 绘制点
                context.fillRect(dot.x - 1, dot.y - 1, 2, 2)
                context.fillStyle = 'rgba(255,218,27,1)'

                drawLine(dot, dots)
            })
        }

        /**
         * 计算距离 并连线
         * @param dot 当前点
         * @param dots 所有点
         */
        function drawLine(dot, dots) {

            var ndots = [warea].concat(dots)

            for (var i = 0; i < ndots.length; i++) {
                var item = ndots[i]

                // 过滤错误信息
                if (dot === item || item.x === null || item.y === null) continue
                // 创建变量
                let xc = dot.x - item.x,
                    yc = dot.y - item.y,
                    dis = '',
                    ratio = ''

                // 两个粒子之间的距离
                dis = Math.sqrt(xc * xc + yc * yc)

                // 判断 粒子 之间的距离
                if (dis < item.max) {

                    // 如果是鼠标,则让其他粒子向鼠标的位置移动
                    if (item === warea && dis > item.max / 10) {
                        dot.x -= xc * 0.03
                        dot.y -= yc * 0.03
                    }


                    // 计算距离比 -- 用于线 厚度
                    ratio = (item.max - dis) / item.max
                    // 画线
                    context.beginPath()
                    context.lineWidth = ratio / 2
                    context.strokeStyle = 'rgba(255,218,27,1)'
                    context.moveTo(dot.x, dot.y)
                    context.lineTo(item.x, item.y)
                    context.stroke()
                }
            }
        }




        //   drawDots()
        function animate() {        // 使用递归实现动画
            requestAnimFrame(animate)       //用递归实现定时器的功效
            drawDots()
        }
        console.log(canvas.getBoundingClientRect())
        animate()
      //
    </script>
</body>

</html>

没什么好说的,直接上代码,这算是canvas的小练习,这是修改的网上的代码,这个可以实现屏幕自适应,而且我原本找的那个代码鼠标事件是绑定在window上的,实测并不好,可能会把点全拉走

效果图:
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

canvas小练习之鼠标粒子特效 的相关文章

随机推荐

  • Entity Framework Core系列教程-2安装EF Core

    安装Entity Framework Core 这里我们将使用EF Core 3 1 因为它是长期支持版本 开发工具使用Visual Studio 2019 编写 NET Core应用程序 EF Core 3 1 支持 NET Standa
  • 华为机试题-字符串最后一个单词的长度

    计算字符串最后一个单词的长度 单词以空格隔开 字符串长度小于5000 输入描述 输入一行 代表要计算的字符串 非空 长度小于5000 输出描述 输出一个整数 表示输入字符串最后一个单词的长度 示例1 输入 hello nowcoder 复制
  • web前端笔记:html5的标签

    在HTML4 01中 lt b gt lt i gt 是视觉要素 presentationl elements 分别表示无意义的加粗 无意义的斜体 表现样式为 font weight bolder 仅仅表示 这里应该用粗体显示 或者 这里应
  • 人脸重建环境配置时的坑

    ERROR Could not install packages due to an EnvironmentError Errno 28 No space left on device 由于是docker环境 所以把 tmp目录下的文件清理
  • 《Apache MINA 2.0 用户指南》第一章:入门

    最近准备将Apache MINA 2 0 用户指南英文文档翻译给大家 但是我偶然一次百度 发现 Defonds 这位大牛已经翻译大部分文档 原文链接 http mina apache org mina project userguide c
  • [C#] 汉字转拼音,支持多音字

    这份代码大概不是严格意义上正确的 但是一般场景用用应该没问题 而且支持dotnet core public static class Pinyin region 拼音对照表 private static string py 一 yi 丁 d
  • Unity 调用系统键盘

    using System Diagnostics using UnityEngine public class KeyboardEvent MonoBehaviour private Process keyboard
  • 第十章 内部类(下)

    第十章 内部类 下 随着后面所讲的内容越来越深入 所以可能理解得比较慢了 同时这里边的文字描述和示例也越来越多 希望大家能够坚持下去 慢慢看完 相信会有所收获 当然如果像我一样一个字一个字的敲一遍 印象会更深的 不骗你 因为有的东西开始真的
  • SpringCloud Alibaba 框架背后的故事

    前言 Spring Cloud Alibaba是Spring Cloud的一个子项目 它是由阿里巴巴公司推出的 用于构建基于微服务架构的分布式应用程序的开源框架 它与Spring Cloud的其他组件 如Netflix OSS 相结合 为开
  • sqli-labs Less5-6(布尔盲注)

    目录 前言 一 Less 5 1 布尔型的注入相比前四关 思路上最大的不同就是通过对错来获取对你来说有用的信息 1 先找到注入点 2 先判断数据库长度 3 判断数据库名中的每一个字母是什么 4 同样得方法测试表名 5 根据第四步得出表名 推
  • 人性的弱点

    附 本作品来自互联网 本人不做任何负责 内容版权归作者所有 人性的弱点 by Dale Carnegie雷吟译 目录 这本书对你有十二种功用 译者序 前言 原著序 如何从这本书里获得最大效益 第一篇 待人的基本技巧 第一章 如欲采蜜 勿蹴蜂
  • QT槽函数的使用

    QT槽函数的使用 例如 在头文件中设置槽函数 public slots void OnClickedButtonEnsure void OnClickedButtonExit cpp文件 构造函数中写入 connect ui pushBut
  • STM32F103ZET6【标准库函数开发】------配置定时器参数的几个常用函数

    TIM TimeBaseInitTypeDef 基本初始化 TIM OCInitTypeDef 比较输出初始化 TIM ICInitTypeDef 输入捕获初始化 TIM BDTRInitTypeDef 断路和死区初始化 TIM TimeB
  • pycharm创建的虚拟环境为什么用conda env list命令查询不到?

    问题描述 pycharm创建的虚拟环境为什么用conda env list命令查询不到 pycharm开发环境可以创建虚拟环境 目的是为隔绝其他环境种库带来的版本干扰 但是发现一个问题 无论是在windows终端 anaconda终端 Py
  • Java课程设计-学籍信息管理系统

    一 系统分析 学生的学籍信息是记录学生的重要信息档案 如何以电子文档形式记录下学生的学籍信息是每个学校必须做的事情 该学生学籍信息管理系统就是为了方便学校记录下每一个学生的基本信息 生成电子数据库 并且能够做到查询 更改 删除 浏览等功能操
  • Unity 移动端触摸屏操作

    Unity 触屏操作 当将Unity游戏运行到IOS或Android设备上时 桌面系统的鼠标左键可以自动变为手机屏幕上的触屏操作 但如多点触屏等操作却是无法利用鼠标操作进行的 Unity的Input类中不仅包含桌面系统的各种输入功能 也包含
  • 关于类和对象

    1 面向对象是一种技术的开发模式 但是最早的时候所使用的模式是面向过程 面向对象就是一种组件化的设计思想 面向过程 指的是针对于某一问题单独提出解决方案及代码开发 面向对象 以一种组件化的形势进行代码的设计 这样开发出来的代码有一个最大的好
  • Python Tkinter实现简单文本编辑器

    下面看看如何利用Tkinter实现一个文本编辑器 语言 python 运行效果 在 Python 代码中使用 Tkinter 的简单文本编辑器应用程序 这 使用Tkinter的简单文本编辑器应用程序 是编码在 python 程序设计语言 该
  • [编写高质量代码:改善java程序的151个建议]建议103 反射访问属性或方法时将Accessible设置为true...

    转载于 https www cnblogs com akingseu p 3506576 html
  • canvas小练习之鼠标粒子特效