<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5制作ascii码表文字特效 - 网页模板</title>
<style>
body {
overflow: hidden;
background-color: #000;
}
canvas {
width: 100%;
height: 100vh;
}
</style>
</head>
<body>
<canvas></canvas><script>
window.onload = () => {
const CANVAS = document.getElementsByTagName("canvas")[0];
const CTX = CANVAS.getContext("2d");
const CHARS = [];
const MAX_CHARS = 200;
const SEPARATION = 1.5;
let ww, wh, camera;
class Vector {
constructor(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
rotate(dir, ang) {
const X = this.x;
const Y = this.y;
const Z = this.z;
const SIN = Math.sin(ang);
const COS = Math.cos(ang);
if (dir === "x") {
this.y = Y * COS - Z * SIN;
this.z = Y * SIN + Z * COS;
} else if (dir === "y") {
this.x = X * COS - Z * SIN;
this.z = X * SIN + Z * COS;
}
}
project() {
const ZP = this.z + camera.z;
const DIV = ZP / 600;
const XP = (this.x + camera.x) / DIV;
const YP = (this.y + camera.y) / DIV;
const CENTER = getCenter();
return [XP + CENTER[0], YP + CENTER[1], ZP];
}
}
class Char {
constructor(letter, pos) {
this.letter = letter;
this.pos = pos;
}
rotate(dir, ang) {
this.pos.rotate(dir, ang);
}
render() {
const PIXEL = this.pos.project();
const XP = PIXEL[0];
const YP = PIXEL[1];
const MAX_SIZE = 50;
const SIZE = (1 / PIXEL[2] * MAX_SIZE) | 0;
const BRIGHTNESS = SIZE / MAX_SIZE;
const COL = `rgba(255, 255, ${100 * BRIGHTNESS | 0 + 150}, ${BRIGHTNESS})`;
CTX.beginPath();
CTX.fillStyle = COL;
CTX.font = SIZE + "px monospace";
CTX.fillText(this.letter, XP, YP);
CTX.fill();
CTX.closePath();
}
}
function getCenter() {
return [ww / 2, wh / 2];
}
function signedRandom() {
return Math.random() - Math.random();
}
function render() {
for (let i = 0; i < CHARS.length; i++) {
CHARS[i].render();
}
}
let time = 0;
function update() {
CTX.clearRect(0, 0, ww, wh);
for (let i = 0; i < CHARS.length; i++) {
const DX = 0.005 * Math.sin(time * 0.001);
const DY = 0.005 * Math.cos(time * 0.001);
CHARS[i].rotate("x", DX);
CHARS[i].rotate("y", DY);
}
++time;
}
function loop() {
window.requestAnimationFrame(loop);
update();
render();
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
function createChars() {
for (let i = 0; i < MAX_CHARS; i++) {
const CHARACTER = String.fromCharCode((Math.random() * 93 + 34) | 0);
const X = signedRandom() * SEPARATION;
const Y = signedRandom() * SEPARATION;
const Z = signedRandom() * SEPARATION;
const POS = new Vector(X, Y, Z);
const CHAR = new Char(CHARACTER, POS);
CHARS.push(CHAR);
}
}
function setDim() {
ww = window.innerWidth;
wh = window.innerHeight;
CANVAS.width = ww;
CANVAS.height = wh;
}
function initCamera() {
camera = new Vector(0, 0, SEPARATION + 1);
}
window.onresize = setDim;
(() => {
setDim();
initCamera();
createChars();
loop();
})();
};
</script>
<div style="text-align:center;margin:50px 0; font:normal 14px/24px 'MicroSoft YaHei';">
<p>适用浏览器:360、FireFox、Chrome、Opera、傲游、搜狗、世界之窗. 不支持Safari、IE8及以下浏览器。</p>
<p>来源:<a href="http://www.moobnn.com/" target="_blank">网页模板</a></p>
</div>
</body>
</html>