ngwr 15.2.0 → 15.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/alert/styles/_index.scss +13 -5
  2. package/bits/border-glow/styles/_rules.scss +60 -49
  3. package/bits/click-spark/click-spark.scss +5 -1
  4. package/bits/click-spark/styles/_index.scss +10 -15
  5. package/bits/click-spark/styles/_rules.scss +20 -0
  6. package/fesm2022/ngwr-alert.mjs +2 -2
  7. package/fesm2022/ngwr-alert.mjs.map +1 -1
  8. package/fesm2022/ngwr-bits-aurora.mjs +108 -52
  9. package/fesm2022/ngwr-bits-aurora.mjs.map +1 -1
  10. package/fesm2022/ngwr-bits-border-glow-testing.mjs +8 -8
  11. package/fesm2022/ngwr-bits-border-glow-testing.mjs.map +1 -1
  12. package/fesm2022/ngwr-bits-border-glow.mjs +29 -26
  13. package/fesm2022/ngwr-bits-border-glow.mjs.map +1 -1
  14. package/fesm2022/ngwr-bits-dot-grid.mjs +11 -14
  15. package/fesm2022/ngwr-bits-dot-grid.mjs.map +1 -1
  16. package/fesm2022/ngwr-bits-fuzzy-text.mjs +18 -4
  17. package/fesm2022/ngwr-bits-fuzzy-text.mjs.map +1 -1
  18. package/fesm2022/ngwr-bits-ripple-grid.mjs +14 -13
  19. package/fesm2022/ngwr-bits-ripple-grid.mjs.map +1 -1
  20. package/fesm2022/ngwr-bits-splash-cursor.mjs +21 -10
  21. package/fesm2022/ngwr-bits-splash-cursor.mjs.map +1 -1
  22. package/fesm2022/ngwr-bits-waves.mjs +10 -15
  23. package/fesm2022/ngwr-bits-waves.mjs.map +1 -1
  24. package/fesm2022/ngwr-breadcrumbs.mjs +18 -2
  25. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  26. package/fesm2022/ngwr-hotkey.mjs +23 -1
  27. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  28. package/fesm2022/ngwr-i18n-ar.mjs +2 -0
  29. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  30. package/fesm2022/ngwr-i18n-cs.mjs +2 -0
  31. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  32. package/fesm2022/ngwr-i18n-de.mjs +2 -0
  33. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  34. package/fesm2022/ngwr-i18n-en.mjs +2 -0
  35. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  36. package/fesm2022/ngwr-i18n-es.mjs +2 -0
  37. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  38. package/fesm2022/ngwr-i18n-fr.mjs +2 -0
  39. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  40. package/fesm2022/ngwr-i18n-he.mjs +2 -0
  41. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  42. package/fesm2022/ngwr-i18n-hi.mjs +2 -0
  43. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  44. package/fesm2022/ngwr-i18n-id.mjs +2 -0
  45. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  46. package/fesm2022/ngwr-i18n-it.mjs +2 -0
  47. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  48. package/fesm2022/ngwr-i18n-ja.mjs +2 -0
  49. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  50. package/fesm2022/ngwr-i18n-ko.mjs +2 -0
  51. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  52. package/fesm2022/ngwr-i18n-nl.mjs +2 -0
  53. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  54. package/fesm2022/ngwr-i18n-pl.mjs +2 -0
  55. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  56. package/fesm2022/ngwr-i18n-pt.mjs +2 -0
  57. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  58. package/fesm2022/ngwr-i18n-ru.mjs +2 -0
  59. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  60. package/fesm2022/ngwr-i18n-sv.mjs +2 -0
  61. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  62. package/fesm2022/ngwr-i18n-tr.mjs +2 -0
  63. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  64. package/fesm2022/ngwr-i18n-uk.mjs +2 -0
  65. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  66. package/fesm2022/ngwr-i18n-vi.mjs +2 -0
  67. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  68. package/fesm2022/ngwr-i18n-zh-tw.mjs +2 -0
  69. package/fesm2022/ngwr-i18n-zh-tw.mjs.map +1 -1
  70. package/fesm2022/ngwr-i18n-zh.mjs +2 -0
  71. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  72. package/fesm2022/ngwr-pagination.mjs +3 -0
  73. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  74. package/fesm2022/ngwr-pipes.mjs +163 -49
  75. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  76. package/fesm2022/ngwr-schema-form.mjs +3 -0
  77. package/fesm2022/ngwr-schema-form.mjs.map +1 -1
  78. package/fesm2022/ngwr-select-testing.mjs +16 -0
  79. package/fesm2022/ngwr-select-testing.mjs.map +1 -1
  80. package/fesm2022/ngwr-select.mjs +218 -38
  81. package/fesm2022/ngwr-select.mjs.map +1 -1
  82. package/fesm2022/ngwr-statistic.mjs +20 -21
  83. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  84. package/fesm2022/ngwr-version.mjs +1 -1
  85. package/fesm2022/ngwr-version.mjs.map +1 -1
  86. package/i18n/ar.json +2 -0
  87. package/i18n/cs.json +2 -0
  88. package/i18n/de.json +2 -0
  89. package/i18n/en.json +2 -0
  90. package/i18n/es.json +2 -0
  91. package/i18n/fr.json +2 -0
  92. package/i18n/he.json +2 -0
  93. package/i18n/hi.json +2 -0
  94. package/i18n/id.json +2 -0
  95. package/i18n/it.json +2 -0
  96. package/i18n/ja.json +2 -0
  97. package/i18n/ko.json +2 -0
  98. package/i18n/nl.json +2 -0
  99. package/i18n/pl.json +2 -0
  100. package/i18n/pt.json +2 -0
  101. package/i18n/ru.json +2 -0
  102. package/i18n/sv.json +2 -0
  103. package/i18n/tr.json +2 -0
  104. package/i18n/uk.json +2 -0
  105. package/i18n/vi.json +2 -0
  106. package/i18n/zh-TW.json +2 -0
  107. package/i18n/zh.json +2 -0
  108. package/llms-full.txt +5 -5
  109. package/package.json +1 -1
  110. package/schematics/use/symbol-map.json +2 -0
  111. package/select/styles/_index.scss +23 -1
  112. package/skills/ngwr/SKILL.md +3 -1
  113. package/skills/ngwr/references/catalog.md +1 -1
  114. package/types/ngwr-alert.d.ts +3 -1
  115. package/types/ngwr-bits-aurora.d.ts +24 -2
  116. package/types/ngwr-bits-border-glow-testing.d.ts +9 -5
  117. package/types/ngwr-bits-border-glow.d.ts +10 -4
  118. package/types/ngwr-bits-fuzzy-text.d.ts +2 -1
  119. package/types/ngwr-bits-ripple-grid.d.ts +7 -2
  120. package/types/ngwr-bits-splash-cursor.d.ts +2 -1
  121. package/types/ngwr-breadcrumbs.d.ts +15 -0
  122. package/types/ngwr-hotkey.d.ts +14 -2
  123. package/types/ngwr-pipes.d.ts +142 -32
  124. package/types/ngwr-select-testing.d.ts +9 -0
  125. package/types/ngwr-select.d.ts +133 -2
  126. package/types/ngwr-sidebar.d.ts +1 -1
  127. package/types/ngwr-version.d.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-bits-splash-cursor.mjs","names":[],"sources":["../../../projects/lib/bits/splash-cursor/fluid.ts","../../../projects/lib/bits/splash-cursor/splash-cursor.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n *\n * WebGL fluid simulation behind `<wr-splash-cursor>`. Port of the engine\n * used by reactbits.dev's SplashCursor (itself based on Pavel Dobryakov's\n * WebGL-Fluid-Simulation, MIT).\n *\n * Framework-free on purpose: `createFluidSimulation(canvas, config)` boots\n * the sim and returns a teardown, or `null` when WebGL isn't available.\n */\n\n/* eslint-disable no-bitwise -- GL bitmasks + string hashing are inherently bitwise */\n\ninterface WrFluidConfig {\n readonly simResolution: number;\n readonly dyeResolution: number;\n readonly densityDissipation: number;\n readonly velocityDissipation: number;\n readonly pressure: number;\n readonly pressureIterations: number;\n readonly curl: number;\n readonly splatRadius: number;\n readonly splatForce: number;\n readonly shading: boolean;\n readonly colorUpdateSpeed: number;\n /** Cycle splat colours through the rainbow; `false` uses `color`. */\n readonly rainbow: boolean;\n /** Fixed splat colour (hex) when `rainbow` is off. */\n readonly color: string;\n}\n\ninterface RGB {\n r: number;\n g: number;\n b: number;\n}\n\ninterface TexFormat {\n readonly internalFormat: number;\n readonly format: number;\n}\n\ninterface GlExt {\n readonly formatRGBA: TexFormat;\n readonly formatRG: TexFormat;\n readonly formatR: TexFormat;\n readonly halfFloatTexType: number;\n readonly supportLinearFiltering: boolean;\n}\n\ninterface FBO {\n readonly texture: WebGLTexture;\n readonly fbo: WebGLFramebuffer;\n readonly width: number;\n readonly height: number;\n readonly texelSizeX: number;\n readonly texelSizeY: number;\n attach(id: number): number;\n}\n\ninterface DoubleFBO {\n width: number;\n height: number;\n texelSizeX: number;\n texelSizeY: number;\n read: FBO;\n write: FBO;\n swap(): void;\n}\n\ninterface Pointer {\n texcoordX: number;\n texcoordY: number;\n prevTexcoordX: number;\n prevTexcoordY: number;\n deltaX: number;\n deltaY: number;\n moved: boolean;\n color: RGB;\n}\n\ntype GL = WebGLRenderingContext | WebGL2RenderingContext;\ntype Uniforms = Record<string, WebGLUniformLocation | null>;\n\nfunction createFluidSimulation(canvas: HTMLCanvasElement, config: WrFluidConfig): (() => void) | null {\n const ctx = getWebGLContext(canvas);\n if (!ctx) return null;\n const { gl, ext } = ctx;\n\n let dyeResolution = config.dyeResolution;\n let shading = config.shading;\n if (!ext.supportLinearFiltering) {\n dyeResolution = 256;\n shading = false;\n }\n\n let active = true;\n let rafId = 0;\n\n // Every GL object this boot creates, so the teardown can free them. The\n // context outlives the sim (an input change reboots on the same canvas),\n // so anything left here is GPU memory nobody can reach again.\n const shaders: WebGLShader[] = [];\n const programs: WebGLProgram[] = [];\n const buffers: WebGLBuffer[] = [];\n\n const pointer: Pointer = {\n texcoordX: 0,\n texcoordY: 0,\n prevTexcoordX: 0,\n prevTexcoordY: 0,\n deltaX: 0,\n deltaY: 0,\n moved: false,\n color: { r: 0, g: 0, b: 0 },\n };\n\n // Shader plumbing\n\n function compile(type: number, source: string, keywords?: readonly string[]): WebGLShader {\n const prefixed = keywords ? keywords.map(k => `#define ${k}\\n`).join('') + source : source;\n const shader = gl.createShader(type)!;\n shaders.push(shader);\n gl.shaderSource(shader, prefixed);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n // eslint-disable-next-line no-console -- GPU shader failures are otherwise invisible\n console.error('wr-splash-cursor shader error:', gl.getShaderInfoLog(shader));\n }\n return shader;\n }\n\n function link(vertex: WebGLShader, fragment: WebGLShader): WebGLProgram {\n const program = gl.createProgram();\n programs.push(program);\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n // eslint-disable-next-line no-console -- GPU link failures are otherwise invisible\n console.error('wr-splash-cursor program error:', gl.getProgramInfoLog(program));\n }\n return program;\n }\n\n function uniformsOf(program: WebGLProgram): Uniforms {\n const out: Uniforms = {};\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n for (let i = 0; i < count; i++) {\n const name = gl.getActiveUniform(program, i)!.name;\n out[name] = gl.getUniformLocation(program, name);\n }\n return out;\n }\n\n class ShaderProgram {\n readonly program: WebGLProgram;\n readonly uniforms: Uniforms;\n\n constructor(vertex: WebGLShader, fragment: WebGLShader) {\n this.program = link(vertex, fragment);\n this.uniforms = uniformsOf(this.program);\n }\n\n bind(): void {\n gl.useProgram(this.program);\n }\n }\n\n /** Display shader with `#define`-keyword program variants. */\n class DisplayMaterial {\n private readonly programs = new Map<number, WebGLProgram>();\n private activeProgram: WebGLProgram | null = null;\n uniforms: Uniforms = {};\n\n constructor(\n private readonly vertex: WebGLShader,\n private readonly fragmentSource: string\n ) {}\n\n setKeywords(keywords: readonly string[]): void {\n let hash = 0;\n for (const k of keywords) hash += hashCode(k);\n let program = this.programs.get(hash);\n if (!program) {\n program = link(this.vertex, compile(gl.FRAGMENT_SHADER, this.fragmentSource, keywords));\n this.programs.set(hash, program);\n }\n if (program === this.activeProgram) return;\n this.uniforms = uniformsOf(program);\n this.activeProgram = program;\n }\n\n bind(): void {\n gl.useProgram(this.activeProgram);\n }\n }\n\n // Shaders\n\n const baseVertexShader = compile(\n gl.VERTEX_SHADER,\n `\n precision highp float;\n attribute vec2 aPosition;\n varying vec2 vUv;\n varying vec2 vL;\n varying vec2 vR;\n varying vec2 vT;\n varying vec2 vB;\n uniform vec2 texelSize;\n\n void main () {\n vUv = aPosition * 0.5 + 0.5;\n vL = vUv - vec2(texelSize.x, 0.0);\n vR = vUv + vec2(texelSize.x, 0.0);\n vT = vUv + vec2(0.0, texelSize.y);\n vB = vUv - vec2(0.0, texelSize.y);\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `\n );\n\n const copyShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n uniform sampler2D uTexture;\n\n void main () {\n gl_FragColor = texture2D(uTexture, vUv);\n }\n `\n );\n\n const clearShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n uniform sampler2D uTexture;\n uniform float value;\n\n void main () {\n gl_FragColor = value * texture2D(uTexture, vUv);\n }\n `\n );\n\n const displayShaderSource = `\n precision highp float;\n precision highp sampler2D;\n varying vec2 vUv;\n varying vec2 vL;\n varying vec2 vR;\n varying vec2 vT;\n varying vec2 vB;\n uniform sampler2D uTexture;\n uniform vec2 texelSize;\n\n void main () {\n vec3 c = texture2D(uTexture, vUv).rgb;\n #ifdef SHADING\n vec3 lc = texture2D(uTexture, vL).rgb;\n vec3 rc = texture2D(uTexture, vR).rgb;\n vec3 tc = texture2D(uTexture, vT).rgb;\n vec3 bc = texture2D(uTexture, vB).rgb;\n\n float dx = length(rc) - length(lc);\n float dy = length(tc) - length(bc);\n\n vec3 n = normalize(vec3(dx, dy, length(texelSize)));\n vec3 l = vec3(0.0, 0.0, 1.0);\n\n float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);\n c *= diffuse;\n #endif\n\n float a = max(c.r, max(c.g, c.b));\n gl_FragColor = vec4(c, a);\n }\n `;\n\n const splatShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision highp float;\n precision highp sampler2D;\n varying vec2 vUv;\n uniform sampler2D uTarget;\n uniform float aspectRatio;\n uniform vec3 color;\n uniform vec2 point;\n uniform float radius;\n\n void main () {\n vec2 p = vUv - point.xy;\n p.x *= aspectRatio;\n vec3 splat = exp(-dot(p, p) / radius) * color;\n vec3 base = texture2D(uTarget, vUv).xyz;\n gl_FragColor = vec4(base + splat, 1.0);\n }\n `\n );\n\n const advectionShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision highp float;\n precision highp sampler2D;\n varying vec2 vUv;\n uniform sampler2D uVelocity;\n uniform sampler2D uSource;\n uniform vec2 texelSize;\n uniform vec2 dyeTexelSize;\n uniform float dt;\n uniform float dissipation;\n\n vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {\n vec2 st = uv / tsize - 0.5;\n vec2 iuv = floor(st);\n vec2 fuv = fract(st);\n\n vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);\n vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);\n vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);\n vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);\n\n return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);\n }\n\n void main () {\n #ifdef MANUAL_FILTERING\n vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize;\n vec4 result = bilerp(uSource, coord, dyeTexelSize);\n #else\n vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;\n vec4 result = texture2D(uSource, coord);\n #endif\n float decay = 1.0 + dissipation * dt;\n gl_FragColor = result / decay;\n }\n `,\n ext.supportLinearFiltering ? undefined : ['MANUAL_FILTERING']\n );\n\n const divergenceShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n varying highp vec2 vL;\n varying highp vec2 vR;\n varying highp vec2 vT;\n varying highp vec2 vB;\n uniform sampler2D uVelocity;\n\n void main () {\n float L = texture2D(uVelocity, vL).x;\n float R = texture2D(uVelocity, vR).x;\n float T = texture2D(uVelocity, vT).y;\n float B = texture2D(uVelocity, vB).y;\n\n vec2 C = texture2D(uVelocity, vUv).xy;\n if (vL.x < 0.0) { L = -C.x; }\n if (vR.x > 1.0) { R = -C.x; }\n if (vT.y > 1.0) { T = -C.y; }\n if (vB.y < 0.0) { B = -C.y; }\n\n float div = 0.5 * (R - L + T - B);\n gl_FragColor = vec4(div, 0.0, 0.0, 1.0);\n }\n `\n );\n\n const curlShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n varying highp vec2 vL;\n varying highp vec2 vR;\n varying highp vec2 vT;\n varying highp vec2 vB;\n uniform sampler2D uVelocity;\n\n void main () {\n float L = texture2D(uVelocity, vL).y;\n float R = texture2D(uVelocity, vR).y;\n float T = texture2D(uVelocity, vT).x;\n float B = texture2D(uVelocity, vB).x;\n float vorticity = R - L - T + B;\n gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0);\n }\n `\n );\n\n const vorticityShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision highp float;\n precision highp sampler2D;\n varying vec2 vUv;\n varying vec2 vL;\n varying vec2 vR;\n varying vec2 vT;\n varying vec2 vB;\n uniform sampler2D uVelocity;\n uniform sampler2D uCurl;\n uniform float curl;\n uniform float dt;\n\n void main () {\n float L = texture2D(uCurl, vL).x;\n float R = texture2D(uCurl, vR).x;\n float T = texture2D(uCurl, vT).x;\n float B = texture2D(uCurl, vB).x;\n float C = texture2D(uCurl, vUv).x;\n\n vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));\n force /= length(force) + 0.0001;\n force *= curl * C;\n force.y *= -1.0;\n\n vec2 velocity = texture2D(uVelocity, vUv).xy;\n velocity += force * dt;\n velocity = min(max(velocity, -1000.0), 1000.0);\n gl_FragColor = vec4(velocity, 0.0, 1.0);\n }\n `\n );\n\n const pressureShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n varying highp vec2 vL;\n varying highp vec2 vR;\n varying highp vec2 vT;\n varying highp vec2 vB;\n uniform sampler2D uPressure;\n uniform sampler2D uDivergence;\n\n void main () {\n float L = texture2D(uPressure, vL).x;\n float R = texture2D(uPressure, vR).x;\n float T = texture2D(uPressure, vT).x;\n float B = texture2D(uPressure, vB).x;\n float C = texture2D(uPressure, vUv).x;\n float divergence = texture2D(uDivergence, vUv).x;\n float pressure = (L + R + B + T - divergence) * 0.25;\n gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0);\n }\n `\n );\n\n const gradientSubtractShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n varying highp vec2 vL;\n varying highp vec2 vR;\n varying highp vec2 vT;\n varying highp vec2 vB;\n uniform sampler2D uPressure;\n uniform sampler2D uVelocity;\n\n void main () {\n float L = texture2D(uPressure, vL).x;\n float R = texture2D(uPressure, vR).x;\n float T = texture2D(uPressure, vT).x;\n float B = texture2D(uPressure, vB).x;\n vec2 velocity = texture2D(uVelocity, vUv).xy;\n velocity.xy -= vec2(R - L, T - B);\n gl_FragColor = vec4(velocity, 0.0, 1.0);\n }\n `\n );\n\n // Fullscreen blit\n\n const vertexBuffer = gl.createBuffer();\n const indexBuffer = gl.createBuffer();\n buffers.push(vertexBuffer, indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), gl.STATIC_DRAW);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 0, 2, 3]), gl.STATIC_DRAW);\n gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(0);\n\n function blit(target: FBO | null, clear = false): void {\n if (target === null) {\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n } else {\n gl.viewport(0, 0, target.width, target.height);\n gl.bindFramebuffer(gl.FRAMEBUFFER, target.fbo);\n }\n if (clear) {\n gl.clearColor(0.0, 0.0, 0.0, 1.0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);\n }\n\n // Framebuffers\n\n function createFBO(w: number, h: number, internalFormat: number, format: number, type: number, param: number): FBO {\n gl.activeTexture(gl.TEXTURE0);\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, param);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, param);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, w, h, 0, format, type, null);\n\n const fbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n gl.viewport(0, 0, w, h);\n gl.clear(gl.COLOR_BUFFER_BIT);\n\n return {\n texture,\n fbo,\n width: w,\n height: h,\n texelSizeX: 1 / w,\n texelSizeY: 1 / h,\n attach(id: number): number {\n gl.activeTexture(gl.TEXTURE0 + id);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n return id;\n },\n };\n }\n\n function disposeFBO(target: FBO): void {\n gl.deleteTexture(target.texture);\n gl.deleteFramebuffer(target.fbo);\n }\n\n function disposeDoubleFBO(target: DoubleFBO): void {\n disposeFBO(target.read);\n disposeFBO(target.write);\n }\n\n function createDoubleFBO(\n w: number,\n h: number,\n internalFormat: number,\n format: number,\n type: number,\n param: number\n ): DoubleFBO {\n let fbo1 = createFBO(w, h, internalFormat, format, type, param);\n let fbo2 = createFBO(w, h, internalFormat, format, type, param);\n return {\n width: w,\n height: h,\n texelSizeX: fbo1.texelSizeX,\n texelSizeY: fbo1.texelSizeY,\n get read() {\n return fbo1;\n },\n set read(value: FBO) {\n fbo1 = value;\n },\n get write() {\n return fbo2;\n },\n set write(value: FBO) {\n fbo2 = value;\n },\n swap(): void {\n const temp = fbo1;\n fbo1 = fbo2;\n fbo2 = temp;\n },\n };\n }\n\n function resizeFBO(\n target: FBO,\n w: number,\n h: number,\n internalFormat: number,\n format: number,\n type: number,\n param: number\n ): FBO {\n const newFBO = createFBO(w, h, internalFormat, format, type, param);\n copyProgram.bind();\n gl.uniform1i(copyProgram.uniforms['uTexture'], target.attach(0));\n blit(newFBO);\n disposeFBO(target);\n return newFBO;\n }\n\n function resizeDoubleFBO(\n target: DoubleFBO,\n w: number,\n h: number,\n internalFormat: number,\n format: number,\n type: number,\n param: number\n ): DoubleFBO {\n if (target.width === w && target.height === h) return target;\n target.read = resizeFBO(target.read, w, h, internalFormat, format, type, param);\n disposeFBO(target.write);\n target.write = createFBO(w, h, internalFormat, format, type, param);\n target.width = w;\n target.height = h;\n target.texelSizeX = 1 / w;\n target.texelSizeY = 1 / h;\n return target;\n }\n\n // Programs + state\n\n const copyProgram = new ShaderProgram(baseVertexShader, copyShader);\n const clearProgram = new ShaderProgram(baseVertexShader, clearShader);\n const splatProgram = new ShaderProgram(baseVertexShader, splatShader);\n const advectionProgram = new ShaderProgram(baseVertexShader, advectionShader);\n const divergenceProgram = new ShaderProgram(baseVertexShader, divergenceShader);\n const curlProgram = new ShaderProgram(baseVertexShader, curlShader);\n const vorticityProgram = new ShaderProgram(baseVertexShader, vorticityShader);\n const pressureProgram = new ShaderProgram(baseVertexShader, pressureShader);\n const gradientSubtractProgram = new ShaderProgram(baseVertexShader, gradientSubtractShader);\n const displayMaterial = new DisplayMaterial(baseVertexShader, displayShaderSource);\n\n let dye!: DoubleFBO;\n let velocity!: DoubleFBO;\n let divergence!: FBO;\n let curl!: FBO;\n let pressure!: DoubleFBO;\n\n function initFramebuffers(): void {\n const simRes = getResolution(config.simResolution);\n const dyeRes = getResolution(dyeResolution);\n const texType = ext.halfFloatTexType;\n const rgba = ext.formatRGBA;\n const rg = ext.formatRG;\n const r = ext.formatR;\n const filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST;\n gl.disable(gl.BLEND);\n\n dye = dye\n ? resizeDoubleFBO(dye, dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering)\n : createDoubleFBO(dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering);\n\n velocity = velocity\n ? resizeDoubleFBO(velocity, simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering)\n : createDoubleFBO(simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering);\n\n // Recreated on every resize rather than resized, so the previous ones go first.\n if (divergence) disposeFBO(divergence);\n if (curl) disposeFBO(curl);\n if (pressure) disposeDoubleFBO(pressure);\n divergence = createFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);\n curl = createFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);\n pressure = createDoubleFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);\n }\n\n displayMaterial.setKeywords(shading ? ['SHADING'] : []);\n initFramebuffers();\n let lastUpdateTime = Date.now();\n let colorUpdateTimer = 0;\n\n // Frame loop\n\n function updateFrame(): void {\n rafId = 0;\n if (!active || !visible) return;\n const dt = calcDeltaTime();\n if (resizeCanvas()) initFramebuffers();\n updateColors(dt);\n applyInputs();\n step(dt);\n render();\n rafId = requestAnimationFrame(updateFrame);\n }\n\n function calcDeltaTime(): number {\n const now = Date.now();\n const dt = Math.min((now - lastUpdateTime) / 1000, 0.016666);\n lastUpdateTime = now;\n return dt;\n }\n\n function resizeCanvas(): boolean {\n const width = scaleByPixelRatio(canvas.clientWidth);\n const height = scaleByPixelRatio(canvas.clientHeight);\n if (canvas.width !== width || canvas.height !== height) {\n canvas.width = width;\n canvas.height = height;\n return true;\n }\n return false;\n }\n\n function updateColors(dt: number): void {\n colorUpdateTimer += dt * config.colorUpdateSpeed;\n if (colorUpdateTimer >= 1) {\n colorUpdateTimer = wrap(colorUpdateTimer, 0, 1);\n pointer.color = generateColor();\n }\n }\n\n function applyInputs(): void {\n if (pointer.moved) {\n pointer.moved = false;\n splatPointer();\n }\n }\n\n function step(dt: number): void {\n gl.disable(gl.BLEND);\n curlProgram.bind();\n gl.uniform2f(curlProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(curlProgram.uniforms['uVelocity'], velocity.read.attach(0));\n blit(curl);\n\n vorticityProgram.bind();\n gl.uniform2f(vorticityProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(vorticityProgram.uniforms['uVelocity'], velocity.read.attach(0));\n gl.uniform1i(vorticityProgram.uniforms['uCurl'], curl.attach(1));\n gl.uniform1f(vorticityProgram.uniforms['curl'], config.curl);\n gl.uniform1f(vorticityProgram.uniforms['dt'], dt);\n blit(velocity.write);\n velocity.swap();\n\n divergenceProgram.bind();\n gl.uniform2f(divergenceProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(divergenceProgram.uniforms['uVelocity'], velocity.read.attach(0));\n blit(divergence);\n\n clearProgram.bind();\n gl.uniform1i(clearProgram.uniforms['uTexture'], pressure.read.attach(0));\n gl.uniform1f(clearProgram.uniforms['value'], config.pressure);\n blit(pressure.write);\n pressure.swap();\n\n pressureProgram.bind();\n gl.uniform2f(pressureProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(pressureProgram.uniforms['uDivergence'], divergence.attach(0));\n for (let i = 0; i < config.pressureIterations; i++) {\n gl.uniform1i(pressureProgram.uniforms['uPressure'], pressure.read.attach(1));\n blit(pressure.write);\n pressure.swap();\n }\n\n gradientSubtractProgram.bind();\n gl.uniform2f(gradientSubtractProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(gradientSubtractProgram.uniforms['uPressure'], pressure.read.attach(0));\n gl.uniform1i(gradientSubtractProgram.uniforms['uVelocity'], velocity.read.attach(1));\n blit(velocity.write);\n velocity.swap();\n\n advectionProgram.bind();\n gl.uniform2f(advectionProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n if (!ext.supportLinearFiltering) {\n gl.uniform2f(advectionProgram.uniforms['dyeTexelSize'], velocity.texelSizeX, velocity.texelSizeY);\n }\n const velocityId = velocity.read.attach(0);\n gl.uniform1i(advectionProgram.uniforms['uVelocity'], velocityId);\n gl.uniform1i(advectionProgram.uniforms['uSource'], velocityId);\n gl.uniform1f(advectionProgram.uniforms['dt'], dt);\n gl.uniform1f(advectionProgram.uniforms['dissipation'], config.velocityDissipation);\n blit(velocity.write);\n velocity.swap();\n\n if (!ext.supportLinearFiltering) {\n gl.uniform2f(advectionProgram.uniforms['dyeTexelSize'], dye.texelSizeX, dye.texelSizeY);\n }\n gl.uniform1i(advectionProgram.uniforms['uVelocity'], velocity.read.attach(0));\n gl.uniform1i(advectionProgram.uniforms['uSource'], dye.read.attach(1));\n gl.uniform1f(advectionProgram.uniforms['dissipation'], config.densityDissipation);\n blit(dye.write);\n dye.swap();\n }\n\n function render(): void {\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.enable(gl.BLEND);\n displayMaterial.bind();\n if (shading) {\n gl.uniform2f(displayMaterial.uniforms['texelSize'], 1 / gl.drawingBufferWidth, 1 / gl.drawingBufferHeight);\n }\n gl.uniform1i(displayMaterial.uniforms['uTexture'], dye.read.attach(0));\n blit(null);\n }\n\n // Splats\n\n function splatPointer(): void {\n const dx = pointer.deltaX * config.splatForce;\n const dy = pointer.deltaY * config.splatForce;\n splat(pointer.texcoordX, pointer.texcoordY, dx, dy, pointer.color);\n }\n\n function clickSplat(): void {\n const color = generateColor();\n color.r *= 10;\n color.g *= 10;\n color.b *= 10;\n const dx = 10 * (Math.random() - 0.5);\n const dy = 30 * (Math.random() - 0.5);\n splat(pointer.texcoordX, pointer.texcoordY, dx, dy, color);\n }\n\n function splat(x: number, y: number, dx: number, dy: number, color: RGB): void {\n splatProgram.bind();\n gl.uniform1i(splatProgram.uniforms['uTarget'], velocity.read.attach(0));\n gl.uniform1f(splatProgram.uniforms['aspectRatio'], canvas.width / canvas.height);\n gl.uniform2f(splatProgram.uniforms['point'], x, y);\n gl.uniform3f(splatProgram.uniforms['color'], dx, dy, 0);\n gl.uniform1f(splatProgram.uniforms['radius'], correctRadius(config.splatRadius / 100));\n blit(velocity.write);\n velocity.swap();\n\n gl.uniform1i(splatProgram.uniforms['uTarget'], dye.read.attach(0));\n gl.uniform3f(splatProgram.uniforms['color'], color.r, color.g, color.b);\n blit(dye.write);\n dye.swap();\n }\n\n function correctRadius(radius: number): number {\n const aspectRatio = canvas.width / canvas.height;\n return aspectRatio > 1 ? radius * aspectRatio : radius;\n }\n\n // Pointer\n\n function pointerDown(posX: number, posY: number): void {\n pointer.moved = false;\n pointer.texcoordX = posX / canvas.width;\n pointer.texcoordY = 1 - posY / canvas.height;\n pointer.prevTexcoordX = pointer.texcoordX;\n pointer.prevTexcoordY = pointer.texcoordY;\n pointer.deltaX = 0;\n pointer.deltaY = 0;\n pointer.color = generateColor();\n }\n\n function pointerMove(posX: number, posY: number, color: RGB): void {\n pointer.prevTexcoordX = pointer.texcoordX;\n pointer.prevTexcoordY = pointer.texcoordY;\n pointer.texcoordX = posX / canvas.width;\n pointer.texcoordY = 1 - posY / canvas.height;\n pointer.deltaX = correctDeltaX(pointer.texcoordX - pointer.prevTexcoordX);\n pointer.deltaY = correctDeltaY(pointer.texcoordY - pointer.prevTexcoordY);\n pointer.moved = Math.abs(pointer.deltaX) > 0 || Math.abs(pointer.deltaY) > 0;\n pointer.color = color;\n }\n\n function correctDeltaX(delta: number): number {\n const aspectRatio = canvas.width / canvas.height;\n return aspectRatio < 1 ? delta * aspectRatio : delta;\n }\n\n function correctDeltaY(delta: number): number {\n const aspectRatio = canvas.width / canvas.height;\n return aspectRatio > 1 ? delta / aspectRatio : delta;\n }\n\n // Colours\n\n function hexToRGB(hex: string): RGB {\n let val = hex.replace('#', '');\n if (val.length === 3) val = val[0] + val[0] + val[1] + val[1] + val[2] + val[2];\n return {\n r: (Number.parseInt(val.slice(0, 2), 16) / 255) * 0.15,\n g: (Number.parseInt(val.slice(2, 4), 16) / 255) * 0.15,\n b: (Number.parseInt(val.slice(4, 6), 16) / 255) * 0.15,\n };\n }\n\n function generateColor(): RGB {\n if (!config.rainbow) return hexToRGB(config.color);\n const c = hsvToRgb(Math.random(), 1, 1);\n c.r *= 0.15;\n c.g *= 0.15;\n c.b *= 0.15;\n return c;\n }\n\n function hsvToRgb(h: number, s: number, v: number): RGB {\n const i = Math.floor(h * 6);\n const f = h * 6 - i;\n const p = v * (1 - s);\n const q = v * (1 - f * s);\n const t = v * (1 - (1 - f) * s);\n switch (i % 6) {\n case 0:\n return { r: v, g: t, b: p };\n case 1:\n return { r: q, g: v, b: p };\n case 2:\n return { r: p, g: v, b: t };\n case 3:\n return { r: p, g: q, b: v };\n case 4:\n return { r: t, g: p, b: v };\n default:\n return { r: v, g: p, b: q };\n }\n }\n\n function wrap(value: number, min: number, max: number): number {\n const range = max - min;\n if (range === 0) return min;\n return ((value - min) % range) + min;\n }\n\n function getResolution(resolution: number): { width: number; height: number } {\n let aspectRatio = gl.drawingBufferWidth / gl.drawingBufferHeight;\n if (aspectRatio < 1) aspectRatio = 1 / aspectRatio;\n const min = Math.round(resolution);\n const max = Math.round(resolution * aspectRatio);\n return gl.drawingBufferWidth > gl.drawingBufferHeight ? { width: max, height: min } : { width: min, height: max };\n }\n\n function scaleByPixelRatio(input: number): number {\n return Math.floor(input * (window.devicePixelRatio || 1));\n }\n\n function hashCode(s: string): number {\n let hash = 0;\n for (let i = 0; i < s.length; i++) {\n hash = (hash << 5) - hash + s.charCodeAt(i);\n hash |= 0;\n }\n return hash;\n }\n\n // Events + boot\n\n let firstMoveHandled = false;\n\n // Coordinates are taken relative to the canvas box: identical to the\n // raw client position for the fullscreen overlay, and it makes a\n // contained canvas track the pointer correctly too.\n const toLocal = (clientX: number, clientY: number): { x: number; y: number } => {\n const rect = canvas.getBoundingClientRect();\n return { x: scaleByPixelRatio(clientX - rect.left), y: scaleByPixelRatio(clientY - rect.top) };\n };\n\n const onMouseDown = (e: MouseEvent): void => {\n const pos = toLocal(e.clientX, e.clientY);\n pointerDown(pos.x, pos.y);\n clickSplat();\n };\n\n const onMouseMove = (e: MouseEvent): void => {\n const pos = toLocal(e.clientX, e.clientY);\n const color = firstMoveHandled ? pointer.color : generateColor();\n firstMoveHandled = true;\n pointerMove(pos.x, pos.y, color);\n };\n\n const onTouchStart = (e: TouchEvent): void => {\n const t = e.targetTouches[0];\n if (!t) return;\n const pos = toLocal(t.clientX, t.clientY);\n pointerDown(pos.x, pos.y);\n };\n\n const onTouchMove = (e: TouchEvent): void => {\n const t = e.targetTouches[0];\n if (!t) return;\n const pos = toLocal(t.clientX, t.clientY);\n pointerMove(pos.x, pos.y, pointer.color);\n };\n\n window.addEventListener('mousedown', onMouseDown);\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('touchstart', onTouchStart, { passive: true });\n window.addEventListener('touchmove', onTouchMove, { passive: true });\n\n // A contained canvas scrolled out of view stops asking for frames, the way\n // `wr-waves` does: the solver runs every pass of the pipeline each frame, for\n // nothing anyone can see. The fullscreen overlay is always in view. Without an\n // observer (jsdom) it simply runs.\n let visible = true;\n const io =\n typeof IntersectionObserver === 'undefined'\n ? null\n : new IntersectionObserver(entries => {\n visible = entries[entries.length - 1].isIntersecting;\n if (visible && active && rafId === 0) {\n // The time away is not simulated: the first frame back steps from now.\n lastUpdateTime = Date.now();\n rafId = requestAnimationFrame(updateFrame);\n }\n });\n io?.observe(canvas);\n\n updateFrame();\n\n return () => {\n active = false;\n cancelAnimationFrame(rafId);\n io?.disconnect();\n window.removeEventListener('mousedown', onMouseDown);\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('touchstart', onTouchStart);\n window.removeEventListener('touchmove', onTouchMove);\n // The context is NOT lost here on purpose — input changes reboot the\n // sim on the same canvas, and a lost context can't be re-acquired. So\n // everything this boot allocated on it is freed by hand instead.\n for (const target of [dye, velocity, pressure]) disposeDoubleFBO(target);\n disposeFBO(divergence);\n disposeFBO(curl);\n for (const program of programs) gl.deleteProgram(program);\n for (const shader of shaders) gl.deleteShader(shader);\n for (const buffer of buffers) gl.deleteBuffer(buffer);\n };\n}\n\n// WebGL context bootstrap\n\nfunction getWebGLContext(canvas: HTMLCanvasElement): { gl: GL; ext: GlExt } | null {\n const params: WebGLContextAttributes = {\n alpha: true,\n depth: false,\n stencil: false,\n antialias: false,\n preserveDrawingBuffer: false,\n };\n\n const gl2 = canvas.getContext('webgl2', params);\n const gl = gl2 ?? canvas.getContext('webgl', params);\n if (!gl) return null;\n const isWebGL2 = !!gl2;\n\n let halfFloat: OES_texture_half_float | null = null;\n let supportLinearFiltering: boolean;\n if (isWebGL2) {\n gl.getExtension('EXT_color_buffer_float');\n supportLinearFiltering = !!gl.getExtension('OES_texture_float_linear');\n } else {\n halfFloat = gl.getExtension('OES_texture_half_float');\n supportLinearFiltering = !!gl.getExtension('OES_texture_half_float_linear');\n }\n gl.clearColor(0, 0, 0, 1);\n\n const halfFloatTexType = isWebGL2\n ? (gl as WebGL2RenderingContext).HALF_FLOAT\n : (halfFloat?.HALF_FLOAT_OES ?? gl.UNSIGNED_BYTE);\n\n let formatRGBA: TexFormat | null;\n let formatRG: TexFormat | null;\n let formatR: TexFormat | null;\n if (isWebGL2) {\n const g2 = gl as WebGL2RenderingContext;\n formatRGBA = getSupportedFormat(g2, g2.RGBA16F, g2.RGBA, halfFloatTexType);\n formatRG = getSupportedFormat(g2, g2.RG16F, g2.RG, halfFloatTexType);\n formatR = getSupportedFormat(g2, g2.R16F, g2.RED, halfFloatTexType);\n } else {\n formatRGBA = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType);\n formatRG = formatRGBA;\n formatR = formatRGBA;\n }\n if (!formatRGBA || !formatRG || !formatR) return null;\n\n return { gl, ext: { formatRGBA, formatRG, formatR, halfFloatTexType, supportLinearFiltering } };\n}\n\nfunction getSupportedFormat(gl: GL, internalFormat: number, format: number, type: number): TexFormat | null {\n if (!supportRenderTextureFormat(gl, internalFormat, format, type)) {\n const g2 = gl as WebGL2RenderingContext;\n switch (internalFormat) {\n case g2.R16F:\n return getSupportedFormat(gl, g2.RG16F, g2.RG, type);\n case g2.RG16F:\n return getSupportedFormat(gl, g2.RGBA16F, g2.RGBA, type);\n default:\n return null;\n }\n }\n return { internalFormat, format };\n}\n\nfunction supportRenderTextureFormat(gl: GL, internalFormat: number, format: number, type: number): boolean {\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 4, 4, 0, format, type, null);\n const fbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n const complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;\n // A probe, run on every boot: free it, or each reboot leaves one behind.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(fbo);\n gl.deleteTexture(texture);\n return complete;\n}\n\nexport { createFluidSimulation };\nexport type { WrFluidConfig };\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n *\n * Angular adaptation of the SplashCursor effect by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/animations/splash-cursor\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport type { ElementRef } from '@angular/core';\nimport { Component, NgZone, PLATFORM_ID, ViewEncapsulation, effect, inject, input, viewChild } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\nimport { createFluidSimulation } from './fluid';\n\n/**\n * Splash cursor — a WebGL fluid simulation that splashes colourful dye\n * wherever the pointer moves or clicks. Renders as a fixed, full-viewport,\n * click-through overlay; mount it once on a page (it follows the pointer\n * everywhere) and it tears down with the component.\n *\n * Renders nothing under `prefers-reduced-motion` or when WebGL is\n * unavailable.\n *\n * @example\n * ```html\n * <wr-splash-cursor />\n * <wr-splash-cursor [rainbow]=\"false\" color=\"#5227ff\" />\n * ```\n *\n * @see https://ngwr.dev/bits/splash-cursor\n */\n@Component({\n selector: 'wr-splash-cursor',\n template: '<canvas #canvas class=\"wr-splash-cursor__canvas\" aria-hidden=\"true\"></canvas>',\n styleUrl: './splash-cursor.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-splash-cursor',\n '[class.wr-splash-cursor--contained]': '!fullscreen()',\n },\n})\nexport class WrSplashCursor {\n /**\n * `true` overlays the whole viewport (reactbits behaviour); `false`\n * fills the nearest positioned ancestor instead — handy for demo boxes,\n * and the dye collides with the box walls. @default true\n */\n readonly fullscreen = input(true, { transform: coerceBooleanProperty });\n\n /** Velocity / pressure grid resolution. @default 128 */\n readonly simResolution = input(128, { transform: numAttr(128) });\n\n /** Dye texture resolution — the visible detail. @default 1440 */\n readonly dyeResolution = input(1440, { transform: numAttr(1440) });\n\n /** How fast the dye fades, higher = shorter trails. @default 3.5 */\n readonly densityDissipation = input(3.5, { transform: numAttr(3.5) });\n\n /** How fast motion settles. @default 2 */\n readonly velocityDissipation = input(2, { transform: numAttr(2) });\n\n /** Pressure retained between frames, 0..1. @default 0.1 */\n readonly pressure = input(0.1, { transform: numAttr(0.1) });\n\n /** Jacobi iterations for the pressure solve. @default 20 */\n readonly pressureIterations = input(20, { transform: numAttr(20) });\n\n /** Vorticity confinement — swirliness. @default 3 */\n readonly curl = input(3, { transform: numAttr(3) });\n\n /** Splat size. @default 0.2 */\n readonly splatRadius = input(0.2, { transform: numAttr(0.2) });\n\n /** Velocity a pointer move injects. @default 6000 */\n readonly splatForce = input(6000, { transform: numAttr(6000) });\n\n /** Pseudo-3D shading on the dye. @default true */\n readonly shading = input(true, { transform: coerceBooleanProperty });\n\n /** How fast the splat colour cycles. @default 10 */\n readonly colorUpdateSpeed = input(10, { transform: numAttr(10) });\n\n /** Cycle splat colours through the rainbow. @default true */\n readonly rainbow = input(true, { transform: coerceBooleanProperty });\n\n /** Fixed splat colour when `rainbow` is off. @default '#ff0000' */\n readonly color = input('#ff0000');\n\n private readonly canvasRef = viewChild<ElementRef<HTMLCanvasElement>>('canvas');\n\n private readonly zone = inject(NgZone);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n constructor() {\n if (!this.isBrowser) return;\n\n // (Re)boot whenever the canvas appears, any input changes, or the OS\n // reduced-motion preference flips. `onCleanup` tears the old sim down.\n effect(onCleanup => {\n const canvas = this.canvasRef()?.nativeElement;\n const config = {\n simResolution: this.simResolution(),\n dyeResolution: this.dyeResolution(),\n densityDissipation: this.densityDissipation(),\n velocityDissipation: this.velocityDissipation(),\n pressure: this.pressure(),\n pressureIterations: this.pressureIterations(),\n curl: this.curl(),\n splatRadius: this.splatRadius(),\n splatForce: this.splatForce(),\n shading: this.shading(),\n colorUpdateSpeed: this.colorUpdateSpeed(),\n rainbow: this.rainbow(),\n color: this.color(),\n };\n if (!canvas || this.platform.prefersReducedMotion()) return;\n const teardown = this.zone.runOutsideAngular(() => createFluidSimulation(canvas, config));\n if (teardown) onCleanup(teardown);\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-bits-splash-cursor.mjs","names":[],"sources":["../../../projects/lib/bits/splash-cursor/fluid.ts","../../../projects/lib/bits/splash-cursor/splash-cursor.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n *\n * WebGL fluid simulation behind `<wr-splash-cursor>`. Port of the engine\n * used by reactbits.dev's SplashCursor (itself based on Pavel Dobryakov's\n * WebGL-Fluid-Simulation, MIT).\n *\n * Framework-free on purpose: `createFluidSimulation(canvas, config)` boots\n * the sim and returns a teardown, or `null` when WebGL isn't available.\n */\n\n/* eslint-disable no-bitwise -- GL bitmasks + string hashing are inherently bitwise */\n\ninterface WrFluidConfig {\n readonly simResolution: number;\n readonly dyeResolution: number;\n readonly densityDissipation: number;\n readonly velocityDissipation: number;\n readonly pressure: number;\n readonly pressureIterations: number;\n readonly curl: number;\n readonly splatRadius: number;\n readonly splatForce: number;\n readonly shading: boolean;\n readonly colorUpdateSpeed: number;\n /** Cycle splat colours through the rainbow; `false` uses `color`. */\n readonly rainbow: boolean;\n /** Fixed splat colour (hex) when `rainbow` is off. */\n readonly color: string;\n}\n\ninterface RGB {\n r: number;\n g: number;\n b: number;\n}\n\ninterface TexFormat {\n readonly internalFormat: number;\n readonly format: number;\n}\n\ninterface GlExt {\n readonly formatRGBA: TexFormat;\n readonly formatRG: TexFormat;\n readonly formatR: TexFormat;\n readonly halfFloatTexType: number;\n readonly supportLinearFiltering: boolean;\n}\n\ninterface FBO {\n readonly texture: WebGLTexture;\n readonly fbo: WebGLFramebuffer;\n readonly width: number;\n readonly height: number;\n readonly texelSizeX: number;\n readonly texelSizeY: number;\n attach(id: number): number;\n}\n\ninterface DoubleFBO {\n width: number;\n height: number;\n texelSizeX: number;\n texelSizeY: number;\n read: FBO;\n write: FBO;\n swap(): void;\n}\n\ninterface Pointer {\n texcoordX: number;\n texcoordY: number;\n prevTexcoordX: number;\n prevTexcoordY: number;\n deltaX: number;\n deltaY: number;\n moved: boolean;\n color: RGB;\n}\n\ntype GL = WebGLRenderingContext | WebGL2RenderingContext;\ntype Uniforms = Record<string, WebGLUniformLocation | null>;\n\nfunction createFluidSimulation(canvas: HTMLCanvasElement, config: WrFluidConfig): (() => void) | null {\n const ctx = getWebGLContext(canvas);\n if (!ctx) return null;\n const { gl, ext } = ctx;\n\n let dyeResolution = config.dyeResolution;\n let shading = config.shading;\n if (!ext.supportLinearFiltering) {\n dyeResolution = 256;\n shading = false;\n }\n\n let active = true;\n let rafId = 0;\n /** Whether the canvas has a layout box with an area; measured by the frame, and by the resize observer. */\n let hasBox = false;\n\n // Every GL object this boot creates, so the teardown can free them. The\n // context outlives the sim (an input change reboots on the same canvas),\n // so anything left here is GPU memory nobody can reach again.\n const shaders: WebGLShader[] = [];\n const programs: WebGLProgram[] = [];\n const buffers: WebGLBuffer[] = [];\n\n const pointer: Pointer = {\n texcoordX: 0,\n texcoordY: 0,\n prevTexcoordX: 0,\n prevTexcoordY: 0,\n deltaX: 0,\n deltaY: 0,\n moved: false,\n color: { r: 0, g: 0, b: 0 },\n };\n\n // Shader plumbing\n\n function compile(type: number, source: string, keywords?: readonly string[]): WebGLShader {\n const prefixed = keywords ? keywords.map(k => `#define ${k}\\n`).join('') + source : source;\n const shader = gl.createShader(type)!;\n shaders.push(shader);\n gl.shaderSource(shader, prefixed);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n // eslint-disable-next-line no-console -- GPU shader failures are otherwise invisible\n console.error('wr-splash-cursor shader error:', gl.getShaderInfoLog(shader));\n }\n return shader;\n }\n\n function link(vertex: WebGLShader, fragment: WebGLShader): WebGLProgram {\n const program = gl.createProgram();\n programs.push(program);\n gl.attachShader(program, vertex);\n gl.attachShader(program, fragment);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n // eslint-disable-next-line no-console -- GPU link failures are otherwise invisible\n console.error('wr-splash-cursor program error:', gl.getProgramInfoLog(program));\n }\n return program;\n }\n\n function uniformsOf(program: WebGLProgram): Uniforms {\n const out: Uniforms = {};\n const count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS) as number;\n for (let i = 0; i < count; i++) {\n const name = gl.getActiveUniform(program, i)!.name;\n out[name] = gl.getUniformLocation(program, name);\n }\n return out;\n }\n\n class ShaderProgram {\n readonly program: WebGLProgram;\n readonly uniforms: Uniforms;\n\n constructor(vertex: WebGLShader, fragment: WebGLShader) {\n this.program = link(vertex, fragment);\n this.uniforms = uniformsOf(this.program);\n }\n\n bind(): void {\n gl.useProgram(this.program);\n }\n }\n\n /** Display shader with `#define`-keyword program variants. */\n class DisplayMaterial {\n private readonly programs = new Map<number, WebGLProgram>();\n private activeProgram: WebGLProgram | null = null;\n uniforms: Uniforms = {};\n\n constructor(\n private readonly vertex: WebGLShader,\n private readonly fragmentSource: string\n ) {}\n\n setKeywords(keywords: readonly string[]): void {\n let hash = 0;\n for (const k of keywords) hash += hashCode(k);\n let program = this.programs.get(hash);\n if (!program) {\n program = link(this.vertex, compile(gl.FRAGMENT_SHADER, this.fragmentSource, keywords));\n this.programs.set(hash, program);\n }\n if (program === this.activeProgram) return;\n this.uniforms = uniformsOf(program);\n this.activeProgram = program;\n }\n\n bind(): void {\n gl.useProgram(this.activeProgram);\n }\n }\n\n // Shaders\n\n const baseVertexShader = compile(\n gl.VERTEX_SHADER,\n `\n precision highp float;\n attribute vec2 aPosition;\n varying vec2 vUv;\n varying vec2 vL;\n varying vec2 vR;\n varying vec2 vT;\n varying vec2 vB;\n uniform vec2 texelSize;\n\n void main () {\n vUv = aPosition * 0.5 + 0.5;\n vL = vUv - vec2(texelSize.x, 0.0);\n vR = vUv + vec2(texelSize.x, 0.0);\n vT = vUv + vec2(0.0, texelSize.y);\n vB = vUv - vec2(0.0, texelSize.y);\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `\n );\n\n const copyShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n uniform sampler2D uTexture;\n\n void main () {\n gl_FragColor = texture2D(uTexture, vUv);\n }\n `\n );\n\n const clearShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n uniform sampler2D uTexture;\n uniform float value;\n\n void main () {\n gl_FragColor = value * texture2D(uTexture, vUv);\n }\n `\n );\n\n const displayShaderSource = `\n precision highp float;\n precision highp sampler2D;\n varying vec2 vUv;\n varying vec2 vL;\n varying vec2 vR;\n varying vec2 vT;\n varying vec2 vB;\n uniform sampler2D uTexture;\n uniform vec2 texelSize;\n\n void main () {\n vec3 c = texture2D(uTexture, vUv).rgb;\n #ifdef SHADING\n vec3 lc = texture2D(uTexture, vL).rgb;\n vec3 rc = texture2D(uTexture, vR).rgb;\n vec3 tc = texture2D(uTexture, vT).rgb;\n vec3 bc = texture2D(uTexture, vB).rgb;\n\n float dx = length(rc) - length(lc);\n float dy = length(tc) - length(bc);\n\n vec3 n = normalize(vec3(dx, dy, length(texelSize)));\n vec3 l = vec3(0.0, 0.0, 1.0);\n\n float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);\n c *= diffuse;\n #endif\n\n float a = max(c.r, max(c.g, c.b));\n gl_FragColor = vec4(c, a);\n }\n `;\n\n const splatShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision highp float;\n precision highp sampler2D;\n varying vec2 vUv;\n uniform sampler2D uTarget;\n uniform float aspectRatio;\n uniform vec3 color;\n uniform vec2 point;\n uniform float radius;\n\n void main () {\n vec2 p = vUv - point.xy;\n p.x *= aspectRatio;\n vec3 splat = exp(-dot(p, p) / radius) * color;\n vec3 base = texture2D(uTarget, vUv).xyz;\n gl_FragColor = vec4(base + splat, 1.0);\n }\n `\n );\n\n const advectionShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision highp float;\n precision highp sampler2D;\n varying vec2 vUv;\n uniform sampler2D uVelocity;\n uniform sampler2D uSource;\n uniform vec2 texelSize;\n uniform vec2 dyeTexelSize;\n uniform float dt;\n uniform float dissipation;\n\n vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {\n vec2 st = uv / tsize - 0.5;\n vec2 iuv = floor(st);\n vec2 fuv = fract(st);\n\n vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);\n vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);\n vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);\n vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);\n\n return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);\n }\n\n void main () {\n #ifdef MANUAL_FILTERING\n vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize;\n vec4 result = bilerp(uSource, coord, dyeTexelSize);\n #else\n vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;\n vec4 result = texture2D(uSource, coord);\n #endif\n float decay = 1.0 + dissipation * dt;\n gl_FragColor = result / decay;\n }\n `,\n ext.supportLinearFiltering ? undefined : ['MANUAL_FILTERING']\n );\n\n const divergenceShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n varying highp vec2 vL;\n varying highp vec2 vR;\n varying highp vec2 vT;\n varying highp vec2 vB;\n uniform sampler2D uVelocity;\n\n void main () {\n float L = texture2D(uVelocity, vL).x;\n float R = texture2D(uVelocity, vR).x;\n float T = texture2D(uVelocity, vT).y;\n float B = texture2D(uVelocity, vB).y;\n\n vec2 C = texture2D(uVelocity, vUv).xy;\n if (vL.x < 0.0) { L = -C.x; }\n if (vR.x > 1.0) { R = -C.x; }\n if (vT.y > 1.0) { T = -C.y; }\n if (vB.y < 0.0) { B = -C.y; }\n\n float div = 0.5 * (R - L + T - B);\n gl_FragColor = vec4(div, 0.0, 0.0, 1.0);\n }\n `\n );\n\n const curlShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n varying highp vec2 vL;\n varying highp vec2 vR;\n varying highp vec2 vT;\n varying highp vec2 vB;\n uniform sampler2D uVelocity;\n\n void main () {\n float L = texture2D(uVelocity, vL).y;\n float R = texture2D(uVelocity, vR).y;\n float T = texture2D(uVelocity, vT).x;\n float B = texture2D(uVelocity, vB).x;\n float vorticity = R - L - T + B;\n gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0);\n }\n `\n );\n\n const vorticityShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision highp float;\n precision highp sampler2D;\n varying vec2 vUv;\n varying vec2 vL;\n varying vec2 vR;\n varying vec2 vT;\n varying vec2 vB;\n uniform sampler2D uVelocity;\n uniform sampler2D uCurl;\n uniform float curl;\n uniform float dt;\n\n void main () {\n float L = texture2D(uCurl, vL).x;\n float R = texture2D(uCurl, vR).x;\n float T = texture2D(uCurl, vT).x;\n float B = texture2D(uCurl, vB).x;\n float C = texture2D(uCurl, vUv).x;\n\n vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));\n force /= length(force) + 0.0001;\n force *= curl * C;\n force.y *= -1.0;\n\n vec2 velocity = texture2D(uVelocity, vUv).xy;\n velocity += force * dt;\n velocity = min(max(velocity, -1000.0), 1000.0);\n gl_FragColor = vec4(velocity, 0.0, 1.0);\n }\n `\n );\n\n const pressureShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n varying highp vec2 vL;\n varying highp vec2 vR;\n varying highp vec2 vT;\n varying highp vec2 vB;\n uniform sampler2D uPressure;\n uniform sampler2D uDivergence;\n\n void main () {\n float L = texture2D(uPressure, vL).x;\n float R = texture2D(uPressure, vR).x;\n float T = texture2D(uPressure, vT).x;\n float B = texture2D(uPressure, vB).x;\n float C = texture2D(uPressure, vUv).x;\n float divergence = texture2D(uDivergence, vUv).x;\n float pressure = (L + R + B + T - divergence) * 0.25;\n gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0);\n }\n `\n );\n\n const gradientSubtractShader = compile(\n gl.FRAGMENT_SHADER,\n `\n precision mediump float;\n precision mediump sampler2D;\n varying highp vec2 vUv;\n varying highp vec2 vL;\n varying highp vec2 vR;\n varying highp vec2 vT;\n varying highp vec2 vB;\n uniform sampler2D uPressure;\n uniform sampler2D uVelocity;\n\n void main () {\n float L = texture2D(uPressure, vL).x;\n float R = texture2D(uPressure, vR).x;\n float T = texture2D(uPressure, vT).x;\n float B = texture2D(uPressure, vB).x;\n vec2 velocity = texture2D(uVelocity, vUv).xy;\n velocity.xy -= vec2(R - L, T - B);\n gl_FragColor = vec4(velocity, 0.0, 1.0);\n }\n `\n );\n\n // Fullscreen blit\n\n const vertexBuffer = gl.createBuffer();\n const indexBuffer = gl.createBuffer();\n buffers.push(vertexBuffer, indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), gl.STATIC_DRAW);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 0, 2, 3]), gl.STATIC_DRAW);\n gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(0);\n\n function blit(target: FBO | null, clear = false): void {\n if (target === null) {\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n } else {\n gl.viewport(0, 0, target.width, target.height);\n gl.bindFramebuffer(gl.FRAMEBUFFER, target.fbo);\n }\n if (clear) {\n gl.clearColor(0.0, 0.0, 0.0, 1.0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);\n }\n\n // Framebuffers\n\n function createFBO(w: number, h: number, internalFormat: number, format: number, type: number, param: number): FBO {\n gl.activeTexture(gl.TEXTURE0);\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, param);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, param);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, w, h, 0, format, type, null);\n\n const fbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n gl.viewport(0, 0, w, h);\n gl.clear(gl.COLOR_BUFFER_BIT);\n\n return {\n texture,\n fbo,\n width: w,\n height: h,\n texelSizeX: 1 / w,\n texelSizeY: 1 / h,\n attach(id: number): number {\n gl.activeTexture(gl.TEXTURE0 + id);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n return id;\n },\n };\n }\n\n function disposeFBO(target: FBO): void {\n gl.deleteTexture(target.texture);\n gl.deleteFramebuffer(target.fbo);\n }\n\n function disposeDoubleFBO(target: DoubleFBO): void {\n disposeFBO(target.read);\n disposeFBO(target.write);\n }\n\n function createDoubleFBO(\n w: number,\n h: number,\n internalFormat: number,\n format: number,\n type: number,\n param: number\n ): DoubleFBO {\n let fbo1 = createFBO(w, h, internalFormat, format, type, param);\n let fbo2 = createFBO(w, h, internalFormat, format, type, param);\n return {\n width: w,\n height: h,\n texelSizeX: fbo1.texelSizeX,\n texelSizeY: fbo1.texelSizeY,\n get read() {\n return fbo1;\n },\n set read(value: FBO) {\n fbo1 = value;\n },\n get write() {\n return fbo2;\n },\n set write(value: FBO) {\n fbo2 = value;\n },\n swap(): void {\n const temp = fbo1;\n fbo1 = fbo2;\n fbo2 = temp;\n },\n };\n }\n\n function resizeFBO(\n target: FBO,\n w: number,\n h: number,\n internalFormat: number,\n format: number,\n type: number,\n param: number\n ): FBO {\n const newFBO = createFBO(w, h, internalFormat, format, type, param);\n copyProgram.bind();\n gl.uniform1i(copyProgram.uniforms['uTexture'], target.attach(0));\n blit(newFBO);\n disposeFBO(target);\n return newFBO;\n }\n\n function resizeDoubleFBO(\n target: DoubleFBO,\n w: number,\n h: number,\n internalFormat: number,\n format: number,\n type: number,\n param: number\n ): DoubleFBO {\n if (target.width === w && target.height === h) return target;\n target.read = resizeFBO(target.read, w, h, internalFormat, format, type, param);\n disposeFBO(target.write);\n target.write = createFBO(w, h, internalFormat, format, type, param);\n target.width = w;\n target.height = h;\n target.texelSizeX = 1 / w;\n target.texelSizeY = 1 / h;\n return target;\n }\n\n // Programs + state\n\n const copyProgram = new ShaderProgram(baseVertexShader, copyShader);\n const clearProgram = new ShaderProgram(baseVertexShader, clearShader);\n const splatProgram = new ShaderProgram(baseVertexShader, splatShader);\n const advectionProgram = new ShaderProgram(baseVertexShader, advectionShader);\n const divergenceProgram = new ShaderProgram(baseVertexShader, divergenceShader);\n const curlProgram = new ShaderProgram(baseVertexShader, curlShader);\n const vorticityProgram = new ShaderProgram(baseVertexShader, vorticityShader);\n const pressureProgram = new ShaderProgram(baseVertexShader, pressureShader);\n const gradientSubtractProgram = new ShaderProgram(baseVertexShader, gradientSubtractShader);\n const displayMaterial = new DisplayMaterial(baseVertexShader, displayShaderSource);\n\n let dye!: DoubleFBO;\n let velocity!: DoubleFBO;\n let divergence!: FBO;\n let curl!: FBO;\n let pressure!: DoubleFBO;\n\n function initFramebuffers(): void {\n const simRes = getResolution(config.simResolution);\n const dyeRes = getResolution(dyeResolution);\n const texType = ext.halfFloatTexType;\n const rgba = ext.formatRGBA;\n const rg = ext.formatRG;\n const r = ext.formatR;\n const filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST;\n gl.disable(gl.BLEND);\n\n dye = dye\n ? resizeDoubleFBO(dye, dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering)\n : createDoubleFBO(dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering);\n\n velocity = velocity\n ? resizeDoubleFBO(velocity, simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering)\n : createDoubleFBO(simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering);\n\n // Recreated on every resize rather than resized, so the previous ones go first.\n if (divergence) disposeFBO(divergence);\n if (curl) disposeFBO(curl);\n if (pressure) disposeDoubleFBO(pressure);\n divergence = createFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);\n curl = createFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);\n pressure = createDoubleFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST);\n }\n\n displayMaterial.setKeywords(shading ? ['SHADING'] : []);\n initFramebuffers();\n let lastUpdateTime = Date.now();\n let colorUpdateTimer = 0;\n\n // Frame loop\n\n function updateFrame(): void {\n rafId = 0;\n if (!active || !visible) return;\n const dt = calcDeltaTime();\n if (resizeCanvas()) initFramebuffers();\n // No box, nothing to see: every pass of the solver would run for an empty\n // canvas, and the resolution maths would divide by a zero-sized drawing\n // buffer. The resize observer wakes the loop once the box is back.\n if (!hasBox) return;\n updateColors(dt);\n applyInputs();\n step(dt);\n render();\n rafId = requestAnimationFrame(updateFrame);\n }\n\n function calcDeltaTime(): number {\n const now = Date.now();\n const dt = Math.min((now - lastUpdateTime) / 1000, 0.016666);\n lastUpdateTime = now;\n return dt;\n }\n\n function resizeCanvas(): boolean {\n const width = scaleByPixelRatio(canvas.clientWidth);\n const height = scaleByPixelRatio(canvas.clientHeight);\n // The layout box, read by the frame itself so the first one knows it too. A\n // box with no area leaves the bitmap as it was: nothing can be seen on it.\n hasBox = width > 0 && height > 0;\n if (!hasBox || (canvas.width === width && canvas.height === height)) return false;\n canvas.width = width;\n canvas.height = height;\n return true;\n }\n\n function updateColors(dt: number): void {\n colorUpdateTimer += dt * config.colorUpdateSpeed;\n if (colorUpdateTimer >= 1) {\n colorUpdateTimer = wrap(colorUpdateTimer, 0, 1);\n pointer.color = generateColor();\n }\n }\n\n function applyInputs(): void {\n if (pointer.moved) {\n pointer.moved = false;\n splatPointer();\n }\n }\n\n function step(dt: number): void {\n gl.disable(gl.BLEND);\n curlProgram.bind();\n gl.uniform2f(curlProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(curlProgram.uniforms['uVelocity'], velocity.read.attach(0));\n blit(curl);\n\n vorticityProgram.bind();\n gl.uniform2f(vorticityProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(vorticityProgram.uniforms['uVelocity'], velocity.read.attach(0));\n gl.uniform1i(vorticityProgram.uniforms['uCurl'], curl.attach(1));\n gl.uniform1f(vorticityProgram.uniforms['curl'], config.curl);\n gl.uniform1f(vorticityProgram.uniforms['dt'], dt);\n blit(velocity.write);\n velocity.swap();\n\n divergenceProgram.bind();\n gl.uniform2f(divergenceProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(divergenceProgram.uniforms['uVelocity'], velocity.read.attach(0));\n blit(divergence);\n\n clearProgram.bind();\n gl.uniform1i(clearProgram.uniforms['uTexture'], pressure.read.attach(0));\n gl.uniform1f(clearProgram.uniforms['value'], config.pressure);\n blit(pressure.write);\n pressure.swap();\n\n pressureProgram.bind();\n gl.uniform2f(pressureProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(pressureProgram.uniforms['uDivergence'], divergence.attach(0));\n for (let i = 0; i < config.pressureIterations; i++) {\n gl.uniform1i(pressureProgram.uniforms['uPressure'], pressure.read.attach(1));\n blit(pressure.write);\n pressure.swap();\n }\n\n gradientSubtractProgram.bind();\n gl.uniform2f(gradientSubtractProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n gl.uniform1i(gradientSubtractProgram.uniforms['uPressure'], pressure.read.attach(0));\n gl.uniform1i(gradientSubtractProgram.uniforms['uVelocity'], velocity.read.attach(1));\n blit(velocity.write);\n velocity.swap();\n\n advectionProgram.bind();\n gl.uniform2f(advectionProgram.uniforms['texelSize'], velocity.texelSizeX, velocity.texelSizeY);\n if (!ext.supportLinearFiltering) {\n gl.uniform2f(advectionProgram.uniforms['dyeTexelSize'], velocity.texelSizeX, velocity.texelSizeY);\n }\n const velocityId = velocity.read.attach(0);\n gl.uniform1i(advectionProgram.uniforms['uVelocity'], velocityId);\n gl.uniform1i(advectionProgram.uniforms['uSource'], velocityId);\n gl.uniform1f(advectionProgram.uniforms['dt'], dt);\n gl.uniform1f(advectionProgram.uniforms['dissipation'], config.velocityDissipation);\n blit(velocity.write);\n velocity.swap();\n\n if (!ext.supportLinearFiltering) {\n gl.uniform2f(advectionProgram.uniforms['dyeTexelSize'], dye.texelSizeX, dye.texelSizeY);\n }\n gl.uniform1i(advectionProgram.uniforms['uVelocity'], velocity.read.attach(0));\n gl.uniform1i(advectionProgram.uniforms['uSource'], dye.read.attach(1));\n gl.uniform1f(advectionProgram.uniforms['dissipation'], config.densityDissipation);\n blit(dye.write);\n dye.swap();\n }\n\n function render(): void {\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.enable(gl.BLEND);\n displayMaterial.bind();\n if (shading) {\n gl.uniform2f(displayMaterial.uniforms['texelSize'], 1 / gl.drawingBufferWidth, 1 / gl.drawingBufferHeight);\n }\n gl.uniform1i(displayMaterial.uniforms['uTexture'], dye.read.attach(0));\n blit(null);\n }\n\n // Splats\n\n function splatPointer(): void {\n const dx = pointer.deltaX * config.splatForce;\n const dy = pointer.deltaY * config.splatForce;\n splat(pointer.texcoordX, pointer.texcoordY, dx, dy, pointer.color);\n }\n\n function clickSplat(): void {\n const color = generateColor();\n color.r *= 10;\n color.g *= 10;\n color.b *= 10;\n const dx = 10 * (Math.random() - 0.5);\n const dy = 30 * (Math.random() - 0.5);\n splat(pointer.texcoordX, pointer.texcoordY, dx, dy, color);\n }\n\n function splat(x: number, y: number, dx: number, dy: number, color: RGB): void {\n splatProgram.bind();\n gl.uniform1i(splatProgram.uniforms['uTarget'], velocity.read.attach(0));\n gl.uniform1f(splatProgram.uniforms['aspectRatio'], canvas.width / canvas.height);\n gl.uniform2f(splatProgram.uniforms['point'], x, y);\n gl.uniform3f(splatProgram.uniforms['color'], dx, dy, 0);\n gl.uniform1f(splatProgram.uniforms['radius'], correctRadius(config.splatRadius / 100));\n blit(velocity.write);\n velocity.swap();\n\n gl.uniform1i(splatProgram.uniforms['uTarget'], dye.read.attach(0));\n gl.uniform3f(splatProgram.uniforms['color'], color.r, color.g, color.b);\n blit(dye.write);\n dye.swap();\n }\n\n function correctRadius(radius: number): number {\n const aspectRatio = canvas.width / canvas.height;\n return aspectRatio > 1 ? radius * aspectRatio : radius;\n }\n\n // Pointer\n\n function pointerDown(posX: number, posY: number): void {\n pointer.moved = false;\n pointer.texcoordX = posX / canvas.width;\n pointer.texcoordY = 1 - posY / canvas.height;\n pointer.prevTexcoordX = pointer.texcoordX;\n pointer.prevTexcoordY = pointer.texcoordY;\n pointer.deltaX = 0;\n pointer.deltaY = 0;\n pointer.color = generateColor();\n }\n\n function pointerMove(posX: number, posY: number, color: RGB): void {\n pointer.prevTexcoordX = pointer.texcoordX;\n pointer.prevTexcoordY = pointer.texcoordY;\n pointer.texcoordX = posX / canvas.width;\n pointer.texcoordY = 1 - posY / canvas.height;\n pointer.deltaX = correctDeltaX(pointer.texcoordX - pointer.prevTexcoordX);\n pointer.deltaY = correctDeltaY(pointer.texcoordY - pointer.prevTexcoordY);\n pointer.moved = Math.abs(pointer.deltaX) > 0 || Math.abs(pointer.deltaY) > 0;\n pointer.color = color;\n }\n\n function correctDeltaX(delta: number): number {\n const aspectRatio = canvas.width / canvas.height;\n return aspectRatio < 1 ? delta * aspectRatio : delta;\n }\n\n function correctDeltaY(delta: number): number {\n const aspectRatio = canvas.width / canvas.height;\n return aspectRatio > 1 ? delta / aspectRatio : delta;\n }\n\n // Colours\n\n function hexToRGB(hex: string): RGB {\n let val = hex.replace('#', '');\n if (val.length === 3) val = val[0] + val[0] + val[1] + val[1] + val[2] + val[2];\n return {\n r: (Number.parseInt(val.slice(0, 2), 16) / 255) * 0.15,\n g: (Number.parseInt(val.slice(2, 4), 16) / 255) * 0.15,\n b: (Number.parseInt(val.slice(4, 6), 16) / 255) * 0.15,\n };\n }\n\n function generateColor(): RGB {\n if (!config.rainbow) return hexToRGB(config.color);\n const c = hsvToRgb(Math.random(), 1, 1);\n c.r *= 0.15;\n c.g *= 0.15;\n c.b *= 0.15;\n return c;\n }\n\n function hsvToRgb(h: number, s: number, v: number): RGB {\n const i = Math.floor(h * 6);\n const f = h * 6 - i;\n const p = v * (1 - s);\n const q = v * (1 - f * s);\n const t = v * (1 - (1 - f) * s);\n switch (i % 6) {\n case 0:\n return { r: v, g: t, b: p };\n case 1:\n return { r: q, g: v, b: p };\n case 2:\n return { r: p, g: v, b: t };\n case 3:\n return { r: p, g: q, b: v };\n case 4:\n return { r: t, g: p, b: v };\n default:\n return { r: v, g: p, b: q };\n }\n }\n\n function wrap(value: number, min: number, max: number): number {\n const range = max - min;\n if (range === 0) return min;\n return ((value - min) % range) + min;\n }\n\n function getResolution(resolution: number): { width: number; height: number } {\n let aspectRatio = gl.drawingBufferWidth / gl.drawingBufferHeight;\n if (aspectRatio < 1) aspectRatio = 1 / aspectRatio;\n const min = Math.round(resolution);\n const max = Math.round(resolution * aspectRatio);\n return gl.drawingBufferWidth > gl.drawingBufferHeight ? { width: max, height: min } : { width: min, height: max };\n }\n\n function scaleByPixelRatio(input: number): number {\n return Math.floor(input * (window.devicePixelRatio || 1));\n }\n\n function hashCode(s: string): number {\n let hash = 0;\n for (let i = 0; i < s.length; i++) {\n hash = (hash << 5) - hash + s.charCodeAt(i);\n hash |= 0;\n }\n return hash;\n }\n\n // Events + boot\n\n let firstMoveHandled = false;\n\n // Coordinates are taken relative to the canvas box: identical to the\n // raw client position for the fullscreen overlay, and it makes a\n // contained canvas track the pointer correctly too.\n const toLocal = (clientX: number, clientY: number): { x: number; y: number } => {\n const rect = canvas.getBoundingClientRect();\n return { x: scaleByPixelRatio(clientX - rect.left), y: scaleByPixelRatio(clientY - rect.top) };\n };\n\n const onMouseDown = (e: MouseEvent): void => {\n const pos = toLocal(e.clientX, e.clientY);\n pointerDown(pos.x, pos.y);\n clickSplat();\n };\n\n const onMouseMove = (e: MouseEvent): void => {\n const pos = toLocal(e.clientX, e.clientY);\n const color = firstMoveHandled ? pointer.color : generateColor();\n firstMoveHandled = true;\n pointerMove(pos.x, pos.y, color);\n };\n\n const onTouchStart = (e: TouchEvent): void => {\n const t = e.targetTouches[0];\n if (!t) return;\n const pos = toLocal(t.clientX, t.clientY);\n pointerDown(pos.x, pos.y);\n };\n\n const onTouchMove = (e: TouchEvent): void => {\n const t = e.targetTouches[0];\n if (!t) return;\n const pos = toLocal(t.clientX, t.clientY);\n pointerMove(pos.x, pos.y, pointer.color);\n };\n\n window.addEventListener('mousedown', onMouseDown);\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('touchstart', onTouchStart, { passive: true });\n window.addEventListener('touchmove', onTouchMove, { passive: true });\n\n // A contained canvas scrolled out of view, or one with no box, stops asking for\n // frames, the way `wr-waves` does: the solver runs every pass of the pipeline\n // each frame, for nothing anyone can see. The fullscreen overlay is always in\n // view. Without the observers (jsdom) nothing reports a change, so what the\n // first frame measures stands: a box runs the loop, no box parks it. A box flush\n // against a zero-height clip intersects with nothing showing, and only a second\n // threshold reports the clip moving. It sits below any real ratio, or a clip\n // closing on a transition steps from under it to 0 without crossing anything.\n let visible = true;\n const wake = (): void => {\n if (visible && hasBox && active && rafId === 0) {\n // The time away is not simulated: the first frame back steps from now.\n lastUpdateTime = Date.now();\n rafId = requestAnimationFrame(updateFrame);\n }\n };\n const io =\n typeof IntersectionObserver === 'undefined'\n ? null\n : new IntersectionObserver(\n entries => {\n const { isIntersecting, intersectionRatio } = entries[entries.length - 1];\n visible = isIntersecting && intersectionRatio > 0;\n wake();\n },\n { threshold: [0, 1e-9] }\n );\n io?.observe(canvas);\n // The frame measures the box itself, and a parked loop has no frame: the\n // observer is what hears the box come back.\n const ro =\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver(() => {\n hasBox = canvas.clientWidth > 0 && canvas.clientHeight > 0;\n wake();\n });\n ro?.observe(canvas);\n\n updateFrame();\n\n return () => {\n active = false;\n cancelAnimationFrame(rafId);\n io?.disconnect();\n ro?.disconnect();\n window.removeEventListener('mousedown', onMouseDown);\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('touchstart', onTouchStart);\n window.removeEventListener('touchmove', onTouchMove);\n // The context is NOT lost here on purpose — input changes reboot the\n // sim on the same canvas, and a lost context can't be re-acquired. So\n // everything this boot allocated on it is freed by hand instead.\n for (const target of [dye, velocity, pressure]) disposeDoubleFBO(target);\n disposeFBO(divergence);\n disposeFBO(curl);\n for (const program of programs) gl.deleteProgram(program);\n for (const shader of shaders) gl.deleteShader(shader);\n for (const buffer of buffers) gl.deleteBuffer(buffer);\n };\n}\n\n// WebGL context bootstrap\n\nfunction getWebGLContext(canvas: HTMLCanvasElement): { gl: GL; ext: GlExt } | null {\n const params: WebGLContextAttributes = {\n alpha: true,\n depth: false,\n stencil: false,\n antialias: false,\n preserveDrawingBuffer: false,\n };\n\n const gl2 = canvas.getContext('webgl2', params);\n const gl = gl2 ?? canvas.getContext('webgl', params);\n if (!gl) return null;\n const isWebGL2 = !!gl2;\n\n let halfFloat: OES_texture_half_float | null = null;\n let supportLinearFiltering: boolean;\n if (isWebGL2) {\n gl.getExtension('EXT_color_buffer_float');\n supportLinearFiltering = !!gl.getExtension('OES_texture_float_linear');\n } else {\n halfFloat = gl.getExtension('OES_texture_half_float');\n supportLinearFiltering = !!gl.getExtension('OES_texture_half_float_linear');\n }\n gl.clearColor(0, 0, 0, 1);\n\n const halfFloatTexType = isWebGL2\n ? (gl as WebGL2RenderingContext).HALF_FLOAT\n : (halfFloat?.HALF_FLOAT_OES ?? gl.UNSIGNED_BYTE);\n\n let formatRGBA: TexFormat | null;\n let formatRG: TexFormat | null;\n let formatR: TexFormat | null;\n if (isWebGL2) {\n const g2 = gl as WebGL2RenderingContext;\n formatRGBA = getSupportedFormat(g2, g2.RGBA16F, g2.RGBA, halfFloatTexType);\n formatRG = getSupportedFormat(g2, g2.RG16F, g2.RG, halfFloatTexType);\n formatR = getSupportedFormat(g2, g2.R16F, g2.RED, halfFloatTexType);\n } else {\n formatRGBA = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType);\n formatRG = formatRGBA;\n formatR = formatRGBA;\n }\n if (!formatRGBA || !formatRG || !formatR) return null;\n\n return { gl, ext: { formatRGBA, formatRG, formatR, halfFloatTexType, supportLinearFiltering } };\n}\n\nfunction getSupportedFormat(gl: GL, internalFormat: number, format: number, type: number): TexFormat | null {\n if (!supportRenderTextureFormat(gl, internalFormat, format, type)) {\n const g2 = gl as WebGL2RenderingContext;\n switch (internalFormat) {\n case g2.R16F:\n return getSupportedFormat(gl, g2.RG16F, g2.RG, type);\n case g2.RG16F:\n return getSupportedFormat(gl, g2.RGBA16F, g2.RGBA, type);\n default:\n return null;\n }\n }\n return { internalFormat, format };\n}\n\nfunction supportRenderTextureFormat(gl: GL, internalFormat: number, format: number, type: number): boolean {\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 4, 4, 0, format, type, null);\n const fbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n const complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;\n // A probe, run on every boot: free it, or each reboot leaves one behind.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(fbo);\n gl.deleteTexture(texture);\n return complete;\n}\n\nexport { createFluidSimulation };\nexport type { WrFluidConfig };\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n *\n * Angular adaptation of the SplashCursor effect by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/animations/splash-cursor\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport type { ElementRef } from '@angular/core';\nimport { Component, NgZone, PLATFORM_ID, ViewEncapsulation, effect, inject, input, viewChild } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\nimport { createFluidSimulation } from './fluid';\n\n/**\n * Splash cursor — a WebGL fluid simulation that splashes colourful dye\n * wherever the pointer moves or clicks. Renders as a fixed, full-viewport,\n * click-through overlay; mount it once on a page (it follows the pointer\n * everywhere) and it tears down with the component.\n *\n * Renders nothing under `prefers-reduced-motion` or when WebGL is\n * unavailable. Off screen, or with no box to draw on, the solver stops asking\n * for frames and resumes where it left off.\n *\n * @example\n * ```html\n * <wr-splash-cursor />\n * <wr-splash-cursor [rainbow]=\"false\" color=\"#5227ff\" />\n * ```\n *\n * @see https://ngwr.dev/bits/splash-cursor\n */\n@Component({\n selector: 'wr-splash-cursor',\n template: '<canvas #canvas class=\"wr-splash-cursor__canvas\" aria-hidden=\"true\"></canvas>',\n styleUrl: './splash-cursor.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-splash-cursor',\n '[class.wr-splash-cursor--contained]': '!fullscreen()',\n },\n})\nexport class WrSplashCursor {\n /**\n * `true` overlays the whole viewport (reactbits behaviour); `false`\n * fills the nearest positioned ancestor instead — handy for demo boxes,\n * and the dye collides with the box walls. @default true\n */\n readonly fullscreen = input(true, { transform: coerceBooleanProperty });\n\n /** Velocity / pressure grid resolution. @default 128 */\n readonly simResolution = input(128, { transform: numAttr(128) });\n\n /** Dye texture resolution — the visible detail. @default 1440 */\n readonly dyeResolution = input(1440, { transform: numAttr(1440) });\n\n /** How fast the dye fades, higher = shorter trails. @default 3.5 */\n readonly densityDissipation = input(3.5, { transform: numAttr(3.5) });\n\n /** How fast motion settles. @default 2 */\n readonly velocityDissipation = input(2, { transform: numAttr(2) });\n\n /** Pressure retained between frames, 0..1. @default 0.1 */\n readonly pressure = input(0.1, { transform: numAttr(0.1) });\n\n /** Jacobi iterations for the pressure solve. @default 20 */\n readonly pressureIterations = input(20, { transform: numAttr(20) });\n\n /** Vorticity confinement — swirliness. @default 3 */\n readonly curl = input(3, { transform: numAttr(3) });\n\n /** Splat size. @default 0.2 */\n readonly splatRadius = input(0.2, { transform: numAttr(0.2) });\n\n /** Velocity a pointer move injects. @default 6000 */\n readonly splatForce = input(6000, { transform: numAttr(6000) });\n\n /** Pseudo-3D shading on the dye. @default true */\n readonly shading = input(true, { transform: coerceBooleanProperty });\n\n /** How fast the splat colour cycles. @default 10 */\n readonly colorUpdateSpeed = input(10, { transform: numAttr(10) });\n\n /** Cycle splat colours through the rainbow. @default true */\n readonly rainbow = input(true, { transform: coerceBooleanProperty });\n\n /** Fixed splat colour when `rainbow` is off. @default '#ff0000' */\n readonly color = input('#ff0000');\n\n private readonly canvasRef = viewChild<ElementRef<HTMLCanvasElement>>('canvas');\n\n private readonly zone = inject(NgZone);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n constructor() {\n if (!this.isBrowser) return;\n\n // (Re)boot whenever the canvas appears, any input changes, or the OS\n // reduced-motion preference flips. `onCleanup` tears the old sim down.\n effect(onCleanup => {\n const canvas = this.canvasRef()?.nativeElement;\n const config = {\n simResolution: this.simResolution(),\n dyeResolution: this.dyeResolution(),\n densityDissipation: this.densityDissipation(),\n velocityDissipation: this.velocityDissipation(),\n pressure: this.pressure(),\n pressureIterations: this.pressureIterations(),\n curl: this.curl(),\n splatRadius: this.splatRadius(),\n splatForce: this.splatForce(),\n shading: this.shading(),\n colorUpdateSpeed: this.colorUpdateSpeed(),\n rainbow: this.rainbow(),\n color: this.color(),\n };\n if (!canvas || this.platform.prefersReducedMotion()) return;\n const teardown = this.zone.runOutsideAngular(() => createFluidSimulation(canvas, config));\n if (teardown) onCleanup(teardown);\n });\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from "@angular/core";
