@flighthq/effects-canvas 0.3.1-next.975.01aea94 → 0.4.0-edge.1908.751021c

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 (49) hide show
  1. package/dist/canvasBevelEffect.d.ts.map +1 -1
  2. package/dist/canvasBevelEffect.js +5 -2
  3. package/dist/canvasBevelEffect.js.map +1 -1
  4. package/dist/canvasBloomEffect.d.ts.map +1 -1
  5. package/dist/canvasBloomEffect.js +48 -20
  6. package/dist/canvasBloomEffect.js.map +1 -1
  7. package/dist/canvasDropShadowEffect.js +1 -1
  8. package/dist/canvasDropShadowEffect.js.map +1 -1
  9. package/dist/canvasEffectDropShadowCss.js +8 -7
  10. package/dist/canvasEffectDropShadowCss.js.map +1 -1
  11. package/dist/canvasInnerGlowEffect.js +1 -1
  12. package/dist/canvasInnerGlowEffect.js.map +1 -1
  13. package/dist/canvasInnerShadowEffect.js +1 -1
  14. package/dist/canvasInnerShadowEffect.js.map +1 -1
  15. package/dist/canvasLensDistortionEffect.d.ts +5 -0
  16. package/dist/canvasLensDistortionEffect.d.ts.map +1 -0
  17. package/dist/canvasLensDistortionEffect.js +69 -0
  18. package/dist/canvasLensDistortionEffect.js.map +1 -0
  19. package/dist/canvasOuterGlowEffect.js +1 -1
  20. package/dist/canvasOuterGlowEffect.js.map +1 -1
  21. package/dist/canvasPosterizeEffect.d.ts +5 -0
  22. package/dist/canvasPosterizeEffect.d.ts.map +1 -0
  23. package/dist/canvasPosterizeEffect.js +35 -0
  24. package/dist/canvasPosterizeEffect.js.map +1 -0
  25. package/dist/canvasSourceModeCompositing.js +6 -4
  26. package/dist/canvasSourceModeCompositing.js.map +1 -1
  27. package/dist/canvasTiltShiftEffect.d.ts +5 -0
  28. package/dist/canvasTiltShiftEffect.d.ts.map +1 -0
  29. package/dist/canvasTiltShiftEffect.js +67 -0
  30. package/dist/canvasTiltShiftEffect.js.map +1 -0
  31. package/dist/canvasVignetteEffect.d.ts.map +1 -1
  32. package/dist/canvasVignetteEffect.js +36 -19
  33. package/dist/canvasVignetteEffect.js.map +1 -1
  34. package/dist/contract.d.ts +3 -0
  35. package/dist/contract.d.ts.map +1 -1
  36. package/dist/contract.js +3 -0
  37. package/dist/contract.js.map +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/index.js.map +1 -1
  42. package/package.json +8 -7
  43. package/src/canvasBloomEffect.test.ts +145 -5
  44. package/src/canvasDropShadowEffect.test.ts +0 -4
  45. package/src/canvasEffectDropShadowCss.test.ts +13 -0
  46. package/src/canvasLensDistortionEffect.test.ts +149 -0
  47. package/src/canvasOuterGlowEffect.test.ts +0 -4
  48. package/src/canvasPosterizeEffect.test.ts +138 -0
  49. package/src/canvasTiltShiftEffect.test.ts +156 -0
