html、css、js粒子特效——前端

html、css、js粒子特效——前端

看看效果图
在这里插入图片描述
首先是html结构
使用canvas设置一个画布


        <canvas width="500px" height="500px" id="content">
            您的浏览器版本过低,请升级浏览器!
        </canvas>

下面是js
背景粒子`

et items = document.getElementsByTagName('li')
    let bg = document.getElementById('bg')
    for (let i = 0; i < items.length; i++) {
        let r = parseInt(Math.random() * 30)
        let u = parseInt(Math.random() * 10 + 6)

        let e = Math.random()

        items[i].style.left = r * bg.offsetWidth / 30 + 'px'


        items[i].style.animationDelay = e * 20 + 's'
        items[i].style.animationDuration = u * 2 + 's'

    }

获取画布

var canvas = document.querySelector("#content");
    var context = canvas.getContext("2d");

    // 动画展示范围
    var w = 500,
        h = 500;


    // 封装函数工具
    // 画点
    function drawCircle(x, y, r, color) {
        // 
        context.beginPath();
        context.fillStyle = color;
        context.arc(x, y, r, Math.PI / 180 * 0, Math.PI / 180 * 360);
        context.fill();
    }

    // 画粒子的图像和方法
    class ball {

        constructor(dx, dy) {
            // 从随机位置向dx,dy移动,速度由time决定 


            this.x = range(w);
            this.y = range(h)


            // 目标点坐标
            this.dx = dx;
            this.dy = dy;

            // 总距离
            this.initialX = this.dx - this.x
            this.initialY = this.dy - this.y

            // 时间
            this.time = 100

            // 粒子半径和颜色
            this.r = 1.5;
            this.color = colorR();

        }

画出粒子的轨迹

 draw(count) {
            // 后面是速度方程 时间单位为1
            // this.x += this.initialX /100;
            // this.y += this.initialY /100;
            this.x += this.initialX * 2 / this.time * (1 - count / this.time);
            this.y += this.initialY * 2 / this.time * (1 - count / this.time);
            drawCircle(this.x, this.y, this.r, this.color);
        }
    }

设置随机数、随机颜色、筛选粒子位置、筛选有效像素点

/ 生成随机数
    function range(i) {
        return Math.random() * i;
    }

    function intR(i) {
        return Math.floor(Math.random() * i)
    }
    // 随机颜色
    function colorR() {
        let key = range(1)
        if (key > 0.3) {
            return '#fff'
        } else return '#838383'
    }
    // 筛选粒子位置

    function getImgData(img) {
        context.clearRect(0, 0, w, h);
        context.drawImage(img, 0, 0, 500, 500);

        var copy = context.getImageData(0, 0, 500, 500); // 获取像素点数据            

        img.ballArr = [];

        // 筛选有效像素点

        context.clearRect(0, 0, w, h);

        for (var y = 0; y < h; y += 8) {
            for (var x = 0; x < w; x += 8) {
                // 像素点的序号
                var index = x + y * w;
                // 帅选条件为透明度
                var a = copy.data[index * 4 + 3];
                if (a > 100) {
                    // 符合条件条件的坐标绘制粒子

                    let bal = new ball(x, y);

                    img.ballArr.push(bal);
                    // bal.draw();
                };
            }
        }
    }

动画部分

/ 设置动画
    function animateBall(img) {
        var count = 1;
        clearInterval(t1)
        t1 = setInterval(function () {
            // console.log(ballArr);
            context.clearRect(0, 0, w, h);
            for (var i = 0; i < img.ballArr.length; i++) {
                img.ballArr[i].draw(count);
            }
            if (count == 100) {
                clearInterval(t1);

            }
            count++;
        }, 30)
    }
    // 开始动画
    function start(a, b, t) {
        setTimeout(() => {
            relateTow(a, b)
            animateBall(a)

        }, 4000 * t)
    }
    //连接两个数组
    function relateTow(a, b) {
        for (let i = 0; i < a.ballArr.length; i++) {
            let v = intR(b.ballArr.length)
            a.ballArr[i].x = b.ballArr[v].dx
            a.ballArr[i].initialX = a.ballArr[i].dx - a.ballArr[i].x
            a.ballArr[i].y = b.ballArr[v].dy
            a.ballArr[i].initialY = a.ballArr[i].dy - a.ballArr[i].y
        }
    }

绘图
绘图,这里要用img.onload,且所有的步骤都要写在里面,否则读取不到画布像素,值都为0

var img1 = new Image();
    var img2 = new Image();
    var img3 = new Image();
    var img4 = new Image();
    var img5 = new Image();
    var img6 = new Image();
    var img7 = new Image();

    img1.src = './images/e740e7973ba8559164ed75529ff6f946efd001fc.png@942w_942h_progressive.webp'
    img2.src = './images/916637ae86ff9365700b7f6cf13148e1a4282388.png@942w_942h_progressive.webp'
    img3.src = './images/22d926f0f1e11fb36a69d8393b3e6955448d0231.png@942w_942h_progressive.webp'
    img4.src = './images/3fe9d2cc6a26e765b04450eafedcccc50e7f3a95.png@942w_942h_progressive.webp'
    img5.src = './images/4a2271098cab8382a1d6bc39ceaa9cf6596fa42e.png@942w_942h_progressive.webp'
    img6.src = './images/a555d53276872ec8e04aae88cecda7ca50b2608d.png@942w_942h_progressive.webp'
    img7.src = './images/b5f7d2d2e1d84e998ce71be55e886d74fc7566b0.png@942w_942h_progressive.webp'

这里的图片全是我从网络中寻找的,大家可以自习替换成想要的

最后设置定时器,就算大功告成

var t1 //定时器


    // 获取所有的图形,粒子位置信息
    img1.onload = function () {
        getImgData(img1)
    }
    img2.onload = function () {
        getImgData(img2)
    }
    img3.onload = function () {
        getImgData(img3)
    }
    img4.onload = function () {
        getImgData(img4)
    }
    img5.onload = function () {
        getImgData(img5)
    }
    img6.onload = function () {
        getImgData(img6)
    }
    img7.onload = function () {
        getImgData(img7)
    }

    // 等待图片绘制后开始
    setTimeout(() => {
        const target = () => {
            start(img1, img7, 0)
            start(img2, img1, 1)
            start(img3, img2, 2)
            start(img4, img3, 3)
            start(img5, img4, 4)
            start(img6, img5, 5)
            start(img7, img6, 6)
            return target
        }
        setInterval(target(), 28000)
    }, 100)
}

至此,js部分结束

css样式表

* {
    margin: 0;
    padding: 0;
}

body {
    position: relative;
    width: 100%;
    height: 100vh;
    overflow: hidden;
}

#bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgb(44, 44, 44);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;


}

canvas {
    /* border: 1px solid #838383; */
    position: relative;
    top: -20px;
    display: block;

}


#lizi {
    position: absolute;
    width: 100%;
    height: 100vh;
}

li {
    position: absolute;
    top: 105%;
    left: 0;
    width: 4px;
    height: 4px;
    background-color: rgb(253, 253, 253);
    border-radius: 50%;
    filter: blur(2px);
    list-style: none;

    animation: animate linear infinite;

}

@keyframes animate {
    0% {
        top: 100%;

    }

    100% {
        top: 0%;

    }
}

#decrition {
    position: relative;
    width: 300px;
    height: 5px;
    border-radius: 50%;
    filter: blur(1px);
    background-color: rgb(49, 49, 49);
    animation: animate2 3.5s linear infinite;
}

@keyframes animate2 {
    0% {
        background-color: rgb(49, 49, 49);

    }

    50% {
        background-color: rgb(119, 119, 119);
    }

    100% {
        background-color: rgb(49, 49, 49);

    }
}

大功告成

  • 9
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄东林檎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值