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