svg实现线条绘制三角canvas动画效果代码
代码语言:html
所属分类:动画
代码描述:svg实现线条绘制三角canvas动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> document, body { margin: 0; min-height: 100vh; } body { align-items: center; display: flex; justify-content: center; } #container { align-items: center; display: flex; flex-direction: column; } #container > :first-child { cursor: pointer; } button { max-width: 200px; margin-top: 10px; } canvas, svg { width: 100vw; height: 100vh; } </style> </head> <body > <div id="container"></div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/svg.min.js"></script> <script type="module"> import { Vec2 } from 'https://cdn.skypack.dev/wtc-math'; console.clear(); const config = { drawingType: 1, dimensions: (new Vec2(window.innerWidth, window.innerHeight)).scale(2), breakRun: 2000, maxDepth: 12, maxPerRun: 100, insertType: 1, randomType: 0 }; const vars = { drawing: null, i:0, running: true, triangles: [] } const setup = () => { vars.running = false; setTimeout(() => { vars.running = true; vars.triangles = []; config.insertType = Math.floor(Math.random() * 3); config.randomType = Math.floor(Math.random() * 3); vars.i=0; document.querySelector('#container').innerHTML = ''; vars.drawing = new Drawing(config.drawingType).addTo('#container').size(config.dimensions); document.body.querySelector('#container>:first-child').addEventListener('click', () => { setup(); }); draw(); }, 100); }; window.addEventListener('resize', () => { config.dimensions = ( new Vec2(window.innerWidth, window.innerHeight)).scale(2) setup(); }); let depth = 0; const ts = [ ['a', 'b'], ['b', 'c'], ['c', 'a'] ]; const drawStep = () => { if(!vars.running) return; if(vars.i > 2000) return; let newTriangles = []; vars.triangles.forEach((triangle,i) => { if(i>config.breakRun) { // newTriangles.splice(0,0,triangle); return; } vars.drawing.polygon(triangle.points); let c = triangle.randomCentroid; if(config.randomType == 0) { c = triangle.centroid; } // vars.drawing.circle(c, 5); if(triangle.depth < config.maxDepth) { ts.forEach(t => { const tr = new Triangle(triangle[t[0]], triangle[t[1]], c); tr.depth=triangle.depth+1; newTriangles.push(tr); }); } }); if(config.insertType === 0) { if(vars.triangles.length>config.breakRun) newTriangles = vars.triangles.splice(config.breakRun).concat(newTriangles); } else if(config.insertType === 1) { if(vars.triangles.length>config.breakRun) newTriangles = vars.triangles.splice(config.breakRun).reverse().concat(newTriangles); } else { newTriangles = newTriangles.concat(vars.triangles.splice(config.breakRun)); } vars.triangles = newTriangles; vars.i++; requestAnimationFrame(drawStep); } let interval; const draw = () => { vars.drawing.linewidth = 1; vars.drawing.fill = "#333"; vars.drawing.rect(new Vec2(0,0), config.dimensions); vars.drawing.linewidth = 1; vars.drawing.fill = null; vars.drawing.stroke = 'rgba(255,255,255,.02)' const r = Math.min(config.dimensions.x, config.dimensions.y) * .6; const offset = r * 0.2333; const points = []; for(let i = 0.; i < Math.PI * 2; i += Math.PI * 2. / 3.) { points.push( new Vec2(Math.cos(i+Math.PI*.5) * r + config.dimensions.x / 2, Math.sin(i+Math.PI*.5) * r + config.dimensions.y / 2 - offset) ); } const t = new Triangle(...points); t.depth=0; vars.triangles.push(t); drawStep(); } class Triangle { #points constructor(a, b, c) { this.points = [a, b, c]; } set points(p) { if(p.reduce((a, c) => c instanceof Vec2 ? a+1 : 0, 0) === 3) this.#points = p; } get points() { return this.#points || []; } get a() { return this.#points[0]; } get b() { return this.#points[1]; } get c() { return this.#points[2]; } get circumcenter() { const d = this.b.subtractNew(this.a); const e = this.c.subtractNew(this.a); const bl = d.x * d.x + d.y * d.y; const cl = e.x * e.x + e.y * e.y; const ds = 0.5 / (d.x * e.y - d.y * e.x); return new Vec2( this.a.x + (e.y * bl - d.y * cl) * ds, this.a.y + (d.x * cl - e.x * bl) * ds ); } get randomCentroid() { let a = floatRandomBetween(.2,1.8); let b = floatRandomBetween(.2,1.8); let c = floatRandomBetween(.2,1.8); let abc = a+b+c; const f = (3-abc)/3; a += f; b += f; c += f; return this.a.scaleNew(a).add(this.b.scaleNew(b)).add(this.c.scaleNew(c)).divideScalar(3); } get centroid() { const a = floatRandomBetween(.5,1.5); const b = floatRandomBetween(.5,1.5); const c = floatRandomBetween(.5,1.5); const abc = a+b+c; return this.a.addNew(this.b).add(this.c).divideScalar(3); } get isComplete() { return this.points.reduce((a, c) => c instanceof Vec2 ? a+1 : 0, 0) === 3; } get segments() { return [ { a: this.a, b: this.b, c: this.c, segment: this.a.subtractNew(this.b) }, { .........完整代码请登录后点击上方下载按钮下载查看
网友评论0