TEST

404动画PixiJS代码

本意在hexo测试中的废案,是个很好看的404粒子特效效果的画面,但是由于各种原因,放弃使用,搁置了代码如下:

<script src="//cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.5/pixi.min.js"></script>
<div id="yun"></div>
<script>
/**
* 404 页面
*/
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
},
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
//math2 utils
var Math2={};
Math2.random = function (t, n) {
return Math.random() * (n - t) + t
}, Math2.map = function (t, n, r, a, o) {
return (o - a) * ((t - n) / (r - n)) + a
}, Math2.randomPlusMinus = function (t) {
return t = t ? t : .5, Math.random() > t ? -1 : 1
}, Math2.randomInt = function (t, n) {
return n += 1, Math.floor(Math.random() * (n - t) + t)
}, Math2.randomBool = function (t) {
return t = t ? t : .5, Math.random() < t ? !0 : !1
}, Math2.degToRad = function (t) {
return rad = t * Math.PI / 180, rad
}, Math2.radToDeg = function (t) {
return deg = 180 / (Math.PI * t), deg
}, Math2.rgbToHex = function (t) {
function n(t) {
return ("0" + parseInt(t).toString(16)).slice(-2)
}
t = t.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
var r = n(t[1]) + n(t[2]) + n(t[3]);
return r.toUpperCase()
}, Math2.distance = function (t, n, r, a) {
return Math.sqrt((r - t) * (r - t) + (a - n) * (a - n))
};
//mouse
var mousePos={
x:0,
y:0
};
window.onmousemove = function(e) {
e = e || window.event;
var pageX = e.pageX - 300;
var pageY = e.pageY + 350;
if (pageX === undefined) {
pageX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - 300;
pageY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop + 350;
}
mousePos = {
x: pageX,
y: pageY,
};
};
var options = {
width: 1000,
height: 1000,
keyword: "404",
density: 8,
densityText: 2,
minDist: 20,
};
// initialize canvas
var canvas = document.createElement('canvas');
canvas.width = options.width;
canvas.height = options.height;
canvas.style.width = options.width/2;
canvas.style.height = options.height/2;
canvas.getContext('2d').scale(2,2)
var renderer = new PIXI.autoDetectRenderer(options.width, options.height, {
transparent: true
});
var stage = new PIXI.Container("0X000000", true);
document.getElementById("yun").appendChild(renderer.view);
renderer.view.id = "notFound";
var imageData = false;
var particles =[];
function init() {
positionParticles();
positionText();
}
function positionParticles() {
var canvas = document.createElement("canvas");
canvas.width = 500;
canvas.height = 350;
var context = canvas.getContext("2d");
context.fillStyle = "#000000";
context.font = "300px 'Arial', sans-serif";
context.fillText(options.keyword, 0, 250);
var imageData = context.getImageData(0, 0, 350, 500);
data = imageData.data;
// Iterate each row and column
for (var i = 0; i < imageData.height; i += options.density) {
for (var j = 0; j < imageData.width; j += options.density) {
// Get the color of the pixel
var color = data[((j * (imageData.width * 4)) + (i * 4)) - 1];
// If the color is black, draw pixels
if (color == 255) {
var newPar = particle();
newPar.setPosition(i, j);
particles.push(newPar);
stage.addChild(newPar);
}
}
}
}
function positionText() {
var canvas = document.createElement("canvas");
canvas.width = 400;
canvas.height = 120;
var context = canvas.getContext("2d");
context.fillStyle = "#000000";
context.font = "80px 'Arial', sans-serif";
context.fillText("Not Found", 0, 80);
var imageData = context.getImageData(0, 0, 400, 400);
data = imageData.data;
// Iterate each row and column
for (var i = 0; i < imageData.height; i += options.densityText) {
for (var j = 0; j < imageData.width; j += options.densityText) {
// Get the color of the pixel
var color = data[((j * (imageData.width * 4)) + (i * 4)) - 1];
// If the color is black, draw pixels
if (color == 255) {
var newPar = particle(true);
newPar.setPosition(i, j);
particles.push(newPar);
stage.addChild(newPar);
}
}
}
}
function particle(text) {
$this = new PIXI.Graphics();
if (text == true) {
$this.text = true;
}
$this.beginFill(0X5CC9F5);
var radius;
$this.radius = radius = $this.text ? Math.random() * 3.5 : Math.random() * 10.5;
$this.drawCircle(0, 0, radius);
$this.size = this.radius;
$this.x = -this.width;
$this.y = -this.height;
$this.free = false;
$this.timer = Math2.randomInt(0, 100);
$this.v = Math2.randomPlusMinus() * Math2.random(.5, 1);
$this.hovered = false
$this.alpha = Math2.randomInt(10, 100) / 100;
$this.vy = -5 + parseInt(Math.random() * 10) / 2;
$this.vx = -4 + parseInt(Math.random() * 8);
$this.setPosition = function(x, y) {
if ($this.text) {
$this.x = x + (options.width / 2 - 180);
$this.y = y + (options.height / 2 + 100);
} else {
$this.x = x + (options.width / 2 - 250);
$this.y = y + (options.height / 2 - 175);
}
};
return $this;
}
function update() {
renderer.render(stage);
for (i = 0; i < particles.length; i++) {
var p = particles[i];
if (mousePos.x > p.x && mousePos.x < p.x + p.size && mousePos.y > p.y && mousePos.y < p.y + p.size) {
p.hovered = true;
}
p.scale.x = p.scale.y = scale = Math.max(Math.min(2.5 - (Math2.distance(p.x, p.y, mousePos.x, mousePos.y) / 160), 160), 1);
p.x = p.x + .2 * Math.sin(p.timer * .15)
p.y = p.y + .2 * Math.cos(p.timer * .15)
p.timer = p.timer + p.v;
}
window.requestAnimationFrame(update);
}
init();
update();
</script>

修改样式: themes/yelee/source/css/_partial/article.styl,在 .article-entry 子级中加上如下样式:

注:如果没有该文件可以可另外添加
#notFound {
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%) translateX(-50%);
width: 80%;
height: auto;
}
#yun {
height: 320px;
width: 100%;
position: relative;
}
@media only screen and (max-width: 768px) {
#yun {
height: 300px;
}
#notFound {
width: 100%;
}
}
@media only screen and (max-width: 425px) {
#yun {
height: 200px;
}
#notFound {
width: 120%;
}
}

如果不想主题文件修改你添加的单页面内容,需要在站点配置文件中配置如下:

// 单个文件夹下全部文件:skip_render: test/*
// 单个文件夹下指定类型文件:skip_render: test/*.html
// 单个文件夹下全部文件以及子目录:skip_render: test/**
// 多个文件夹以及各种复杂情况:
// skip_render:
// - `test1/*.html`
// - `test2/**`
比如 skip_render: pages/** 代表 source/pages/ 目录下所有东西都不会被修改

本文信息

作者LL
发布时间
文章分类技术

版权许可

本文采用 CC BY-SA 4.0 协议授权

保留署名与相同方式共享即可转载、引用或再创作。转载时请注明出处并附上本文链接。

评论

留言系统基于 Disqus,发言前可查看 评论规则。部分网络环境可能无法正常加载。