svg模仿指纹纹理效果代码
代码语言:html
所属分类:背景
代码描述:svg模仿指纹纹理效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> document, body { background: #111122; 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; } .tracer { color: #fff; } </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'; import fitCurve from 'https://cdn.skypack.dev/fit-curves'; console.clear(); const config = { seed: 1337, drawingType: 1, dimensions: new Vec2(700, 700), nscale: .00125, sscale: 20, stepSize: 25, num: 1, r: 5, k: 8, testGridSize: 1, offset: new Vec2(10, -200), sneks: 200 }; const vars = { noise: null, grid: null, drawing: null } const setup = () => { const container = document.querySelector('#container'); config.offset.x = floatRandomBetween(-1000, 1000); config.offset.y = floatRandomBetween(-1000, 1000); config.nscale = floatRandomBetween(.000005, .002); container.innerHTML = ''; vars.drawing = new Drawing(config.drawingType).addTo('#container').size(config.dimensions); const t = document.createElement('div') t.className = 'tracer'; container.appendChild(t) vars.bluenoise = new BlueNoise({ size: config.dimensions.addNew(new Vec2(config.r*-1, config.r*-1)), offset: new Vec2(config.r*1, config.r*1), r: config.r, k: config.k }); vars.noise = new SimplexNoise(config.seed); vars.grid = new Grid({ cellSize: new Vec2(config.testGridSize, config.testGridSize), fill: -1 }); /// Create the download button // const dl = document.createElement('button'); // dl.innerText = 'download'; // dl.addEventListener('click', () => { // vars.drawing.download(); // }); // container.appendChild(dl); document.body.querySelector('#container>:first-child').addEventListener('click', () => { setup(); }); draw(); drawStep(); } let sneki = 0; const drawStep = () => { const sneks = []; if (vars.bluenoise.news.length > 0) { requestAnimationFrame(drawStep) for (let i = 0; i < config.sneks; i++) { const [p] = vars.bluenoise.news.splice(Math.floor(Math.random() * vars.bluenoise.news.length), 1.); if (!p) continue; if (p.subtractNew(config.dimensions.scaleNew(.5)).length > 200) continue; const pos = p; const dir = new Vec2(1, 0); const f = field(pos, 1., sneki+1); dir.angle = f.noise; // vars.drawing.stroke = '#ff0000AA'; // vars.drawing.circle(pos, 1); const distancebreak = 3; let cont = false; for (let x = -distancebreak*.5; x <= distancebreak*.5; x++) { for (let y = -distancebreak*.5; y <= distancebreak*.5; y++) { const offset = new Vec2(x, y); const t = vars.grid.getChildAtPosition(pos.addNew(offset)); if (t !== -1) cont = true; } } if (cont) continue; // vars.drawing.circle(pos, .5); const s = new Snek(pos, { direction: dir, maxLength: 2000, id: sneki++, distanceProjection: 5, distanceBreak: distancebreak, projectionBreakMultiplier: 0 }); sneks.push(s); // projectionBreakMultiplier: 2 // } } // for(let j = 0; j < config.lineLength; j++) { for (let i = 0; i < sneks.length; i++) { sneks[i].walkOut(); } // } // document.querySelector('.tracer').innerHTML = vars.bluenoise.news.length; for (let i = 0; i < sneks.length; i++) { vars.drawing.path(sneks[i].bezier); } } let interval; const draw = () => { vars.drawing.stroke = '#AAA'; vars.drawing.c.fillStyle = "#111122"; vars.drawing.c.fillRect(0, 0, config.dimensions.x, config.dimensions.y); vars.drawing.rect(new Vec2(0, 0), config.dimensions); vars.drawing.c.lineWidth = 1.5; while (vars.bluenoise.active.length > 0) { vars.bluenoise.step(); } } setTimeout(() => { setup(); }, 500); const ngon = (pos, r, nsides) => { const a = Math.atan2(pos.y, pos.x) + Math.PI*.5; const split = (Math.PI*2) / nsides; return pos.length * Math.cos(split * Math.floor(.5 + a / split) - a) - r; } const field = (pos, id = 1, instanceID = 0)=> { const normpos = pos.subtractNew(config.dimensions.scaleNew(.5)); const mask1 = ngon(normpos, 200, 40) < Math.random()*10; const mask2 = ngon(normpos.addNew(new Vec2(0, 50)), 250, 3) < 0.; let mask; if (!id) { if (mask2) { id = 2.; } else if (mask1) { id = 1.; } } let n; if (id == 1.) { n = vars.noise.noise2D(pos.addNew(config.offset).scale(config.nscale).array)*Math.PI; // const a = Math.atan2(normpos.y, normpos.x); // n = a - .5; } else if (id == 2.) { // const a = Math.atan2(normpos.y, normpos.x) + Math.PI * .5; // n = a + .8; const a = Math.atan2(normpos.y, normpos.x); n = a + .5; // n = noise.noise2D(pos.addNew(config.offset).scale(config.nscale).array)*Math.PI; } // let apos = pos.subtractNew(dimensions.scaleNew(.5)); // let a = Math.atan2(apos.y, apos.x) + Math.PI * .5; // const n = noise.noise2D(pos.addNew(config.offset).scale(config.nscale).array)*Math.PI; // const n = a + .8; // const mask = pos.subtractNew(dimensions.scaleNew(.5)).length < 350; // const mask = ngon(normpos, 150, 3) < 0.; return { noise: n, mask: instanceID % 3 == 0 ? true: mask1, id: id }; } class Snek { static #defaults = { grid: vars.grid, head: true, tail: true, direction: new Vec2(1, 0), maxLength: 1000, stepSize: 1, fieldID: 1, distanceBreak: 5, distanceProjection: 5, minLength: 10, id: 0, bailout: 10000, projectionBreakMultiplier: .5 }; #alive = [true, true]; /* Two alive directions per snek */ #directions = [0, 0]; /* The direction of the head and tail */ #positions = [0, 0]; /* The position of the head and tail */ #maxLength = 1000; /* The maximum length of the whole snake */ #stepSize = 1; #fieldID = 1; #distanceBreak = 5; #distanceProjection = 5; #minLength = 5; #points = []; #id = 0; #bailout = 10000; #projectionBreakMultiplier = ..........完整代码请登录后点击上方下载按钮下载查看
网友评论0