雨夾雪背景特效

在這暖暖的冬天,給自己的網站加點雪花特效簡直美滋滋啊。

來給生活比個樣!

效果圖:

 

實現代碼:

<!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 style="width: 100%;height: 100%;background:#add8e6;">
    
</body>
</html>
<script>
    class Snow {
        constructor (opt = {}) {
            // 是否是雨
            this.isRain = opt.isRain || false
            // 元素
            this.el = null
            // 傾斜方向
            this.dir = opt.dir || 'r'
            // 直徑
            this.width = 0
            // 最大直徑
            this.maxWidth = opt.maxWidth || 80
            // 最小直徑
            this.minWidth = opt.minWidth || 2
            // 透明度
            this.opacity = 0
            // 水平位置
            this.x = 0
            // 重置位置
            this.y = 0
            // z軸位置
            this.z = 0
            // 水平速度
            this.sx = 0
            // 是否左右搖擺
            this.isSwing = false
            // 左右搖擺的步長
            this.stepSx = 0.02
            // 左右搖擺的正弦函數x變量
            this.swingRadian = 1
            // 左右搖擺的正弦x步長
            this.swingStep = 0.01
            // 垂直速度
            this.sy = 0
            // 最大速度
            this.maxSpeed = opt.maxSpeed || 4
            // 最小速度
            this.minSpeed = opt.minSpeed || 1
            // 快速劃過的最大速度
            this.quickMaxSpeed = opt.quickMaxSpeed || 10
            // 快速劃過的最小速度
            this.quickMinSpeed = opt.quickMinSpeed || 8
            // 快速劃過的寬度
            this.quickWidth = opt.quickWidth || 80
            // 快速劃過的透明度
            this.quickOpacity = opt.quickOpacity || 0.2
            // 窗口尺寸
            this.windowWidth = window.innerWidth
            this.windowHeight = window.innerHeight

            this.init()
        }

        // 隨機初始化屬性
        init (reset) {
            let isQuick = Math.random() > 0.8
            this.isSwing = Math.random() > 0.8
            this.width = isQuick ? this.quickWidth : Math.floor(Math.random() * this.maxWidth + this.minWidth)
            this.opacity = isQuick ? this.quickOpacity : Math.random()
            this.x = Math.floor(Math.random() * (this.windowWidth - this.width))
            this.y = Math.floor(Math.random() * (this.windowHeight - this.width))
            if (reset && Math.random() > 0.8) {
                this.x = -this.width
            } else if (reset) {
                this.y = -this.width
            }
            this.sy = isQuick ? Math.random() * this.quickMaxSpeed + this.quickMinSpeed : Math.random() * this.maxSpeed + this.minSpeed
            this.sx = this.dir === 'r' ? this.sy : -this.sy
            this.z = isQuick ? Math.random() * 300 + 200 : 0
            this.swingStep = 0.01 * Math.random()
            this.swingRadian = Math.random() * (1.1 - 0.9) + 0.9
        }

        // 設置樣式
        setStyle () {
            this.el.style.cssText = `
                position: fixed;
                left: 0;
                top: 0;
                display: block;
                width: ${this.isRain ? 1 : this.width}px;
                height: ${this.width}px;
                opacity: ${this.opacity};
                background-image: radial-gradient(#fff 0%, rgba(255, 255, 255, 0) 60%);
                border-radius: 50%;
                z-index: 9999999999999;
                pointer-events: none;
                transform: translate(${this.x}px, ${this.y}px) ${this.getRotate(this.sy, this.sx)};
            `
        }

        // 渲染
        render () {
            this.el = document.createElement('div')
            this.setStyle()
            document.body.appendChild(this.el)
        }

        move () {
            if (this.isSwing) {
                // if (this.sx >= 1 || this.sx <= -1) {
                //     this.stepSx = -this.stepSx
                // }
                // this.sx += this.stepSx
                if (this.swingRadian > 1.1 || this.swingRadian < 0.9) {
                    this.swingStep = -this.swingStep
                }
                this.swingRadian += this.swingStep
                if (this.isRain) {
                    this.x += this.sx
                } else {
                    this.x += this.sx * Math.sin(this.swingRadian * Math.PI)
                }
                this.y -= this.sy * Math.cos(this.swingRadian * Math.PI)
            } else {
                this.x += this.sx
                this.y += this.sy
            }
            // 完全離開窗口就調一下初始化方法,另外還需要修改一下init方法,因爲重新出現我們是希望它的y座標爲0或者小於0,這樣就不會又憑空出現的感覺,而是從天上下來的
            if (this.x < -this.width || this.x > this.windowWidth || this.y > this.windowHeight) {
            this.init(true)
            this.setStyle()
            }
            this.el.style.transform = `translate3d(${this.x}px, ${this.y}px, ${this.z}px) ${this.getRotate(this.sy, this.sx)}`
        }

        getRotate(sy, sx) {
            return this.isRain ? `rotate(${sx === 0 ? 0 : (90 + Math.atan(sy / sx) * (180 / Math.PI))}deg)` : ''
        }
    }

    class Snows {
        constructor(opt = {}) {
            this.num = opt.num || 100
            this.opt = opt
            this.snowList = []
            this.createSnows()
            this.moveSnow()
        }
        createSnows () {
            this.snowList = []
            for (let i = 0; i < this.num; i++) {
                let snow = new Snow(this.opt)
                snow.render()
                this.snowList.push(snow)
            }
        }
        moveSnow () {
            window.requestAnimationFrame(() => {
                this.snowList.forEach((item) => {
                    item.move()
                })
                this.moveSnow()
            })
        }
    }
    new Snows({
        isRain: true,
        num: 300,
        maxSpeed: 15
    })
    new Snows({
        isRain: false,
        num: 150
    })
</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", .5),
            c: n(i, "color", "0,0,0"),
            n: n(i, "count", 99)
        }
    }
    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(i, x) {
            for (i.x += i.xa, i.y += i.ya, i.xa *= i.x > a || i.x < 0 ? -1 : 1, i.ya *= i.y > c || i.y < 0 ? -1 : 1, r.fillRect(i.x - .5, i.y - .5, 1, 1), e = x + 1; e < u.length; e++) n = u[e],
            null !== n.x && null !== n.y && (o = i.x - n.x, m = i.y - n.y, l = o * o + m * m, l < n.max && (n === y && l >= n.max / 2 && (i.x -= .03 * o, i.y -= .03 * m), t = (n.max - l) / n.max, r.beginPath(), r.lineWidth = t / 2, r.strokeStyle = "rgba(" + d.c + "," + (t + .2) + ")", r.moveTo(i.x, i.y), r.lineTo(n.x, n.y), r.stroke()))
        }),
        x(i)
    }
    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;
        s.push({
            x: h,
            y: g,
            xa: v,
            ya: p,
            max: 6e3
        })
    }
    u = s.concat([y]),
    setTimeout(function() {
        i()
    },
    100)
} ();

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章