svg+js实现粒子水母动画效果代码
代码语言:html
所属分类:粒子
代码描述:svg+js实现粒子水母动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Lora', serif; } :root { --sky-blue: #0e85b5; --dark: #181818; } body { display: grid; font-family: 'Silkscreen', sans-serif; color: white; background: var(--dark); justify-items: center; user-select: none; width: 100%; height: 100vh; height: 100dvh; } svg { justify-self: stretch; align-self: stretch; background: #181818; } .free { display: none; visibility: hidden; } </style> </head> <body > <svg id="image" viewBox="-0.5 -0.5 1 1"> <circle class="point" r="5" stroke="aqua" stroke-width="0.005" fill="#181818" /> <rect fill="none" stroke="#555" stroke-width="0.001" x="-0.3" y="-0.3" width="0.6" height="0.6" /> </svg> <script type="module"> // Oscar Saharoy 2023 // ======================== math export const range = (n) => Object.keys(Array(n).fill(0)).map(parseFloat); export function sum(arr) { return arr.reduce((acc, val) => acc + val, 0); } export const rotateX = (theta) => [[1, 0, 0], [0, Math.cos(theta), -Math.sin(theta)], [0, Math.sin(theta), Math.cos(theta)]]; export const rotateY = (theta) => [[Math.cos(theta), 0, Math.sin(theta)], [0, 1, 0], [-Math.sin(theta), 0, Math.cos(theta)]]; export const rotateZ = (theta) => [[Math.cos(theta), -Math.sin(theta), 0], [Math.sin(theta), Math.cos(theta), 0], [0, 0, 1]]; export const rotate2D = (theta) => [[Math.cos(theta), -Math.sin(theta)], [Math.sin(theta), Math.cos(theta)]]; export const identity = (rows) => range(rows).map(x => range(rows).map(y => x == y ? 1 : 0)); export const vec0 = (rows) => Array(rows).fill(0); export const scaleVec = (vec, f) => vec.map(x => x * f); export const addVec = (vecA, vecB) => vecA.map((_, i) => vecA[i] + vecB[i]); export const subVec = (vecA, vecB) => vecA.map((_, i) => vecA[i] - vecB[i]); export const scaleMat = (mat, f) => mat.map(row => scaleVec(row, f)); export const dot = (vecA, vecB) => vecA.reduce((sum, _, i) => sum + vecA[i] * vecB[i], 0); export const cross = (vecA, vecB) => [ vecA[1] * vecB[2] - vecA[2] * vecB[1], vecA[2] * vecB[0] - vecA[0] * vecB[2], vecA[0] * vecB[1] - vecA[1] * vecB[0]]; export const meanVec = (vecs) => scaleVec( vecs.reduce((acc, vec) => addVec(acc, vec), vec0(vecs[0].length)), 1 / vecs.length); export const length2 = (vec) => vec.reduce((acc, val) => acc + val * val, 0); export const length = (vec) => Math.sqrt(length2(vec)); export const arg = (vec) => Math.atan2(vec[1], vec[0]); export const normalise = (vec) => scaleVec(vec, 1 / length(vec)); export const matVecMul = (mat, vec) => mat.map(row => dot(row, vec)); export const transpose = (mat) => mat[0].map((_, j) => mat.map((_, i) => mat[i][j])); export const matMatMul = (matA, matB) => transpose(transpose(matB).map(colB => matA.map(rowA => dot(colB, rowA)))); export const matMultiMul = (...mats) => mats.length == 2 ? matMatMul(...mats) : matMatMul(mats[0], matMultiMul(...mats.slice(1))); export const vecString = (vec) => `[ ${vec.reduce((acc, val, j) => acc + (j > 0 ? ", " : "") + val.toPrecision(5), "")} ]`; export const matString = (mat) => `[${mat.reduce((str, row, i) => str + vecString(row) + (i < mat.length - 1 ? ",\n " : ""), "")}]`; export const degrees = (radians) => (radians % (2 * Math.PI) + 2 * Math.PI) % (2 * Math.PI) / Math.PI * 180; export const radians = (degrees) => (degrees % 360 + 360) % 360 * Math.PI / 180; const cosD = (degrees) => Math.cos(radians(degrees)); const sinD = (degrees) => Math.sin(radians(degrees)); export function distBetweenLines(line1, line2) { const perpToBoth = cross(line1.dir, line2.dir); return dot(subVec(line1.origin, line2.origin), perpToBoth) / dot(perpToBoth, perpToBoth); } export function pointDistToLine(point, line) { const pr = subVec(point, line.origin); return Math.sqrt(dot(pr, pr) - dot(pr, normalise(line.dir)) ** 2); } export function projectOntoPlane(direction, planeNormal).........完整代码请登录后点击上方下载按钮下载查看
网友评论0