svg+js实现随机破碎效果代码
代码语言:html
所属分类:其他
代码描述:svg+js实现随机破碎效果代码,点击可更换破碎效果。
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> body { width: 100vw; height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; background-color: #000; margin: 0; padding: 0; color: #999; font-family: sans-serif; } #controls { padding: 20px; } .row { margin-bottom: 10px; text-align: center; } .container { display: flex; flex-direction: column; filter: url(#goo); } </style> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="600" viewBox="0 0 600 600"> <defs> <linearGradient id="grad" x1="0%" y1="100%" x2="10%" y2="0%"> <stop offset="0%" style="stop-color:rgb(255,255,255);stop-opacity:0.2" /> <stop offset="100%" style="stop-color:rgb(255,255,255);stop-opacity:0.1" /> </linearGradient> </defs> <rect x="0" y="0" width="600" height="600" fill="rgb(252,68,63)" /> <!-- filter="url(#goo)" --> <g id="content"> </g> </svg> <div id="controls"> <div class="row"> <button id="exportpng">Export PNG</button> <button id="exportsvg">Export SVG</button> </div> <div class="row"> <input type="checkbox" checked name="autoplay" id="autoplay" /> <label for="autoplay">Autoplay</label> </div> </div> <script> const ns = 'http://www.w3.org/2000/svg'; const svg = document.querySelector('svg'); const content = svg.getElementById('content'); const element = (type, attrs) => { const el = document.createElementNS(ns, type); for (let key in attrs) { el.setAttribute(key, attrs[key]); } return el; }; const rand = (a, b) => Math.random() * (b - a) + a; const add = (a, b) => a.map((v, i) => v + b[i]); const scale = (a, k) => a.map(v => v * k); const sub = (a, b) => add(a, scale(b, -1)); const dist = (a, b) => Math.hypot(...add(a, scale(b, -1))); const lerp = (a, b, t) => a.map((v, i) => v * (1 - t) + b[i] * t); const hslToRgb = (h, s, l) => { let r, g, b; if (s == 0) { r = g = b = l; // achromatic } else { const hue2rgb = (p, q, t) => { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; }; var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; }; const d = (instructions) => instructions.map(([type, ...pts]) => type + pts.map(pt => ` ${pt[0].toFixed(4)} ${pt[1].toFixed(4)}`).join('')).join(' '); const append = el => content.appendChild(el); const clear = () => { while (content.firstChild) { content.removeChild(content.firstChild); } }; const generate = () => { clear(); const contours = [ [[100, 100], [500, 100], [500, 500], [100, 500]]]; const totalLength = contour => { let total = 0; for (let i = 0; i < contour.length; i++) { total += dist(contour[(i + 1) % contour.length], contour[i]); } return total; }; const pointAtLength = (contour, len) => { let lenSoFar = 0; let idx = 0; for (let i = 0;; i = (i + 1) % contour.length) { const nextLen = dist(contour[i], contour[(i + 1) % contour.length]); if (lenSoFar + nextLen > len) { idx = i + (lenSoFar + nextLen - len) / nextLen; break; } else { lenSoFar += nextLen; } } pt = lerp( contour[Math.floor(idx)], contour[Math.ceil(idx) % contour.length], idx - Math.floor(idx)); return [pt, idx]; }; const split = pts => { const sideLengths = pts.map((pt, i) => dist(pt, pts[(i + 1) % pts.length])); const sideIndices = pts.map((_, i) => i).sort((a, b) => sideLengths[b] - sideLengths[a]); const id1 = rand(sideIndices[0], sideIndices[0] + 1); //const id2 = rand(sideIndices[1], sideIndices[1]+1); const id2 = (Math.floor(id1) + 2 + (1 - (id1 - Math.........完整代码请登录后点击上方下载按钮下载查看
网友评论0