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