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]]] } } return isc } TruncatedOctahedron = ls => { let shp = [], a = [] mind = 6e6 for(let i=6;i--;){ X = S(p=Math.PI*2/6*i+Math.PI/6)*ls Y = C(p)*ls Z = 0 if(Y<mind) mind = Y a = [...a, [X, Y, Z]] } let theta = .6154797086703867 a.map(v=>{ X = v[0] Y = v[1] - mind Z = v[2] R(0,theta,0) v[0] = X v[1] = Y v[2] = Z+1.5 }) b = JSON.parse(JSON.stringify(a)).map(v=>{ v[1] *= -1 return v }) shp = [...shp, a, b] e = JSON.parse(JSON.stringify(shp)).map(v=>{ v.map(q=>{ X = q[0] Y = q[1] Z = q[2] R(0,0,Math.PI) q[0] = X q[1] = Y q[2] = Z }) return v }) shp = [...shp, ...e] e = JSON.parse(JSON.stringify(shp)).map(v=>{ v.map(q=>{ X = q[0] Y = q[1] Z = q[2] R(0,0,Math.PI/2) q[0] = X q[1] = Y q[2] = Z }) return v }) shp = [...shp, ...e] coords = [ [[3,1],[4,3],[4,4],[3,2]], [[3,4],[3,3],[2,4],[6,2]], [[1,4],[0,3],[0,4],[4,2]], [[1,1],[1,2],[6,4],[7,3]], [[3,5],[7,5],[1,5],[3,0]], [[2,5],[6,5],[0,5],[4,5]] ] a = [] coords.map(v=>{ b = [] v.map(q=>{ X = shp[q[0]][q[1]][0] Y = shp[q[0]][q[1]][1] Z = shp[q[0]][q[1]][2] b = [...b, [X,Y,Z]] }) a = [...a, b] }) shp = [...shp, ...a] return shp.map(v=>{ v.map(q=>{ q[0]/=3 q[1]/=3 q[2]/=3 q[0]*=ls q[1]*=ls q[2]*=ls }) return v }) } Torus = (rw, cl, ls1, ls2, parts=1, twists=0, part_spacing=1.5) => { t_ = C(t)*8 let ret = [], tx=0, ty=0, tz=0, prl1 = 0, p2a = 0, prl2=0, p2b = 0 tx1=ty1=tz1=tx2=ty2=tz2=0 for(let m=parts;m--;){ avgs = Array(rw).fill().map(v=>[0,0,0]) for(j=rw;j--;)for(let i = cl;i--;){ if(parts>1){ ls3 = ls1*part_spacing X = S(p=Math.PI*2/parts*m) * ls3 Y = C(p) * ls3 Z = 0 R(prl1 = Math.PI*2/rw*(j-1)*twists+t_,0,0) tx1 = X ty1 = Y tz1 = Z R(0, 0, Math.PI*2/rw*(j-1)) ax1 = X ay1 = Y az1 = Z X = S(p=Math.PI*2/parts*m) * ls3 Y = C(p) * ls3 Z = 0 R(prl2 = Math.PI*2/rw*(j)*twists+t_,0,0) tx2 = X ty2 = Y tz2 = Z R(0, 0, Math.PI*2/rw*j) ax2 = X ay2 = Y az2 = Z p1a = Math.atan2(ax2-ax1,az2-az1) p2a = Math.PI/2+Math.acos((ay2-ay1)/(Math.hypot(ax2-ax1,ay2-ay1,az2-az1)+.001)) X = S(p=Math.PI*2/parts*m) * ls3 Y = C(p) * ls3 Z = 0 R(Math.PI*2/rw*(j)*twists+t_,0,0) tx1b = X ty1b = Y tz1b = Z R(0, 0, Math.PI*2/rw*j) ax1b = X ay1b = Y az1b = Z X = S(p=Math.PI*2/parts*m) * ls3 Y = C(p) * ls3 Z = 0 R(Math.PI*2/rw*(j+1)*twists+t_,0,0) tx2b = X ty2b = Y tz2b = Z R(0, 0, Math.PI*2/rw*(j+1)) ax2b = X ay2b = Y az2b = Z p1b = Math.atan2(ax2b-ax1b,az2b-az1b) p2b = Math.PI/2+Math.acos((ay2b-ay1b)/(Math.hypot(ax2b-ax1b,ay2b-ay1b,az2b-az1b)+.001)) } a = [] X = S(p=Math.PI*2/cl*i) * ls1 Y = C(p) * ls1 Z = 0 //R(0,0,-p1a) R(prl1,p2a,0) X += ls2 + tx1, Y += ty1, Z += tz1 R(0, 0, Math.PI*2/rw*j) a = [...a, [X,Y,Z]] X = S(p=Math.PI*2/cl*(i+1)) * ls1 Y = C(p) * ls1 Z = 0 //R(0,0,-p1a) R(prl1,p2a,0) X += ls2 + tx1, Y += ty1, Z += tz1 R(0, 0, Math.PI*2/rw*j) a = [...a, [X,Y,Z]] X = S(p=Math.PI*2/cl*(i+1)) * ls1 Y = C(p) * ls1 Z = 0 //R(0,0,-p1b) R(prl2,p2b,0) X += ls2 + tx2, Y += ty2, Z += tz2 R(0, 0, Math.PI*2/rw*(j+1)) a = [...a, [X,Y,Z]] X = S(p=Math.PI*2/cl*i) * ls1 Y = C(p) * ls1 Z = 0 //R(0,0,-p1b) R(prl2,p2b,0) X += ls2 + tx2, Y += ty2, Z += tz2 R(0, 0, Math.PI*2/rw*(j+1)) a = [...a, [X,Y,Z]] ret = [...ret, a] } } return ret } Cylinder = (rw, cl, ls1, ls2, caps=false) => { let a = [] for(let i=rw;i--;){ let b = [] for(let j=cl;j--;){ X = S(p=Math.PI*2/cl*j) * ls1 Y = (1/rw*i-.5)*ls2 Z = C(p) * ls1 b = [...b, [X,Y,Z]] } if(caps) a = [...a, b] for(let j=cl;j--;){ b = [] X = S(p=Math.PI*2/cl*j) * ls1 Y = (1/rw*i-.5)*ls2 Z = C(p) * ls1 b = [...b, [X,Y,Z]] X = S(p=Math.PI*2/cl*(j+1)) * ls1 Y = (1/rw*i-.5)*ls2 Z = C(p) * ls1 b = [...b, [X,Y,Z]] X = S(p=Math.PI*2/cl*(j+1)) * ls1 Y = (1/rw*(i+1)-.5)*ls2 Z = C(p) * ls1 b = [...b, [X,Y,Z]] X = S(p=Math.PI*2/cl*j) * ls1 Y = (1/rw*(i+1)-.5)*ls2 Z = C(p) * ls1 b = [...b, [X,Y,Z]] a = [...a, b] } } b = [] for(let j=cl;j--;){ X = S(p=Math.PI*2/cl*j) * ls1 Y = ls2/2 Z = C(p) * ls1 //b = [...b, [X,Y,Z]] } if(caps) a = [...a, b] return a .........完整代码请登录后点击上方下载按钮下载查看
网友评论0