目录
-
- 效果
- 代码
- 说明
效果
代码 index.html
3D canvas cube - 锐客网
src="https://www.it610.com/article/js/index.js">
index.js
var width, height;
var canvas = document.querySelector('canvas');
canvas.width = width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
canvas.height = height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var ctx = canvas.getContext('2d');
ctx.translate(canvas.width / 2, canvas.height / 2);
var points = [];
var depth = 8;
var scale = 70;
for (var x = -depth/2;
x <= depth/2;
x++) {
for (var y = -depth/2;
y <= depth/2;
y++) {
for (var z = -depth/2;
z <= depth/2;
z++) {
points.push([x * scale, y * scale, z * scale]);
}
}
}var minDistance = 1000;
var maxDistance = 2000;
var f = 500;
var rot = 0;
var direction = -1;
var distance;
ctx.fillStyle = '#333';
requestAnimationFrame(function loop() {
rot += .75;
distance = maxDistance - (maxDistance - minDistance) * Math.abs(Math.sin(rot/100));
ctx.clearRect( -width / 2, -height / 2, width, height);
var cpm = [
[f, 0, 0, 0],
[0, f, 0, 0],
[0, 0, 1, distance]
];
var rotX = getRotateY(rot);
var rotY = getRotateY(rot*2);
var rotZ = getRotateZ(rot*3);
var transformMatrix = matrixMultiply(rotY, rotZ);
transformMatrix = matrixMultiply(transformMatrix, rotX);
points
.forEach(function(point) {
var imagePoint = getImagePoint(matrixTimesVec(transformMatrix, point), cpm);
if (imagePoint[2] < 0) { return;
}var size = 5 * f / imagePoint[2];
var x = imagePoint[0] / imagePoint[2];
var y = imagePoint[1] / imagePoint[2];
ctx.beginPath();
ctx.arc(x, y, size, 0, 2 * Math.PI, true);
ctx.fill();
});
requestAnimationFrame(loop);
});
function getImagePoint(point3D, cameraProjectionMatrix) {
// make homogenous
var homogenousPoint3D = point3D.concat([1]);
return matrixTimesVec(cameraProjectionMatrix, homogenousPoint3D);
}function add(a, b) { return a + b;
}function getRotateZ(deg) {
var rad = deg * Math.PI / 180;
var cos = Math.cos(rad);
var sin = Math.sin(rad);
return[
[cos, -sin, 0],
[sin,cos, 0],
[0,0, 1]
];
}function getRotateY(deg) {
var rad = deg * Math.PI / 180;
var cos = Math.cos(rad);
var sin = Math.sin(rad);
return[
[ cos, 0, sin],
[0, 1,0],
[-sin, 0, cos]
];
}function getRotateX(deg) {
var rad = deg * Math.PI / 180;
var cos = Math.cos(rad);
var sin = Math.sin(rad);
return[
[1,0,0],
[0, cos, -sin],
[0, sin,cos]
];
}function matrixTimesVec(matrix, vec) {
return deepCopy(matrix).map(function(row) {
return row.map(function(cell, i) {
return cell * vec[i];
}).reduce(add, 0);
});
}function deepCopy(arr) {
return arr.slice(0).map(function(v) {
return Array.isArray(v) ? deepCopy(v) : v;
});
}function matrixMultiply(m1, m2) {
var m1_0 = m1[0];
var m1_1 = m1[1];
var m1_2 = m1[2];
var m2_0 = m2[0];
var m2_1 = m2[1];
var m2_2 = m2[2];
var m1_0_0 = m1_0[0];
var m1_0_1 = m1_0[1];
var m1_0_2 = m1_0[2];
var m1_1_0 = m1_1[0];
var m1_1_1 = m1_1[1];
var m1_1_2 = m1_1[2];
var m1_2_0 = m1_2[0];
var m1_2_1 = m1_2[1];
var m1_2_2 = m1_2[2];
var m2_0_0 = m2_0[0];
var m2_0_1 = m2_0[1];
var m2_0_2 = m2_0[2];
var m2_1_0 = m2_1[0];
var m2_1_1 = m2_1[1];
var m2_1_2 = m2_1[2];
var m2_2_0 = m2_2[0];
var m2_2_1 = m2_2[1];
var m2_2_2 = m2_2[2];
return [
[m1_0_0 * m2_0_0 + m1_0_1 * m2_1_0 + m1_0_2 * m2_2_0, m1_0_0 * m2_0_1 + m1_0_1 * m2_1_1 + m1_0_2 * m2_2_1, m1_0_0 * m2_0_2 + m1_0_1 * m2_1_2 + m1_0_2 * m2_2_2],
[m1_1_0 * m2_0_0 + m1_1_1 * m2_1_0 + m1_1_2 * m2_2_0, m1_1_0 * m2_0_1 + m1_1_1 * m2_1_1 + m1_1_2 * m2_2_1, m1_1_0 * m2_0_2 + m1_1_1 * m2_1_2 + m1_1_2 * m2_2_2],
[m1_2_0 * m2_0_0 + m1_2_1 * m2_1_0 + m1_2_2 * m2_2_0, m1_2_0 * m2_0_1 + m1_2_1 * m2_1_1 + m1_2_2 * m2_2_1, m1_2_0 * m2_0_2 + m1_2_1 * m2_1_2 + m1_2_2 * m2_2_2]
];
}
【html|【HTML——3d粒子特效(效果+代码)】】style.css
html, body {
width: 100%;
height: 100%;
background: linear-gradient(-135deg,
rgba(110, 90, 255, 0.23),
rgba(255, 90, 70, 0.25)
);
}
说明
另外,我也将这个特效上传到了“资源
”,包括所有代码,并且可以直接运行!欢迎各位下载!
推荐阅读
- 小小的项目|【HTML——简易 飞机大战 小游戏(效果+代码)】
- html|【HTML——彩虹马 特效(效果+代码)】
- Java|JavaScript基础
- 福昕软件与中国船级社签署框架合作协议,共建数字船舶发展新高地
- javascript|vue从零搭建一个前中后台权限管理模板
- javascript|手摸手,带你用vue撸后台 系列一(基础篇)
- 前端|Linux常用指令大全【详解】
- 前端|vant的picker组件,传值为对象数组,colunmsFieldNames属性
- 前端|javascript百炼成仙 第一章 掌握JavaScript基础1.4数据类型