@visactor/vrender-animate 1.0.12 → 1.0.13

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 (80) hide show
  1. package/cjs/custom/disappear/base/CustomEffectBase.d.ts +32 -0
  2. package/cjs/custom/disappear/base/CustomEffectBase.js +81 -0
  3. package/cjs/custom/disappear/base/CustomEffectBase.js.map +1 -0
  4. package/cjs/custom/disappear/base/DisappearAnimateBase.d.ts +34 -0
  5. package/cjs/custom/disappear/base/DisappearAnimateBase.js +138 -0
  6. package/cjs/custom/disappear/base/DisappearAnimateBase.js.map +1 -0
  7. package/cjs/custom/disappear/base/ImageProcessUtils.d.ts +20 -0
  8. package/cjs/custom/disappear/base/ImageProcessUtils.js +80 -0
  9. package/cjs/custom/disappear/base/ImageProcessUtils.js.map +1 -0
  10. package/cjs/custom/disappear/dissolve.d.ts +27 -0
  11. package/cjs/custom/disappear/dissolve.js +237 -0
  12. package/cjs/custom/disappear/dissolve.js.map +1 -0
  13. package/cjs/custom/disappear/distortion.d.ts +22 -0
  14. package/cjs/custom/disappear/distortion.js +120 -0
  15. package/cjs/custom/disappear/distortion.js.map +1 -0
  16. package/cjs/custom/disappear/gaussian-blur.d.ts +13 -0
  17. package/cjs/custom/disappear/gaussian-blur.js +65 -0
  18. package/cjs/custom/disappear/gaussian-blur.js.map +1 -0
  19. package/cjs/custom/disappear/glitch.d.ts +20 -0
  20. package/cjs/custom/disappear/glitch.js +161 -0
  21. package/cjs/custom/disappear/glitch.js.map +1 -0
  22. package/cjs/custom/disappear/grayscale.d.ts +23 -0
  23. package/cjs/custom/disappear/grayscale.js +126 -0
  24. package/cjs/custom/disappear/grayscale.js.map +1 -0
  25. package/cjs/custom/disappear/particle.d.ts +49 -0
  26. package/cjs/custom/disappear/particle.js +191 -0
  27. package/cjs/custom/disappear/particle.js.map +1 -0
  28. package/cjs/custom/disappear/pixelation.d.ts +13 -0
  29. package/cjs/custom/disappear/pixelation.js +48 -0
  30. package/cjs/custom/disappear/pixelation.js.map +1 -0
  31. package/cjs/custom/register.d.ts +8 -1
  32. package/cjs/custom/register.js +72 -2
  33. package/cjs/custom/register.js.map +1 -1
  34. package/cjs/custom/richtext/input-richtext.js +1 -1
  35. package/cjs/custom/richtext/output-richtext.js +1 -1
  36. package/cjs/custom/richtext/slide-out-richtext.js +1 -1
  37. package/cjs/step.d.ts +0 -1
  38. package/cjs/step.js +0 -2
  39. package/cjs/step.js.map +1 -1
  40. package/dist/index.es.js +2251 -4
  41. package/es/custom/disappear/base/CustomEffectBase.d.ts +32 -0
  42. package/es/custom/disappear/base/CustomEffectBase.js +69 -0
  43. package/es/custom/disappear/base/CustomEffectBase.js.map +1 -0
  44. package/es/custom/disappear/base/DisappearAnimateBase.d.ts +34 -0
  45. package/es/custom/disappear/base/DisappearAnimateBase.js +132 -0
  46. package/es/custom/disappear/base/DisappearAnimateBase.js.map +1 -0
  47. package/es/custom/disappear/base/ImageProcessUtils.d.ts +20 -0
  48. package/es/custom/disappear/base/ImageProcessUtils.js +72 -0
  49. package/es/custom/disappear/base/ImageProcessUtils.js.map +1 -0
  50. package/es/custom/disappear/dissolve.d.ts +27 -0
  51. package/es/custom/disappear/dissolve.js +231 -0
  52. package/es/custom/disappear/dissolve.js.map +1 -0
  53. package/es/custom/disappear/distortion.d.ts +22 -0
  54. package/es/custom/disappear/distortion.js +112 -0
  55. package/es/custom/disappear/distortion.js.map +1 -0
  56. package/es/custom/disappear/gaussian-blur.d.ts +13 -0
  57. package/es/custom/disappear/gaussian-blur.js +59 -0
  58. package/es/custom/disappear/gaussian-blur.js.map +1 -0
  59. package/es/custom/disappear/glitch.d.ts +20 -0
  60. package/es/custom/disappear/glitch.js +155 -0
  61. package/es/custom/disappear/glitch.js.map +1 -0
  62. package/es/custom/disappear/grayscale.d.ts +23 -0
  63. package/es/custom/disappear/grayscale.js +117 -0
  64. package/es/custom/disappear/grayscale.js.map +1 -0
  65. package/es/custom/disappear/particle.d.ts +49 -0
  66. package/es/custom/disappear/particle.js +185 -0
  67. package/es/custom/disappear/particle.js.map +1 -0
  68. package/es/custom/disappear/pixelation.d.ts +13 -0
  69. package/es/custom/disappear/pixelation.js +42 -0
  70. package/es/custom/disappear/pixelation.js.map +1 -0
  71. package/es/custom/register.d.ts +8 -1
  72. package/es/custom/register.js +20 -2
  73. package/es/custom/register.js.map +1 -1
  74. package/es/custom/richtext/input-richtext.js +1 -1
  75. package/es/custom/richtext/output-richtext.js +1 -1
  76. package/es/custom/richtext/slide-out-richtext.js +1 -1
  77. package/es/step.d.ts +0 -1
  78. package/es/step.js +0 -2
  79. package/es/step.js.map +1 -1
  80. package/package.json +4 -4
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ }), exports.Dissolve = void 0;
6
+
7
+ const CustomEffectBase_1 = require("./base/CustomEffectBase"), ImageProcessUtils_1 = require("./base/ImageProcessUtils");
8
+
9
+ class Dissolve extends CustomEffectBase_1.HybridEffectBase {
10
+ constructor(from, to, duration, easing, params) {
11
+ var _a, _b, _c, _d;
12
+ super(from, to, duration, easing, params), this.noiseData = null;
13
+ const rawNoiseScale = null === (_a = null == params ? void 0 : params.options) || void 0 === _a ? void 0 : _a.noiseScale, clampedNoiseScale = void 0 !== rawNoiseScale ? Math.max(0, Math.floor(rawNoiseScale)) : 8;
14
+ this.dissolveConfig = {
15
+ dissolveType: (null === (_b = null == params ? void 0 : params.options) || void 0 === _b ? void 0 : _b.dissolveType) || "outward",
16
+ useWebGL: void 0 === (null === (_c = null == params ? void 0 : params.options) || void 0 === _c ? void 0 : _c.useWebGL) || params.options.useWebGL,
17
+ noiseScale: clampedNoiseScale,
18
+ fadeEdge: void 0 === (null === (_d = null == params ? void 0 : params.options) || void 0 === _d ? void 0 : _d.fadeEdge) || params.options.fadeEdge
19
+ };
20
+ }
21
+ getShaderSources() {
22
+ return {
23
+ vertex: ImageProcessUtils_1.ShaderLibrary.STANDARD_VERTEX_SHADER,
24
+ fragment: `\n precision mediump float;\n uniform sampler2D u_texture;\n uniform sampler2D u_noiseTexture;\n uniform float u_time;\n uniform int u_dissolveType;\n uniform vec2 u_resolution;\n uniform float u_noiseScale;\n uniform bool u_fadeEdge;\n varying vec2 v_texCoord;\n\n ${ImageProcessUtils_1.ShaderLibrary.SHADER_FUNCTIONS}\n\n // 向外溶解函数\n float outwardDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n vec2 center = vec2(0.5, 0.5);\n float distFromCenter = length(uv - center);\n float maxDist = length(vec2(0.5, 0.5));\n\n // 归一化距离 (0为中心,1为边缘)\n float normalizedDist = distFromCenter / maxDist;\n\n // 向外溶解:从边缘开始溶解,time控制溶解进度\n // 增加安全边距,确保动画结束时完全溶解\n float edgeThreshold = 1.2 - time * 1.5;\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n // 添加基于像素大小的噪声,让边缘呈现颗粒状\n vec2 pixelCoord = uv * resolution; // 转换为像素坐标\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.4; // 增强噪声影响\n edgeThreshold += noiseInfluence;\n return normalizedDist > edgeThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.15; // 渐变宽度\n return 1.0 - smoothstep(edgeThreshold - fadeWidth, edgeThreshold, normalizedDist);\n } else {\n // 硬边缘:返回0或1\n return normalizedDist > edgeThreshold ? 0.0 : 1.0;\n }\n }\n }\n\n // 向内溶解函数\n float inwardDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n vec2 center = vec2(0.5, 0.5);\n float distFromCenter = length(uv - center);\n float maxDist = length(vec2(0.5, 0.5));\n\n float normalizedDist = distFromCenter / maxDist;\n\n // 向内溶解:从中心开始溶解,time控制溶解进度\n // 增加系数,确保动画结束时完全溶解\n float centerThreshold = time * 1.4;\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.4;\n centerThreshold += noiseInfluence;\n return normalizedDist < centerThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.15; // 渐变宽度\n return smoothstep(centerThreshold, centerThreshold + fadeWidth, normalizedDist);\n } else {\n // 硬边缘:返回0或1\n return normalizedDist < centerThreshold ? 0.0 : 1.0;\n }\n }\n }\n\n // 径向溶解函数\n float radialDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n vec2 center = vec2(0.5, 0.5);\n float angle = atan(uv.y - center.y, uv.x - center.x);\n float normalizedAngle = (angle + 3.14159) / (2.0 * 3.14159);\n\n // 径向溶解:按角度顺序溶解,time控制溶解进度\n // 增加系数,确保动画结束时完全溶解\n float angleThreshold = time * 1.2;\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n angleThreshold += noiseInfluence;\n return normalizedAngle < angleThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(angleThreshold, angleThreshold + fadeWidth, normalizedAngle);\n } else {\n // 硬边缘:返回0或1\n return normalizedAngle < angleThreshold ? 0.0 : 1.0;\n }\n }\n }\n\n // 从左到右溶解函数\n float leftToRightDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n // 左到右溶解:从x=0开始向x=1溶解\n float dissolvePosition = time * 1.2; // 增加系数确保完全溶解\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolvePosition += noiseInfluence;\n return uv.x < dissolvePosition ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(dissolvePosition, dissolvePosition + fadeWidth, uv.x);\n } else {\n // 硬边缘:返回0或1\n return uv.x < dissolvePosition ? 0.0 : 1.0;\n }\n }\n }\n\n // 从右到左溶解函数\n float rightToLeftDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n // 右到左溶解:从x=1开始向x=0溶解\n float dissolvePosition = 1.0 - time * 1.2; // 增加系数确保完全溶解\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolvePosition += noiseInfluence;\n return uv.x > dissolvePosition ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(dissolvePosition - fadeWidth, dissolvePosition, uv.x);\n } else {\n // 硬边缘:返回0或1\n return uv.x > dissolvePosition ? 0.0 : 1.0;\n }\n }\n }\n\n // 从上到下溶解函数\n float topToBottomDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n // 上到下溶解:从y=0开始向y=1溶解\n float dissolvePosition = time * 1.2; // 增加系数确保完全溶解\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolvePosition += noiseInfluence;\n return uv.y < dissolvePosition ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(dissolvePosition, dissolvePosition + fadeWidth, uv.y);\n } else {\n // 硬边缘:返回0或1\n return uv.y < dissolvePosition ? 0.0 : 1.0;\n }\n }\n }\n\n // 从下到上溶解函数\n float bottomToTopDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n // 下到上溶解:从y=1开始向y=0溶解\n float dissolvePosition = 1.0 - time * 1.2; // 增加系数确保完全溶解\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolvePosition += noiseInfluence;\n return uv.y > dissolvePosition ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(dissolvePosition - fadeWidth, dissolvePosition, uv.y);\n } else {\n // 硬边缘:返回0或1\n return uv.y > dissolvePosition ? 0.0 : 1.0;\n }\n }\n }\n\n void main() {\n vec2 uv = v_texCoord;\n vec4 texColor = texture2D(u_texture, uv);\n\n float alpha = 1.0;\n\n // 根据溶解类型选择对应的溶解函数\n if (u_dissolveType == 0) {\n alpha = outwardDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 1) {\n alpha = inwardDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 2) {\n alpha = radialDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 3) {\n alpha = leftToRightDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 4) {\n alpha = rightToLeftDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 5) {\n alpha = topToBottomDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 6) {\n alpha = bottomToTopDissolve(uv, u_time, u_noiseScale, u_resolution);\n }\n\n gl_FragColor = vec4(texColor.rgb, texColor.a * alpha);\n }\n `
25
+ };
26
+ }
27
+ applyWebGLEffect(canvas) {
28
+ if (!this.gl || !this.program || !this.webglCanvas) return canvas;
29
+ this.setupWebGLState(canvas);
30
+ const texture = this.createTextureFromCanvas(canvas);
31
+ if (!texture) return canvas;
32
+ this.noiseData || (this.noiseData = ImageProcessUtils_1.ImageProcessUtils.generateNoiseTexture(256, 256));
33
+ const noiseTexture = this.gl.createTexture();
34
+ this.gl.activeTexture(this.gl.TEXTURE1), this.gl.bindTexture(this.gl.TEXTURE_2D, noiseTexture),
35
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.LUMINANCE, 256, 256, 0, this.gl.LUMINANCE, this.gl.UNSIGNED_BYTE, this.noiseData),
36
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.REPEAT),
37
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.REPEAT),
38
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR),
39
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
40
+ const vertexBuffer = this.createFullScreenQuad();
41
+ return vertexBuffer ? (this.gl.useProgram(this.program), this.setupVertexAttributes(),
42
+ this.setUniforms(), this.gl.enable(this.gl.BLEND), this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA),
43
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4), this.gl.deleteTexture(texture),
44
+ this.gl.deleteTexture(noiseTexture), this.gl.deleteBuffer(vertexBuffer), this.webglCanvas) : canvas;
45
+ }
46
+ setUniforms() {
47
+ if (!this.gl || !this.program || !this.webglCanvas) return;
48
+ const textureLocation = this.gl.getUniformLocation(this.program, "u_texture"), noiseTextureLocation = this.gl.getUniformLocation(this.program, "u_noiseTexture"), timeLocation = this.gl.getUniformLocation(this.program, "u_time"), dissolveTypeLocation = this.gl.getUniformLocation(this.program, "u_dissolveType"), resolutionLocation = this.gl.getUniformLocation(this.program, "u_resolution"), noiseScaleLocation = this.gl.getUniformLocation(this.program, "u_noiseScale"), fadeEdgeLocation = this.gl.getUniformLocation(this.program, "u_fadeEdge");
49
+ this.gl.uniform1i(textureLocation, 0), this.gl.uniform1i(noiseTextureLocation, 1),
50
+ this.gl.uniform1f(timeLocation, this.currentAnimationRatio), this.gl.uniform2f(resolutionLocation, this.webglCanvas.width, this.webglCanvas.height),
51
+ this.gl.uniform1f(noiseScaleLocation, this.dissolveConfig.noiseScale), this.gl.uniform1i(fadeEdgeLocation, this.dissolveConfig.fadeEdge ? 1 : 0);
52
+ this.gl.uniform1i(dissolveTypeLocation, {
53
+ outward: 0,
54
+ inward: 1,
55
+ radial: 2,
56
+ leftToRight: 3,
57
+ rightToLeft: 4,
58
+ topToBottom: 5,
59
+ bottomToTop: 6
60
+ }[this.dissolveConfig.dissolveType] || 0);
61
+ }
62
+ applyCanvas2DEffect(canvas) {
63
+ const outputCanvas = this.createOutputCanvas(canvas);
64
+ if (!outputCanvas) return canvas;
65
+ const {canvas: outputCanvasElement, ctx: ctx} = outputCanvas, imageData = ctx.getImageData(0, 0, canvas.width, canvas.height), progress = this.currentAnimationRatio;
66
+ let dissolvedImageData;
67
+ switch (this.dissolveConfig.dissolveType) {
68
+ case "outward":
69
+ dissolvedImageData = this.applyOutwardDissolve(imageData, progress);
70
+ break;
71
+
72
+ case "inward":
73
+ dissolvedImageData = this.applyInwardDissolve(imageData, progress);
74
+ break;
75
+
76
+ case "radial":
77
+ dissolvedImageData = this.applyRadialDissolve(imageData, progress);
78
+ break;
79
+
80
+ case "leftToRight":
81
+ dissolvedImageData = this.applyLeftToRightDissolve(imageData, progress);
82
+ break;
83
+
84
+ case "rightToLeft":
85
+ dissolvedImageData = this.applyRightToLeftDissolve(imageData, progress);
86
+ break;
87
+
88
+ case "topToBottom":
89
+ dissolvedImageData = this.applyTopToBottomDissolve(imageData, progress);
90
+ break;
91
+
92
+ case "bottomToTop":
93
+ dissolvedImageData = this.applyBottomToTopDissolve(imageData, progress);
94
+ break;
95
+
96
+ default:
97
+ dissolvedImageData = imageData;
98
+ }
99
+ return ctx.putImageData(dissolvedImageData, 0, 0), outputCanvasElement;
100
+ }
101
+ applyOutwardDissolve(imageData, progress) {
102
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length);
103
+ result.set(data);
104
+ const centerX = width / 2, centerY = height / 2, maxDist = Math.sqrt(centerX * centerX + centerY * centerY), pixelSize = this.dissolveConfig.noiseScale;
105
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
106
+ const dx = x - centerX, dy = y - centerY, normalizedDist = Math.sqrt(dx * dx + dy * dy) / maxDist;
107
+ let dissolveThreshold = 1.2 - 1.4 * progress, alpha = 1;
108
+ if (pixelSize > 0) {
109
+ dissolveThreshold += .4 * (ImageProcessUtils_1.ImageProcessUtils.pixelNoise(x, y, pixelSize) - .5),
110
+ alpha = normalizedDist > dissolveThreshold ? 0 : 1;
111
+ } else if (this.dissolveConfig.fadeEdge) {
112
+ const fadeStart = dissolveThreshold - .15;
113
+ alpha = normalizedDist < fadeStart ? 1 : normalizedDist > dissolveThreshold ? 0 : 1 - (normalizedDist - fadeStart) / (dissolveThreshold - fadeStart);
114
+ } else alpha = normalizedDist > dissolveThreshold ? 0 : 1;
115
+ const index = 4 * (y * width + x);
116
+ result[index + 3] = Math.floor(result[index + 3] * alpha);
117
+ }
118
+ return new ImageData(result, width, height);
119
+ }
120
+ applyInwardDissolve(imageData, progress) {
121
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length);
122
+ result.set(data);
123
+ const centerX = width / 2, centerY = height / 2, maxDist = Math.sqrt(centerX * centerX + centerY * centerY), pixelSize = this.dissolveConfig.noiseScale;
124
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
125
+ const dx = x - centerX, dy = y - centerY, normalizedDist = Math.sqrt(dx * dx + dy * dy) / maxDist;
126
+ let dissolveThreshold = 1.4 * progress, alpha = 1;
127
+ if (pixelSize > 0) {
128
+ dissolveThreshold += .4 * (ImageProcessUtils_1.ImageProcessUtils.pixelNoise(x, y, pixelSize) - .5),
129
+ alpha = normalizedDist < dissolveThreshold ? 0 : 1;
130
+ } else if (this.dissolveConfig.fadeEdge) {
131
+ const fadeEnd = dissolveThreshold + .15;
132
+ alpha = normalizedDist < dissolveThreshold ? 0 : normalizedDist > fadeEnd ? 1 : (normalizedDist - dissolveThreshold) / (fadeEnd - dissolveThreshold);
133
+ } else alpha = normalizedDist < dissolveThreshold ? 0 : 1;
134
+ const index = 4 * (y * width + x);
135
+ result[index + 3] = Math.floor(result[index + 3] * alpha);
136
+ }
137
+ return new ImageData(result, width, height);
138
+ }
139
+ applyRadialDissolve(imageData, progress) {
140
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length);
141
+ result.set(data);
142
+ const centerX = width / 2, centerY = height / 2, pixelSize = this.dissolveConfig.noiseScale;
143
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
144
+ const dx = x - centerX, dy = y - centerY, normalizedAngle = (Math.atan2(dy, dx) + Math.PI) / (2 * Math.PI);
145
+ let dissolveThreshold = 1.2 * progress, alpha = 1;
146
+ if (pixelSize > 0) {
147
+ dissolveThreshold += .3 * (ImageProcessUtils_1.ImageProcessUtils.pixelNoise(x, y, pixelSize) - .5),
148
+ alpha = normalizedAngle < dissolveThreshold ? 0 : 1;
149
+ } else if (this.dissolveConfig.fadeEdge) {
150
+ const fadeEnd = dissolveThreshold + .08;
151
+ alpha = normalizedAngle < dissolveThreshold ? 0 : normalizedAngle > fadeEnd ? 1 : (normalizedAngle - dissolveThreshold) / (fadeEnd - dissolveThreshold);
152
+ } else alpha = normalizedAngle < dissolveThreshold ? 0 : 1;
153
+ const index = 4 * (y * width + x);
154
+ result[index + 3] = Math.floor(result[index + 3] * alpha);
155
+ }
156
+ return new ImageData(result, width, height);
157
+ }
158
+ applyLeftToRightDissolve(imageData, progress) {
159
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length);
160
+ result.set(data);
161
+ const pixelSize = this.dissolveConfig.noiseScale;
162
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
163
+ const normalizedX = x / width;
164
+ let dissolveThreshold = 1.2 * progress, alpha = 1;
165
+ if (pixelSize > 0) {
166
+ dissolveThreshold += .3 * (ImageProcessUtils_1.ImageProcessUtils.pixelNoise(x, y, pixelSize) - .5),
167
+ alpha = normalizedX < dissolveThreshold ? 0 : 1;
168
+ } else if (this.dissolveConfig.fadeEdge) {
169
+ const fadeEnd = dissolveThreshold + .08;
170
+ alpha = normalizedX < dissolveThreshold ? 0 : normalizedX > fadeEnd ? 1 : (normalizedX - dissolveThreshold) / (fadeEnd - dissolveThreshold);
171
+ } else alpha = normalizedX < dissolveThreshold ? 0 : 1;
172
+ const index = 4 * (y * width + x);
173
+ result[index + 3] = Math.floor(result[index + 3] * alpha);
174
+ }
175
+ return new ImageData(result, width, height);
176
+ }
177
+ applyRightToLeftDissolve(imageData, progress) {
178
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length);
179
+ result.set(data);
180
+ const pixelSize = this.dissolveConfig.noiseScale;
181
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
182
+ const normalizedX = x / width;
183
+ let dissolveThreshold = 1 - 1.2 * progress, alpha = 1;
184
+ if (pixelSize > 0) {
185
+ dissolveThreshold += .3 * (ImageProcessUtils_1.ImageProcessUtils.pixelNoise(x, y, pixelSize) - .5),
186
+ alpha = normalizedX > dissolveThreshold ? 0 : 1;
187
+ } else if (this.dissolveConfig.fadeEdge) {
188
+ const fadeStart = dissolveThreshold - .08;
189
+ alpha = normalizedX < fadeStart ? 1 : normalizedX > dissolveThreshold ? 0 : 1 - (normalizedX - fadeStart) / (dissolveThreshold - fadeStart);
190
+ } else alpha = normalizedX > dissolveThreshold ? 0 : 1;
191
+ const index = 4 * (y * width + x);
192
+ result[index + 3] = Math.floor(result[index + 3] * alpha);
193
+ }
194
+ return new ImageData(result, width, height);
195
+ }
196
+ applyTopToBottomDissolve(imageData, progress) {
197
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length);
198
+ result.set(data);
199
+ const pixelSize = this.dissolveConfig.noiseScale;
200
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
201
+ const normalizedY = y / height;
202
+ let dissolveThreshold = 1.2 * progress, alpha = 1;
203
+ if (pixelSize > 0) {
204
+ dissolveThreshold += .3 * (ImageProcessUtils_1.ImageProcessUtils.pixelNoise(x, y, pixelSize) - .5),
205
+ alpha = normalizedY < dissolveThreshold ? 0 : 1;
206
+ } else if (this.dissolveConfig.fadeEdge) {
207
+ const fadeEnd = dissolveThreshold + .08;
208
+ alpha = normalizedY < dissolveThreshold ? 0 : normalizedY > fadeEnd ? 1 : (normalizedY - dissolveThreshold) / (fadeEnd - dissolveThreshold);
209
+ } else alpha = normalizedY < dissolveThreshold ? 0 : 1;
210
+ const index = 4 * (y * width + x);
211
+ result[index + 3] = Math.floor(result[index + 3] * alpha);
212
+ }
213
+ return new ImageData(result, width, height);
214
+ }
215
+ applyBottomToTopDissolve(imageData, progress) {
216
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length);
217
+ result.set(data);
218
+ const pixelSize = this.dissolveConfig.noiseScale;
219
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
220
+ const normalizedY = y / height;
221
+ let dissolveThreshold = 1 - 1.2 * progress, alpha = 1;
222
+ if (pixelSize > 0) {
223
+ dissolveThreshold += .3 * (ImageProcessUtils_1.ImageProcessUtils.pixelNoise(x, y, pixelSize) - .5),
224
+ alpha = normalizedY > dissolveThreshold ? 0 : 1;
225
+ } else if (this.dissolveConfig.fadeEdge) {
226
+ const fadeStart = dissolveThreshold - .08;
227
+ alpha = normalizedY < fadeStart ? 1 : normalizedY > dissolveThreshold ? 0 : 1 - (normalizedY - fadeStart) / (dissolveThreshold - fadeStart);
228
+ } else alpha = normalizedY > dissolveThreshold ? 0 : 1;
229
+ const index = 4 * (y * width + x);
230
+ result[index + 3] = Math.floor(result[index + 3] * alpha);
231
+ }
232
+ return new ImageData(result, width, height);
233
+ }
234
+ }
235
+
236
+ exports.Dissolve = Dissolve;
237
+ //# sourceMappingURL=dissolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/custom/disappear/dissolve.ts"],"names":[],"mappings":";;;AACA,8DAA2D;AAC3D,gEAA4E;AAc5E,MAAa,QAAS,SAAQ,mCAAgB;IAO5C,YAAY,IAAU,EAAE,EAAQ,EAAE,QAAgB,EAAE,MAAkB,EAAE,MAAW;;QACjF,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAHpC,cAAS,GAAsB,IAAI,CAAC;QAM1C,MAAM,aAAa,GAAG,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,0CAAE,UAAU,CAAC;QAClD,MAAM,iBAAiB,GAAG,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnG,IAAI,CAAC,cAAc,GAAG;YACpB,YAAY,EAAE,CAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,0CAAE,YAAY,KAAI,SAAS;YACxD,QAAQ,EAAE,CAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,0CAAE,QAAQ,MAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YAClF,UAAU,EAAE,iBAAiB;YAC7B,QAAQ,EAAE,CAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,0CAAE,QAAQ,MAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;SACnF,CAAC;IACJ,CAAC;IAKS,gBAAgB;QACxB,MAAM,YAAY,GAAG,iCAAa,CAAC,sBAAsB,CAAC;QAE1D,MAAM,cAAc,GAAG;;;;;;;;;;;QAWnB,iCAAa,CAAC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+NjC,CAAC;QAEF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC5D,CAAC;IAKS,gBAAgB,CAAC,MAAyB;QAClD,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAClD,OAAO,MAAM,CAAC;SACf;QAGD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAG7B,MAAM,OAAO,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,MAAM,CAAC;SACf;QAGD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,SAAS,GAAG,qCAAiB,CAAC,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;SACnE;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;QAC7C,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAChB,IAAI,CAAC,EAAE,CAAC,UAAU,EAClB,CAAC,EACD,IAAI,CAAC,EAAE,CAAC,SAAS,EACjB,GAAG,EACH,GAAG,EACH,CAAC,EACD,IAAI,CAAC,EAAE,CAAC,SAAS,EACjB,IAAI,CAAC,EAAE,CAAC,aAAa,EACrB,IAAI,CAAC,SAAS,CACf,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAClF,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAClF,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QACtF,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAGtF,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACjD,IAAI,CAAC,YAAY,EAAE;YACjB,OAAO,MAAM,CAAC;SACf;QAGD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAG7B,IAAI,CAAC,WAAW,EAAE,CAAC;QAGnB,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC;QAGlE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAGjD,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QACpC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAEnC,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAKO,WAAW;QACjB,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAClD,OAAO;SACR;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC9E,MAAM,oBAAoB,GAAG,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACxF,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACxE,MAAM,oBAAoB,GAAG,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACxF,MAAM,kBAAkB,GAAG,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACpF,MAAM,kBAAkB,GAAG,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACpF,MAAM,gBAAgB,GAAG,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAEhF,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC5D,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACvF,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACtE,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAG1E,MAAM,eAAe,GAA8B;YACjD,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,CAAC;YACT,MAAM,EAAE,CAAC;YACT,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;SACf,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,oBAAoB,EAAE,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IAClG,CAAC;IAKS,mBAAmB,CAAC,MAAyB;QACrD,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,EAAE;YACjB,OAAO,MAAM,CAAC;SACf;QAED,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC;QAE1D,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,qBAAqB,CAAC;QAE5C,IAAI,kBAA6B,CAAC;QAGlC,QAAQ,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE;YACxC,KAAK,SAAS;gBACZ,kBAAkB,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACpE,MAAM;YACR,KAAK,QAAQ;gBACX,kBAAkB,GAAG,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACnE,MAAM;YACR,KAAK,QAAQ;gBACX,kBAAkB,GAAG,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACnE,MAAM;YACR,KAAK,aAAa;gBAChB,kBAAkB,GAAG,IAAI,CAAC,wBAAwB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACxE,MAAM;YACR,KAAK,aAAa;gBAChB,kBAAkB,GAAG,IAAI,CAAC,wBAAwB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACxE,MAAM;YACR,KAAK,aAAa;gBAChB,kBAAkB,GAAG,IAAI,CAAC,wBAAwB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACxE,MAAM;YACR,KAAK,aAAa;gBAChB,kBAAkB,GAAG,IAAI,CAAC,wBAAwB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACxE,MAAM;YACR;gBACE,kBAAkB,GAAG,SAAS,CAAC;SAClC;QAED,GAAG,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3C,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAGO,oBAAoB,CAAC,SAAoB,EAAE,QAAgB;QACjE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC;QAGjE,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;QAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC9B,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;gBACvB,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;gBACvB,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;gBACpD,MAAM,cAAc,GAAG,cAAc,GAAG,OAAO,CAAC;gBAGhD,IAAI,iBAAiB,GAAG,GAAG,GAAG,QAAQ,GAAG,GAAG,CAAC;gBAC7C,IAAI,KAAK,GAAG,GAAG,CAAC;gBAEhB,IAAI,SAAS,GAAG,CAAC,EAAE;oBAEjB,MAAM,UAAU,GAAG,qCAAiB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;oBACjE,MAAM,cAAc,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;oBAChD,iBAAiB,IAAI,cAAc,CAAC;oBAEpC,KAAK,GAAG,cAAc,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;iBACxD;qBAAM;oBAEL,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;wBAEhC,MAAM,SAAS,GAAG,IAAI,CAAC;wBACvB,MAAM,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAC;wBAChD,MAAM,OAAO,GAAG,iBAAiB,CAAC;wBAElC,IAAI,cAAc,GAAG,SAAS,EAAE;4BAC9B,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM,IAAI,cAAc,GAAG,OAAO,EAAE;4BACnC,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM;4BAEL,KAAK,GAAG,GAAG,GAAG,CAAC,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;yBACpE;qBACF;yBAAM;wBAEL,KAAK,GAAG,cAAc,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;qBACxD;iBACF;gBAED,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;aAC3D;SACF;QAED,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAGO,mBAAmB,CAAC,SAAoB,EAAE,QAAgB;QAChE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC;QAEjE,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;QAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC9B,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;gBACvB,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;gBACvB,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;gBACpD,MAAM,cAAc,GAAG,cAAc,GAAG,OAAO,CAAC;gBAGhD,IAAI,iBAAiB,GAAG,QAAQ,GAAG,GAAG,CAAC;gBACvC,IAAI,KAAK,GAAG,GAAG,CAAC;gBAEhB,IAAI,SAAS,GAAG,CAAC,EAAE;oBAEjB,MAAM,UAAU,GAAG,qCAAiB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;oBACjE,MAAM,cAAc,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;oBAChD,iBAAiB,IAAI,cAAc,CAAC;oBAEpC,KAAK,GAAG,cAAc,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;iBACxD;qBAAM;oBAEL,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;wBAEhC,MAAM,SAAS,GAAG,IAAI,CAAC;wBACvB,MAAM,SAAS,GAAG,iBAAiB,CAAC;wBACpC,MAAM,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAAC;wBAE9C,IAAI,cAAc,GAAG,SAAS,EAAE;4BAC9B,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM,IAAI,cAAc,GAAG,OAAO,EAAE;4BACnC,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM;4BAEL,KAAK,GAAG,CAAC,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;yBAC9D;qBACF;yBAAM;wBAEL,KAAK,GAAG,cAAc,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;qBACxD;iBACF;gBAED,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;aAC3D;SACF;QAED,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAGO,mBAAmB,CAAC,SAAoB,EAAE,QAAgB;QAChE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;QAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC9B,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;gBACvB,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;gBACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBACjC,MAAM,eAAe,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;gBAG1D,IAAI,iBAAiB,GAAG,QAAQ,GAAG,GAAG,CAAC;gBACvC,IAAI,KAAK,GAAG,GAAG,CAAC;gBAEhB,IAAI,SAAS,GAAG,CAAC,EAAE;oBAEjB,MAAM,UAAU,GAAG,qCAAiB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;oBACjE,MAAM,cAAc,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;oBAChD,iBAAiB,IAAI,cAAc,CAAC;oBAEpC,KAAK,GAAG,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;iBACzD;qBAAM;oBAEL,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;wBAEhC,MAAM,SAAS,GAAG,IAAI,CAAC;wBACvB,MAAM,SAAS,GAAG,iBAAiB,CAAC;wBACpC,MAAM,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAAC;wBAE9C,IAAI,eAAe,GAAG,SAAS,EAAE;4BAC/B,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM,IAAI,eAAe,GAAG,OAAO,EAAE;4BACpC,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM;4BAEL,KAAK,GAAG,CAAC,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;yBAC/D;qBACF;yBAAM;wBAEL,KAAK,GAAG,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;qBACzD;iBACF;gBAED,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;aAC3D;SACF;QAED,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAGO,wBAAwB,CAAC,SAAoB,EAAE,QAAgB;QACrE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;QAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC9B,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC;gBAG9B,IAAI,iBAAiB,GAAG,QAAQ,GAAG,GAAG,CAAC;gBACvC,IAAI,KAAK,GAAG,GAAG,CAAC;gBAEhB,IAAI,SAAS,GAAG,CAAC,EAAE;oBAEjB,MAAM,UAAU,GAAG,qCAAiB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;oBACjE,MAAM,cAAc,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;oBAChD,iBAAiB,IAAI,cAAc,CAAC;oBAEpC,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;iBACrD;qBAAM;oBAEL,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;wBAEhC,MAAM,SAAS,GAAG,IAAI,CAAC;wBACvB,MAAM,SAAS,GAAG,iBAAiB,CAAC;wBACpC,MAAM,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAAC;wBAE9C,IAAI,WAAW,GAAG,SAAS,EAAE;4BAC3B,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM,IAAI,WAAW,GAAG,OAAO,EAAE;4BAChC,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM;4BAEL,KAAK,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;yBAC3D;qBACF;yBAAM;wBAEL,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;qBACrD;iBACF;gBAED,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;aAC3D;SACF;QAED,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAGO,wBAAwB,CAAC,SAAoB,EAAE,QAAgB;QACrE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;QAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC9B,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC;gBAG9B,IAAI,iBAAiB,GAAG,GAAG,GAAG,QAAQ,GAAG,GAAG,CAAC;gBAC7C,IAAI,KAAK,GAAG,GAAG,CAAC;gBAEhB,IAAI,SAAS,GAAG,CAAC,EAAE;oBAEjB,MAAM,UAAU,GAAG,qCAAiB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;oBACjE,MAAM,cAAc,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;oBAChD,iBAAiB,IAAI,cAAc,CAAC;oBAEpC,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;iBACrD;qBAAM;oBAEL,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;wBAEhC,MAAM,SAAS,GAAG,IAAI,CAAC;wBACvB,MAAM,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAC;wBAChD,MAAM,OAAO,GAAG,iBAAiB,CAAC;wBAElC,IAAI,WAAW,GAAG,SAAS,EAAE;4BAC3B,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM,IAAI,WAAW,GAAG,OAAO,EAAE;4BAChC,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM;4BAEL,KAAK,GAAG,GAAG,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;yBACjE;qBACF;yBAAM;wBAEL,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;qBACrD;iBACF;gBAED,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;aAC3D;SACF;QAED,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAGO,wBAAwB,CAAC,SAAoB,EAAE,QAAgB;QACrE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;QAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC9B,MAAM,WAAW,GAAG,CAAC,GAAG,MAAM,CAAC;gBAG/B,IAAI,iBAAiB,GAAG,QAAQ,GAAG,GAAG,CAAC;gBACvC,IAAI,KAAK,GAAG,GAAG,CAAC;gBAEhB,IAAI,SAAS,GAAG,CAAC,EAAE;oBAEjB,MAAM,UAAU,GAAG,qCAAiB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;oBACjE,MAAM,cAAc,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;oBAChD,iBAAiB,IAAI,cAAc,CAAC;oBAEpC,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;iBACrD;qBAAM;oBAEL,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;wBAEhC,MAAM,SAAS,GAAG,IAAI,CAAC;wBACvB,MAAM,SAAS,GAAG,iBAAiB,CAAC;wBACpC,MAAM,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAAC;wBAE9C,IAAI,WAAW,GAAG,SAAS,EAAE;4BAC3B,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM,IAAI,WAAW,GAAG,OAAO,EAAE;4BAChC,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM;4BAEL,KAAK,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;yBAC3D;qBACF;yBAAM;wBAEL,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;qBACrD;iBACF;gBAED,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;aAC3D;SACF;QAED,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAGO,wBAAwB,CAAC,SAAoB,EAAE,QAAgB;QACrE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;QAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC9B,MAAM,WAAW,GAAG,CAAC,GAAG,MAAM,CAAC;gBAG/B,IAAI,iBAAiB,GAAG,GAAG,GAAG,QAAQ,GAAG,GAAG,CAAC;gBAC7C,IAAI,KAAK,GAAG,GAAG,CAAC;gBAEhB,IAAI,SAAS,GAAG,CAAC,EAAE;oBAEjB,MAAM,UAAU,GAAG,qCAAiB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;oBACjE,MAAM,cAAc,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;oBAChD,iBAAiB,IAAI,cAAc,CAAC;oBAEpC,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;iBACrD;qBAAM;oBAEL,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;wBAEhC,MAAM,SAAS,GAAG,IAAI,CAAC;wBACvB,MAAM,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAC;wBAChD,MAAM,OAAO,GAAG,iBAAiB,CAAC;wBAElC,IAAI,WAAW,GAAG,SAAS,EAAE;4BAC3B,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM,IAAI,WAAW,GAAG,OAAO,EAAE;4BAChC,KAAK,GAAG,GAAG,CAAC;yBACb;6BAAM;4BAEL,KAAK,GAAG,GAAG,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;yBACjE;qBACF;yBAAM;wBAEL,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;qBACrD;iBACF;gBAED,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;aAC3D;SACF;QAED,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;CACF;AAxyBD,4BAwyBC","file":"dissolve.js","sourcesContent":["import type { EasingType } from '@visactor/vrender-core';\nimport { HybridEffectBase } from './base/CustomEffectBase';\nimport { ImageProcessUtils, ShaderLibrary } from './base/ImageProcessUtils';\n\n// 向外溶解效果配置接口\nexport interface DissolveConfig {\n dissolveType?: 'outward' | 'inward' | 'radial' | 'leftToRight' | 'rightToLeft' | 'topToBottom' | 'bottomToTop'; // 溶解效果类型\n useWebGL?: boolean; // 是否使用WebGL实现\n noiseScale?: number; // 溶解颗粒大小(像素值,0为平滑溶解,1-20为颗粒溶解)\n fadeEdge?: boolean; // 是否启用边缘渐变\n}\n\n/**\n * 溶解效果类 - 使用HybridEffectBase重构\n * 支持多种溶解模式:向外、向内、径向、方向性溶解等\n */\nexport class Dissolve extends HybridEffectBase {\n // 溶解配置,参数验证并设置默认值\n private dissolveConfig: Required<DissolveConfig>;\n\n // WebGL噪声纹理缓存\n private noiseData: Uint8Array | null = null;\n\n constructor(from: null, to: null, duration: number, easing: EasingType, params: any) {\n super(from, to, duration, easing, params);\n\n // 初始化溶解配置,使用传入的参数或默认值,并进行参数验证\n const rawNoiseScale = params?.options?.noiseScale;\n const clampedNoiseScale = rawNoiseScale !== undefined ? Math.max(0, Math.floor(rawNoiseScale)) : 8;\n\n this.dissolveConfig = {\n dissolveType: params?.options?.dissolveType || 'outward',\n useWebGL: params?.options?.useWebGL !== undefined ? params.options.useWebGL : true,\n noiseScale: clampedNoiseScale, // 确保是非负整数,默认8px颗粒,0为平滑\n fadeEdge: params?.options?.fadeEdge !== undefined ? params.options.fadeEdge : true\n };\n }\n\n /**\n * WebGL着色器源码\n */\n protected getShaderSources(): { vertex: string; fragment: string } {\n const vertexShader = ShaderLibrary.STANDARD_VERTEX_SHADER;\n\n const fragmentShader = `\n precision mediump float;\n uniform sampler2D u_texture;\n uniform sampler2D u_noiseTexture;\n uniform float u_time;\n uniform int u_dissolveType;\n uniform vec2 u_resolution;\n uniform float u_noiseScale;\n uniform bool u_fadeEdge;\n varying vec2 v_texCoord;\n\n ${ShaderLibrary.SHADER_FUNCTIONS}\n\n // 向外溶解函数\n float outwardDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n vec2 center = vec2(0.5, 0.5);\n float distFromCenter = length(uv - center);\n float maxDist = length(vec2(0.5, 0.5));\n\n // 归一化距离 (0为中心,1为边缘)\n float normalizedDist = distFromCenter / maxDist;\n\n // 向外溶解:从边缘开始溶解,time控制溶解进度\n // 增加安全边距,确保动画结束时完全溶解\n float edgeThreshold = 1.2 - time * 1.5;\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n // 添加基于像素大小的噪声,让边缘呈现颗粒状\n vec2 pixelCoord = uv * resolution; // 转换为像素坐标\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.4; // 增强噪声影响\n edgeThreshold += noiseInfluence;\n return normalizedDist > edgeThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.15; // 渐变宽度\n return 1.0 - smoothstep(edgeThreshold - fadeWidth, edgeThreshold, normalizedDist);\n } else {\n // 硬边缘:返回0或1\n return normalizedDist > edgeThreshold ? 0.0 : 1.0;\n }\n }\n }\n\n // 向内溶解函数\n float inwardDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n vec2 center = vec2(0.5, 0.5);\n float distFromCenter = length(uv - center);\n float maxDist = length(vec2(0.5, 0.5));\n\n float normalizedDist = distFromCenter / maxDist;\n\n // 向内溶解:从中心开始溶解,time控制溶解进度\n // 增加系数,确保动画结束时完全溶解\n float centerThreshold = time * 1.4;\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.4;\n centerThreshold += noiseInfluence;\n return normalizedDist < centerThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.15; // 渐变宽度\n return smoothstep(centerThreshold, centerThreshold + fadeWidth, normalizedDist);\n } else {\n // 硬边缘:返回0或1\n return normalizedDist < centerThreshold ? 0.0 : 1.0;\n }\n }\n }\n\n // 径向溶解函数\n float radialDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n vec2 center = vec2(0.5, 0.5);\n float angle = atan(uv.y - center.y, uv.x - center.x);\n float normalizedAngle = (angle + 3.14159) / (2.0 * 3.14159);\n\n // 径向溶解:按角度顺序溶解,time控制溶解进度\n // 增加系数,确保动画结束时完全溶解\n float angleThreshold = time * 1.2;\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n angleThreshold += noiseInfluence;\n return normalizedAngle < angleThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(angleThreshold, angleThreshold + fadeWidth, normalizedAngle);\n } else {\n // 硬边缘:返回0或1\n return normalizedAngle < angleThreshold ? 0.0 : 1.0;\n }\n }\n }\n\n // 从左到右溶解函数\n float leftToRightDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n // 左到右溶解:从x=0开始向x=1溶解\n float dissolvePosition = time * 1.2; // 增加系数确保完全溶解\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolvePosition += noiseInfluence;\n return uv.x < dissolvePosition ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(dissolvePosition, dissolvePosition + fadeWidth, uv.x);\n } else {\n // 硬边缘:返回0或1\n return uv.x < dissolvePosition ? 0.0 : 1.0;\n }\n }\n }\n\n // 从右到左溶解函数\n float rightToLeftDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n // 右到左溶解:从x=1开始向x=0溶解\n float dissolvePosition = 1.0 - time * 1.2; // 增加系数确保完全溶解\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolvePosition += noiseInfluence;\n return uv.x > dissolvePosition ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(dissolvePosition - fadeWidth, dissolvePosition, uv.x);\n } else {\n // 硬边缘:返回0或1\n return uv.x > dissolvePosition ? 0.0 : 1.0;\n }\n }\n }\n\n // 从上到下溶解函数\n float topToBottomDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n // 上到下溶解:从y=0开始向y=1溶解\n float dissolvePosition = time * 1.2; // 增加系数确保完全溶解\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolvePosition += noiseInfluence;\n return uv.y < dissolvePosition ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(dissolvePosition, dissolvePosition + fadeWidth, uv.y);\n } else {\n // 硬边缘:返回0或1\n return uv.y < dissolvePosition ? 0.0 : 1.0;\n }\n }\n }\n\n // 从下到上溶解函数\n float bottomToTopDissolve(vec2 uv, float time, float pixelSize, vec2 resolution) {\n // 下到上溶解:从y=1开始向y=0溶解\n float dissolvePosition = 1.0 - time * 1.2; // 增加系数确保完全溶解\n\n // 当pixelSize > 0时添加颗粒效果\n if (pixelSize > 0.0) {\n vec2 pixelCoord = uv * resolution;\n float noiseValue = pixelNoise(pixelCoord, pixelSize);\n float noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolvePosition += noiseInfluence;\n return uv.y > dissolvePosition ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (u_fadeEdge) {\n // 柔和边缘:返回渐变值\n float fadeWidth = 0.08; // 渐变宽度\n return smoothstep(dissolvePosition - fadeWidth, dissolvePosition, uv.y);\n } else {\n // 硬边缘:返回0或1\n return uv.y > dissolvePosition ? 0.0 : 1.0;\n }\n }\n }\n\n void main() {\n vec2 uv = v_texCoord;\n vec4 texColor = texture2D(u_texture, uv);\n\n float alpha = 1.0;\n\n // 根据溶解类型选择对应的溶解函数\n if (u_dissolveType == 0) {\n alpha = outwardDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 1) {\n alpha = inwardDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 2) {\n alpha = radialDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 3) {\n alpha = leftToRightDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 4) {\n alpha = rightToLeftDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 5) {\n alpha = topToBottomDissolve(uv, u_time, u_noiseScale, u_resolution);\n } else if (u_dissolveType == 6) {\n alpha = bottomToTopDissolve(uv, u_time, u_noiseScale, u_resolution);\n }\n\n gl_FragColor = vec4(texColor.rgb, texColor.a * alpha);\n }\n `;\n\n return { vertex: vertexShader, fragment: fragmentShader };\n }\n\n /**\n * WebGL溶解效果实现\n */\n protected applyWebGLEffect(canvas: HTMLCanvasElement): HTMLCanvasElement {\n if (!this.gl || !this.program || !this.webglCanvas) {\n return canvas;\n }\n\n // 设置WebGL状态\n this.setupWebGLState(canvas);\n\n // 创建主纹理\n const texture = this.createTextureFromCanvas(canvas);\n if (!texture) {\n return canvas;\n }\n\n // 创建噪声纹理\n if (!this.noiseData) {\n this.noiseData = ImageProcessUtils.generateNoiseTexture(256, 256);\n }\n const noiseTexture = this.gl.createTexture();\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, noiseTexture);\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.LUMINANCE,\n 256,\n 256,\n 0,\n this.gl.LUMINANCE,\n this.gl.UNSIGNED_BYTE,\n this.noiseData\n );\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.REPEAT);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.REPEAT);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n\n // 创建顶点缓冲区\n const vertexBuffer = this.createFullScreenQuad();\n if (!vertexBuffer) {\n return canvas;\n }\n\n // 使用着色器程序并设置属性\n this.gl.useProgram(this.program);\n this.setupVertexAttributes();\n\n // 设置uniform变量\n this.setUniforms();\n\n // 启用混合以支持透明度\n this.gl.enable(this.gl.BLEND);\n this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);\n\n // 绘制\n this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);\n\n // 清理资源\n this.gl.deleteTexture(texture);\n this.gl.deleteTexture(noiseTexture);\n this.gl.deleteBuffer(vertexBuffer);\n\n return this.webglCanvas;\n }\n\n /**\n * 设置WebGL uniform变量\n */\n private setUniforms(): void {\n if (!this.gl || !this.program || !this.webglCanvas) {\n return;\n }\n\n const textureLocation = this.gl.getUniformLocation(this.program, 'u_texture');\n const noiseTextureLocation = this.gl.getUniformLocation(this.program, 'u_noiseTexture');\n const timeLocation = this.gl.getUniformLocation(this.program, 'u_time');\n const dissolveTypeLocation = this.gl.getUniformLocation(this.program, 'u_dissolveType');\n const resolutionLocation = this.gl.getUniformLocation(this.program, 'u_resolution');\n const noiseScaleLocation = this.gl.getUniformLocation(this.program, 'u_noiseScale');\n const fadeEdgeLocation = this.gl.getUniformLocation(this.program, 'u_fadeEdge');\n\n this.gl.uniform1i(textureLocation, 0);\n this.gl.uniform1i(noiseTextureLocation, 1);\n this.gl.uniform1f(timeLocation, this.currentAnimationRatio);\n this.gl.uniform2f(resolutionLocation, this.webglCanvas.width, this.webglCanvas.height);\n this.gl.uniform1f(noiseScaleLocation, this.dissolveConfig.noiseScale);\n this.gl.uniform1i(fadeEdgeLocation, this.dissolveConfig.fadeEdge ? 1 : 0);\n\n // 设置溶解类型映射\n const dissolveTypeMap: { [key: string]: number } = {\n outward: 0,\n inward: 1,\n radial: 2,\n leftToRight: 3,\n rightToLeft: 4,\n topToBottom: 5,\n bottomToTop: 6\n };\n this.gl.uniform1i(dissolveTypeLocation, dissolveTypeMap[this.dissolveConfig.dissolveType] || 0);\n }\n\n /**\n * Canvas 2D溶解效果实现\n */\n protected applyCanvas2DEffect(canvas: HTMLCanvasElement): HTMLCanvasElement {\n const outputCanvas = this.createOutputCanvas(canvas);\n if (!outputCanvas) {\n return canvas;\n }\n\n const { canvas: outputCanvasElement, ctx } = outputCanvas;\n\n const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n const progress = this.currentAnimationRatio;\n\n let dissolvedImageData: ImageData;\n\n // 根据溶解类型应用不同的溶解算法\n switch (this.dissolveConfig.dissolveType) {\n case 'outward':\n dissolvedImageData = this.applyOutwardDissolve(imageData, progress);\n break;\n case 'inward':\n dissolvedImageData = this.applyInwardDissolve(imageData, progress);\n break;\n case 'radial':\n dissolvedImageData = this.applyRadialDissolve(imageData, progress);\n break;\n case 'leftToRight':\n dissolvedImageData = this.applyLeftToRightDissolve(imageData, progress);\n break;\n case 'rightToLeft':\n dissolvedImageData = this.applyRightToLeftDissolve(imageData, progress);\n break;\n case 'topToBottom':\n dissolvedImageData = this.applyTopToBottomDissolve(imageData, progress);\n break;\n case 'bottomToTop':\n dissolvedImageData = this.applyBottomToTopDissolve(imageData, progress);\n break;\n default:\n dissolvedImageData = imageData;\n }\n\n ctx.putImageData(dissolvedImageData, 0, 0);\n return outputCanvasElement;\n }\n\n // Canvas 2D 实现 - 向外溶解\n private applyOutwardDissolve(imageData: ImageData, progress: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n result.set(data);\n\n const centerX = width / 2;\n const centerY = height / 2;\n const maxDist = Math.sqrt(centerX * centerX + centerY * centerY);\n\n // 直接使用noiseScale作为像素颗粒大小\n const pixelSize = this.dissolveConfig.noiseScale;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const dx = x - centerX;\n const dy = y - centerY;\n const distFromCenter = Math.sqrt(dx * dx + dy * dy);\n const normalizedDist = distFromCenter / maxDist;\n\n // 向外溶解:从边缘开始,增加安全边距确保完全溶解\n let dissolveThreshold = 1.2 - progress * 1.4;\n let alpha = 1.0;\n\n if (pixelSize > 0) {\n // 颗粒效果:使用基于像素网格的噪声,产生颗粒状效果\n const noiseValue = ImageProcessUtils.pixelNoise(x, y, pixelSize);\n const noiseInfluence = (noiseValue - 0.5) * 0.4; // 增强噪声影响\n dissolveThreshold += noiseInfluence;\n\n alpha = normalizedDist > dissolveThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (this.dissolveConfig.fadeEdge) {\n // 柔和边缘:使用渐变值\n const fadeWidth = 0.15; // 渐变宽度\n const fadeStart = dissolveThreshold - fadeWidth;\n const fadeEnd = dissolveThreshold;\n\n if (normalizedDist < fadeStart) {\n alpha = 1.0;\n } else if (normalizedDist > fadeEnd) {\n alpha = 0.0;\n } else {\n // 线性插值产生渐变\n alpha = 1.0 - (normalizedDist - fadeStart) / (fadeEnd - fadeStart);\n }\n } else {\n // 硬边缘:使用0或1\n alpha = normalizedDist > dissolveThreshold ? 0.0 : 1.0;\n }\n }\n\n const index = (y * width + x) * 4;\n result[index + 3] = Math.floor(result[index + 3] * alpha);\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n // Canvas 2D 实现 - 向内溶解\n private applyInwardDissolve(imageData: ImageData, progress: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n result.set(data);\n\n const centerX = width / 2;\n const centerY = height / 2;\n const maxDist = Math.sqrt(centerX * centerX + centerY * centerY);\n\n const pixelSize = this.dissolveConfig.noiseScale;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const dx = x - centerX;\n const dy = y - centerY;\n const distFromCenter = Math.sqrt(dx * dx + dy * dy);\n const normalizedDist = distFromCenter / maxDist;\n\n // 向内溶解:从中心开始,增加系数确保完全溶解\n let dissolveThreshold = progress * 1.4;\n let alpha = 1.0;\n\n if (pixelSize > 0) {\n // 颗粒效果\n const noiseValue = ImageProcessUtils.pixelNoise(x, y, pixelSize);\n const noiseInfluence = (noiseValue - 0.5) * 0.4;\n dissolveThreshold += noiseInfluence;\n\n alpha = normalizedDist < dissolveThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (this.dissolveConfig.fadeEdge) {\n // 柔和边缘:使用渐变值\n const fadeWidth = 0.15; // 渐变宽度\n const fadeStart = dissolveThreshold;\n const fadeEnd = dissolveThreshold + fadeWidth;\n\n if (normalizedDist < fadeStart) {\n alpha = 0.0;\n } else if (normalizedDist > fadeEnd) {\n alpha = 1.0;\n } else {\n // 线性插值产生渐变\n alpha = (normalizedDist - fadeStart) / (fadeEnd - fadeStart);\n }\n } else {\n // 硬边缘:使用0或1\n alpha = normalizedDist < dissolveThreshold ? 0.0 : 1.0;\n }\n }\n\n const index = (y * width + x) * 4;\n result[index + 3] = Math.floor(result[index + 3] * alpha);\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n // Canvas 2D 实现 - 径向溶解\n private applyRadialDissolve(imageData: ImageData, progress: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n result.set(data);\n\n const centerX = width / 2;\n const centerY = height / 2;\n const pixelSize = this.dissolveConfig.noiseScale;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const dx = x - centerX;\n const dy = y - centerY;\n const angle = Math.atan2(dy, dx);\n const normalizedAngle = (angle + Math.PI) / (2 * Math.PI);\n\n // 径向溶解:按角度顺序,增加系数确保完全溶解\n let dissolveThreshold = progress * 1.2;\n let alpha = 1.0;\n\n if (pixelSize > 0) {\n // 颗粒效果\n const noiseValue = ImageProcessUtils.pixelNoise(x, y, pixelSize);\n const noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolveThreshold += noiseInfluence;\n\n alpha = normalizedAngle < dissolveThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (this.dissolveConfig.fadeEdge) {\n // 柔和边缘:使用渐变值\n const fadeWidth = 0.08; // 渐变宽度\n const fadeStart = dissolveThreshold;\n const fadeEnd = dissolveThreshold + fadeWidth;\n\n if (normalizedAngle < fadeStart) {\n alpha = 0.0;\n } else if (normalizedAngle > fadeEnd) {\n alpha = 1.0;\n } else {\n // 线性插值产生渐变\n alpha = (normalizedAngle - fadeStart) / (fadeEnd - fadeStart);\n }\n } else {\n // 硬边缘:使用0或1\n alpha = normalizedAngle < dissolveThreshold ? 0.0 : 1.0;\n }\n }\n\n const index = (y * width + x) * 4;\n result[index + 3] = Math.floor(result[index + 3] * alpha);\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n // Canvas 2D 实现 - 从左到右溶解\n private applyLeftToRightDissolve(imageData: ImageData, progress: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n result.set(data);\n\n const pixelSize = this.dissolveConfig.noiseScale;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const normalizedX = x / width;\n\n // 从左到右溶解:增加系数确保完全溶解\n let dissolveThreshold = progress * 1.2;\n let alpha = 1.0;\n\n if (pixelSize > 0) {\n // 颗粒效果\n const noiseValue = ImageProcessUtils.pixelNoise(x, y, pixelSize);\n const noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolveThreshold += noiseInfluence;\n\n alpha = normalizedX < dissolveThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (this.dissolveConfig.fadeEdge) {\n // 柔和边缘:使用渐变值\n const fadeWidth = 0.08; // 渐变宽度\n const fadeStart = dissolveThreshold;\n const fadeEnd = dissolveThreshold + fadeWidth;\n\n if (normalizedX < fadeStart) {\n alpha = 0.0;\n } else if (normalizedX > fadeEnd) {\n alpha = 1.0;\n } else {\n // 线性插值产生渐变\n alpha = (normalizedX - fadeStart) / (fadeEnd - fadeStart);\n }\n } else {\n // 硬边缘:使用0或1\n alpha = normalizedX < dissolveThreshold ? 0.0 : 1.0;\n }\n }\n\n const index = (y * width + x) * 4;\n result[index + 3] = Math.floor(result[index + 3] * alpha);\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n // Canvas 2D 实现 - 从右到左溶解\n private applyRightToLeftDissolve(imageData: ImageData, progress: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n result.set(data);\n\n const pixelSize = this.dissolveConfig.noiseScale;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const normalizedX = x / width;\n\n // 从右到左溶解:增加系数确保完全溶解\n let dissolveThreshold = 1.0 - progress * 1.2;\n let alpha = 1.0;\n\n if (pixelSize > 0) {\n // 颗粒效果\n const noiseValue = ImageProcessUtils.pixelNoise(x, y, pixelSize);\n const noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolveThreshold += noiseInfluence;\n\n alpha = normalizedX > dissolveThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (this.dissolveConfig.fadeEdge) {\n // 柔和边缘:使用渐变值\n const fadeWidth = 0.08; // 渐变宽度\n const fadeStart = dissolveThreshold - fadeWidth;\n const fadeEnd = dissolveThreshold;\n\n if (normalizedX < fadeStart) {\n alpha = 1.0;\n } else if (normalizedX > fadeEnd) {\n alpha = 0.0;\n } else {\n // 线性插值产生渐变\n alpha = 1.0 - (normalizedX - fadeStart) / (fadeEnd - fadeStart);\n }\n } else {\n // 硬边缘:使用0或1\n alpha = normalizedX > dissolveThreshold ? 0.0 : 1.0;\n }\n }\n\n const index = (y * width + x) * 4;\n result[index + 3] = Math.floor(result[index + 3] * alpha);\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n // Canvas 2D 实现 - 从上到下溶解\n private applyTopToBottomDissolve(imageData: ImageData, progress: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n result.set(data);\n\n const pixelSize = this.dissolveConfig.noiseScale;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const normalizedY = y / height;\n\n // 从上到下溶解:增加系数确保完全溶解\n let dissolveThreshold = progress * 1.2;\n let alpha = 1.0;\n\n if (pixelSize > 0) {\n // 颗粒效果\n const noiseValue = ImageProcessUtils.pixelNoise(x, y, pixelSize);\n const noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolveThreshold += noiseInfluence;\n\n alpha = normalizedY < dissolveThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (this.dissolveConfig.fadeEdge) {\n // 柔和边缘:使用渐变值\n const fadeWidth = 0.08; // 渐变宽度\n const fadeStart = dissolveThreshold;\n const fadeEnd = dissolveThreshold + fadeWidth;\n\n if (normalizedY < fadeStart) {\n alpha = 0.0;\n } else if (normalizedY > fadeEnd) {\n alpha = 1.0;\n } else {\n // 线性插值产生渐变\n alpha = (normalizedY - fadeStart) / (fadeEnd - fadeStart);\n }\n } else {\n // 硬边缘:使用0或1\n alpha = normalizedY < dissolveThreshold ? 0.0 : 1.0;\n }\n }\n\n const index = (y * width + x) * 4;\n result[index + 3] = Math.floor(result[index + 3] * alpha);\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n // Canvas 2D 实现 - 从下到上溶解\n private applyBottomToTopDissolve(imageData: ImageData, progress: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n result.set(data);\n\n const pixelSize = this.dissolveConfig.noiseScale;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const normalizedY = y / height;\n\n // 从下到上溶解:增加系数确保完全溶解\n let dissolveThreshold = 1.0 - progress * 1.2;\n let alpha = 1.0;\n\n if (pixelSize > 0) {\n // 颗粒效果\n const noiseValue = ImageProcessUtils.pixelNoise(x, y, pixelSize);\n const noiseInfluence = (noiseValue - 0.5) * 0.3;\n dissolveThreshold += noiseInfluence;\n\n alpha = normalizedY > dissolveThreshold ? 0.0 : 1.0;\n } else {\n // 平滑溶解:根据fadeEdge决定是否使用渐变\n if (this.dissolveConfig.fadeEdge) {\n // 柔和边缘:使用渐变值\n const fadeWidth = 0.08; // 渐变宽度\n const fadeStart = dissolveThreshold - fadeWidth;\n const fadeEnd = dissolveThreshold;\n\n if (normalizedY < fadeStart) {\n alpha = 1.0;\n } else if (normalizedY > fadeEnd) {\n alpha = 0.0;\n } else {\n // 线性插值产生渐变\n alpha = 1.0 - (normalizedY - fadeStart) / (fadeEnd - fadeStart);\n }\n } else {\n // 硬边缘:使用0或1\n alpha = normalizedY > dissolveThreshold ? 0.0 : 1.0;\n }\n }\n\n const index = (y * width + x) * 4;\n result[index + 3] = Math.floor(result[index + 3] * alpha);\n }\n }\n\n return new ImageData(result, width, height);\n }\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import type { EasingType } from '@visactor/vrender-core';
2
+ import { HybridEffectBase } from './base/CustomEffectBase';
3
+ export interface DistortionConfig {
4
+ distortionType?: 'wave' | 'ripple' | 'swirl';
5
+ strength?: number;
6
+ useWebGL?: boolean;
7
+ }
8
+ export declare class Distortion extends HybridEffectBase {
9
+ private distortionConfig;
10
+ constructor(from: null, to: null, duration: number, easing: EasingType, params: any);
11
+ protected getShaderSources(): {
12
+ vertex: string;
13
+ fragment: string;
14
+ } | null;
15
+ protected applyWebGLEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null;
16
+ private setDistortionUniforms;
17
+ protected applyCanvas2DEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null;
18
+ private applyWaveDistortion;
19
+ private applyRippleDistortion;
20
+ private applySwirlDistortion;
21
+ protected afterStageRender(stage: any, canvas: HTMLCanvasElement): HTMLCanvasElement | void | null | false;
22
+ }
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ }), exports.Distortion = void 0;
6
+
7
+ const CustomEffectBase_1 = require("./base/CustomEffectBase");
8
+
9
+ class Distortion extends CustomEffectBase_1.HybridEffectBase {
10
+ constructor(from, to, duration, easing, params) {
11
+ var _a, _b, _c;
12
+ super(from, to, duration, easing, params), this.distortionConfig = {
13
+ distortionType: (null === (_a = null == params ? void 0 : params.options) || void 0 === _a ? void 0 : _a.distortionType) || "wave",
14
+ strength: (null === (_b = null == params ? void 0 : params.options) || void 0 === _b ? void 0 : _b.strength) || .3,
15
+ useWebGL: void 0 === (null === (_c = null == params ? void 0 : params.options) || void 0 === _c ? void 0 : _c.useWebGL) || params.options.useWebGL
16
+ };
17
+ }
18
+ getShaderSources() {
19
+ return {
20
+ vertex: "\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n varying vec2 v_texCoord;\n\n void main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n ",
21
+ fragment: "\n precision mediump float;\n uniform sampler2D u_texture;\n uniform float u_time;\n uniform float u_strength;\n uniform int u_distortionType;\n uniform vec2 u_resolution;\n varying vec2 v_texCoord;\n\n // 波浪扭曲函数\n vec2 wave(vec2 uv, float time, float strength) {\n float waveX = sin(uv.y * 10.0 + time * 3.0) * strength * 0.1;\n float waveY = sin(uv.x * 10.0 + time * 2.0) * strength * 0.1;\n return uv + vec2(waveX, waveY);\n }\n\n // 涟漪扭曲函数\n vec2 ripple(vec2 uv, float time, float strength) {\n vec2 center = vec2(0.5, 0.5);\n float distance = length(uv - center);\n float ripple = sin(distance * 20.0 - time * 5.0) * strength * 0.1;\n vec2 direction = normalize(uv - center);\n return uv + direction * ripple;\n }\n\n // 漩涡扭曲函数\n vec2 swirl(vec2 uv, float time, float strength) {\n vec2 center = vec2(0.5, 0.5);\n vec2 delta = uv - center;\n float dist = length(delta);\n float originalAngle = atan(delta.y, delta.x);\n float rotationAngle = dist * strength * time * 2.0;\n float finalAngle = originalAngle + rotationAngle;\n return center + dist * vec2(cos(finalAngle), sin(finalAngle));\n }\n\n void main() {\n vec2 uv = v_texCoord;\n\n // 根据扭曲类型应用相应变换\n if (u_distortionType == 0) {\n uv = wave(uv, u_time, u_strength);\n } else if (u_distortionType == 1) {\n uv = ripple(uv, u_time, u_strength);\n } else if (u_distortionType == 2) {\n uv = swirl(uv, u_time, u_strength);\n }\n\n // 边界检查\n if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n } else {\n gl_FragColor = texture2D(u_texture, uv);\n }\n }\n "
22
+ };
23
+ }
24
+ applyWebGLEffect(canvas) {
25
+ if (!this.gl || !this.program || !this.webglCanvas) return null;
26
+ this.setupWebGLState(canvas);
27
+ const texture = this.createTextureFromCanvas(canvas);
28
+ if (!texture) return null;
29
+ const vertexBuffer = this.createFullScreenQuad();
30
+ if (!vertexBuffer) return this.gl.deleteTexture(texture), null;
31
+ try {
32
+ return this.gl.useProgram(this.program), this.setupVertexAttributes(), this.setDistortionUniforms(),
33
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4), this.webglCanvas;
34
+ } finally {
35
+ this.gl.deleteTexture(texture), this.gl.deleteBuffer(vertexBuffer);
36
+ }
37
+ }
38
+ setDistortionUniforms() {
39
+ if (!this.gl || !this.program) return;
40
+ const currentTime = this.getAnimationTime(), timeLocation = this.gl.getUniformLocation(this.program, "u_time"), strengthLocation = this.gl.getUniformLocation(this.program, "u_strength"), distortionTypeLocation = this.gl.getUniformLocation(this.program, "u_distortionType"), resolutionLocation = this.gl.getUniformLocation(this.program, "u_resolution");
41
+ this.gl.uniform1f(timeLocation, currentTime), this.gl.uniform1f(strengthLocation, this.distortionConfig.strength),
42
+ this.gl.uniform2f(resolutionLocation, this.webglCanvas.width, this.webglCanvas.height);
43
+ this.gl.uniform1i(distortionTypeLocation, {
44
+ wave: 0,
45
+ ripple: 1,
46
+ swirl: 2
47
+ }[this.distortionConfig.distortionType] || 0);
48
+ }
49
+ applyCanvas2DEffect(canvas) {
50
+ const outputCanvas = this.createOutputCanvas(canvas);
51
+ if (!outputCanvas) return null;
52
+ const {ctx: ctx} = outputCanvas;
53
+ try {
54
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height), currentTime = this.getAnimationTime();
55
+ let distortedImageData;
56
+ switch (this.distortionConfig.distortionType) {
57
+ case "wave":
58
+ distortedImageData = this.applyWaveDistortion(imageData, this.distortionConfig.strength, currentTime);
59
+ break;
60
+
61
+ case "ripple":
62
+ distortedImageData = this.applyRippleDistortion(imageData, this.distortionConfig.strength, currentTime);
63
+ break;
64
+
65
+ case "swirl":
66
+ distortedImageData = this.applySwirlDistortion(imageData, this.distortionConfig.strength, currentTime);
67
+ break;
68
+
69
+ default:
70
+ distortedImageData = imageData;
71
+ }
72
+ return ctx.clearRect(0, 0, canvas.width, canvas.height), ctx.putImageData(distortedImageData, 0, 0),
73
+ outputCanvas.canvas;
74
+ } catch (error) {
75
+ return console.warn("Canvas 2D distortion effect failed:", error), null;
76
+ }
77
+ }
78
+ applyWaveDistortion(imageData, strength, time) {
79
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length);
80
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
81
+ const waveX = Math.sin(.1 * y + 3 * time) * strength * 20, waveY = Math.sin(.1 * x + 2 * time) * strength * 20, sourceX = Math.round(x - waveX), sourceY = Math.round(y - waveY), targetIndex = 4 * (y * width + x);
82
+ if (sourceX >= 0 && sourceX < width && sourceY >= 0 && sourceY < height) {
83
+ const sourceIndex = 4 * (sourceY * width + sourceX);
84
+ result[targetIndex] = data[sourceIndex], result[targetIndex + 1] = data[sourceIndex + 1],
85
+ result[targetIndex + 2] = data[sourceIndex + 2], result[targetIndex + 3] = data[sourceIndex + 3];
86
+ } else result[targetIndex + 3] = 0;
87
+ }
88
+ return new ImageData(result, width, height);
89
+ }
90
+ applyRippleDistortion(imageData, strength, time) {
91
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length), centerX = width / 2, centerY = height / 2;
92
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
93
+ const dx = x - centerX, dy = y - centerY, distance = Math.sqrt(dx * dx + dy * dy), ripple = Math.sin(.2 * distance - 5 * time) * strength * 10, angle = Math.atan2(dy, dx), sourceX = Math.round(x - Math.cos(angle) * ripple), sourceY = Math.round(y - Math.sin(angle) * ripple), targetIndex = 4 * (y * width + x);
94
+ if (sourceX >= 0 && sourceX < width && sourceY >= 0 && sourceY < height) {
95
+ const sourceIndex = 4 * (sourceY * width + sourceX);
96
+ result[targetIndex] = data[sourceIndex], result[targetIndex + 1] = data[sourceIndex + 1],
97
+ result[targetIndex + 2] = data[sourceIndex + 2], result[targetIndex + 3] = data[sourceIndex + 3];
98
+ } else result[targetIndex + 3] = 0;
99
+ }
100
+ return new ImageData(result, width, height);
101
+ }
102
+ applySwirlDistortion(imageData, strength, time) {
103
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length), centerX = width / 2, centerY = height / 2;
104
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
105
+ const dx = x - centerX, dy = y - centerY, distance = Math.sqrt(dx * dx + dy * dy), finalAngle = Math.atan2(dy, dx) + distance * strength * time * .02, sourceX = Math.round(centerX + distance * Math.cos(finalAngle)), sourceY = Math.round(centerY + distance * Math.sin(finalAngle)), targetIndex = 4 * (y * width + x);
106
+ if (sourceX >= 0 && sourceX < width && sourceY >= 0 && sourceY < height) {
107
+ const sourceIndex = 4 * (sourceY * width + sourceX);
108
+ result[targetIndex] = data[sourceIndex], result[targetIndex + 1] = data[sourceIndex + 1],
109
+ result[targetIndex + 2] = data[sourceIndex + 2], result[targetIndex + 3] = data[sourceIndex + 3];
110
+ } else result[targetIndex + 3] = 0;
111
+ }
112
+ return new ImageData(result, width, height);
113
+ }
114
+ afterStageRender(stage, canvas) {
115
+ return this.distortionConfig.strength <= 0 ? canvas : super.afterStageRender(stage, canvas);
116
+ }
117
+ }
118
+
119
+ exports.Distortion = Distortion;
120
+ //# sourceMappingURL=distortion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/custom/disappear/distortion.ts"],"names":[],"mappings":"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","file":"distortion.js","sourcesContent":["import type { EasingType } from '@visactor/vrender-core';\nimport { HybridEffectBase } from './base/CustomEffectBase';\n\n// 扭曲效果配置接口\nexport interface DistortionConfig {\n distortionType?: 'wave' | 'ripple' | 'swirl'; // 扭曲效果类型\n strength?: number; // 扭曲强度\n useWebGL?: boolean; // 是否使用WebGL实现\n}\n/**\n * 扭曲消失动画效果 - 重构版\n * 使用HybridEffectBase实现WebGL和Canvas 2D双重支持\n */\nexport class Distortion extends HybridEffectBase {\n private distortionConfig: Partial<DistortionConfig>;\n\n constructor(from: null, to: null, duration: number, easing: EasingType, params: any) {\n super(from, to, duration, easing, params);\n\n this.distortionConfig = {\n distortionType: params?.options?.distortionType || 'wave',\n strength: params?.options?.strength || 0.3,\n useWebGL: params?.options?.useWebGL !== undefined ? params.options.useWebGL : true\n };\n }\n\n /**\n * WebGL实现:着色器扭曲效果\n */\n protected getShaderSources(): { vertex: string; fragment: string } | null {\n const vertexShader = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n varying vec2 v_texCoord;\n\n void main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n `;\n\n const fragmentShader = `\n precision mediump float;\n uniform sampler2D u_texture;\n uniform float u_time;\n uniform float u_strength;\n uniform int u_distortionType;\n uniform vec2 u_resolution;\n varying vec2 v_texCoord;\n\n // 波浪扭曲函数\n vec2 wave(vec2 uv, float time, float strength) {\n float waveX = sin(uv.y * 10.0 + time * 3.0) * strength * 0.1;\n float waveY = sin(uv.x * 10.0 + time * 2.0) * strength * 0.1;\n return uv + vec2(waveX, waveY);\n }\n\n // 涟漪扭曲函数\n vec2 ripple(vec2 uv, float time, float strength) {\n vec2 center = vec2(0.5, 0.5);\n float distance = length(uv - center);\n float ripple = sin(distance * 20.0 - time * 5.0) * strength * 0.1;\n vec2 direction = normalize(uv - center);\n return uv + direction * ripple;\n }\n\n // 漩涡扭曲函数\n vec2 swirl(vec2 uv, float time, float strength) {\n vec2 center = vec2(0.5, 0.5);\n vec2 delta = uv - center;\n float dist = length(delta);\n float originalAngle = atan(delta.y, delta.x);\n float rotationAngle = dist * strength * time * 2.0;\n float finalAngle = originalAngle + rotationAngle;\n return center + dist * vec2(cos(finalAngle), sin(finalAngle));\n }\n\n void main() {\n vec2 uv = v_texCoord;\n\n // 根据扭曲类型应用相应变换\n if (u_distortionType == 0) {\n uv = wave(uv, u_time, u_strength);\n } else if (u_distortionType == 1) {\n uv = ripple(uv, u_time, u_strength);\n } else if (u_distortionType == 2) {\n uv = swirl(uv, u_time, u_strength);\n }\n\n // 边界检查\n if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n } else {\n gl_FragColor = texture2D(u_texture, uv);\n }\n }\n `;\n\n return { vertex: vertexShader, fragment: fragmentShader };\n }\n\n protected applyWebGLEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null {\n if (!this.gl || !this.program || !this.webglCanvas) {\n return null;\n }\n\n // 使用基类提供的公共方法\n this.setupWebGLState(canvas);\n\n // 创建纹理\n const texture = this.createTextureFromCanvas(canvas);\n if (!texture) {\n return null;\n }\n\n // 创建顶点缓冲区\n const vertexBuffer = this.createFullScreenQuad();\n if (!vertexBuffer) {\n this.gl.deleteTexture(texture);\n return null;\n }\n\n try {\n // 使用着色器程序\n this.gl.useProgram(this.program);\n\n // 设置顶点属性\n this.setupVertexAttributes();\n\n // 设置uniform变量\n this.setDistortionUniforms();\n\n // 绘制\n this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);\n\n return this.webglCanvas;\n } finally {\n // 清理资源\n this.gl.deleteTexture(texture);\n this.gl.deleteBuffer(vertexBuffer);\n }\n }\n\n /**\n * 设置扭曲效果的uniform变量\n */\n private setDistortionUniforms(): void {\n if (!this.gl || !this.program) {\n return;\n }\n\n const currentTime = this.getAnimationTime();\n\n // 获取uniform位置\n const timeLocation = this.gl.getUniformLocation(this.program, 'u_time');\n const strengthLocation = this.gl.getUniformLocation(this.program, 'u_strength');\n const distortionTypeLocation = this.gl.getUniformLocation(this.program, 'u_distortionType');\n const resolutionLocation = this.gl.getUniformLocation(this.program, 'u_resolution');\n\n // 设置uniform值\n this.gl.uniform1f(timeLocation, currentTime);\n this.gl.uniform1f(strengthLocation, this.distortionConfig.strength);\n this.gl.uniform2f(resolutionLocation, this.webglCanvas.width, this.webglCanvas.height);\n\n // 扭曲类型映射\n const distortionTypeMap: { [key: string]: number } = {\n wave: 0,\n ripple: 1,\n swirl: 2\n };\n this.gl.uniform1i(distortionTypeLocation, distortionTypeMap[this.distortionConfig.distortionType] || 0);\n }\n\n /**\n * Canvas 2D实现:软件扭曲效果\n */\n protected applyCanvas2DEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null {\n const outputCanvas = this.createOutputCanvas(canvas);\n if (!outputCanvas) {\n return null;\n }\n\n const { ctx } = outputCanvas;\n\n try {\n // 获取图像数据\n const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n const currentTime = this.getAnimationTime();\n\n // 应用对应的扭曲算法\n let distortedImageData: ImageData;\n\n switch (this.distortionConfig.distortionType) {\n case 'wave':\n distortedImageData = this.applyWaveDistortion(imageData, this.distortionConfig.strength, currentTime);\n break;\n case 'ripple':\n distortedImageData = this.applyRippleDistortion(imageData, this.distortionConfig.strength, currentTime);\n break;\n case 'swirl':\n distortedImageData = this.applySwirlDistortion(imageData, this.distortionConfig.strength, currentTime);\n break;\n default:\n distortedImageData = imageData;\n }\n\n // 清空画布并绘制扭曲后的图像\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.putImageData(distortedImageData, 0, 0);\n\n return outputCanvas.canvas;\n } catch (error) {\n console.warn('Canvas 2D distortion effect failed:', error);\n return null;\n }\n }\n\n /**\n * Canvas 2D波浪扭曲实现\n */\n private applyWaveDistortion(imageData: ImageData, strength: number, time: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n // 波浪扭曲计算\n const waveX = Math.sin(y * 0.1 + time * 3) * strength * 20;\n const waveY = Math.sin(x * 0.1 + time * 2) * strength * 20;\n\n const sourceX = Math.round(x - waveX);\n const sourceY = Math.round(y - waveY);\n\n const targetIndex = (y * width + x) * 4;\n\n if (sourceX >= 0 && sourceX < width && sourceY >= 0 && sourceY < height) {\n const sourceIndex = (sourceY * width + sourceX) * 4;\n result[targetIndex] = data[sourceIndex];\n result[targetIndex + 1] = data[sourceIndex + 1];\n result[targetIndex + 2] = data[sourceIndex + 2];\n result[targetIndex + 3] = data[sourceIndex + 3];\n } else {\n result[targetIndex + 3] = 0; // 透明\n }\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n /**\n * Canvas 2D涟漪扭曲实现\n */\n private applyRippleDistortion(imageData: ImageData, strength: number, time: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n const centerX = width / 2;\n const centerY = height / 2;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const dx = x - centerX;\n const dy = y - centerY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 涟漪效果\n const ripple = Math.sin(distance * 0.2 - time * 5) * strength * 10;\n const angle = Math.atan2(dy, dx);\n\n const sourceX = Math.round(x - Math.cos(angle) * ripple);\n const sourceY = Math.round(y - Math.sin(angle) * ripple);\n\n const targetIndex = (y * width + x) * 4;\n\n if (sourceX >= 0 && sourceX < width && sourceY >= 0 && sourceY < height) {\n const sourceIndex = (sourceY * width + sourceX) * 4;\n result[targetIndex] = data[sourceIndex];\n result[targetIndex + 1] = data[sourceIndex + 1];\n result[targetIndex + 2] = data[sourceIndex + 2];\n result[targetIndex + 3] = data[sourceIndex + 3];\n } else {\n result[targetIndex + 3] = 0;\n }\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n /**\n * Canvas 2D漩涡扭曲实现\n */\n private applySwirlDistortion(imageData: ImageData, strength: number, time: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n const centerX = width / 2;\n const centerY = height / 2;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const dx = x - centerX;\n const dy = y - centerY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n const originalAngle = Math.atan2(dy, dx);\n\n // 旋转角度随时间和强度增长\n const rotationAngle = distance * strength * time * 0.02;\n const finalAngle = originalAngle + rotationAngle;\n\n const sourceX = Math.round(centerX + distance * Math.cos(finalAngle));\n const sourceY = Math.round(centerY + distance * Math.sin(finalAngle));\n\n const targetIndex = (y * width + x) * 4;\n\n if (sourceX >= 0 && sourceX < width && sourceY >= 0 && sourceY < height) {\n const sourceIndex = (sourceY * width + sourceX) * 4;\n result[targetIndex] = data[sourceIndex];\n result[targetIndex + 1] = data[sourceIndex + 1];\n result[targetIndex + 2] = data[sourceIndex + 2];\n result[targetIndex + 3] = data[sourceIndex + 3];\n } else {\n result[targetIndex + 3] = 0;\n }\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n /**\n * 重写主要渲染方法,添加强度检查\n */\n protected afterStageRender(stage: any, canvas: HTMLCanvasElement): HTMLCanvasElement | void | null | false {\n // 如果强度为0,直接返回原图\n if (this.distortionConfig.strength <= 0) {\n return canvas;\n }\n\n // 调用父类的智能渲染选择逻辑\n return super.afterStageRender(stage, canvas);\n }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { EasingType } from '@visactor/vrender-core';
2
+ import { AStageAnimate } from '../custom-animate';
3
+ export interface BlurConfig {
4
+ blurRadius: number;
5
+ useOptimizedBlur: boolean;
6
+ }
7
+ export declare class GaussianBlur extends AStageAnimate<any> {
8
+ private blurConfig;
9
+ constructor(from: null, to: null, duration: number, easing: EasingType, params: any);
10
+ private applyCSSBlur;
11
+ private applyDownsampleBlur;
12
+ protected afterStageRender(stage: any, canvas: HTMLCanvasElement): HTMLCanvasElement | void | null | false;
13
+ }