@@ -1 +1 @@
1
- {"version":3,"file":"canvasBevelEffect.d.ts","sourceRoot":"","sources":["../src/canvasBevelEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AA0BlC,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CAAC;AACR,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CAAC;AAeR,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,GAClC,IAAI,CAON;AAED,eAAO,MAAM,8BAA8B,EAAE,wBAE5C,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAExE"}
1
+ {"version":3,"file":"canvasBevelEffect.d.ts","sourceRoot":"","sources":["../src/canvasBevelEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AA0BlC,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CAAC;AACR,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CAAC;AAeR,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,GAClC,IAAI,CAON;AAED,eAAO,MAAM,8BAA8B,EAAE,wBAE5C,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAExE"}
@@ -1,3 +1,4 @@
1
+ import { getColorAlpha, getColorRgb } from '@flighthq/color/contract';
1
2
  import { drawCanvasEffectPass } from './canvasEffectCompositing';
2
3
  import { acquireCanvasRenderTarget, createCanvasRenderTargetPool, releaseCanvasRenderTarget, } from './canvasRenderEffectPipeline';
3
4
  import { registerCanvasRenderEffect } from './canvasRenderEffectRegistry';
@@ -53,13 +54,15 @@ function applyBevelEffectToCanvasWithPool(source, dest, pool, effect) {
53
54
  clearCanvasTarget(side);
54
55
  compositeCanvasImage(side, lit);
55
56
  compositeCanvasImage(side, shade, 0, 0, 'destination-out');
56
- drawCanvasTintedAlphaMask(tinted, side, effect.highlightColor ?? 0xffffff, effect.highlightAlpha ?? 1, strength);
57
+ const highlightPacked = effect.highlightColor ?? 0xffffffff;
58
+ drawCanvasTintedAlphaMask(tinted, side, getColorRgb(highlightPacked), (effect.highlightAlpha ?? 1) * getColorAlpha(highlightPacked), strength);
57
59
  compositeCanvasImage(band, tinted);
58
60
  // Shadow side: the same difference the other way round.
59
61
  clearCanvasTarget(side);
60
62
  compositeCanvasImage(side, shade);
61
63
  compositeCanvasImage(side, lit, 0, 0, 'destination-out');
62
- drawCanvasTintedAlphaMask(tinted, side, effect.shadowColor ?? 0x000000, effect.shadowAlpha ?? 1, strength);
64
+ const shadowPacked = effect.shadowColor ?? 0x000000ff;
65
+ drawCanvasTintedAlphaMask(tinted, side, getColorRgb(shadowPacked), (effect.shadowAlpha ?? 1) * getColorAlpha(shadowPacked), strength);
63
66
  compositeCanvasImage(band, tinted);
64
67
  clipCanvasBevelBand(band, source, effect.bevelType);
65
68
  clearCanvasTarget(dest);
@@ -1 +1 @@
1
- {"version":3,"file":"canvasBevelEffect.js","sourceRoot":"","sources":["../src/canvasBevelEffect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvasBevelEffect.js","sourceRoot":"","sources":["../src/canvasBevelEffect.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"canvasBloomEffect.d.ts","sourceRoot":"","sources":["../src/canvasBloomEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAUlC,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CAkCN;AAED,eAAO,MAAM,8BAA8B,EAAE,wBAE5C,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAExE"}
1
+ {"version":3,"file":"canvasBloomEffect.d.ts","sourceRoot":"","sources":["../src/canvasBloomEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AA0BlC,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC5B,IAAI,CA6CN;AAED,eAAO,MAAM,8BAA8B,EAAE,wBAE5C,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAExE"}
@@ -1,22 +1,46 @@
1
1
  import { computeBloomBlurRadius } from '@flighthq/effects/contract';
2
- import { drawCanvasEffectPass } from './canvasEffectCompositing';
2
+ import { drawCanvasEffectPass, drawCanvasImageDataPass } from './canvasEffectCompositing';
3
3
  import { acquireCanvasRenderTarget, releaseCanvasRenderTarget } from './canvasRenderEffectPipeline';
4
4
  import { registerCanvasRenderEffect } from './canvasRenderEffectRegistry';
5
- // Bloom (REAL): bright-pass → blur the bright branch → additively composite back. Multi-pass: it
6
- // acquires a scratch canvas from the pool, isolates bright pixels by pushing contrast hard so dim
7
- // pixels crush to black, blurs that branch, then draws it over the scene with the 'lighter'
8
- // (additive) composite op scaled by intensity (applied via the temp canvas's globalAlpha).
5
+ // Bloom (REAL): bright-pass → blur the bright branch → additively composite back, matching the Gl/Wgpu
6
+ // recipe term for term — a LUMINANCE GATE `step(threshold, dot(rgb, (0.2126, 0.7152, 0.0722)))` on the
7
+ // bright branch, and `scene + bloom * intensity` on the composite.
8
+ //
9
+ // ★ BOTH OF THOSE USED TO BE CSS-FILTER APPROXIMATIONS, AND BOTH WERE WRONG IN WAYS A PICTURE SHOWED.
10
+ //
11
+ // The bright pass was `contrast(1 + threshold*6) brightness(1 - threshold)`, which is PER CHANNEL: CSS
12
+ // filters have no notion of luminance, so each channel crushes against the same point independently. A
13
+ // yellow tile (255,255,92) lost its blue entirely — 0.36 falls below the crush point — so no blue was
14
+ // ever added back, and the tile's core stayed at 92 while Gl's reached 221. A tile whose every channel
15
+ // sits above the crush point agreed on both backends, which is the signature that named the cause.
16
+ //
17
+ // The composite scaled `ctx.globalAlpha` by intensity, and globalAlpha is CLAMPED TO 1 — so an
18
+ // intensity of 1.4 was structurally inexpressible, not merely lossy: 1.4 and 1.0 rendered identically,
19
+ // verified by measurement. Additive compositing above 1x needs the arithmetic, not the alpha channel.
20
+ //
21
+ // Both are now per-pixel through `drawCanvasImageDataPass`, the same primitive that made posterize,
22
+ // lens distortion and tilt shift reachable when `ctx.filter` could not spell them. The blur BETWEEN
23
+ // them stays a CSS blur, which is correct: a blur is spatial and per-channel by nature, so it is the
24
+ // one stage where the filter chain and the shader already agree.
9
25
  export function applyBloomEffectToCanvas(source, dest, pool, effect) {
10
26
  const threshold = effect.threshold ?? 0.8;
11
27
  const intensity = effect.intensity ?? 1;
12
28
  const radius = computeBloomBlurRadius(effect);
13
- // Bright pass: crush sub-threshold pixels toward black with a high-contrast / low-brightness CSS
14
- // chain. contrast amplifies the gap around mid-grey; the brightness shift biases the crush point so
15
- // a higher threshold keeps fewer pixels lit.
16
- const contrast = 1 + threshold * 6;
17
- const brightnessShift = 1 - threshold;
29
+ // Bright pass: keep a pixel whole when its LUMINANCE clears the threshold, and zero it otherwise.
30
+ // This is the shader's `step(threshold, l)` and not an approximation of it — the gate is on one
31
+ // luminance value, so a colour with a dim channel survives intact rather than losing that channel.
18
32
  const bright = acquireCanvasRenderTarget(pool, source.width, source.height);
19
- drawCanvasEffectPass(bright, source, `contrast(${contrast}) brightness(${brightnessShift})`);
33
+ drawCanvasImageDataPass(bright, source, (data, pixelCount) => {
34
+ for (let pixel = 0; pixel < pixelCount; pixel++) {
35
+ const at = pixel * 4;
36
+ const luminance = (0.2126 * data[at] + 0.7152 * data[at + 1] + 0.0722 * data[at + 2]) / 255;
37
+ if (luminance >= threshold)
38
+ continue;
39
+ data[at] = 0;
40
+ data[at + 1] = 0;
41
+ data[at + 2] = 0;
42
+ }
43
+ });
20
44
  // Blur the bright branch in place via a second scratch canvas (CSS blur draws blurred → blurred2).
21
45
  const blurred = acquireCanvasRenderTarget(pool, source.width, source.height);
22
46
  if (radius > 0) {
@@ -25,16 +49,20 @@ export function applyBloomEffectToCanvas(source, dest, pool, effect) {
25
49
  else {
26
50
  drawCanvasEffectPass(blurred, bright, 'none');
27
51
  }
28
- // Composite: scene first, then the bloom branch added on top (additive 'lighter'), scaled by intensity.
52
+ // Composite: `scene + bloom * intensity`, computed rather than composited, because an intensity above
53
+ // 1 has to be expressible. `globalAlpha` cannot carry it — it is clamped to 1, so every intensity at
54
+ // or above 1 produced one picture.
29
55
  drawCanvasEffectPass(dest, source, 'none');
30
- const ctx = dest.context;
31
- ctx.save();
32
- ctx.setTransform(1, 0, 0, 1, 0, 0);
33
- ctx.globalCompositeOperation = 'lighter';
34
- ctx.globalAlpha = Math.max(0, Math.min(1, intensity));
35
- ctx.filter = 'none';
36
- ctx.drawImage(blurred.canvas, 0, 0);
37
- ctx.restore();
56
+ const bloom = blurred.context.getImageData(0, 0, blurred.width, blurred.height).data;
57
+ drawCanvasImageDataPass(dest, dest, (data, pixelCount) => {
58
+ for (let pixel = 0; pixel < pixelCount; pixel++) {
59
+ const at = pixel * 4;
60
+ // Alpha is the scene's, exactly as the shader writes `scene.a` and leaves the bloom's alpha out.
61
+ data[at] = data[at] + bloom[at] * intensity;
62
+ data[at + 1] = data[at + 1] + bloom[at + 1] * intensity;
63
+ data[at + 2] = data[at + 2] + bloom[at + 2] * intensity;
64
+ }
65
+ });
38
66
  releaseCanvasRenderTarget(pool, bright);
39
67
  releaseCanvasRenderTarget(pool, blurred);
40
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"canvasBloomEffect.js","sourceRoot":"","sources":["../src/canvasBloomEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AASpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACpG,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E,iGAAiG;AACjG,kGAAkG;AAClG,4FAA4F;AAC5F,2FAA2F;AAC3F,MAAM,UAAU,wBAAwB,CACtC,MAAoC,EACpC,IAAkC,EAClC,IAA4B,EAC5B,MAA6B;IAE7B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC;IAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE9C,iGAAiG;IACjG,oGAAoG;IACpG,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC;IACnC,MAAM,eAAe,GAAG,CAAC,GAAG,SAAS,CAAC;IACtC,MAAM,MAAM,GAAG,yBAAyB,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5E,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,QAAQ,gBAAgB,eAAe,GAAG,CAAC,CAAC;IAE7F,mGAAmG;IACnG,MAAM,OAAO,GAAG,yBAAyB,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7E,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC,CAAC;IAC7D,CAAC;SAAM,CAAC;QACN,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAED,wGAAwG;IACxG,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;IACzB,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACnC,GAAG,CAAC,wBAAwB,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IACtD,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACpB,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACpC,GAAG,CAAC,OAAO,EAAE,CAAC;IAEd,yBAAyB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,MAAM,8BAA8B,GAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IACtF,wBAAwB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAqB,CAAC,CAAC;AAClF,CAAC,CAAC;AAEF,MAAM,UAAU,yBAAyB,CAAC,KAAwB;IAChE,0BAA0B,CAAC,KAAK,EAAE,aAAa,EAAE,8BAA8B,CAAC,CAAC;AACnF,CAAC"}
1
+ {"version":3,"file":"canvasBloomEffect.js","sourceRoot":"","sources":["../src/canvasBloomEffect.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,7 @@ function applyDropShadowEffectToCanvasWithPool(source, dest, pool, effect) {
31
31
  const shadowPasses = Math.max(1, Math.floor(strength));
32
32
  const blur = Math.max(0, ((effect.blurX ?? 4) + (effect.blurY ?? 4)) / 2);
33
33
  const sourceMode = effect.sourceMode ?? 'draw';
34
- drawCanvasTintedAlphaMask(mask, source, effect.color ?? 0, effect.alpha ?? 1, tintStrength);
34
+ drawCanvasTintedAlphaMask(mask, source, effect.color ?? 0x000000ff, effect.alpha ?? 1, tintStrength);
35
35
  drawCanvasEffectPass(blurred, mask, blur > 0 ? `blur(${blur}px)` : 'none');
36
36
  clearCanvasTarget(dest);
37
37
  for (let i = 0; i < shadowPasses; i++) {
@@ -1 +1 @@
1
- {"version":3,"file":"canvasDropShadowEffect.js","sourceRoot":"","sources":["../src/canvasDropShadowEffect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvasDropShadowEffect.js","sourceRoot":"","sources":["../src/canvasDropShadowEffect.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ export function computeDropShadowEffectCss(effect) {
13
13
  const radians = (angle * Math.PI) / 180;
14
14
  const dx = Math.round(Math.cos(radians) * distance);
15
15
  const dy = Math.round(Math.sin(radians) * distance);
16
- return `drop-shadow(${dx}px ${dy}px ${blurX}px ${cssRgbaFromColor(effect.color ?? 0, effect.alpha ?? 1)})`;
16
+ return `drop-shadow(${dx}px ${dy}px ${blurX}px ${cssRgbaFromColor(effect.color ?? 0x000000ff, effect.alpha ?? 1)})`;
17
17
  }
18
18
  // Outer-glow composite effect as a centered (no offset) CSS `drop-shadow()` string.
19
19
  // Only sourceMode 'draw' and isotropic blur can be represented by CSS-only drop-shadow().
@@ -24,13 +24,14 @@ export function computeOuterGlowEffectCss(effect) {
24
24
  const blurY = effect.blurY ?? 6;
25
25
  if (blurX !== blurY)
26
26
  return null;
27
- return `drop-shadow(0px 0px ${blurX}px ${cssRgbaFromColor(effect.color ?? 0xff0000, effect.alpha ?? 1)})`;
27
+ return `drop-shadow(0px 0px ${blurX}px ${cssRgbaFromColor(effect.color ?? 0xff0000ff, effect.alpha ?? 1)})`;
28
28
  }
29
- // Packed 0xRRGGBB integer + separate alpha to a CSS `rgba()` string (alpha fixed to 3 decimals).
29
+ // Flight's packed sRGB `0xRRGGBBAA` plus the effect-level alpha, to a CSS `rgba()` string (alpha fixed to
30
+ // 3 decimals). The color's own alpha multiplies the effect's, so a caller never splits the value itself.
30
31
  function cssRgbaFromColor(color, alpha) {
31
- const r = (color >> 16) & 0xff;
32
- const g = (color >> 8) & 0xff;
33
- const b = color & 0xff;
34
- return `rgba(${r},${g},${b},${alpha.toFixed(3)})`;
32
+ const r = (color >>> 24) & 0xff;
33
+ const g = (color >>> 16) & 0xff;
34
+ const b = (color >>> 8) & 0xff;
35
+ return `rgba(${r},${g},${b},${(alpha * ((color & 0xff) / 255)).toFixed(3)})`;
35
36
  }
36
37
  //# sourceMappingURL=canvasEffectDropShadowCss.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvasEffectDropShadowCss.js","sourceRoot":"","sources":["../src/canvasEffectDropShadowCss.ts"],"names":[],"mappings":"AAEA,wGAAwG;AACxG,0FAA0F;AAC1F,wGAAwG;AACxG,MAAM,UAAU,0BAA0B,CAAC,MAAkC;IAC3E,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IACpD,OAAO,eAAe,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,gBAAgB,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;AAC7G,CAAC;AAED,oFAAoF;AACpF,0FAA0F;AAC1F,MAAM,UAAU,yBAAyB,CAAC,MAAiC;IACzE,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,uBAAuB,KAAK,MAAM,gBAAgB,CAAC,MAAM,CAAC,KAAK,IAAI,QAAQ,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;AAC5G,CAAC;AAED,iGAAiG;AACjG,SAAS,gBAAgB,CAAC,KAAa,EAAE,KAAa;IACpD,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAC/B,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;IACvB,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"canvasEffectDropShadowCss.js","sourceRoot":"","sources":["../src/canvasEffectDropShadowCss.ts"],"names":[],"mappings":"AAEA,wGAAwG;AACxG,0FAA0F;AAC1F,wGAAwG;AACxG,MAAM,UAAU,0BAA0B,CAAC,MAAkC;IAC3E,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IACpD,OAAO,eAAe,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,gBAAgB,CAAC,MAAM,CAAC,KAAK,IAAI,UAAU,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;AACtH,CAAC;AAED,oFAAoF;AACpF,0FAA0F;AAC1F,MAAM,UAAU,yBAAyB,CAAC,MAAiC;IACzE,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,uBAAuB,KAAK,MAAM,gBAAgB,CAAC,MAAM,CAAC,KAAK,IAAI,UAAU,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;AAC9G,CAAC;AAED,0GAA0G;AAC1G,yGAAyG;AACzG,SAAS,gBAAgB,CAAC,KAAa,EAAE,KAAa;IACpD,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;IAC/B,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAC/E,CAAC"}
@@ -19,7 +19,7 @@ function applyInnerGlowEffectToCanvasWithPool(source, dest, pool, effect) {
19
19
  const strength = effect.strength ?? 1;
20
20
  const glowPasses = Math.max(1, Math.floor(strength));
21
21
  const blur = Math.max(0, ((effect.blurX ?? 6) + (effect.blurY ?? 6)) / 2);
22
- drawCanvasInvertedTintedAlphaMask(mask, source, effect.color ?? 0xffffff, effect.alpha ?? 1, Math.min(1, strength));
22
+ drawCanvasInvertedTintedAlphaMask(mask, source, effect.color ?? 0xffffffff, effect.alpha ?? 1, Math.min(1, strength));
23
23
  drawCanvasEffectPass(glow, mask, blur > 0 ? `blur(${blur}px)` : 'none');
24
24
  // Clip to the source alpha. Without this the blurred inversion still covers the whole exterior, which
25
25
  // would paint the glow outside the shape as well as inside it.
@@ -1 +1 @@
1
- {"version":3,"file":"canvasInnerGlowEffect.js","sourceRoot":"","sources":["../src/canvasInnerGlowEffect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvasInnerGlowEffect.js","sourceRoot":"","sources":["../src/canvasInnerGlowEffect.ts"],"names":[],"mappings":"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"}
@@ -24,7 +24,7 @@ function applyInnerShadowEffectToCanvasWithPool(source, dest, pool, effect) {
24
24
  const distance = effect.distance ?? 4;
25
25
  const offsetX = Math.cos(angle) * distance;
26
26
  const offsetY = Math.sin(angle) * distance;
27
- drawCanvasInvertedTintedAlphaMask(mask, source, effect.color ?? 0x000000, effect.alpha ?? 1, Math.min(1, strength));
27
+ drawCanvasInvertedTintedAlphaMask(mask, source, effect.color ?? 0x000000ff, effect.alpha ?? 1, Math.min(1, strength));
28
28
  drawCanvasEffectPass(blurred, mask, blur > 0 ? `blur(${blur}px)` : 'none');
29
29
  // The offset is its own pass into a cleared target rather than a shifted draw into `blurred`, because
30
30
  // drawing a target onto itself at an offset would read pixels it is concurrently writing.
@@ -1 +1 @@
1
- {"version":3,"file":"canvasInnerShadowEffect.js","sourceRoot":"","sources":["../src/canvasInnerShadowEffect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvasInnerShadowEffect.js","sourceRoot":"","sources":["../src/canvasInnerShadowEffect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { CanvasRenderEffectRunner, CanvasRenderState, CanvasRenderTarget, LensDistortionEffect } from '@flighthq/types/contract';
2
+ export declare function applyLensDistortionEffectToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, effect: Readonly<LensDistortionEffect>): void;
3
+ export declare const defaultCanvasLensDistortionEffectRunner: CanvasRenderEffectRunner;
4
+ export declare function registerCanvasLensDistortionEffect(state: CanvasRenderState): void;
5
+ //# sourceMappingURL=canvasLensDistortionEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasLensDistortionEffect.d.ts","sourceRoot":"","sources":["../src/canvasLensDistortionEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAiBlC,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GACrC,IAAI,CAqDN;AAED,eAAO,MAAM,uCAAuC,EAAE,wBAErD,CAAC;AAEF,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAEjF"}
@@ -0,0 +1,69 @@
1
+ import { drawCanvasImageDataPass } from './canvasEffectCompositing';
2
+ import { registerCanvasRenderEffect } from './canvasRenderEffectRegistry';
3
+ // Lens distortion (REAL): remap uv by the same radial polynomial the Gl/Wgpu recipe uses —
4
+ // `centered = (uv - 0.5) / scale; distorted = centered * (1 + amount * dot(centered, centered)) + 0.5` —
5
+ // sampling the source at the distorted coordinate and writing opaque black where it leaves the frame.
6
+ //
7
+ // ★ THIS IS A RESAMPLE, NOT A COLOUR OP, which is why it needs the ImageData pass rather than a CSS
8
+ // filter chain. It reads the whole source once into a snapshot and writes a fresh buffer, because the
9
+ // destination pixel at (x, y) reads a SOURCE pixel somewhere else entirely: transforming in place would
10
+ // feed already-distorted pixels back into later samples.
11
+ //
12
+ // ★ SAMPLING IS BILINEAR, MATCHING THE GPU'S `linear` filter. Nearest-neighbour would land within a
13
+ // pixel of the right answer everywhere and still look wrong along every edge in the picture, which is
14
+ // the difference between "the parameter is observable" and "the backends agree".
15
+ export function applyLensDistortionEffectToCanvas(source, dest, effect) {
16
+ const amount = effect.amount ?? 0.2;
17
+ const scale = effect.scale ?? 1;
18
+ drawCanvasImageDataPass(dest, source, (data, pixelCount) => {
19
+ const width = source.width;
20
+ const height = Math.max(1, Math.round(pixelCount / Math.max(1, width)));
21
+ const snapshot = new Uint8ClampedArray(data);
22
+ for (let y = 0; y < height; y++) {
23
+ for (let x = 0; x < width; x++) {
24
+ const out = (y * width + x) * 4;
25
+ // Pixel CENTRES, matching how the GPU rasterizer hands v_texCoord to the fragment shader; using
26
+ // x/width instead would sample half a texel off across the whole frame.
27
+ const centeredX = ((x + 0.5) / width - 0.5) / scale;
28
+ const centeredY = ((y + 0.5) / height - 0.5) / scale;
29
+ const radiusSquared = centeredX * centeredX + centeredY * centeredY;
30
+ const factor = 1 + amount * radiusSquared;
31
+ const u = centeredX * factor + 0.5;
32
+ const v = centeredY * factor + 0.5;
33
+ if (u < 0 || u > 1 || v < 0 || v > 1) {
34
+ data[out] = 0;
35
+ data[out + 1] = 0;
36
+ data[out + 2] = 0;
37
+ data[out + 3] = 255;
38
+ continue;
39
+ }
40
+ const sampleX = u * width - 0.5;
41
+ const sampleY = v * height - 0.5;
42
+ const x0 = Math.floor(sampleX);
43
+ const y0 = Math.floor(sampleY);
44
+ const fx = sampleX - x0;
45
+ const fy = sampleY - y0;
46
+ const x1 = Math.min(width - 1, Math.max(0, x0 + 1));
47
+ const y1 = Math.min(height - 1, Math.max(0, y0 + 1));
48
+ const cx0 = Math.min(width - 1, Math.max(0, x0));
49
+ const cy0 = Math.min(height - 1, Math.max(0, y0));
50
+ const topLeft = (cy0 * width + cx0) * 4;
51
+ const topRight = (cy0 * width + x1) * 4;
52
+ const bottomLeft = (y1 * width + cx0) * 4;
53
+ const bottomRight = (y1 * width + x1) * 4;
54
+ for (let channel = 0; channel < 4; channel++) {
55
+ const top = snapshot[topLeft + channel] * (1 - fx) + snapshot[topRight + channel] * fx;
56
+ const bottom = snapshot[bottomLeft + channel] * (1 - fx) + snapshot[bottomRight + channel] * fx;
57
+ data[out + channel] = Math.round(top * (1 - fy) + bottom * fy);
58
+ }
59
+ }
60
+ }
61
+ });
62
+ }
63
+ export const defaultCanvasLensDistortionEffectRunner = (ctx, effect) => {
64
+ applyLensDistortionEffectToCanvas(ctx.source, ctx.dest, effect);
65
+ };
66
+ export function registerCanvasLensDistortionEffect(state) {
67
+ registerCanvasRenderEffect(state, 'LensDistortionEffect', defaultCanvasLensDistortionEffectRunner);
68
+ }
69
+ //# sourceMappingURL=canvasLensDistortionEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasLensDistortionEffect.js","sourceRoot":"","sources":["../src/canvasLensDistortionEffect.ts"],"names":[],"mappings":"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"}
@@ -27,7 +27,7 @@ function applyOuterGlowEffectToCanvasWithPool(source, dest, pool, effect) {
27
27
  const glowPasses = Math.max(1, Math.floor(strength));
28
28
  const blur = Math.max(0, ((effect.blurX ?? 6) + (effect.blurY ?? 6)) / 2);
29
29
  const sourceMode = effect.sourceMode ?? 'draw';
30
- drawCanvasTintedAlphaMask(mask, source, effect.color ?? 0xff0000, effect.alpha ?? 1, tintStrength);
30
+ drawCanvasTintedAlphaMask(mask, source, effect.color ?? 0xff0000ff, effect.alpha ?? 1, tintStrength);
31
31
  drawCanvasEffectPass(blurred, mask, blur > 0 ? `blur(${blur}px)` : 'none');
32
32
  clearCanvasTarget(dest);
33
33
  for (let i = 0; i < glowPasses; i++) {
@@ -1 +1 @@
1
- {"version":3,"file":"canvasOuterGlowEffect.js","sourceRoot":"","sources":["../src/canvasOuterGlowEffect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvasOuterGlowEffect.js","sourceRoot":"","sources":["../src/canvasOuterGlowEffect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { CanvasRenderEffectRunner, CanvasRenderState, CanvasRenderTarget, PosterizeEffect } from '@flighthq/types/contract';
2
+ export declare function applyPosterizeEffectToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, effect: Readonly<PosterizeEffect>): void;
3
+ export declare const defaultCanvasPosterizeEffectRunner: CanvasRenderEffectRunner;
4
+ export declare function registerCanvasPosterizeEffect(state: CanvasRenderState): void;
5
+ //# sourceMappingURL=canvasPosterizeEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasPosterizeEffect.d.ts","sourceRoot":"","sources":["../src/canvasPosterizeEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAkBlC,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAChC,IAAI,CAYN;AAED,eAAO,MAAM,kCAAkC,EAAE,wBAEhD,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAE5E"}
@@ -0,0 +1,35 @@
1
+ import { drawCanvasImageDataPass } from './canvasEffectCompositing';
2
+ import { registerCanvasRenderEffect } from './canvasRenderEffectRegistry';
3
+ // Posterize (REAL): floor each channel to `levels` discrete steps, matching the Gl/Wgpu recipe
4
+ // `floor(c * levels) / (levels - 1)` exactly rather than approximating it.
5
+ //
6
+ // ★ THE QUANTISATION IS DONE PER PIXEL, NOT THROUGH A CSS FILTER, because no CSS filter expresses a
7
+ // step function. `drawCanvasImageDataPass` is the package's existing primitive for exactly this case,
8
+ // and its presence is the reason this cell was implementable at all: the scene had been declared a
9
+ // backend CONTROL on the belief that Canvas 2D can only reach what `ctx.filter` can spell.
10
+ //
11
+ // ★ THE 255-DOMAIN ROUNDING IS THE WHOLE DIFFICULTY. The GPU works in floats and writes an 8-bit result
12
+ // once, at the end. Doing the same arithmetic on bytes rounds twice — once reading the byte, once
13
+ // writing it — and a step function amplifies a half-level rounding difference into a whole band moving.
14
+ // So the byte is converted to the float domain, quantised there with the identical expression, and only
15
+ // then rounded back, with the same clamp the shader applies.
16
+ export function applyPosterizeEffectToCanvas(source, dest, effect) {
17
+ const levels = Math.max(2, effect.levels ?? 8);
18
+ drawCanvasImageDataPass(dest, source, (data, pixelCount) => {
19
+ for (let pixel = 0; pixel < pixelCount; pixel++) {
20
+ const at = pixel * 4;
21
+ for (let channel = 0; channel < 3; channel++) {
22
+ const value = data[at + channel] / 255;
23
+ const quantised = Math.floor(value * levels) / (levels - 1);
24
+ data[at + channel] = Math.round(Math.max(0, Math.min(1, quantised)) * 255);
25
+ }
26
+ }
27
+ });
28
+ }
29
+ export const defaultCanvasPosterizeEffectRunner = (ctx, effect) => {
30
+ applyPosterizeEffectToCanvas(ctx.source, ctx.dest, effect);
31
+ };
32
+ export function registerCanvasPosterizeEffect(state) {
33
+ registerCanvasRenderEffect(state, 'PosterizeEffect', defaultCanvasPosterizeEffectRunner);
34
+ }
35
+ //# sourceMappingURL=canvasPosterizeEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasPosterizeEffect.js","sourceRoot":"","sources":["../src/canvasPosterizeEffect.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E,+FAA+F;AAC/F,2EAA2E;AAC3E,EAAE;AACF,oGAAoG;AACpG,sGAAsG;AACtG,mGAAmG;AACnG,2FAA2F;AAC3F,EAAE;AACF,wGAAwG;AACxG,kGAAkG;AAClG,wGAAwG;AACxG,wGAAwG;AACxG,6DAA6D;AAC7D,MAAM,UAAU,4BAA4B,CAC1C,MAAoC,EACpC,IAAkC,EAClC,MAAiC;IAEjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAC/C,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE;QACzD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC;YAChD,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;YACrB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;gBAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,GAAG,OAAO,CAAE,GAAG,GAAG,CAAC;gBACxC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC5D,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,kCAAkC,GAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC1F,4BAA4B,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAyB,CAAC,CAAC;AAChF,CAAC,CAAC;AAEF,MAAM,UAAU,6BAA6B,CAAC,KAAwB;IACpE,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,EAAE,kCAAkC,CAAC,CAAC;AAC3F,CAAC"}
@@ -61,11 +61,13 @@ export function drawCanvasTintedAlphaMask(dest, source, color, alpha, strength)
61
61
  ctx.fillRect(0, 0, dest.width, dest.height);
62
62
  ctx.restore();
63
63
  }
64
+ // Takes Flight's packed sRGB `0xRRGGBBAA`; the color's own alpha multiplies the caller's alpha, which is
65
+ // the effect-level opacity. One decode point for every canvas tint, so no call site repeats the split.
64
66
  function cssRgbaFromColor(color, alpha) {
65
- const r = (color >> 16) & 0xff;
66
- const g = (color >> 8) & 0xff;
67
- const b = color & 0xff;
68
- const a = Math.max(0, Math.min(1, alpha));
67
+ const r = (color >>> 24) & 0xff;
68
+ const g = (color >>> 16) & 0xff;
69
+ const b = (color >>> 8) & 0xff;
70
+ const a = Math.max(0, Math.min(1, alpha * ((color & 0xff) / 255)));
69
71
  return `rgba(${r},${g},${b},${a.toFixed(3)})`;
70
72
  }
71
73
  //# sourceMappingURL=canvasSourceModeCompositing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"canvasSourceModeCompositing.js","sourceRoot":"","sources":["../src/canvasSourceModeCompositing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvasSourceModeCompositing.js","sourceRoot":"","sources":["../src/canvasSourceModeCompositing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { CanvasRenderEffectRunner, CanvasRenderState, CanvasRenderTarget, TiltShiftEffect } from '@flighthq/types/contract';
2
+ export declare function applyTiltShiftEffectToCanvas(source: Readonly<CanvasRenderTarget>, dest: Readonly<CanvasRenderTarget>, effect: Readonly<TiltShiftEffect>): void;
3
+ export declare const defaultCanvasTiltShiftEffectRunner: CanvasRenderEffectRunner;
4
+ export declare function registerCanvasTiltShiftEffect(state: CanvasRenderState): void;
5
+ //# sourceMappingURL=canvasTiltShiftEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasTiltShiftEffect.d.ts","sourceRoot":"","sources":["../src/canvasTiltShiftEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAiBlC,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAChC,IAAI,CAiDN;AAED,eAAO,MAAM,kCAAkC,EAAE,wBAEhD,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAE5E"}
@@ -0,0 +1,67 @@
1
+ import { drawCanvasImageDataPass } from './canvasEffectCompositing';
2
+ import { registerCanvasRenderEffect } from './canvasRenderEffectRegistry';
3
+ // Tilt shift (REAL): keep a horizontal focus band sharp and blur above and below it, matching the
4
+ // Gl/Wgpu recipe tap for tap — seven uniformly weighted vertical samples spaced `radius` pixels apart,
5
+ // where `radius = smoothstep(width/2, width/2 + width, |y - center|) * blur`.
6
+ //
7
+ // ★ THE TAP COUNT AND WEIGHTING ARE PART OF THE PICTURE, not an implementation detail. A Gaussian of
8
+ // the same nominal radius would be a defensible blur and a different image; seven equal taps is what
9
+ // the other two backends draw, so it is what agreement means here.
10
+ //
11
+ // ★ `center` IS MEASURED DOWN FROM THE TOP EDGE (see TiltShiftEffect). Canvas ImageData is already
12
+ // top-down, so this runner passes the value straight through where the Gl runner must flip it. That
13
+ // asymmetry is the convention working, not a discrepancy — and a centred band hides it completely,
14
+ // because |y - 0.5| is symmetric, so only an off-centre band can show it going wrong.
15
+ export function applyTiltShiftEffectToCanvas(source, dest, effect) {
16
+ const center = effect.center ?? 0.5;
17
+ const bandWidth = effect.width ?? 0.3;
18
+ const blur = effect.blur ?? 4;
19
+ drawCanvasImageDataPass(dest, source, (data, pixelCount) => {
20
+ const width = source.width;
21
+ const height = Math.max(1, Math.round(pixelCount / Math.max(1, width)));
22
+ // The taps read the ORIGINAL image. Blurring in place would feed each row's own blurred result
23
+ // into the next row's taps, which is a different (and direction-dependent) operator.
24
+ const snapshot = new Uint8ClampedArray(data);
25
+ const edge = bandWidth * 0.5;
26
+ for (let y = 0; y < height; y++) {
27
+ const distance = Math.abs((y + 0.5) / height - center);
28
+ const ramp = Math.max(0, Math.min(1, (distance - edge) / Math.max(1e-6, bandWidth)));
29
+ const radius = ramp * ramp * (3 - 2 * ramp) * blur;
30
+ for (let x = 0; x < width; x++) {
31
+ const out = (y * width + x) * 4;
32
+ let red = 0;
33
+ let green = 0;
34
+ let blue = 0;
35
+ let alpha = 0;
36
+ for (let tap = -TAP_REACH; tap <= TAP_REACH; tap++) {
37
+ // The GPU offsets by `tap * radius * texel`, which lands on a fractional row; its linear
38
+ // sampler then interpolates. Rounding to the nearest row instead would quantise the ramp
39
+ // into visible bands wherever radius passes a half-pixel.
40
+ const sampleY = y + tap * radius;
41
+ const low = Math.max(0, Math.min(height - 1, Math.floor(sampleY)));
42
+ const high = Math.max(0, Math.min(height - 1, low + 1));
43
+ const blend = Math.max(0, Math.min(1, sampleY - Math.floor(sampleY)));
44
+ const lowAt = (low * width + x) * 4;
45
+ const highAt = (high * width + x) * 4;
46
+ red += snapshot[lowAt] * (1 - blend) + snapshot[highAt] * blend;
47
+ green += snapshot[lowAt + 1] * (1 - blend) + snapshot[highAt + 1] * blend;
48
+ blue += snapshot[lowAt + 2] * (1 - blend) + snapshot[highAt + 2] * blend;
49
+ alpha += snapshot[lowAt + 3] * (1 - blend) + snapshot[highAt + 3] * blend;
50
+ }
51
+ data[out] = Math.round(red / TAP_COUNT);
52
+ data[out + 1] = Math.round(green / TAP_COUNT);
53
+ data[out + 2] = Math.round(blue / TAP_COUNT);
54
+ data[out + 3] = Math.round(alpha / TAP_COUNT);
55
+ }
56
+ }
57
+ });
58
+ }
59
+ export const defaultCanvasTiltShiftEffectRunner = (ctx, effect) => {
60
+ applyTiltShiftEffectToCanvas(ctx.source, ctx.dest, effect);
61
+ };
62
+ export function registerCanvasTiltShiftEffect(state) {
63
+ registerCanvasRenderEffect(state, 'TiltShiftEffect', defaultCanvasTiltShiftEffectRunner);
64
+ }
65
+ const TAP_REACH = 3;
66
+ const TAP_COUNT = TAP_REACH * 2 + 1;
67
+ //# sourceMappingURL=canvasTiltShiftEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvasTiltShiftEffect.js","sourceRoot":"","sources":["../src/canvasTiltShiftEffect.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"canvasVignetteEffect.d.ts","sourceRoot":"","sources":["../src/canvasVignetteEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAQlC,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAC/B,IAAI,CAoCN;AAED,eAAO,MAAM,iCAAiC,EAAE,wBAE/C,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAE3E"}
1
+ {"version":3,"file":"canvasVignetteEffect.d.ts","sourceRoot":"","sources":["../src/canvasVignetteEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAgBlC,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAClC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAC/B,IAAI,CA+CN;AAED,eAAO,MAAM,iCAAiC,EAAE,wBAE/C,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAE3E"}