html5实现3d粒子旋转,HTML5 Canvas三维空间中粒子球体嵌套旋转动画

JavaScript

语言:

JaveScriptBabelCoffeeScript

确定

//------------------

var stats = new Stats();

stats.showPanel(1);

document.body.appendChild(stats.dom);

//------------------

var canvas = document.getElementById("canvas");

var ctx = canvas.getContext("2d");

var cw = (canvas.width = 500),

cx = cw / 2;

var ch = (canvas.height = 500),

cy = ch / 2;

var m = {

x: 0,

y: 0

};

var target = {

x: 0,

y: 0

};

var speed = 0.0005;

var easing = 0.90;

var frames = 0;

var balls = [];

var vp = {

x: cx,

y: cy

}; //vanishing point

var fl = 250; // focal length

function Ball(R) {

this.R = R;

this.r = .04 * this.R;

// 3D position

this.pos = spherePointPicking(this.R)

// 2D position

this.x = this.pos.x + cx;

this.y = this.pos.y + cy;

this.a = {

x: 0,

y: 0

};

this.scale = {

x: 1,

y: 1

};

this.c = oGrd(this.r / 2, 210);

this.rotateX = function(angle) {

var cos = Math.cos(angle);

var sin = Math.sin(angle);

var y1 = this.pos.y * cos - this.pos.z * sin;

var z1 = this.pos.z * cos + this.pos.y * sin;

this.pos.y = y1;

this.pos.z = z1;

};

this.rotateY = function(angle) {

var cos = Math.cos(angle);

var sin = Math.sin(angle);

var x1 = this.pos.x * cos - this.pos.z * sin;

var z1 = this.pos.z * cos + this.pos.x * sin;

this.pos.x = x1;

this.pos.z = z1;

};

this.draw3D = function() {

if (this.pos.z > -fl) {

var scale = fl / (fl - this.pos.z);

this.scale = {

x: scale,

y: scale

};

this.x = vp.x + this.pos.x * scale;

this.y = vp.y + this.pos.y * scale;

this.visible = true;

} else {

this.visible = false;

}

};

this.draw2D = function() {

ctx.save();

ctx.translate(this.x, this.y);

ctx.scale(this.scale.x, this.scale.y);

ctx.beginPath();

ctx.fillStyle = this.c;

ctx.fillRect(0, 0, this.r, this.r);

ctx.restore();

};

}

for (var i = 0; i < 1000; i++) {

balls.push(new Ball(150));

balls.push(new Ball(75));

}

function Draw() {

t = new Date().getTime() / 127;

stats.begin();

ctx.clearRect(0, 0, cw, ch);

frames += .1;

//t = new Date().getTime() / 127;

m.x = cx + Math.cos(t / 43 + Math.cos(t / 47 + frames)) * 8;

m.y = cy + Math.sin(t / 31 + Math.cos(t / 37 + frames)) * 8;

target.x = (m.y - vp.y) * speed;

target.y = (m.x - vp.x) * speed;

balls.map(function(b) {

b.draw3D();

});

balls.sort(function(a, b) {

return a.pos.z - b.pos.z;

});

target.x *= easing;

target.y *= easing;

balls.map(function(b) {

b.rotateX(target.x);

b.rotateY(target.y);

if (b.visible) {

b.draw2D();

}

});

stats.end();

requestId = window.requestAnimationFrame(Draw);

}

Draw();

function oGrd(r, h) {

grd = ctx.createRadialGradient(r, r, 0, r, r, r);

grd.addColorStop(0, "hsla(" + h + ",95%,95%, 1)");

grd.addColorStop(0.4, "hsla(" + h + ",95%,45%,.5)");

grd.addColorStop(1, "hsla(" + h + ", 95%, 45%, 0)");

return grd;

}

function spherePointPicking(R) {

//How to generate random points on a sphere:

//https://math.stackexchange.com/questions/1585975/how-to-generate-random-points-on-a-sphere#1586185

var u1 = Math.random();

var u2 = Math.random();

var s = Math.acos(2 * u1 - 1) - Math.PI / 2;

var t = 2 * Math.PI * u2;

return {

x: R * Math.cos(s) * Math.cos(t),

y: R * Math.cos(s) * Math.sin(t),

z: R * Math.sin(s)

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值