canvas卷积动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas卷积动画效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { font-family: Arial, Helvetica, "Liberation Sans", FreeSans, sans-serif; background-color: #000; margin: 0; padding: 0; border-width: 0; cursor: pointer; caret-color: transparent; } </style> </head> <body > <script > window.addEventListener("load", function () { "use strict"; let canv, ctx; // canvas and context let maxx, maxy; // canvas dimensions let radius, x0, y0, x1, y1, nbPts, theta; let grid, nbx, nby; // for animation let events; let ui, uiv; let rotSpeed = 0.3 / 1000; // rotation speed, in radians / ms let rotColor = "#0ff"; // shortcuts for Math. const mrandom = Math.random; const mfloor = Math.floor; const mround = Math.round; const mceil = Math.ceil; const mabs = Math.abs; const mmin = Math.min; const mmax = Math.max; const mPI = Math.PI; const mPIS2 = Math.PI / 2; const mPIS3 = Math.PI / 3; const m2PI = Math.PI * 2; const m2PIS3 = Math.PI * 2 / 3; const msin = Math.sin; const mcos = Math.cos; const mtan = Math.tan; const matan2 = Math.atan2; const mhypot = Math.hypot; const msqrt = Math.sqrt; const sqrt3 = msqrt(3); const hsqrt3 = msqrt(3) / 2; //------------------------------------------------------------------------ function alea(mini, maxi) { // random number in given range if (typeof maxi == 'undefined') return mini * mrandom(); // range 0..mini return mini + mrandom() * (maxi - mini); // range mini..maxi } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function intAlea(mini, maxi) { // random integer in given range (mini..maxi - 1 or 0..mini - 1) // if (typeof maxi == 'undefined') return mfloor(mini * mrandom()); // range 0..mini - 1 return mini + mfloor(mrandom() * (maxi - mini)); // range mini .. maxi - 1 } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class CircularNoise { constructor(period, amplitude, initTime = 0) { /* period should be > 0, and great in comparision to the time interval of successive calls "great" means at least 10 times, though this limit is not strict Depending on usage, it may be useful to think it represents milliseconds "amplitude" is the maximum change (+ or -) of output in an interval of "period" - should be << 1 since autput is in range 0-1 */ this.prevTime = initTime; this.period = period; this.amplitude = amplitude; this.currentPeriod = (0.75 + 0.5 * Math.random()) * this.period; // 1 +/- 0.25 this.phase = Math.random(); // phase is going from 0 1 this.v0 = Math.random(); this.v1 = this.v0 + this.amplitude * 2 * (Math.random() - 0.5); } value(t) { // returns a number in range 0-1 let dt = t - this.prevTime; // supposed to be > 0, since time is increasing let dPhase = dt / this.currentPeriod; // supposed to be < 1 this.phase += dPhase; if (dPhase > 1) { this.currentPeriod = (0.75 + 0.5 * Math.random()) * this.period; this.phase %= 1; this.v0 = this.v1 % 1; while (this.v0 < 0) this.v0 += 1; this.v1 = this.v0 + this.amplitude * 2 * (Math.random() - 0.5); } this.prevTime = t; let ph = (3 - 2 * this.phase) * this.phase * this.phase; return this.v1 * this.phase + this.v0 * (1 - this.phase); }} //------------------------------------------------------------------------ // for curves inside circles //------------------------------------------------------------------------ function calcAlpha(angle, beta) { const mc = mabs(mcos(angle / 2)); if (mc < 1e-3) return 0.4845; return 1.3333333333333333333 * (1 - beta / mc); } // calcAlpha function arcPerp(th0, th1, alpha) { /* for a unity circle centered in (0, 0) returns values for a bezier cubic curve perpendicular to circle connecting point at angle th0 to point at angle th1 at distance alpha from centre */ let angle = mabs(th0 - th1); if (angle > mPI) angle = m2PI - angle; alpha = 1 - calcAlpha(angle, alpha); const mc0 = mcos(th0); const ms0 = msin(th0); const mc1 = mcos(th1); const ms1 = msin(th1); return [{ x: mc0, y: ms0 }, { x: alpha * mc0, y: alpha * ms0 }, { x: alpha * mc1, y: alpha * ms1 }, { x: mc1, y: ms1 }]; } function autoArcPerp(th0, th1, sect) { /* like arc, but alpha is evaluated automatically so as to have : - angle == 0 => alpha = 1 - angle == sect => alpha = small this "small" comes from the "z" coefficient below. Experience shows that z = 1 for sect == PI, and z = 0.8 for sect == PI / 3 are suitable */ let angle = mabs(th0 - th1) % m2PI; // 0 .. 2 pi if (angle > mPI) angle = m2PI - angle; // 0 .. pi const z = (1 * (sect - mPI / 3) + 0.8 * (mPI - sect)) / (mPI - mPI / 3); // 0.8 for sect==mPI/3, 1 for sect == mPI let alpha = 1 - z * angle / sect; alpha = 1.0 - calcAlpha(angle, alpha); const mc0 = mcos(th0); const ms0 = msin(th0); const mc1 = mcos(th1); const ms1 = msin(th1); return [{ x: mc0, y: ms0 }, { x: alpha * mc0, y: alpha * ms0 }, { x: alpha * mc1, y: alpha * ms1 }, { x: mc1, y: ms1 }]; } function scaleArc(arc, xc, yc, radius) { return arc.map(p => ({ x: p.x * radius + xc, y: p.y * radius + yc })); // apply radius and position of center } //------------------------------------------------------------------------ // for curves between circles //------------------------------------------------------------------------ function normalizedRadiiConnection(anglec, angle, alpha) { /* connection line between two tangent circles of radius 1 the first circle has its center in (0,0) the second circle has its center in (cos(anglec),sin(anglec)) angle is a direction (0 = horizontally rightwards, pi/2 = downwards) alpha is a factor : 0 => Bézier curve will be a straignt line, 1 => Bézier curve will be (almost) a circle arc alpha > 1 is possible, alpha < 0 is not The curve connects "smoothly" the radius from first circle in direction alpha, to the radius in second circle symmetrical of (radius in c1) with respect to the symmetry axis of the two circles */ const dx = mcos(anglec); const dy = msin(anglec); const ca = mcos(angle); const sa = msin(angle); const c = ca * dx + sa * dy; // if < 0 , problems are to be expected... const cu = c; const s = sa * dx - ca * dy; const su = s; const cb = dx; const sb = dy; const p0 = { x: ca, y: sa }; const ddx = -c * cb - s * sb; const ddy = -c * sb + s * cb; const p3 = { x: 2 * dx + ddx, y: 2 * dy + ddy }; const rad = msqrt((1 - cu) / (1 + cu)); const beta = rad * mabs(mabs(su) < 0.01 ? 2 * su * alpha / 3 : 1.3333333333 * alpha * (1 - cu) / su); // distance between control points and ends of arc const p1 = { x: p0.x + beta * ca, y: p0.y + beta * sa }; const p2 = { x: p3.x + beta * ddx, y: p3.y + beta * ddy }; return [p0, p1, p2, p3]; } //------------------------------------------------------------------------ class Circle { constructor(kx, ky) { this.kx = kx; this.ky = ky; this.xc = maxx / .........完整代码请登录后点击上方下载按钮下载查看
网友评论0