canvas实现炫酷泡泡穿透彩色弹珠爆炸粒子动画效果代码
代码语言:html
所属分类:粒子
代码描述:canvas实现炫酷泡泡穿透彩色弹珠爆炸粒子动画效果代码
代码标签: canvas 炫酷 泡泡 穿透 彩色 弹珠 爆炸 粒子 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
body, html{
margin: 0;
height: 100vh;
background: linear-gradient(-45deg, #204, #000);
overflow: hidden;
}
#c{
border: 3px solid #0Ff3;
position: absolute;
background: #04f1;
left: 50%;
top: 50%;
border-radius: 10px;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<canvas id=c></canvas>
<!-- partial -->
<script >
c = document.querySelector('#c')
c.width = 1920
c.height = 1080
x = c.getContext('2d')
C = Math.cos
S = Math.sin
t = 0
T = Math.tan
rsz = window.onresize = () =>{
let b = document.body
let margin = 10
let n
let d = .5625
if(b.clientHeight/b.clientWidth > d){
c.style.width = `${(n=b.clientWidth) - margin*2}px`
c.style.height = `${n*d - margin*2}px`
}else{
c.style.height = `${(n=b.clientHeight) - margin*2}px`
c.style.width = `${n/d - margin*2}px`
}
}
rsz()
async function Draw(){
if(!t){
oX = oY = oZ = 0
Rn = Math.random
R = (Rl,Pt,Yw,m) => {
let p
M = Math
A = M.atan2
H = M.hypot
X = S(p=A(X,Z)+Yw) * (d=H(X,Z))
Z = C(p)*d
X = S(p=A(X,Y)+Rl) * (d=H(X,Y))
Y = C(p) * d
Y = S(p=A(Y,Z)+Pt) * (d=H(Y,Z))
Z = C(p)*d
if(m){
X+=oX
Y+=oY
Z+=oZ
}
}
R2=(Rl,Pt,Yw,m=false)=>{
M=Math
A=M.atan2
H=M.hypot
if(m){
X-=oX
Y-=oY
Z-=oZ
}
X=S(p=A(X,Y)+Rl)*(d=H(X,Y))
Y=C(p)*d
Y=S(p=A(Y,Z)+Pt)*(d=H(Y,Z))
Z=C(p)*d
X=S(p=A(X,Z)+Yw)*(d=H(X,Z))
Z=C(p)*d
}
Q = () => [c.width/2+X/Z*900, c.height/2+Y/Z*900]
I=(A,B,M,D,E,F,G,H)=>(K=((G-E)*(B-F)-(H-F)*(A-E))/(J=(H-F)*(M-A)-(G-E)*(D-B)))>=0&&K<=1&&(L=((M-A)*(B-F)-(D-B)*(A-E))/J)>=0&&L<=1?[A+K*(M-A),B+K*(D-B)]:0
Normal = (facet, autoFlipNormals=false, X1=0, Y1=0, Z1=0) => {
let ax = 0, ay = 0, az = 0
facet.map(q_=>{ ax += q_[0], ay += q_[1], az += q_[2] })
ax /= facet.length, ay /= facet.length, az /= facet.length
let b1 = facet[2][0]-facet[1][0], b2 = facet[2][1]-facet[1][1], b3 = facet[2][2]-facet[1][2]
let c1 = facet[1][0]-facet[0][0], c2 = facet[1][1]-facet[0][1], c3 = facet[1][2]-facet[0][2]
crs = [b2*c3-b3*c2,b3*c1-b1*c3,b1*c2-b2*c1]
d = Math.hypot(...crs)+.001
let nls = 1 //normal line length
crs = crs.map(q=>q/d*nls)
let X1_ = ax, Y1_ = ay, Z1_ = az
let flip = 1
if(autoFlipNormals){
let d1_ = Math.hypot(X1_-X1,Y1_-Y1,Z1_-Z1)
let d2_ = Math.hypot(X1-(ax + crs[0]/99),Y1-(ay + crs[1]/99),Z1-(az + crs[2]/99))
flip = d2_>d1_?-1:1
}
let X2_ = ax + (crs[0]*=flip), Y2_ = ay + (crs[1]*=flip), Z2_ = az + (crs[2]*=flip)
return [X1_, Y1_, Z1_, X2_, Y2_, Z2_]
}
async function loadOBJ(url, scale, tx, ty, tz, rl, pt, yw, recenter=true) {
let res
await fetch(url, res => res).then(data=>data.text()).then(data=>{
a=[]
data.split("\nv ").map(v=>{
a=[...a, v.split("\n")[0]]
})
a=a.filter((v,i)=>i).map(v=>[...v.split(' ').map(n=>(+n.replace("\n", '')))])
ax=ay=az=0
a.map(v=>{
v[1]*=-1
if(recenter){
ax+=v[0]
ay+=v[1]
az+=v[2]
}
})
ax/=a.length
ay/=a.length
az/=a.length
a.map(v=>{
X=(v[0]-ax)*scale
Y=(v[1]-ay)*scale
Z=(v[2]-az)*scale
R2(rl,pt,yw,0)
v[0]=X
v[1]=Y * (url.indexOf('bug')!=-1?2:1)
v[2]=Z
})
maxY=-6e6
a.map(v=>{
if(v[1]>maxY)maxY=v[1]
})
a.map(v=>{
v[1]-=maxY-oY
v[0]+=tx
v[1]+=ty
v[2]+=tz
})
b=[]
data.split("\nf ").map(v=>{
b=[...b, v.split("\n")[0]]
})
b.shift()
b=b.map(v=>v.split(' '))
b=b.map(v=>{
v=v.map(q=>{
return +q.split('/')[0]
})
v=v.filter(q=>q)
return v
})
res=[]
b.map(v=>{
e=[]
v.map(q=>{
e=[...e, a[q-1]]
})
e = e.filter(q=>q)
res=[...res, e]
})
})
return res
}
reflect = (a, n) => {
let d1 = Math.hypot(...a)+.0001
let d2 = Math.hypot(...n)+.0001
a[0]/=d1
a[1]/=d1
a[2]/=d1
n[0]/=d2
n[1]/=d2
n[2]/=d2
let dot = -a[0]*n[0] + -a[1]*n[1] + -a[2]*n[2]
let rx = -a[0] - 2 * n[0] * dot
let ry = -a[1] - 2 * n[1] * dot
let rz = -a[2] - 2 * n[2] * dot
return [-rx*d1, -ry*d1, -rz*d1]
}
geoSphere = (mx, my, mz, iBc, size) => {
let collapse=0
let B=Array(iBc).fill().map(v=>{
X = Rn()-.5
Y = Rn()-.5
Z = Rn()-.5
return [X,Y,Z]
})
for(let m=99;m--;){
B.map((v,i)=>{
X = v[0]
Y = v[1]
Z = v[2]
B.map((q,j)=>{
if(j!=i){
X2=q[0]
Y2=q[1]
Z2=q[2]
d=1+(Math.hypot(X-X2,Y-Y2,Z-Z2)*(3+iBc/40)*3)**4
X+=(X-X2)*99/d
Y+=(Y-Y2)*99/d
Z+=(Z-Z2)*99/d
}
})
d=Math.hypot(X,Y,Z)
v[0]=X/d
v[1]=Y/d
v[2]=Z/d
if(collapse){
d=25+Math.hypot(X,Y,Z)
v[0]=(X-X/d)/1.1
v[1]=(Y-Y/d)/1.1
v[2]=(Z-Z/d)/1.1
}
})
}
mind = 6e6
B.map((v,i)=>{
X1 = v[0]
Y1 = v[1]
Z1 = v[2]
B.map((q,j)=>{
X2 = q[0]
Y2 = q[1]
Z2 = q[2]
if(i!=j){
d = Math.hypot(a=X1-X2, b=Y1-Y2, e=Z1-Z2)
if(d<mind) mind = d
}
})
})
a = []
B.map((v,i)=>{
X1 = v[0]
Y1 = v[1]
Z1 = v[2]
B.map((q,j)=>{
X2 = q[0]
Y2 = q[1]
Z2 = q[2]
if(i!=j){
d = Math.hypot(X1-X2, Y1-Y2, Z1-Z2)
if(d<mind*2){
if(!a.filter(q=>q[0]==X2&&q[1]==Y2&&q[2]==Z2&&q[3]==X1&&q[4]==Y1&&q[5]==Z1).length) a = [...a, [X1*size,Y1*size,Z1*size,X2*size,Y2*size,Z2*size]]
}
}
})
})
B.map(v=>{
v[0]*=size
v[1]*=size
v[2]*=size
v[0]+=mx
v[1]+=my
v[2]+=mz
})
return [mx, my, mz, size, B, a]
}
burst = new Image()
burst.src = "//repo.bfw.wiki/bfwrepo/images/burst/burst.png"
starsLoaded = false, starImgs = [{loaded: false}]
starImgs = Array(9).fill().map((v,i) => {
let a = {img: new Image(), loaded: false}
a.img.onload = () => {
a.loaded = true
setTimeout(()=>{
if(starImgs.filter(v=>v.loaded).length == 9) starsLoaded = true
}, 0)
}
a.img.src = `//repo.bfw.wiki/bfwrepo/images/burst/star${i+1}.png`
return a
})
lineFaceI = (X1, Y1, Z1, X2, Y2, Z2, facet, autoFlipNormals=false, showNormals=false) => {
let X_, Y_, Z_, d, m, l_,K,J,L,p
let I_=(A,B,M,D,E,F,G,H)=>(K=((G-E)*(B-F)-(H-F)*(A-E))/(J=(H-F)*(M-A)-(G-E)*(D-B)))>=0&&K<=1&&(L=((M-A)*(B-F)-(D-B)*(A-E))/J)>=0&&L<=1?[A+K*(M-A),B+K*(D-B)]:0
let Q_=()=>[c.width/2+X_/Z_*900,c.height/2+Y_/Z_*900]
let R_ = (Rl,Pt,Yw,m)=>{
let M=Math, A=M.atan2, H=M.hypot
X_=S(p=A(X_,Y_)+Rl)*(d=H(X_,Y_)),Y_=C(p)*d,X_=S(p=A(X_,Z_)+Yw)*(d=H(X_,Z_)),Z_=C(p)*d,Y_=S(p=A(Y_,Z_)+Pt)*(d=H(Y_,Z_)),Z_=C(p)*d
if(m){ X_+=oX,Y_+=oY,Z_+=oZ }
}
let rotSwitch = m =>{
switch(m){
case 0: R_(0,0,Math.PI/2); break
case 1: R_(0,Math.PI/2,0); break
case 2: R_(Math.PI/2,0,Math.PI/2); break
}
}
let ax = 0, ay = 0, az = 0
facet.map(q_=>{ ax += q_[0], ay += q_[1], az += q_[2] })
ax /= facet.length, ay /= facet.length, az /= facet.length
let b1 = facet[2][0]-facet[1][0], b2 = facet[2][1]-facet[1][1], b3 = facet[2][2]-facet[1][2]
let c1 = facet[1][0]-facet[0][0], c2 = facet[1][1]-facet[0][1], c3 = facet[1][2]-facet[0][2]
let crs = [b2*c3-b3*c2,b3*c1-b1*c3,b1*c2-b2*c1]
d = Math.hypot(...crs)+.001
let nls = 1 //normal line length
crs = crs.map(q=>q/d*nls)
let X1_ = ax, Y1_ = ay, Z1_ = az
let flip = 1
if(autoFlipNormals){
let d1_ = Math.hypot(X1_-X1,Y1_-Y1,Z1_-Z1)
let d2_ = Math.hypot(X1-(ax + crs[0]/99),Y1-(ay + crs[1]/99),Z1-(az + crs[2]/99))
flip = d2_>d1_?-1:1
}
let X2_ = ax + (crs[0]*=flip), Y2_ = ay + (crs[1]*=flip), Z2_ = az + (crs[2]*=flip)
if(showNormals){
x.beginPath()
X_ = X1_, Y_ = Y1_, Z_ = Z1_
R_(Rl,Pt,Yw,1)
if(Z_>0) x.lineTo(...Q_())
X_ = X2_, Y_ = Y2_, Z_ = Z2_
R_(Rl,Pt,Yw,1)
if(Z_>0) x.lineTo(...Q_())
x.lineWidth = 5
x.strokeStyle='#f004'
x.stroke()
}
let p1_ = Math.atan2(X2_-X1_,Z2_-Z1_)
let p2_ = -(Math.acos((Y2_-Y1_)/(Math.hypot(X2_-X1_,Y2_-Y1_,Z2_-Z1_)+.001))+Math.PI/2)
let isc = false, iscs = [false,false,false]
X_ = X1, Y_ = Y1, Z_ = Z1
R_(0,-p2_,-p1_)
let rx_ = X_, ry_ = Y_, rz_ = Z_
for(let m=3;m--;){
if(isc === false){
X_ = rx_, Y_ = ry_, Z_ = rz_
rotSwitch(m)
X1_ = X_, Y1_ = Y_, Z1_ = Z_ = 5, X_ = X2, Y_ = Y2, Z_ = Z2
R_(0,-p2_,-p1_)
rotSwitch(m)
X2_ = X_, Y2_ = Y_, Z2_ = Z_
facet.map((q_,j_)=>{
if(isc === false){
let l = j_
X_ = facet[l][0], Y_ = facet[l][1], Z_ = facet[l][2]
R_(0,-p2_,-p1_)
rotSwitch(m)
let X3_=X_, Y3_=Y_, Z3_=Z_
l = (j_+1)%facet.length
X_ = facet[l][0], Y_ = facet[l][1], Z_ = facet[l][2]
R_(0,-p2_,-p1_)
rotSwitch(m)
let X4_ = X_, Y4_ = Y_, Z4_ = Z_
if(l_=I_(X1_,Y1_,X2_,Y2_,X3_,Y3_,X4_,Y4_)) iscs[m] = l_
}
})
}
}
if(iscs.filter(v=>v!==false).length==3){
let iscx = iscs[1][0], iscy = iscs[0][1], iscz = iscs[0][0]
let pointInPoly = true
ax=0, ay=0, az=0
facet.map((q_, j_)=>{ ax+=q_[0], ay+=q_[1], az+=q_[2] })
ax/=facet.length, ay/=facet.length, az/=facet.length
X_ = ax, Y_ = ay, Z_ = az
R_(0,-p2_,-p1_)
X1_ = X_, Y1_ = Y_, Z1_ = Z_
X2_ = iscx, Y2_ = iscy, Z2_ = iscz
facet.map((q_,j_)=>{
if(pointInPoly){
let l = j_
X_ = facet[l][0], Y_ = facet[l][1], Z_ = facet[l][2]
R_(0,-p2_,-p1_)
let X3_ = X_, Y3_ = Y_, Z3_ = Z_
l = (j_+1)%facet.length
X_ = facet[l][0], Y_ = facet[l][1], Z_ = facet[l][2]
R_(0,-p2_,-p1_)
let X4_ = X_, Y4_ = Y_, Z4_ = Z_
if(I_(X1_,Y1_,X2_,Y2_,X3_,Y3_,X4_,Y4_)) pointInPoly = false
}
})
if(pointInPoly){
X_ = iscx, Y_ = iscy, Z_ = iscz
R_(0,p2_,0)
R_(0,0,p1_)
isc = [[X_,Y_,Z_], [crs[0],crs[1],crs[2]]]
}
}
re.........完整代码请登录后点击上方下载按钮下载查看
网友评论0