Zhouyao's Blog

Do Something Big With Us

代码实现页面下雪效果

《代码实现页面下雪效果》

最后更新于 2017.11.14 09:41

起因

看到土豆的博客中有下雪的效果,于是也想搞一个,但是我的主题并没有使用GreenGrapes2,所以必须想个办法看看怎么调用下雪的这个效果。

在这里使用了两个方法,选哪一个都可以。

个人推荐第二种,因为第一种的确没有什么影响,不过对于强迫症来说还是比较难受的,尤其是在进行开发者模式中,对于调试者的体验来说还是比较差的。

Demo

相关资料在本文最下方。

干活

方法一

方法一是采用纯代码方法,不采用任何js和css脚本,在header.php/footer.php/single.php中均可使用,直接调用图片‘snow.png’,然后利用随机数进行屏幕的随机落下,雪花的大小为使用者感觉雪花距离自己的远近。

代码如下:

<script type="text/javascript" language="javascript">// <![CDATA[
(function() {
    function k(a, b, c) {
        if (a.addEventListener) a.addEventListener(b, c, false);
        else a.attachEvent && a.attachEvent("on" + b, c)
    }
    function g(a) {
        if (typeof window.onload != "function") window.onload = a;
        else {
            var b = window.onload;
            window.onload = function() {
                b();
                a()
            }
        }
    }
    function h() {
        var a = {};
        for (type in {
            Top: "",
            Left: ""
        }) {
            var b = type == "Top" ? "Y": "X";
            if (typeof window["page" + b + "Offset"] != "undefined") 
a[type.toLowerCase()] = window["page" + b + "Offset"];
            else {
b = document.documentElement.clientHeight ? document.documentElement: document.body;
                a[type.toLowerCase()] = b["scroll" + type]
            }
        }
        return a
    }
    function l() {
        var a = document.body,
        b;
        if (window.innerHeight) b = window.innerHeight;
        else if (a.parentElement.clientHeight) b = a.parentElement.clientHeight;
        else if (a && a.clientHeight) b = a.clientHeight;
        return b
    }
    function i(a) {
        this.parent = document.body;
        this.createEl(this.parent, a);
        this.size = Math.random() * 1500 - 1200;/**雪花大小的相关设定,均调用随机函数Math.random**/
        this.el.style.width = Math.round(this.size) + "px";
        this.el.style.height = Math.round(this.size) + "px";
        this.maxLeft = document.body.offsetWidth - this.size;
        this.maxTop = document.body.offsetHeight - this.size;
        this.left = Math.random() * this.maxLeft;
        this.top = h().top + 1;
        this.angle = 1.4 + 0.2 * Math.random();
        this.minAngle = 1.4;
        this.maxAngle = 1.6;
        this.angleDelta = 0.01 * Math.random();
        this.speed = 2 + Math.random()
    }
    var j = false;
    g(function() {
        j = true
    });
    var f = true;
    window.createSnow = function(a, b) {
        if (j) {
            var c = [],
            m = setInterval(function() {
                f && b > c.length && Math.random() 
< b * 0.0025 && c.push(new i(a)); ! f && !c.length && clearInterval(m);
                for (var e = h().top, n = l(), d = c.length - 1; d >= 0; d--) 
if (c[d]) if (c[d].top < e || c[d].top + c[d].size + 1 > e + n) {
                    c[d].remove();
                    c[d] = null;
                    c.splice(d, 1)
                } else {
                    c[d].move();
                    c[d].draw()
                }
            },
            40);
            k(window, "scroll",
            function() {
                for (var e = c.length - 1; e >= 0; e--) c[e].draw()
            })
        } else g(function() {
            createSnow(a, b)
        })
    };
    window.removeSnow = function() {
        f = false
    };
    i.prototype = {
        createEl: function(a, b) {
            this.el = document.createElement("img");
            this.el.setAttribute
("src", b + " ");/**在双引号中写入snow的地址**/
            this.el.style.position = "absolute";
            this.el.style.display = "block";
            this.el.style.zIndex = "99999";
            this.parent.appendChild(this.el)
        },
        move: function() {
            if (this.angle < this.minAngle || this.angle > this.maxAngle) 
this.angleDelta = -this.angleDelta;
            this.angle += this.angleDelta;
            this.left += this.speed * Math.cos(this.angle * Math.PI);
            this.top -= this.speed * Math.sin(this.angle * Math.PI);
            if (this.left < 0) this.left = this.maxLeft;
            else if (this.left > this.maxLeft) this.left = 0
        },
        draw: function() {
            this.el.style.top = Math.round(this.top) + "px";
            this.el.style.left = Math.round(this.left) + "px"
        },
        remove: function() {
            this.parent.removeChild(this.el);
            this.parent = this.el = null
        }
    }
})();
createSnow("", 60);/**雪花密度**/
// ]]></script>

把这段代码贴到header或footer中,如果仅仅只想在文章页中显示,粘贴到single页中就可以。

缺点:

如下图所示,采取这种类型的下雪效果,会在开发者模式的Elements中不断地刷新,会导致查看数据困难。

《代码实现页面下雪效果》

 

方法二

方法二是在TG中询问了一下土豆,先到Git上把土豆的three.js和snow.css下载下来,悄悄地偷来的还有snow.png.

头部引入snow.css,尾部引入three.js,加一个div,class为snow,然后再来那段JavaScript函数就可以了

那就开始干活吧~