2
- import { Component, DestroyRef, ElementRef, NgZone, PLATFORM_ID, ViewEncapsulation, afterNextRender, effect, inject, input, signal, untracked, viewChild } from "@angular/core";
2
+ import { Component, DestroyRef, ElementRef, NgZone, PLATFORM_ID, ViewEncapsulation, afterNextRender, afterRenderEffect, effect, inject, input, signal, untracked, viewChild } from "@angular/core";
3
3
  import { isPlatformBrowser } from "@angular/common";
4
4
  import { numAttr, resolveCssColor, watchColorScheme } from "ngwr/utils";
5
5
  import { WrPlatform } from "ngwr/platform";
@@ -407,27 +407,22 @@ var WrWaves = class WrWaves {
407
407
  constructor() {
408
408
  if (!this.isBrowser) return;
409
409
  afterNextRender(() => this.zone.runOutsideAngular(() => this.boot()));
410
- effect(() => {
410
+ afterRenderEffect(() => {
411
+ if (!this.booted()) return;
412
+ const still = this.platform.prefersReducedMotion();
411
413
  this.xGap();
412
414
  this.yGap();
413
- if (!this.ctx) return;
414
- this.setLines();
415
- if (this.platform.prefersReducedMotion()) this.drawLines();
415
+ if (still) this.lineColor();
416
+ untracked(() => {
417
+ this.setLines();
418
+ if (still) this.drawLines();
419
+ });
416
420
  });
417
421
  watchColorScheme(() => {
418
422
  if (this.booted() && this.platform.prefersReducedMotion()) this.drawLines();
419
423
  });
420
424
  effect((onCleanup) => {
421
- if (!this.booted()) return;
422
- if (this.platform.prefersReducedMotion()) {
423
- this.lineColor();
424
- untracked(() => {
425
- this.setLines();
426
- this.drawLines();
427
- });
428
- return;
429
- }
430
- if (!this.hasBox()) return;
425
+ if (!this.booted() || !this.hasBox() || this.platform.prefersReducedMotion()) return;
431
426
  onCleanup(this.zone.runOutsideAngular(() => this.animate()));
432
427
  });
433
428
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-bits-waves.mjs","names":[],"sources":["../../../projects/lib/bits/waves/waves.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n *\n * Angular adaptation of the Waves background by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/backgrounds/waves\n *\n * A grid of vertical lines drawn on a 2D canvas. Each point drifts on\n * perlin noise and is pushed around by the pointer with a spring\n * (tension + friction) pulling it back to rest. Each line is drawn as\n * quadratic curves through the points' midpoints, not as straight segments.\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n NgZone,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr, resolveCssColor, watchColorScheme } from 'ngwr/utils';\n\n// Perlin noise (Stefan Gustavson's reference permutation)\n/* eslint-disable no-bitwise -- permutation-table hashing is inherently bitwise */\n\nclass Grad {\n constructor(\n private readonly x: number,\n private readonly y: number\n ) {}\n\n dot2(x: number, y: number): number {\n return this.x * x + this.y * y;\n }\n}\n\nconst GRAD3: readonly Grad[] = [\n new Grad(1, 1),\n new Grad(-1, 1),\n new Grad(1, -1),\n new Grad(-1, -1),\n new Grad(1, 0),\n new Grad(-1, 0),\n new Grad(1, 0),\n new Grad(-1, 0),\n new Grad(0, 1),\n new Grad(0, -1),\n new Grad(0, 1),\n new Grad(0, -1),\n];\n\n// prettier-ignore\nconst P: readonly number[] = [\n 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240,\n 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88,\n 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83,\n 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216,\n 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186,\n 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,\n 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,\n 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193,\n 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157,\n 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128,\n 195, 78, 66, 215, 61, 156, 180,\n];\n\nclass Noise {\n private readonly perm = new Array<number>(512);\n private readonly gradP = new Array<Grad>(512);\n\n constructor(seed: number) {\n if (seed > 0 && seed < 1) seed *= 65536;\n seed = Math.floor(seed);\n if (seed < 256) seed |= seed << 8;\n for (let i = 0; i < 256; i++) {\n const v = i & 1 ? P[i] ^ (seed & 255) : P[i] ^ ((seed >> 8) & 255);\n this.perm[i] = this.perm[i + 256] = v;\n this.gradP[i] = this.gradP[i + 256] = GRAD3[v % 12];\n }\n }\n\n private fade(t: number): number {\n return t * t * t * (t * (t * 6 - 15) + 10);\n }\n\n private lerp(a: number, b: number, t: number): number {\n return (1 - t) * a + t * b;\n }\n\n perlin2(x: number, y: number): number {\n let gx = Math.floor(x);\n let gy = Math.floor(y);\n x -= gx;\n y -= gy;\n gx &= 255;\n gy &= 255;\n const n00 = this.gradP[gx + this.perm[gy]].dot2(x, y);\n const n01 = this.gradP[gx + this.perm[gy + 1]].dot2(x, y - 1);\n const n10 = this.gradP[gx + 1 + this.perm[gy]].dot2(x - 1, y);\n const n11 = this.gradP[gx + 1 + this.perm[gy + 1]].dot2(x - 1, y - 1);\n const u = this.fade(x);\n return this.lerp(this.lerp(n00, n10, u), this.lerp(n01, n11, u), this.fade(y));\n }\n}\n\n/* eslint-enable no-bitwise */\n// Component\n\ninterface WavePoint {\n x: number;\n y: number;\n wave: { x: number; y: number };\n cursor: { x: number; y: number; vx: number; vy: number };\n}\n\n/**\n * Wave-field background — a grid of lines drifting on perlin noise,\n * nudged by the pointer. Fills its nearest positioned ancestor; put it\n * behind hero copy or section content.\n *\n * Colours are theme-aware by default: a soft dark line on light surfaces,\n * a faint white line on dark — override with `[lineColor]`.\n *\n * @example\n * ```html\n * <section style=\"position: relative\">\n * <wr-waves />\n * <h1>Hero copy above the waves</h1>\n * </section>\n * ```\n *\n * @see https://ngwr.dev/bits/waves\n */\n/**\n * The most bitmap pixels the canvas is backed with. The field is redrawn every\n * frame, so the backing store is a per-frame cost: a 1280-wide hero keeps the\n * full 2x (about 2.3 MP), and a wider one steps down toward 1x instead of\n * growing to a 3456-pixel-wide bitmap on a large retina window.\n */\nconst MAX_CANVAS_PIXELS = 2_500_000;\n\n@Component({\n selector: 'wr-waves',\n template: '<canvas #canvas class=\"wr-waves__canvas\" aria-hidden=\"true\"></canvas>',\n styleUrl: './waves.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-waves',\n '[style.background-color]': 'backgroundColor()',\n // Feeds the CSS stand-in grid (see waves.scss) so it matches the real\n // spacing, and switches it off the moment the canvas has painted.\n '[style.--wr-waves-x-gap.px]': 'xGap()',\n '[class.wr-waves--painted]': 'painted()',\n },\n})\nexport class WrWaves {\n /** Line stroke colour, any CSS colour. When unset, empty or blank, `--wr-waves-line-color` decides. */\n readonly lineColor = input<string | null>(null);\n\n /** Background fill behind the lines. @default 'transparent' */\n readonly backgroundColor = input('transparent');\n\n /** Horizontal noise drift per ms. @default 0.0125 */\n readonly waveSpeedX = input(0.0125, { transform: numAttr(0.0125) });\n\n /** Vertical noise drift per ms. @default 0.005 */\n readonly waveSpeedY = input(0.005, { transform: numAttr(0.005) });\n\n /** Horizontal wave amplitude in px. @default 32 */\n readonly waveAmpX = input(32, { transform: numAttr(32) });\n\n /** Vertical wave amplitude in px. @default 16 */\n readonly waveAmpY = input(16, { transform: numAttr(16) });\n\n /** Horizontal gap between lines in px. @default 10 */\n readonly xGap = input(10, { transform: numAttr(10) });\n\n /** Vertical gap between points on a line in px. @default 32 */\n readonly yGap = input(32, { transform: numAttr(32) });\n\n /** Velocity damping of the cursor spring, 0..1. @default 0.925 */\n readonly friction = input(0.925, { transform: numAttr(0.925) });\n\n /** Pull-back strength of the cursor spring. @default 0.005 */\n readonly tension = input(0.005, { transform: numAttr(0.005) });\n\n /** Max px a point can be dragged from rest. @default 100 */\n readonly maxCursorMove = input(100, { transform: numAttr(100) });\n\n private readonly canvasRef = viewChild.required<ElementRef<HTMLCanvasElement>>('canvas');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private ctx: CanvasRenderingContext2D | null = null;\n private readonly noise = new Noise(Math.random());\n private lines: WavePoint[][] = [];\n /** The host's layout box, in CSS pixels before any transform: what the grid is laid out in. */\n private box = { width: 0, height: 0 };\n /** Bitmap pixels per CSS pixel the canvas is backed at; 0 until the first fit. */\n private ratio = 0;\n private readonly mouse = { x: -10, y: 0, lx: 0, ly: 0, sx: 0, sy: 0, v: 0, vs: 0, a: 0, set: false };\n private rafId = 0;\n\n /**\n * Flips once the canvas has drawn, which retires the CSS stand-in grid.\n *\n * A canvas cannot be prerendered, so on an SSR'd or prerendered page this\n * element is simply blank until the bundle has loaded and hydration has run —\n * measured at ~2.8s on ngwr.dev's own home page. The stylesheet paints a static\n * grid of the same colour and pitch in the meantime, straight from the\n * prerendered HTML, and this hands over to the real thing.\n */\n protected readonly painted = signal(false);\n\n /** Flips once `boot()` has a context and a grid — the motion half waits for it. */\n private readonly booted = signal(false);\n\n /**\n * Whether the box has an area. The intersection observer calls a zero-area host\n * intersecting and sends no entry when it gains a size, so this reads the box instead.\n */\n private readonly hasBox = signal(false);\n\n constructor() {\n if (!this.isBrowser) return;\n\n afterNextRender(() => this.zone.runOutsideAngular(() => this.boot()));\n\n // Re-seed the grid when geometry inputs change. The bitmap is left alone,\n // so the next frame draws over the old grid rather than over a blank canvas.\n effect(() => {\n this.xGap();\n this.yGap();\n if (!this.ctx) return;\n this.setLines();\n // And paint it, when there is no frame loop to. Under\n // `prefers-reduced-motion` the grid is drawn once and no frame follows,\n // so a later gap change rebuilt the grid and left it undrawn — with\n // `.wr-waves--painted` already on the host, so the element stayed\n // visible and empty.\n if (this.platform.prefersReducedMotion()) this.drawLines();\n });\n\n // The still grid keeps the line colour it was drawn with, so a scheme switch\n // under reduced motion re-resolves it and draws the grid again. The loop\n // needs no help: every frame it draws resolves the colour afresh.\n watchColorScheme(() => {\n if (this.booted() && this.platform.prefersReducedMotion()) this.drawLines();\n });\n\n // Motion or a still grid, decided live: a preference switched while the page\n // is open used to keep the field drifting until a reload, because `boot()`\n // read it once.\n effect(onCleanup => {\n if (!this.booted()) return;\n if (this.platform.prefersReducedMotion()) {\n // One static, undisturbed grid — no drift, no loop, no pointer\n // reactivity. Repainted when the line colour changes, since there is\n // no next frame to pick it up.\n this.lineColor();\n untracked(() => {\n this.setLines();\n this.drawLines();\n });\n return;\n }\n if (!this.hasBox()) return;\n onCleanup(this.zone.runOutsideAngular(() => this.animate()));\n });\n }\n\n // Setup\n\n private boot(): void {\n const canvas = this.canvasRef().nativeElement;\n this.ctx = canvas.getContext('2d');\n if (!this.ctx) return;\n\n // `clientWidth` and not `getBoundingClientRect()`: the rect is the box after\n // transforms, and no observer hears of a transform, so a field booted inside\n // a dialog's scale-in kept a bitmap 96% of its box, stretched by CSS once\n // the animation ended. The observer's first entry follows with the exact,\n // sub-pixel size.\n const hostEl = this.host.nativeElement;\n this.fit(hostEl.clientWidth, hostEl.clientHeight);\n this.setLines();\n\n // The box is the observer's to follow, transforms excluded. A window resize\n // is for the pixel ratio, which browser zoom and a move to another screen\n // change with no box change at all.\n const onResize = (): void => this.resize(this.box.width, this.box.height);\n window.addEventListener('resize', onResize);\n const ro = new ResizeObserver(entries => {\n const rect = entries[entries.length - 1]?.contentRect;\n if (rect) this.resize(rect.width, rect.height);\n });\n ro.observe(hostEl);\n this.destroyRef.onDestroy(() => {\n window.removeEventListener('resize', onResize);\n ro.disconnect();\n });\n this.booted.set(true);\n }\n\n /** Start the drift and the pointer reactivity; returns what stops both. */\n private animate(): () => void {\n const onMouseMove = (e: MouseEvent): void => this.updateMouse(e.clientX, e.clientY);\n const onTouchMove = (e: TouchEvent): void => this.updateMouse(e.touches[0].clientX, e.touches[0].clientY);\n\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('touchmove', onTouchMove, { passive: true });\n\n const run = (): void => {\n if (this.rafId === 0) this.rafId = requestAnimationFrame(t => this.tick(t));\n };\n const halt = (): void => {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n };\n // Off screen the field stops asking for frames: it is decoration, and a\n // canvas redrawn out of sight still costs the browser a frame every frame.\n // Firefox on a wide retina window showed it: scrolled back up, the page\n // above the fold stayed blank for seconds until this loop and the pixel\n // budget below went in. Without an observer (jsdom) it simply runs. A box\n // flush against a zero-height clip intersects with nothing showing, and only a\n // second threshold reports the clip moving. It sits below any real ratio, or a\n // clip closing on a transition steps from under it to 0 without crossing anything.\n const io =\n typeof IntersectionObserver === 'undefined'\n ? null\n : new IntersectionObserver(\n entries => {\n const { isIntersecting, intersectionRatio } = entries[entries.length - 1];\n if (isIntersecting && intersectionRatio > 0) run();\n else halt();\n },\n { threshold: [0, 1e-9] }\n );\n if (io) io.observe(this.host.nativeElement);\n else run();\n\n return () => {\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('touchmove', onTouchMove);\n io?.disconnect();\n halt();\n };\n }\n\n /** Fit the canvas to a new box or pixel ratio and, when that cleared it, repaint at once. */\n private resize(width: number, height: number): void {\n const moved = width !== this.box.width || height !== this.box.height;\n if (!this.fit(width, height)) return;\n if (moved) {\n this.setLines();\n // Re-seeded points sit at rest. A drifting field puts them where the next\n // frame will, or the repaint below shows straight lines until it comes.\n if (!this.platform.prefersReducedMotion()) this.drift(performance.now());\n }\n // Observer entries arrive after the frame's own callbacks and before its\n // paint, and the fit cleared the bitmap, so a repaint left to the next frame\n // would leave this one blank: a resize drag flickered every frame.\n this.drawLines();\n }\n\n /**\n * Back the canvas for a `width` × `height` box, in CSS pixels, at the screen's\n * pixel ratio. Returns whether anything changed: writing `canvas.width` clears\n * the bitmap even to the value it already has, so an unchanged box is left alone.\n */\n private fit(width: number, height: number): boolean {\n // Backed at the screen's pixel ratio. A bitmap the size of the CSS box is\n // upscaled on a 2x screen, which smears every 1px line across two device\n // pixels and steps its curves. Capped at 2: the field repaints every frame,\n // and a 3x phone would push half as many pixels again for no visible gain.\n // Capped again by `MAX_CANVAS_PIXELS`, never below 1.\n const area = width * height;\n const budget = area > 0 ? Math.sqrt(MAX_CANVAS_PIXELS / area) : 2;\n const ratio = Math.max(1, Math.min(window.devicePixelRatio || 1, 2, budget));\n if (width === this.box.width && height === this.box.height && ratio === this.ratio) return false;\n\n this.box = { width, height };\n this.ratio = ratio;\n this.hasBox.set(width > 0 && height > 0);\n const canvas = this.canvasRef().nativeElement;\n canvas.width = Math.round(width * ratio);\n canvas.height = Math.round(height * ratio);\n // Resizing the bitmap resets the context, transform included, so the scale\n // goes on afterwards. Every coordinate below stays in CSS pixels.\n this.ctx?.setTransform(ratio, 0, 0, ratio, 0, 0);\n return true;\n }\n\n private setLines(): void {\n const { width, height } = this.box;\n this.lines = [];\n const oWidth = width + 200;\n const oHeight = height + 30;\n const xGap = this.xGap();\n const yGap = this.yGap();\n const totalLines = Math.ceil(oWidth / xGap);\n const totalPoints = Math.ceil(oHeight / yGap);\n const xStart = (width - xGap * totalLines) / 2;\n const yStart = (height - yGap * totalPoints) / 2;\n for (let i = 0; i <= totalLines; i++) {\n const pts: WavePoint[] = [];\n for (let j = 0; j <= totalPoints; j++) {\n pts.push({\n x: xStart + xGap * i,\n y: yStart + yGap * j,\n wave: { x: 0, y: 0 },\n cursor: { x: 0, y: 0, vx: 0, vy: 0 },\n });\n }\n this.lines.push(pts);\n }\n }\n\n // Frame loop\n\n private tick(time: number): void {\n const mouse = this.mouse;\n mouse.sx += (mouse.x - mouse.sx) * 0.1;\n mouse.sy += (mouse.y - mouse.sy) * 0.1;\n const dx = mouse.x - mouse.lx;\n const dy = mouse.y - mouse.ly;\n const d = Math.hypot(dx, dy);\n mouse.v = d;\n mouse.vs += (d - mouse.vs) * 0.1;\n mouse.vs = Math.min(100, mouse.vs);\n mouse.lx = mouse.x;\n mouse.ly = mouse.y;\n mouse.a = Math.atan2(dy, dx);\n\n this.movePoints(time);\n this.drawLines();\n this.rafId = requestAnimationFrame(t => this.tick(t));\n }\n\n /** Put every point where the noise drifts it at `time`. */\n private drift(time: number): void {\n const waveSpeedX = this.waveSpeedX();\n const waveSpeedY = this.waveSpeedY();\n const waveAmpX = this.waveAmpX();\n const waveAmpY = this.waveAmpY();\n\n for (const pts of this.lines) {\n for (const p of pts) {\n const move = this.noise.perlin2((p.x + time * waveSpeedX) * 0.002, (p.y + time * waveSpeedY) * 0.0015) * 12;\n p.wave.x = Math.cos(move) * waveAmpX;\n p.wave.y = Math.sin(move) * waveAmpY;\n }\n }\n }\n\n private movePoints(time: number): void {\n this.drift(time);\n\n const mouse = this.mouse;\n const friction = this.friction();\n const tension = this.tension();\n const maxCursorMove = this.maxCursorMove();\n\n for (const pts of this.lines) {\n for (const p of pts) {\n const dx = p.x - mouse.sx;\n const dy = p.y - mouse.sy;\n const dist = Math.hypot(dx, dy);\n const l = Math.max(175, mouse.vs);\n if (dist < l) {\n const s = 1 - dist / l;\n const f = Math.cos(dist * 0.001) * s;\n p.cursor.vx += Math.cos(mouse.a) * f * l * mouse.vs * 0.00065;\n p.cursor.vy += Math.sin(mouse.a) * f * l * mouse.vs * 0.00065;\n }\n\n p.cursor.vx += (0 - p.cursor.x) * tension;\n p.cursor.vy += (0 - p.cursor.y) * tension;\n p.cursor.vx *= friction;\n p.cursor.vy *= friction;\n p.cursor.x += p.cursor.vx * 2;\n p.cursor.y += p.cursor.vy * 2;\n p.cursor.x = Math.min(maxCursorMove, Math.max(-maxCursorMove, p.cursor.x));\n p.cursor.y = Math.min(maxCursorMove, Math.max(-maxCursorMove, p.cursor.y));\n }\n }\n }\n\n private moved(point: WavePoint, withCursor: boolean): { x: number; y: number } {\n const x = point.x + point.wave.x + (withCursor ? point.cursor.x : 0);\n const y = point.y + point.wave.y + (withCursor ? point.cursor.y : 0);\n return { x: Math.round(x * 10) / 10, y: Math.round(y * 10) / 10 };\n }\n\n private drawLines(): void {\n const ctx = this.ctx;\n if (!ctx) return;\n // Retire the CSS stand-in: from here the canvas has real pixels. Set inside\n // the draw rather than at the end of `boot()` so it can never switch the\n // fallback off before something has actually been painted. Runs outside\n // Angular (the rAF loop does), so `signal.set` schedules the one host-binding\n // update it needs; every later call is a no-op on an unchanged value.\n if (!this.painted()) this.painted.set(true);\n const { width, height } = this.box;\n ctx.clearRect(0, 0, width, height);\n ctx.beginPath();\n ctx.strokeStyle = this.resolveLineColor();\n for (const points of this.lines) {\n // Both ends stay where the grid put them, as they did when each line was\n // a polyline; only the interior follows the pointer.\n const last = points.length - 1;\n const path = points.map((p, idx) => this.moved(p, idx > 0 && idx < last));\n // A curve through the MIDPOINTS, with each grid point as its control.\n // Joining the points themselves with `lineTo` put a corner at every one,\n // and at the default 32px pitch they read as a jagged line. Consecutive\n // curves share a tangent at the midpoint between them, so the line bends\n // without a kink anywhere and still passes near every point.\n ctx.moveTo(path[0].x, path[0].y);\n for (let i = 1; i < last; i++) {\n const p = path[i];\n const next = path[i + 1];\n ctx.quadraticCurveTo(p.x, p.y, (p.x + next.x) / 2, (p.y + next.y) / 2);\n }\n ctx.lineTo(path[last].x, path[last].y);\n }\n ctx.stroke();\n }\n\n /**\n * Explicit input wins; otherwise the theme's `--wr-waves-line-color`. Either\n * is resolved through the cascade before it reaches `strokeStyle`, which\n * reads neither a custom property nor the `light-dark()` the hook holds.\n * Called on every draw, so a colour-scheme change lands on the next frame.\n */\n private resolveLineColor(): string {\n const expression = (this.lineColor() ?? '').trim() || 'var(--wr-waves-line-color)';\n return resolveCssColor(this.canvasRef().nativeElement, expression, 'rgba(15, 23, 42, 0.12)');\n }\n\n private updateMouse(x: number, y: number): void {\n // Re-read the box each move — cheaper than tracking scroll, and the\n // host is usually a hero that rarely reflows mid-gesture. The rect is the\n // box as drawn, after any transform on the host or an ancestor, and the\n // grid is laid out in the box before them, so the pointer is scaled back.\n const rect = this.host.nativeElement.getBoundingClientRect();\n const mouse = this.mouse;\n mouse.x = (x - rect.left) * (rect.width > 0 ? this.box.width / rect.width : 1);\n mouse.y = (y - rect.top) * (rect.height > 0 ? this.box.height / rect.height : 1);\n if (!mouse.set) {\n mouse.sx = mouse.x;\n mouse.sy = mouse.y;\n mouse.lx = mouse.x;\n mouse.ly = mouse.y;\n mouse.set = true;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-bits-waves.mjs","names":[],"sources":["../../../projects/lib/bits/waves/waves.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n *\n * Angular adaptation of the Waves background by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/backgrounds/waves\n *\n * A grid of vertical lines drawn on a 2D canvas. Each point drifts on\n * perlin noise and is pushed around by the pointer with a spring\n * (tension + friction) pulling it back to rest. Each line is drawn as\n * quadratic curves through the points' midpoints, not as straight segments.\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n NgZone,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n afterRenderEffect,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr, resolveCssColor, watchColorScheme } from 'ngwr/utils';\n\n// Perlin noise (Stefan Gustavson's reference permutation)\n/* eslint-disable no-bitwise -- permutation-table hashing is inherently bitwise */\n\nclass Grad {\n constructor(\n private readonly x: number,\n private readonly y: number\n ) {}\n\n dot2(x: number, y: number): number {\n return this.x * x + this.y * y;\n }\n}\n\nconst GRAD3: readonly Grad[] = [\n new Grad(1, 1),\n new Grad(-1, 1),\n new Grad(1, -1),\n new Grad(-1, -1),\n new Grad(1, 0),\n new Grad(-1, 0),\n new Grad(1, 0),\n new Grad(-1, 0),\n new Grad(0, 1),\n new Grad(0, -1),\n new Grad(0, 1),\n new Grad(0, -1),\n];\n\n// prettier-ignore\nconst P: readonly number[] = [\n 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240,\n 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88,\n 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83,\n 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216,\n 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186,\n 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,\n 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,\n 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193,\n 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157,\n 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128,\n 195, 78, 66, 215, 61, 156, 180,\n];\n\nclass Noise {\n private readonly perm = new Array<number>(512);\n private readonly gradP = new Array<Grad>(512);\n\n constructor(seed: number) {\n if (seed > 0 && seed < 1) seed *= 65536;\n seed = Math.floor(seed);\n if (seed < 256) seed |= seed << 8;\n for (let i = 0; i < 256; i++) {\n const v = i & 1 ? P[i] ^ (seed & 255) : P[i] ^ ((seed >> 8) & 255);\n this.perm[i] = this.perm[i + 256] = v;\n this.gradP[i] = this.gradP[i + 256] = GRAD3[v % 12];\n }\n }\n\n private fade(t: number): number {\n return t * t * t * (t * (t * 6 - 15) + 10);\n }\n\n private lerp(a: number, b: number, t: number): number {\n return (1 - t) * a + t * b;\n }\n\n perlin2(x: number, y: number): number {\n let gx = Math.floor(x);\n let gy = Math.floor(y);\n x -= gx;\n y -= gy;\n gx &= 255;\n gy &= 255;\n const n00 = this.gradP[gx + this.perm[gy]].dot2(x, y);\n const n01 = this.gradP[gx + this.perm[gy + 1]].dot2(x, y - 1);\n const n10 = this.gradP[gx + 1 + this.perm[gy]].dot2(x - 1, y);\n const n11 = this.gradP[gx + 1 + this.perm[gy + 1]].dot2(x - 1, y - 1);\n const u = this.fade(x);\n return this.lerp(this.lerp(n00, n10, u), this.lerp(n01, n11, u), this.fade(y));\n }\n}\n\n/* eslint-enable no-bitwise */\n// Component\n\ninterface WavePoint {\n x: number;\n y: number;\n wave: { x: number; y: number };\n cursor: { x: number; y: number; vx: number; vy: number };\n}\n\n/**\n * Wave-field background — a grid of lines drifting on perlin noise,\n * nudged by the pointer. Fills its nearest positioned ancestor; put it\n * behind hero copy or section content.\n *\n * Colours are theme-aware by default: a soft dark line on light surfaces,\n * a faint white line on dark — override with `[lineColor]`.\n *\n * @example\n * ```html\n * <section style=\"position: relative\">\n * <wr-waves />\n * <h1>Hero copy above the waves</h1>\n * </section>\n * ```\n *\n * @see https://ngwr.dev/bits/waves\n */\n/**\n * The most bitmap pixels the canvas is backed with. The field is redrawn every\n * frame, so the backing store is a per-frame cost: a 1280-wide hero keeps the\n * full 2x (about 2.3 MP), and a wider one steps down toward 1x instead of\n * growing to a 3456-pixel-wide bitmap on a large retina window.\n */\nconst MAX_CANVAS_PIXELS = 2_500_000;\n\n@Component({\n selector: 'wr-waves',\n template: '<canvas #canvas class=\"wr-waves__canvas\" aria-hidden=\"true\"></canvas>',\n styleUrl: './waves.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-waves',\n '[style.background-color]': 'backgroundColor()',\n // Feeds the CSS stand-in grid (see waves.scss) so it matches the real\n // spacing, and switches it off the moment the canvas has painted.\n '[style.--wr-waves-x-gap.px]': 'xGap()',\n '[class.wr-waves--painted]': 'painted()',\n },\n})\nexport class WrWaves {\n /** Line stroke colour, any CSS colour. When unset, empty or blank, `--wr-waves-line-color` decides. */\n readonly lineColor = input<string | null>(null);\n\n /** Background fill behind the lines. @default 'transparent' */\n readonly backgroundColor = input('transparent');\n\n /** Horizontal noise drift per ms. @default 0.0125 */\n readonly waveSpeedX = input(0.0125, { transform: numAttr(0.0125) });\n\n /** Vertical noise drift per ms. @default 0.005 */\n readonly waveSpeedY = input(0.005, { transform: numAttr(0.005) });\n\n /** Horizontal wave amplitude in px. @default 32 */\n readonly waveAmpX = input(32, { transform: numAttr(32) });\n\n /** Vertical wave amplitude in px. @default 16 */\n readonly waveAmpY = input(16, { transform: numAttr(16) });\n\n /** Horizontal gap between lines in px. @default 10 */\n readonly xGap = input(10, { transform: numAttr(10) });\n\n /** Vertical gap between points on a line in px. @default 32 */\n readonly yGap = input(32, { transform: numAttr(32) });\n\n /** Velocity damping of the cursor spring, 0..1. @default 0.925 */\n readonly friction = input(0.925, { transform: numAttr(0.925) });\n\n /** Pull-back strength of the cursor spring. @default 0.005 */\n readonly tension = input(0.005, { transform: numAttr(0.005) });\n\n /** Max px a point can be dragged from rest. @default 100 */\n readonly maxCursorMove = input(100, { transform: numAttr(100) });\n\n private readonly canvasRef = viewChild.required<ElementRef<HTMLCanvasElement>>('canvas');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private ctx: CanvasRenderingContext2D | null = null;\n private readonly noise = new Noise(Math.random());\n private lines: WavePoint[][] = [];\n /** The host's layout box, in CSS pixels before any transform: what the grid is laid out in. */\n private box = { width: 0, height: 0 };\n /** Bitmap pixels per CSS pixel the canvas is backed at; 0 until the first fit. */\n private ratio = 0;\n private readonly mouse = { x: -10, y: 0, lx: 0, ly: 0, sx: 0, sy: 0, v: 0, vs: 0, a: 0, set: false };\n private rafId = 0;\n\n /**\n * Flips once the canvas has drawn, which retires the CSS stand-in grid.\n *\n * A canvas cannot be prerendered, so on an SSR'd or prerendered page this\n * element is simply blank until the bundle has loaded and hydration has run —\n * measured at ~2.8s on ngwr.dev's own home page. The stylesheet paints a static\n * grid of the same colour and pitch in the meantime, straight from the\n * prerendered HTML, and this hands over to the real thing.\n */\n protected readonly painted = signal(false);\n\n /** Flips once `boot()` has a context and a grid — the motion half waits for it. */\n private readonly booted = signal(false);\n\n /**\n * Whether the box has an area. The intersection observer calls a zero-area host\n * intersecting and sends no entry when it gains a size, so this reads the box instead.\n */\n private readonly hasBox = signal(false);\n\n constructor() {\n if (!this.isBrowser) return;\n\n afterNextRender(() => this.zone.runOutsideAngular(() => this.boot()));\n\n // Re-seed the grid when geometry inputs change. The bitmap is left alone,\n // so the next frame draws over the old grid rather than over a blank canvas.\n // And paint it, when there is no frame loop to: under\n // `prefers-reduced-motion` one static, undisturbed grid is drawn and no\n // frame follows, so a later gap change rebuilt the grid and left it undrawn\n // — with `.wr-waves--painted` already on the host, so the element stayed\n // visible and empty. The same still grid is drawn when the line colour\n // changes, and the moment motion stops. After render rather than an\n // `effect`, which runs before a directive's host binding: a still grid\n // drawn then would miss a hook it changes in the same pass.\n afterRenderEffect(() => {\n if (!this.booted()) return;\n const still = this.platform.prefersReducedMotion();\n this.xGap();\n this.yGap();\n // Only a still grid has to hear of a new colour: the loop resolves it every frame.\n if (still) this.lineColor();\n untracked(() => {\n this.setLines();\n if (still) this.drawLines();\n });\n });\n\n // The still grid keeps the line colour it was drawn with, so a scheme switch\n // under reduced motion re-resolves it and draws the grid again. The loop\n // needs no help: every frame it draws resolves the colour afresh.\n watchColorScheme(() => {\n if (this.booted() && this.platform.prefersReducedMotion()) this.drawLines();\n });\n\n // Motion, decided live: a preference switched while the page is open used to\n // keep the field drifting until a reload, because `boot()` read it once.\n // Never under `prefers-reduced-motion` — no drift, no loop, no pointer\n // reactivity; the still grid above is what that shows — and not with no box\n // to draw on.\n effect(onCleanup => {\n if (!this.booted() || !this.hasBox() || this.platform.prefersReducedMotion()) return;\n onCleanup(this.zone.runOutsideAngular(() => this.animate()));\n });\n }\n\n // Setup\n\n private boot(): void {\n const canvas = this.canvasRef().nativeElement;\n this.ctx = canvas.getContext('2d');\n if (!this.ctx) return;\n\n // `clientWidth` and not `getBoundingClientRect()`: the rect is the box after\n // transforms, and no observer hears of a transform, so a field booted inside\n // a dialog's scale-in kept a bitmap 96% of its box, stretched by CSS once\n // the animation ended. The observer's first entry follows with the exact,\n // sub-pixel size.\n const hostEl = this.host.nativeElement;\n this.fit(hostEl.clientWidth, hostEl.clientHeight);\n this.setLines();\n\n // The box is the observer's to follow, transforms excluded. A window resize\n // is for the pixel ratio, which browser zoom and a move to another screen\n // change with no box change at all.\n const onResize = (): void => this.resize(this.box.width, this.box.height);\n window.addEventListener('resize', onResize);\n const ro = new ResizeObserver(entries => {\n const rect = entries[entries.length - 1]?.contentRect;\n if (rect) this.resize(rect.width, rect.height);\n });\n ro.observe(hostEl);\n this.destroyRef.onDestroy(() => {\n window.removeEventListener('resize', onResize);\n ro.disconnect();\n });\n this.booted.set(true);\n }\n\n /** Start the drift and the pointer reactivity; returns what stops both. */\n private animate(): () => void {\n const onMouseMove = (e: MouseEvent): void => this.updateMouse(e.clientX, e.clientY);\n const onTouchMove = (e: TouchEvent): void => this.updateMouse(e.touches[0].clientX, e.touches[0].clientY);\n\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('touchmove', onTouchMove, { passive: true });\n\n const run = (): void => {\n if (this.rafId === 0) this.rafId = requestAnimationFrame(t => this.tick(t));\n };\n const halt = (): void => {\n cancelAnimationFrame(this.rafId);\n this.rafId = 0;\n };\n // Off screen the field stops asking for frames: it is decoration, and a\n // canvas redrawn out of sight still costs the browser a frame every frame.\n // Firefox on a wide retina window showed it: scrolled back up, the page\n // above the fold stayed blank for seconds until this loop and the pixel\n // budget below went in. Without an observer (jsdom) it simply runs. A box\n // flush against a zero-height clip intersects with nothing showing, and only a\n // second threshold reports the clip moving. It sits below any real ratio, or a\n // clip closing on a transition steps from under it to 0 without crossing anything.\n const io =\n typeof IntersectionObserver === 'undefined'\n ? null\n : new IntersectionObserver(\n entries => {\n const { isIntersecting, intersectionRatio } = entries[entries.length - 1];\n if (isIntersecting && intersectionRatio > 0) run();\n else halt();\n },\n { threshold: [0, 1e-9] }\n );\n if (io) io.observe(this.host.nativeElement);\n else run();\n\n return () => {\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('touchmove', onTouchMove);\n io?.disconnect();\n halt();\n };\n }\n\n /** Fit the canvas to a new box or pixel ratio and, when that cleared it, repaint at once. */\n private resize(width: number, height: number): void {\n const moved = width !== this.box.width || height !== this.box.height;\n if (!this.fit(width, height)) return;\n if (moved) {\n this.setLines();\n // Re-seeded points sit at rest. A drifting field puts them where the next\n // frame will, or the repaint below shows straight lines until it comes.\n if (!this.platform.prefersReducedMotion()) this.drift(performance.now());\n }\n // Observer entries arrive after the frame's own callbacks and before its\n // paint, and the fit cleared the bitmap, so a repaint left to the next frame\n // would leave this one blank: a resize drag flickered every frame.\n this.drawLines();\n }\n\n /**\n * Back the canvas for a `width` × `height` box, in CSS pixels, at the screen's\n * pixel ratio. Returns whether anything changed: writing `canvas.width` clears\n * the bitmap even to the value it already has, so an unchanged box is left alone.\n */\n private fit(width: number, height: number): boolean {\n // Backed at the screen's pixel ratio. A bitmap the size of the CSS box is\n // upscaled on a 2x screen, which smears every 1px line across two device\n // pixels and steps its curves. Capped at 2: the field repaints every frame,\n // and a 3x phone would push half as many pixels again for no visible gain.\n // Capped again by `MAX_CANVAS_PIXELS`, never below 1.\n const area = width * height;\n const budget = area > 0 ? Math.sqrt(MAX_CANVAS_PIXELS / area) : 2;\n const ratio = Math.max(1, Math.min(window.devicePixelRatio || 1, 2, budget));\n if (width === this.box.width && height === this.box.height && ratio === this.ratio) return false;\n\n this.box = { width, height };\n this.ratio = ratio;\n this.hasBox.set(width > 0 && height > 0);\n const canvas = this.canvasRef().nativeElement;\n canvas.width = Math.round(width * ratio);\n canvas.height = Math.round(height * ratio);\n // Resizing the bitmap resets the context, transform included, so the scale\n // goes on afterwards. Every coordinate below stays in CSS pixels.\n this.ctx?.setTransform(ratio, 0, 0, ratio, 0, 0);\n return true;\n }\n\n private setLines(): void {\n const { width, height } = this.box;\n this.lines = [];\n const oWidth = width + 200;\n const oHeight = height + 30;\n const xGap = this.xGap();\n const yGap = this.yGap();\n const totalLines = Math.ceil(oWidth / xGap);\n const totalPoints = Math.ceil(oHeight / yGap);\n const xStart = (width - xGap * totalLines) / 2;\n const yStart = (height - yGap * totalPoints) / 2;\n for (let i = 0; i <= totalLines; i++) {\n const pts: WavePoint[] = [];\n for (let j = 0; j <= totalPoints; j++) {\n pts.push({\n x: xStart + xGap * i,\n y: yStart + yGap * j,\n wave: { x: 0, y: 0 },\n cursor: { x: 0, y: 0, vx: 0, vy: 0 },\n });\n }\n this.lines.push(pts);\n }\n }\n\n // Frame loop\n\n private tick(time: number): void {\n const mouse = this.mouse;\n mouse.sx += (mouse.x - mouse.sx) * 0.1;\n mouse.sy += (mouse.y - mouse.sy) * 0.1;\n const dx = mouse.x - mouse.lx;\n const dy = mouse.y - mouse.ly;\n const d = Math.hypot(dx, dy);\n mouse.v = d;\n mouse.vs += (d - mouse.vs) * 0.1;\n mouse.vs = Math.min(100, mouse.vs);\n mouse.lx = mouse.x;\n mouse.ly = mouse.y;\n mouse.a = Math.atan2(dy, dx);\n\n this.movePoints(time);\n this.drawLines();\n this.rafId = requestAnimationFrame(t => this.tick(t));\n }\n\n /** Put every point where the noise drifts it at `time`. */\n private drift(time: number): void {\n const waveSpeedX = this.waveSpeedX();\n const waveSpeedY = this.waveSpeedY();\n const waveAmpX = this.waveAmpX();\n const waveAmpY = this.waveAmpY();\n\n for (const pts of this.lines) {\n for (const p of pts) {\n const move = this.noise.perlin2((p.x + time * waveSpeedX) * 0.002, (p.y + time * waveSpeedY) * 0.0015) * 12;\n p.wave.x = Math.cos(move) * waveAmpX;\n p.wave.y = Math.sin(move) * waveAmpY;\n }\n }\n }\n\n private movePoints(time: number): void {\n this.drift(time);\n\n const mouse = this.mouse;\n const friction = this.friction();\n const tension = this.tension();\n const maxCursorMove = this.maxCursorMove();\n\n for (const pts of this.lines) {\n for (const p of pts) {\n const dx = p.x - mouse.sx;\n const dy = p.y - mouse.sy;\n const dist = Math.hypot(dx, dy);\n const l = Math.max(175, mouse.vs);\n if (dist < l) {\n const s = 1 - dist / l;\n const f = Math.cos(dist * 0.001) * s;\n p.cursor.vx += Math.cos(mouse.a) * f * l * mouse.vs * 0.00065;\n p.cursor.vy += Math.sin(mouse.a) * f * l * mouse.vs * 0.00065;\n }\n\n p.cursor.vx += (0 - p.cursor.x) * tension;\n p.cursor.vy += (0 - p.cursor.y) * tension;\n p.cursor.vx *= friction;\n p.cursor.vy *= friction;\n p.cursor.x += p.cursor.vx * 2;\n p.cursor.y += p.cursor.vy * 2;\n p.cursor.x = Math.min(maxCursorMove, Math.max(-maxCursorMove, p.cursor.x));\n p.cursor.y = Math.min(maxCursorMove, Math.max(-maxCursorMove, p.cursor.y));\n }\n }\n }\n\n private moved(point: WavePoint, withCursor: boolean): { x: number; y: number } {\n const x = point.x + point.wave.x + (withCursor ? point.cursor.x : 0);\n const y = point.y + point.wave.y + (withCursor ? point.cursor.y : 0);\n return { x: Math.round(x * 10) / 10, y: Math.round(y * 10) / 10 };\n }\n\n private drawLines(): void {\n const ctx = this.ctx;\n if (!ctx) return;\n // Retire the CSS stand-in: from here the canvas has real pixels. Set inside\n // the draw rather than at the end of `boot()` so it can never switch the\n // fallback off before something has actually been painted. Runs outside\n // Angular (the rAF loop does), so `signal.set` schedules the one host-binding\n // update it needs; every later call is a no-op on an unchanged value.\n if (!this.painted()) this.painted.set(true);\n const { width, height } = this.box;\n ctx.clearRect(0, 0, width, height);\n ctx.beginPath();\n ctx.strokeStyle = this.resolveLineColor();\n for (const points of this.lines) {\n // Both ends stay where the grid put them, as they did when each line was\n // a polyline; only the interior follows the pointer.\n const last = points.length - 1;\n const path = points.map((p, idx) => this.moved(p, idx > 0 && idx < last));\n // A curve through the MIDPOINTS, with each grid point as its control.\n // Joining the points themselves with `lineTo` put a corner at every one,\n // and at the default 32px pitch they read as a jagged line. Consecutive\n // curves share a tangent at the midpoint between them, so the line bends\n // without a kink anywhere and still passes near every point.\n ctx.moveTo(path[0].x, path[0].y);\n for (let i = 1; i < last; i++) {\n const p = path[i];\n const next = path[i + 1];\n ctx.quadraticCurveTo(p.x, p.y, (p.x + next.x) / 2, (p.y + next.y) / 2);\n }\n ctx.lineTo(path[last].x, path[last].y);\n }\n ctx.stroke();\n }\n\n /**\n * Explicit input wins; otherwise the theme's `--wr-waves-line-color`. Either\n * is resolved through the cascade before it reaches `strokeStyle`, which\n * reads neither a custom property nor the `light-dark()` the hook holds.\n * Called on every draw, so a colour-scheme change lands on the next frame.\n */\n private resolveLineColor(): string {\n const expression = (this.lineColor() ?? '').trim() || 'var(--wr-waves-line-color)';\n return resolveCssColor(this.canvasRef().nativeElement, expression, 'rgba(15, 23, 42, 0.12)');\n }\n\n private updateMouse(x: number, y: number): void {\n // Re-read the box each move — cheaper than tracking scroll, and the\n // host is usually a hero that rarely reflows mid-gesture. The rect is the\n // box as drawn, after any transform on the host or an ancestor, and the\n // grid is laid out in the box before them, so the pointer is scaled back.\n const rect = this.host.nativeElement.getBoundingClientRect();\n const mouse = this.mouse;\n mouse.x = (x - rect.left) * (rect.width > 0 ? this.box.width / rect.width : 1);\n mouse.y = (y - rect.top) * (rect.height > 0 ? this.box.height / rect.height : 1);\n if (!mouse.set) {\n mouse.sx = mouse.x;\n mouse.sy = mouse.y;\n mouse.lx = mouse.x;\n mouse.ly = mouse.y;\n mouse.set = true;\n }\n }\n}\n"],"mappings":"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"}
@@ -104,6 +104,7 @@ i0.ɵɵngDeclareClassMetadata({
104
104
  var WrBreadcrumbsItem = class WrBreadcrumbsItem {
105
105
  href = input(null, ...ngDevMode ? [{ debugName: "href" }] : /* istanbul ignore next */ []);
106
106
  routerLink = input(null, ...ngDevMode ? [{ debugName: "routerLink" }] : /* istanbul ignore next */ []);
107
+ queryParams = input(null, ...ngDevMode ? [{ debugName: "queryParams" }] : /* istanbul ignore next */ []);
107
108
  external = input(false, ...ngDevMode ? [{ debugName: "external" }] : /* istanbul ignore next */ []);
108
109
  icon = input(null, ...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
109
110
  isLink = computed(() => this.href() != null || this.routerLink() != null, ...ngDevMode ? [{ debugName: "isLink" }] : /* istanbul ignore next */ []);
@@ -138,6 +139,13 @@ var WrBreadcrumbsItem = class WrBreadcrumbsItem {
138
139
  isRequired: false,
139
140
  transformFunction: null
140
141
  },
142
+ queryParams: {
143
+ classPropertyName: "queryParams",
144
+ publicName: "queryParams",
145
+ isSignal: true,
146
+ isRequired: false,
147
+ transformFunction: null
148
+ },
141
149
  external: {
142
150
  classPropertyName: "external",
143
151
  publicName: "external",
@@ -158,7 +166,7 @@ var WrBreadcrumbsItem = class WrBreadcrumbsItem {
158
166
  classAttribute: "wr-breadcrumbs__item"
159
167
  },
160
168
  ngImport: i0,
161
- template: "<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them — the\n last in static order — and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null —\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n}\n",
169
+ template: "<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them — the\n last in static order — and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null —\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\" [queryParams]=\"queryParams()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n}\n",
162
170
  dependencies: [
163
171
  {
164
172
  kind: "directive",
@@ -218,7 +226,7 @@ i0.ɵɵngDeclareClassMetadata({
218
226
  class: "wr-breadcrumbs__item",
219
227
  role: "listitem"
220
228
  },
221
- template: "<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them — the\n last in static order — and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null —\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n}\n"
229
+ template: "<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them — the\n last in static order — and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null —\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\" [queryParams]=\"queryParams()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n}\n"
222
230
  }]
223
231
  }],
224
232
  propDecorators: {
@@ -238,6 +246,14 @@ i0.ɵɵngDeclareClassMetadata({
238
246
  required: false
239
247
  }]
240
248
  }],
249
+ queryParams: [{
250
+ type: i0.Input,
251
+ args: [{
252
+ isSignal: true,
253
+ alias: "queryParams",
254
+ required: false
255
+ }]
256
+ }],
241
257
  external: [{
242
258
  type: i0.Input,
243
259
  args: [{