在header中添加如下代码:

<link href="https://www.akillii.com/wp-content/themes/Kratos-master/snow.css" rel="stylesheet"/>

《代码实现页面下雪效果》

 

在footer中添加如下代码:

<script type="text/javascript" src="https://www.akillii.com/wp-content/themes/Kratos-master/three.js"></script>
<script type="text/javascript">
		function randomRange(t, i) {
			return Math.random() * (i - t) + t
		}
		Particle3D = function(t) {
			THREE.Particle.call(this, t),
			this.velocity = new THREE.Vector3(0, -6, 0),
			this.velocity.rotateX(randomRange( - 45, 45)),
			this.velocity.rotateY(randomRange(0, 360)),
			this.gravity = new THREE.Vector3(0, -0, 0),
			this.drag = 1
		},
		Particle3D.prototype = new THREE.Particle,
		Particle3D.prototype.constructor = Particle3D,
		Particle3D.prototype.updatePhysics = function() {
			this.velocity.multiplyScalar(this.drag),
			this.velocity.addSelf(this.gravity),
			this.position.addSelf(this.velocity)
		};
		var TO_RADIANS = Math.PI / 180;
		THREE.Vector3.prototype.rotateY = function(t) {
			cosRY = Math.cos(t * TO_RADIANS),
			sinRY = Math.sin(t * TO_RADIANS);
			var i = this.z,
			o = this.x;
			this.x = o * cosRY + i * sinRY,
			this.z = o * -sinRY + i * cosRY
		},
		THREE.Vector3.prototype.rotateX = function(t) {
			cosRY = Math.cos(t * TO_RADIANS),
			sinRY = Math.sin(t * TO_RADIANS);
			var i = this.z,
			o = this.y;
			this.y = o * cosRY + i * sinRY,
			this.z = o * -sinRY + i * cosRY
		},
		THREE.Vector3.prototype.rotateZ = function(t) {
			cosRY = Math.cos(t * TO_RADIANS),
			sinRY = Math.sin(t * TO_RADIANS);
			var i = this.x,
			o = this.y;
			this.y = o * cosRY + i * sinRY,
			this.x = o * -sinRY + i * cosRY
		};
		$(function() {
			var container = document.querySelector(".Snow");
			if (/MSIE 6|MSIE 7|MSIE 8/.test(navigator.userAgent)) {
				return
			} else {
				if (/MSIE 9|MSIE 10/.test(navigator.userAgent)) {
					$(container).css("height", $(window).height()).bind("click",
					function() {
						$(this).fadeOut(1000,
						function() {
							$(this).remove()
						})
					})
				}
			}
			var containerWidth = $(container).width();
			var containerHeight = $(container).height();
			var particle;
			var camera;
			var scene;
			var renderer;
			var mouseX = 0;
			var mouseY = 0;
			var windowHalfX = window.innerWidth / 2;
			var windowHalfY = window.innerHeight / 2;
			var particles = [];
			var particleImage = new Image();
			particleImage.src = "";//写入你的雪花图片地址
			var snowNum = 300;
			function init() {
				camera = new THREE.PerspectiveCamera(75, containerWidth / containerHeight, 1, 10000);
				camera.position.z = 1000;
				scene = new THREE.Scene();
				scene.add(camera);
				renderer = new THREE.CanvasRenderer();
				renderer.setSize(containerWidth, containerHeight);
				var material = new THREE.ParticleBasicMaterial({
					map: new THREE.Texture(particleImage)
				});
				for (var i = 0; i < snowNum; i++) {
					particle = new Particle3D(material);
					particle.position.x = Math.random() * 2000 - 1000;
					particle.position.y = Math.random() * 2000 - 1000;
					particle.position.z = Math.random() * 2000 - 1000;
					particle.scale.x = particle.scale.y = 1;
					scene.add(particle);
					particles.push(particle)
				}
				try {
					container.appendChild(renderer.domElement);
				} catch(err) {}
				document.addEventListener("mousemove", onDocumentMouseMove, false);
				setInterval(loop, 1000 / 40)
			}
			function onDocumentMouseMove(event) {
				mouseX = event.clientX - windowHalfX;
				mouseY = event.clientY - windowHalfY
			}
			function loop() {
				for (var i = 0; i < particles.length; i++) {
					var particle = particles[i];
					particle.updatePhysics();
					with(particle.position) {
						if (y < -1000) {
							y += 2000
						}
						if (x > 1000) {
							x -= 2000
						} else {
							if (x < -1000) {
								x += 2000
							}
						}
						if (z > 1000) {
							z -= 2000
						} else {
							if (z < -1000) {
								z += 2000
							}
						}
					}
				}
				camera.position.x += (mouseX - camera.position.x) * 0.005;
				camera.position.y += ( - mouseY - camera.position.y) * 0.005;
				camera.lookAt(scene.position);
				renderer.render(scene, camera)
			}
			init()
		});
		</script>
		<div id="Snow" class="Snow"></div>

在</footer>结束后插入代码块

《代码实现页面下雪效果》

这样就可以做出一模一样的下雪效果了。

注意

在第二种方法中,snow.css和three.js,权限设定均为766,文件所属和组改为www,否则会不能实现相应的代码效果。

资料分享

Github传送====>https://github.com/AKILLII/Sharing/tree/master/Snow

有问题TG,Email均可

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

− 2 = 4

This site uses Akismet to reduce spam. Learn how your comment data is processed.