@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,65 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ }), exports.GaussianBlur = void 0;
6
+
7
+ const vrender_core_1 = require("@visactor/vrender-core"), custom_animate_1 = require("../custom-animate");
8
+
9
+ class GaussianBlur extends custom_animate_1.AStageAnimate {
10
+ constructor(from, to, duration, easing, params) {
11
+ var _a, _b;
12
+ super(from, to, duration, easing, params), this.blurConfig = {
13
+ blurRadius: (null === (_a = null == params ? void 0 : params.options) || void 0 === _a ? void 0 : _a.blurRadius) || 8,
14
+ useOptimizedBlur: void 0 === (null === (_b = null == params ? void 0 : params.options) || void 0 === _b ? void 0 : _b.useOptimizedBlur) || params.options.useOptimizedBlur
15
+ };
16
+ }
17
+ applyCSSBlur(canvas, radius) {
18
+ const c = vrender_core_1.vglobal.createCanvas({
19
+ width: canvas.width,
20
+ height: canvas.height,
21
+ dpr: vrender_core_1.vglobal.devicePixelRatio
22
+ }), ctx = c.getContext("2d");
23
+ return ctx ? (ctx.filter = `blur(${radius}px)`, ctx.drawImage(canvas, 0, 0), ctx.filter = "none",
24
+ c) : canvas;
25
+ }
26
+ applyDownsampleBlur(imageData, radius) {
27
+ const {width: width, height: height} = imageData, downsample = Math.max(1, Math.floor(radius / 2)), smallWidth = Math.floor(width / downsample), smallHeight = Math.floor(height / downsample), tempCanvas = vrender_core_1.vglobal.createCanvas({
28
+ width: smallWidth,
29
+ height: smallHeight,
30
+ dpr: 1
31
+ }), tempCtx = tempCanvas.getContext("2d");
32
+ if (!tempCtx) return imageData;
33
+ const originalCanvas = vrender_core_1.vglobal.createCanvas({
34
+ width: width,
35
+ height: height,
36
+ dpr: 1
37
+ }), originalCtx = originalCanvas.getContext("2d");
38
+ return originalCtx ? (originalCtx.putImageData(imageData, 0, 0), tempCtx.drawImage(originalCanvas, 0, 0, smallWidth, smallHeight),
39
+ tempCtx.filter = `blur(${radius / downsample}px)`, tempCtx.drawImage(tempCanvas, 0, 0),
40
+ tempCtx.filter = "none", originalCtx.clearRect(0, 0, width, height), originalCtx.drawImage(tempCanvas, 0, 0, width, height),
41
+ originalCtx.getImageData(0, 0, width, height)) : imageData;
42
+ }
43
+ afterStageRender(stage, canvas) {
44
+ if (this.blurConfig.blurRadius <= 0) return canvas;
45
+ let result;
46
+ if (this.blurConfig.useOptimizedBlur) result = this.applyCSSBlur(canvas, this.blurConfig.blurRadius); else {
47
+ const c = vrender_core_1.vglobal.createCanvas({
48
+ width: canvas.width,
49
+ height: canvas.height,
50
+ dpr: vrender_core_1.vglobal.devicePixelRatio
51
+ }), ctx = c.getContext("2d");
52
+ if (!ctx) return !1;
53
+ ctx.clearRect(0, 0, canvas.width, canvas.height), ctx.drawImage(canvas, 0, 0);
54
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height), blurredImageData = this.applyDownsampleBlur(imageData, this.blurConfig.blurRadius);
55
+ ctx.putImageData(blurredImageData, 0, 0), result = c;
56
+ }
57
+ const ctx = result.getContext("2d");
58
+ return ctx && (ctx.globalCompositeOperation = "overlay", ctx.fillStyle = "rgba(255, 255, 255, 0.1)",
59
+ ctx.fillRect(0, 0, result.width, result.height), ctx.globalCompositeOperation = "source-over"),
60
+ result;
61
+ }
62
+ }
63
+
64
+ exports.GaussianBlur = GaussianBlur;
65
+ //# sourceMappingURL=gaussian-blur.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/custom/disappear/gaussian-blur.ts"],"names":[],"mappings":"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","file":"gaussian-blur.js","sourcesContent":["import type { EasingType } from '@visactor/vrender-core';\nimport { vglobal } from '@visactor/vrender-core';\nimport { AStageAnimate } from '../custom-animate';\n\n// 模糊效果配置接口\nexport interface BlurConfig {\n blurRadius: number;\n useOptimizedBlur: boolean;\n}\n\nexport class GaussianBlur extends AStageAnimate<any> {\n // 模糊配置\n private blurConfig: BlurConfig;\n\n constructor(from: null, to: null, duration: number, easing: EasingType, params: any) {\n super(from, to, duration, easing, params);\n\n this.blurConfig = {\n blurRadius: params?.options?.blurRadius || 8,\n useOptimizedBlur: params?.options?.useOptimizedBlur !== undefined ? params.options.useOptimizedBlur : true\n };\n }\n // 使用CSS滤镜(性能最好)\n private applyCSSBlur(canvas: HTMLCanvasElement, radius: number): HTMLCanvasElement {\n const c = vglobal.createCanvas({\n width: canvas.width,\n height: canvas.height,\n dpr: vglobal.devicePixelRatio\n });\n const ctx = c.getContext('2d');\n if (!ctx) {\n return canvas;\n }\n\n // 使用CSS滤镜进行模糊\n ctx.filter = `blur(${radius}px)`;\n ctx.drawImage(canvas, 0, 0);\n ctx.filter = 'none';\n\n return c;\n }\n\n // 降采样模糊(减少计算量)\n private applyDownsampleBlur(imageData: ImageData, radius: number): ImageData {\n const { width, height } = imageData;\n\n // 降采样因子,减少计算量\n const downsample = Math.max(1, Math.floor(radius / 2));\n const smallWidth = Math.floor(width / downsample);\n const smallHeight = Math.floor(height / downsample);\n\n // 创建小尺寸的临时canvas\n const tempCanvas = vglobal.createCanvas({\n width: smallWidth,\n height: smallHeight,\n dpr: 1\n });\n const tempCtx = tempCanvas.getContext('2d');\n if (!tempCtx) {\n return imageData;\n }\n\n // 将图像绘制到小canvas上\n const originalCanvas = vglobal.createCanvas({\n width: width,\n height: height,\n dpr: 1\n });\n const originalCtx = originalCanvas.getContext('2d');\n if (!originalCtx) {\n return imageData;\n }\n\n originalCtx.putImageData(imageData, 0, 0);\n\n // 缩小绘制(自动插值)\n tempCtx.drawImage(originalCanvas, 0, 0, smallWidth, smallHeight);\n\n // 应用模糊到小图像\n tempCtx.filter = `blur(${radius / downsample}px)`;\n tempCtx.drawImage(tempCanvas, 0, 0);\n tempCtx.filter = 'none';\n\n // 放大回原尺寸\n originalCtx.clearRect(0, 0, width, height);\n originalCtx.drawImage(tempCanvas, 0, 0, width, height);\n\n return originalCtx.getImageData(0, 0, width, height);\n }\n\n protected afterStageRender(stage: any, canvas: HTMLCanvasElement): HTMLCanvasElement | void | null | false {\n // 如果模糊强度为0,直接返回原图\n if (this.blurConfig.blurRadius <= 0) {\n return canvas;\n }\n\n let result: HTMLCanvasElement;\n\n if (this.blurConfig.useOptimizedBlur) {\n // 使用CSS滤镜(性能最好)\n result = this.applyCSSBlur(canvas, this.blurConfig.blurRadius);\n } else {\n // 使用传统的像素级模糊\n const c = vglobal.createCanvas({\n width: canvas.width,\n height: canvas.height,\n dpr: vglobal.devicePixelRatio\n });\n const ctx = c.getContext('2d');\n if (!ctx) {\n return false;\n }\n\n // 清空画布\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // 绘制原始图像\n ctx.drawImage(canvas, 0, 0);\n\n // 获取图像数据\n const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n\n // 高质量模式下统一使用降采样模糊\n const blurredImageData = this.applyDownsampleBlur(imageData, this.blurConfig.blurRadius);\n\n // 将模糊后的图像数据绘制到画布上\n ctx.putImageData(blurredImageData, 0, 0);\n\n result = c;\n }\n\n // 添加一个半透明的覆盖层来增强效果\n const ctx = result.getContext('2d');\n if (ctx) {\n ctx.globalCompositeOperation = 'overlay';\n ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';\n ctx.fillRect(0, 0, result.width, result.height);\n ctx.globalCompositeOperation = 'source-over';\n }\n\n return result;\n }\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import type { EasingType } from '@visactor/vrender-core';
2
+ import { Canvas2DEffectBase } from './base/CustomEffectBase';
3
+ export interface GlitchConfig {
4
+ effectType?: 'rgb-shift' | 'digital-distortion' | 'scan-lines' | 'data-corruption';
5
+ intensity?: number;
6
+ }
7
+ export declare class Glitch extends Canvas2DEffectBase {
8
+ private glitchConfig;
9
+ constructor(from: null, to: null, duration: number, easing: EasingType, params: any);
10
+ protected applyCanvas2DEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null;
11
+ private applyRGBShiftGlitch;
12
+ private applyDigitalDistortionGlitch;
13
+ private applyScanLineGlitch;
14
+ private applyDataCorruptionGlitch;
15
+ private generateRandomOffset;
16
+ private processDigitalDistortion;
17
+ private shiftSliceHorizontal;
18
+ private processDataCorruption;
19
+ private corruptBlock;
20
+ }
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ }), exports.Glitch = void 0;
6
+
7
+ const CustomEffectBase_1 = require("./base/CustomEffectBase"), ImageProcessUtils_1 = require("./base/ImageProcessUtils");
8
+
9
+ class Glitch extends CustomEffectBase_1.Canvas2DEffectBase {
10
+ constructor(from, to, duration, easing, params) {
11
+ var _a, _b;
12
+ super(from, to, duration, easing, params), this.glitchConfig = {
13
+ effectType: (null === (_a = null == params ? void 0 : params.options) || void 0 === _a ? void 0 : _a.effectType) || "rgb-shift",
14
+ intensity: void 0 !== (null === (_b = null == params ? void 0 : params.options) || void 0 === _b ? void 0 : _b.intensity) ? params.options.intensity : .5
15
+ };
16
+ }
17
+ applyCanvas2DEffect(canvas) {
18
+ if (this.glitchConfig.intensity <= 0) {
19
+ const outputCanvas = this.createOutputCanvas(canvas);
20
+ return outputCanvas ? outputCanvas.canvas : null;
21
+ }
22
+ try {
23
+ switch (this.glitchConfig.effectType) {
24
+ case "rgb-shift":
25
+ default:
26
+ return this.applyRGBShiftGlitch(canvas);
27
+
28
+ case "digital-distortion":
29
+ return this.applyDigitalDistortionGlitch(canvas);
30
+
31
+ case "scan-lines":
32
+ return this.applyScanLineGlitch(canvas);
33
+
34
+ case "data-corruption":
35
+ return this.applyDataCorruptionGlitch(canvas);
36
+ }
37
+ } catch (error) {
38
+ return console.warn("Glitch effect failed:", error), null;
39
+ }
40
+ }
41
+ applyRGBShiftGlitch(canvas) {
42
+ const outputCanvas = this.createOutputCanvas(canvas);
43
+ if (!outputCanvas) return null;
44
+ const {ctx: ctx} = outputCanvas;
45
+ try {
46
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
47
+ const dynamicIntensity = ImageProcessUtils_1.ImageProcessUtils.calculateDynamicStrength(this.glitchConfig.intensity, this.getAnimationTime()), maxOffset = Math.floor(20 * dynamicIntensity), redOffset = this.generateRandomOffset(maxOffset), greenOffset = this.generateRandomOffset(maxOffset, .3), blueOffset = this.generateRandomOffset(-maxOffset), tempCanvas = ImageProcessUtils_1.ImageProcessUtils.createTempCanvas(canvas.width, canvas.height), tempCtx = tempCanvas.getContext("2d");
48
+ tempCtx.drawImage(canvas, 0, 0);
49
+ const originalImageData = tempCtx.getImageData(0, 0, canvas.width, canvas.height), redChannelData = ImageProcessUtils_1.ImageProcessUtils.extractChannel(originalImageData, 0), greenChannelData = ImageProcessUtils_1.ImageProcessUtils.extractChannel(originalImageData, 1), blueChannelData = ImageProcessUtils_1.ImageProcessUtils.extractChannel(originalImageData, 2);
50
+ return ctx.globalCompositeOperation = "screen", tempCtx.clearRect(0, 0, canvas.width, canvas.height),
51
+ tempCtx.putImageData(redChannelData, 0, 0), ctx.drawImage(tempCanvas, redOffset.x, redOffset.y),
52
+ tempCtx.clearRect(0, 0, canvas.width, canvas.height), tempCtx.putImageData(greenChannelData, 0, 0),
53
+ ctx.drawImage(tempCanvas, greenOffset.x, greenOffset.y), tempCtx.clearRect(0, 0, canvas.width, canvas.height),
54
+ tempCtx.putImageData(blueChannelData, 0, 0), ctx.drawImage(tempCanvas, blueOffset.x, blueOffset.y),
55
+ ctx.globalCompositeOperation = "source-over", outputCanvas.canvas;
56
+ } catch (error) {
57
+ return console.warn("RGB shift glitch failed:", error), null;
58
+ }
59
+ }
60
+ applyDigitalDistortionGlitch(canvas) {
61
+ const outputCanvas = this.createOutputCanvas(canvas);
62
+ if (!outputCanvas) return null;
63
+ const {ctx: ctx} = outputCanvas;
64
+ try {
65
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height), dynamicIntensity = ImageProcessUtils_1.ImageProcessUtils.calculateDynamicStrength(this.glitchConfig.intensity, this.getAnimationTime()), distortedImageData = this.processDigitalDistortion(imageData, dynamicIntensity);
66
+ return ctx.clearRect(0, 0, canvas.width, canvas.height), ctx.putImageData(distortedImageData, 0, 0),
67
+ outputCanvas.canvas;
68
+ } catch (error) {
69
+ return console.warn("Digital distortion glitch failed:", error), null;
70
+ }
71
+ }
72
+ applyScanLineGlitch(canvas) {
73
+ const outputCanvas = this.createOutputCanvas(canvas);
74
+ if (!outputCanvas) return null;
75
+ const {ctx: ctx} = outputCanvas;
76
+ try {
77
+ const dynamicIntensity = ImageProcessUtils_1.ImageProcessUtils.calculateDynamicStrength(this.glitchConfig.intensity, this.getAnimationTime()), lineSpacing = Math.max(2, Math.floor(10 - 8 * dynamicIntensity));
78
+ ctx.globalCompositeOperation = "multiply";
79
+ for (let y = 0; y < canvas.height; y += lineSpacing) if (Math.random() < dynamicIntensity) {
80
+ const opacity = .1 + .4 * dynamicIntensity;
81
+ ctx.fillStyle = `rgba(0, 0, 0, ${opacity})`, ctx.fillRect(0, y, canvas.width, 1);
82
+ }
83
+ ctx.globalCompositeOperation = "screen";
84
+ const brightLineCount = Math.floor(20 * dynamicIntensity);
85
+ for (let i = 0; i < brightLineCount; i++) {
86
+ const y = Math.random() * canvas.height, opacity = .3 * dynamicIntensity;
87
+ ctx.fillStyle = `rgba(255, 255, 255, ${opacity})`, ctx.fillRect(0, Math.floor(y), canvas.width, 1);
88
+ }
89
+ return ctx.globalCompositeOperation = "source-over", outputCanvas.canvas;
90
+ } catch (error) {
91
+ return console.warn("Scan line glitch failed:", error), null;
92
+ }
93
+ }
94
+ applyDataCorruptionGlitch(canvas) {
95
+ const outputCanvas = this.createOutputCanvas(canvas);
96
+ if (!outputCanvas) return null;
97
+ const {ctx: ctx} = outputCanvas;
98
+ try {
99
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height), dynamicIntensity = ImageProcessUtils_1.ImageProcessUtils.calculateDynamicStrength(this.glitchConfig.intensity, this.getAnimationTime()), corruptedImageData = this.processDataCorruption(imageData, dynamicIntensity);
100
+ return ctx.clearRect(0, 0, canvas.width, canvas.height), ctx.putImageData(corruptedImageData, 0, 0),
101
+ outputCanvas.canvas;
102
+ } catch (error) {
103
+ return console.warn("Data corruption glitch failed:", error), null;
104
+ }
105
+ }
106
+ generateRandomOffset(maxOffset, scale = 1) {
107
+ return {
108
+ x: (Math.random() - .5) * maxOffset,
109
+ y: (Math.random() - .5) * maxOffset * scale
110
+ };
111
+ }
112
+ processDigitalDistortion(imageData, intensity) {
113
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data), sliceCount = Math.floor(20 * intensity) + 5, sliceHeight = Math.floor(height / sliceCount);
114
+ for (let i = 0; i < sliceCount; i++) if (Math.random() < intensity) {
115
+ const y = i * sliceHeight, sliceEnd = Math.min(y + sliceHeight, height), offset = Math.floor((Math.random() - .5) * width * intensity * .1);
116
+ this.shiftSliceHorizontal(result, width, height, y, sliceEnd, offset);
117
+ }
118
+ const noiseIntensity = .3 * intensity;
119
+ for (let i = 0; i < data.length; i += 4) Math.random() < noiseIntensity && (result[i] = 255 * Math.random(),
120
+ result[i + 1] = 255 * Math.random(), result[i + 2] = 255 * Math.random());
121
+ return new ImageData(result, width, height);
122
+ }
123
+ shiftSliceHorizontal(data, width, height, startY, endY, offset) {
124
+ const tempRow = new Uint8ClampedArray(4 * width);
125
+ for (let y = startY; y < endY; y++) {
126
+ const rowStart = y * width * 4;
127
+ for (let x = 0; x < 4 * width; x++) tempRow[x] = data[rowStart + x];
128
+ for (let x = 0; x < width; x++) {
129
+ const targetIndex = rowStart + 4 * x, sourceIndex = 4 * ((x - offset + width) % width);
130
+ data[targetIndex] = tempRow[sourceIndex], data[targetIndex + 1] = tempRow[sourceIndex + 1],
131
+ data[targetIndex + 2] = tempRow[sourceIndex + 2], data[targetIndex + 3] = tempRow[sourceIndex + 3];
132
+ }
133
+ }
134
+ }
135
+ processDataCorruption(imageData, intensity) {
136
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data), stripeCount = Math.floor(15 * intensity) + 5;
137
+ for (let i = 0; i < stripeCount; i++) if (Math.random() < intensity) {
138
+ const x = Math.floor(Math.random() * width), stripeWidth = Math.floor(5 * Math.random()) + 1, color = Math.random() < .5 ? 0 : 255;
139
+ for (let y = 0; y < height; y++) for (let dx = 0; dx < stripeWidth && x + dx < width; dx++) {
140
+ const index = 4 * (y * width + x + dx);
141
+ result[index] = color, result[index + 1] = color, result[index + 2] = color;
142
+ }
143
+ }
144
+ const corruptionCount = Math.floor(20 * intensity);
145
+ for (let i = 0; i < corruptionCount; i++) {
146
+ const blockX = Math.floor(Math.random() * width), blockY = Math.floor(Math.random() * height), blockW = Math.floor(20 * Math.random()) + 5, blockH = Math.floor(10 * Math.random()) + 2;
147
+ this.corruptBlock(result, width, height, blockX, blockY, blockW, blockH);
148
+ }
149
+ return new ImageData(result, width, height);
150
+ }
151
+ corruptBlock(data, width, height, x, y, w, h) {
152
+ for (let dy = 0; dy < h && y + dy < height; dy++) for (let dx = 0; dx < w && x + dx < width; dx++) {
153
+ const index = 4 * ((y + dy) * width + (x + dx));
154
+ Math.random() < .7 && (data[index] = 255 * Math.random(), data[index + 1] = 255 * Math.random(),
155
+ data[index + 2] = 255 * Math.random());
156
+ }
157
+ }
158
+ }
159
+
160
+ exports.Glitch = Glitch;
161
+ //# sourceMappingURL=glitch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/custom/disappear/glitch.ts"],"names":[],"mappings":"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","file":"glitch.js","sourcesContent":["import type { EasingType } from '@visactor/vrender-core';\nimport { Canvas2DEffectBase } from './base/CustomEffectBase';\n// import { GlitchEffectConfig, EffectConfigFactory, EffectType } from './base/DisappearEffectConfig';\nimport { ImageProcessUtils } from './base/ImageProcessUtils';\n\n// 故障效果配置接口\nexport interface GlitchConfig {\n effectType?: 'rgb-shift' | 'digital-distortion' | 'scan-lines' | 'data-corruption'; // 故障效果类型\n intensity?: number; // 故障强度 0-1\n}\n\n/**\n * 故障消失动画效果 - 重构版\n * 使用Canvas2DEffectBase实现,专注于2D图像处理的故障效果\n */\nexport class Glitch extends Canvas2DEffectBase {\n private glitchConfig: Required<GlitchConfig>;\n\n constructor(from: null, to: null, duration: number, easing: EasingType, params: any) {\n super(from, to, duration, easing, params);\n\n this.glitchConfig = {\n effectType: params?.options?.effectType || 'rgb-shift',\n // intensity 可能为 0\n intensity: params?.options?.intensity !== undefined ? params.options.intensity : 0.5\n };\n }\n\n /**\n * Canvas 2D故障效果主入口\n */\n protected applyCanvas2DEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null {\n // 如果强度为0,创建一个原图副本返回\n if (this.glitchConfig.intensity <= 0) {\n const outputCanvas = this.createOutputCanvas(canvas);\n return outputCanvas ? outputCanvas.canvas : null;\n }\n\n try {\n // 根据故障类型应用对应效果\n switch (this.glitchConfig.effectType) {\n case 'rgb-shift':\n return this.applyRGBShiftGlitch(canvas);\n case 'digital-distortion':\n return this.applyDigitalDistortionGlitch(canvas);\n case 'scan-lines':\n return this.applyScanLineGlitch(canvas);\n case 'data-corruption':\n return this.applyDataCorruptionGlitch(canvas);\n default:\n return this.applyRGBShiftGlitch(canvas);\n }\n } catch (error) {\n console.warn('Glitch effect failed:', error);\n return null;\n }\n }\n\n /**\n * RGB通道偏移故障效果\n * 分离RGB通道并应用不同的偏移,产生色散效果\n */\n private applyRGBShiftGlitch(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 ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // 计算基于动画进度的动态强度\n const dynamicIntensity = ImageProcessUtils.calculateDynamicStrength(\n this.glitchConfig.intensity,\n this.getAnimationTime()\n );\n\n // 计算偏移量 - 增强色散效果\n const maxOffset = Math.floor(dynamicIntensity * 20);\n const redOffset = this.generateRandomOffset(maxOffset);\n const greenOffset = this.generateRandomOffset(maxOffset, 0.3);\n const blueOffset = this.generateRandomOffset(-maxOffset);\n\n // 获取原始图像数据\n const tempCanvas = ImageProcessUtils.createTempCanvas(canvas.width, canvas.height);\n const tempCtx = tempCanvas.getContext('2d');\n tempCtx.drawImage(canvas, 0, 0);\n const originalImageData = tempCtx.getImageData(0, 0, canvas.width, canvas.height);\n\n // 创建RGB通道分离的图像数据\n const redChannelData = ImageProcessUtils.extractChannel(originalImageData, 0);\n const greenChannelData = ImageProcessUtils.extractChannel(originalImageData, 1);\n const blueChannelData = ImageProcessUtils.extractChannel(originalImageData, 2);\n\n // 使用screen混合模式绘制分离的通道\n ctx.globalCompositeOperation = 'screen';\n\n // 绘制红色通道\n tempCtx.clearRect(0, 0, canvas.width, canvas.height);\n tempCtx.putImageData(redChannelData, 0, 0);\n ctx.drawImage(tempCanvas, redOffset.x, redOffset.y);\n\n // 绘制绿色通道\n tempCtx.clearRect(0, 0, canvas.width, canvas.height);\n tempCtx.putImageData(greenChannelData, 0, 0);\n ctx.drawImage(tempCanvas, greenOffset.x, greenOffset.y);\n\n // 绘制蓝色通道\n tempCtx.clearRect(0, 0, canvas.width, canvas.height);\n tempCtx.putImageData(blueChannelData, 0, 0);\n ctx.drawImage(tempCanvas, blueOffset.x, blueOffset.y);\n\n // 恢复正常混合模式\n ctx.globalCompositeOperation = 'source-over';\n\n return outputCanvas.canvas;\n } catch (error) {\n console.warn('RGB shift glitch failed:', error);\n return null;\n }\n }\n\n /**\n * 数字扭曲故障效果\n * 应用水平切片偏移和随机像素噪声\n */\n private applyDigitalDistortionGlitch(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 dynamicIntensity = ImageProcessUtils.calculateDynamicStrength(\n this.glitchConfig.intensity,\n this.getAnimationTime()\n );\n\n // 应用数字扭曲\n const distortedImageData = this.processDigitalDistortion(imageData, dynamicIntensity);\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('Digital distortion glitch failed:', error);\n return null;\n }\n }\n\n /**\n * 扫描线故障效果\n * 添加水平扫描线和随机亮线效果\n */\n private applyScanLineGlitch(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 const dynamicIntensity = ImageProcessUtils.calculateDynamicStrength(\n this.glitchConfig.intensity,\n this.getAnimationTime()\n );\n\n // 添加暗扫描线\n const lineSpacing = Math.max(2, Math.floor(10 - dynamicIntensity * 8));\n ctx.globalCompositeOperation = 'multiply';\n\n for (let y = 0; y < canvas.height; y += lineSpacing) {\n if (Math.random() < dynamicIntensity) {\n const opacity = 0.1 + dynamicIntensity * 0.4;\n ctx.fillStyle = `rgba(0, 0, 0, ${opacity})`;\n ctx.fillRect(0, y, canvas.width, 1);\n }\n }\n\n // 添加随机亮线\n ctx.globalCompositeOperation = 'screen';\n const brightLineCount = Math.floor(dynamicIntensity * 20);\n for (let i = 0; i < brightLineCount; i++) {\n const y = Math.random() * canvas.height;\n const opacity = dynamicIntensity * 0.3;\n ctx.fillStyle = `rgba(255, 255, 255, ${opacity})`;\n ctx.fillRect(0, Math.floor(y), canvas.width, 1);\n }\n\n // 恢复正常混合模式\n ctx.globalCompositeOperation = 'source-over';\n\n return outputCanvas.canvas;\n } catch (error) {\n console.warn('Scan line glitch failed:', error);\n return null;\n }\n }\n\n /**\n * 数据损坏故障效果\n * 创建垂直条纹和随机块状损坏效果\n */\n private applyDataCorruptionGlitch(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 dynamicIntensity = ImageProcessUtils.calculateDynamicStrength(\n this.glitchConfig.intensity,\n this.getAnimationTime()\n );\n\n // 应用数据损坏\n const corruptedImageData = this.processDataCorruption(imageData, dynamicIntensity);\n\n // 清空画布并绘制损坏后的图像\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.putImageData(corruptedImageData, 0, 0);\n\n return outputCanvas.canvas;\n } catch (error) {\n console.warn('Data corruption glitch failed:', error);\n return null;\n }\n }\n\n /**\n * 生成随机偏移量\n */\n private generateRandomOffset(maxOffset: number, scale: number = 1): { x: number; y: number } {\n return {\n x: (Math.random() - 0.5) * maxOffset,\n y: (Math.random() - 0.5) * maxOffset * scale\n };\n }\n\n /**\n * 处理数字扭曲算法\n */\n private processDigitalDistortion(imageData: ImageData, intensity: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data);\n\n // 随机水平切片\n const sliceCount = Math.floor(intensity * 20) + 5;\n const sliceHeight = Math.floor(height / sliceCount);\n\n for (let i = 0; i < sliceCount; i++) {\n if (Math.random() < intensity) {\n const y = i * sliceHeight;\n const sliceEnd = Math.min(y + sliceHeight, height);\n const offset = Math.floor((Math.random() - 0.5) * width * intensity * 0.1);\n\n // 水平偏移切片\n this.shiftSliceHorizontal(result, width, height, y, sliceEnd, offset);\n }\n }\n\n // 添加随机像素噪声\n const noiseIntensity = intensity * 0.3;\n for (let i = 0; i < data.length; i += 4) {\n if (Math.random() < noiseIntensity) {\n result[i] = Math.random() * 255; // R\n result[i + 1] = Math.random() * 255; // G\n result[i + 2] = Math.random() * 255; // B\n }\n }\n\n return new ImageData(result, width, height);\n }\n\n /**\n * 水平切片偏移算法\n */\n private shiftSliceHorizontal(\n data: Uint8ClampedArray,\n width: number,\n height: number,\n startY: number,\n endY: number,\n offset: number\n ): void {\n const tempRow = new Uint8ClampedArray(width * 4);\n\n for (let y = startY; y < endY; y++) {\n const rowStart = y * width * 4;\n\n // 保存当前行\n for (let x = 0; x < width * 4; x++) {\n tempRow[x] = data[rowStart + x];\n }\n\n // 应用偏移\n for (let x = 0; x < width; x++) {\n const sourceX = (x - offset + width) % width;\n const targetIndex = rowStart + x * 4;\n const sourceIndex = sourceX * 4;\n\n data[targetIndex] = tempRow[sourceIndex];\n data[targetIndex + 1] = tempRow[sourceIndex + 1];\n data[targetIndex + 2] = tempRow[sourceIndex + 2];\n data[targetIndex + 3] = tempRow[sourceIndex + 3];\n }\n }\n }\n\n /**\n * 处理数据损坏算法\n */\n private processDataCorruption(imageData: ImageData, intensity: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data);\n\n // 随机垂直条纹\n const stripeCount = Math.floor(intensity * 15) + 5;\n for (let i = 0; i < stripeCount; i++) {\n if (Math.random() < intensity) {\n const x = Math.floor(Math.random() * width);\n const stripeWidth = Math.floor(Math.random() * 5) + 1;\n const color = Math.random() < 0.5 ? 0 : 255;\n\n for (let y = 0; y < height; y++) {\n for (let dx = 0; dx < stripeWidth && x + dx < width; dx++) {\n const index = (y * width + x + dx) * 4;\n result[index] = color; // R\n result[index + 1] = color; // G\n result[index + 2] = color; // B\n }\n }\n }\n }\n\n // 随机块状损坏\n const corruptionCount = Math.floor(intensity * 20);\n for (let i = 0; i < corruptionCount; i++) {\n const blockX = Math.floor(Math.random() * width);\n const blockY = Math.floor(Math.random() * height);\n const blockW = Math.floor(Math.random() * 20) + 5;\n const blockH = Math.floor(Math.random() * 10) + 2;\n\n this.corruptBlock(result, width, height, blockX, blockY, blockW, blockH);\n }\n\n return new ImageData(result, width, height);\n }\n\n /**\n * 损坏指定区域的像素块\n */\n private corruptBlock(\n data: Uint8ClampedArray,\n width: number,\n height: number,\n x: number,\n y: number,\n w: number,\n h: number\n ): void {\n for (let dy = 0; dy < h && y + dy < height; dy++) {\n for (let dx = 0; dx < w && x + dx < width; dx++) {\n const index = ((y + dy) * width + (x + dx)) * 4;\n if (Math.random() < 0.7) {\n data[index] = Math.random() * 255;\n data[index + 1] = Math.random() * 255;\n data[index + 2] = Math.random() * 255;\n }\n }\n }\n }\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import type { EasingType } from '@visactor/vrender-core';
2
+ import { HybridEffectBase } from './base/CustomEffectBase';
3
+ export interface ColorEffectConfig {
4
+ effectType: 'grayscale' | 'sepia';
5
+ strength: number;
6
+ useWebGL: boolean;
7
+ }
8
+ export declare class Grayscale extends HybridEffectBase {
9
+ private colorConfig;
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 setColorUniforms;
17
+ protected applyCanvas2DEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null;
18
+ private canUseCSSFilter;
19
+ private applyCSSFilter;
20
+ private applyGrayscaleEffect;
21
+ private applySepiaEffect;
22
+ protected afterStageRender(stage: any, canvas: HTMLCanvasElement): HTMLCanvasElement | void | null | false;
23
+ }
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ }), exports.Grayscale = void 0;
6
+
7
+ const CustomEffectBase_1 = require("./base/CustomEffectBase"), ImageProcessUtils_1 = require("./base/ImageProcessUtils");
8
+
9
+ class Grayscale extends CustomEffectBase_1.HybridEffectBase {
10
+ constructor(from, to, duration, easing, params) {
11
+ var _a, _b, _c;
12
+ super(from, to, duration, easing, params);
13
+ const rawStrength = void 0 !== (null === (_a = null == params ? void 0 : params.options) || void 0 === _a ? void 0 : _a.strength) ? params.options.strength : 1, clampedStrength = Math.max(0, Math.min(1, rawStrength));
14
+ this.colorConfig = {
15
+ effectType: (null === (_b = null == params ? void 0 : params.options) || void 0 === _b ? void 0 : _b.effectType) || "grayscale",
16
+ strength: clampedStrength,
17
+ useWebGL: void 0 === (null === (_c = null == params ? void 0 : params.options) || void 0 === _c ? void 0 : _c.useWebGL) || params.options.useWebGL
18
+ };
19
+ }
20
+ getShaderSources() {
21
+ return {
22
+ vertex: ImageProcessUtils_1.ShaderLibrary.STANDARD_VERTEX_SHADER,
23
+ fragment: `\n precision mediump float;\n uniform sampler2D u_texture;\n uniform float u_time;\n uniform float u_strength;\n uniform int u_effectType;\n uniform vec2 u_resolution;\n varying vec2 v_texCoord;\n\n ${ImageProcessUtils_1.ShaderLibrary.SHADER_FUNCTIONS}\n\n void main() {\n vec2 uv = v_texCoord;\n vec4 originalColor = texture2D(u_texture, uv);\n vec3 color = originalColor.rgb;\n\n // 计算动态强度\n float dynamicStrength = calculateDynamicStrength(u_strength, u_time);\n\n if (u_effectType == 0) {\n // 灰度效果\n float gray = luminance(color);\n vec3 grayColor = vec3(gray);\n color = mix(color, grayColor, dynamicStrength);\n } else if (u_effectType == 1) {\n // 褐色调效果\n vec3 sepiaColor = sepia(color);\n color = mix(color, sepiaColor, dynamicStrength);\n }\n\n gl_FragColor = vec4(color, originalColor.a);\n }\n `
24
+ };
25
+ }
26
+ applyWebGLEffect(canvas) {
27
+ if (!this.gl || !this.program || !this.webglCanvas) return null;
28
+ this.setupWebGLState(canvas);
29
+ const texture = this.createTextureFromCanvas(canvas);
30
+ if (!texture) return null;
31
+ const vertexBuffer = this.createFullScreenQuad();
32
+ if (!vertexBuffer) return this.gl.deleteTexture(texture), null;
33
+ try {
34
+ return this.gl.useProgram(this.program), this.setupVertexAttributes(), this.setColorUniforms(),
35
+ this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4), this.webglCanvas;
36
+ } finally {
37
+ this.gl.deleteTexture(texture), this.gl.deleteBuffer(vertexBuffer);
38
+ }
39
+ }
40
+ setColorUniforms() {
41
+ if (!this.gl || !this.program) return;
42
+ const currentTime = this.getAnimationTime(), timeLocation = this.gl.getUniformLocation(this.program, "u_time"), strengthLocation = this.gl.getUniformLocation(this.program, "u_strength"), effectTypeLocation = this.gl.getUniformLocation(this.program, "u_effectType"), resolutionLocation = this.gl.getUniformLocation(this.program, "u_resolution");
43
+ this.gl.uniform1f(timeLocation, currentTime), this.gl.uniform1f(strengthLocation, this.colorConfig.strength),
44
+ this.gl.uniform2f(resolutionLocation, this.webglCanvas.width, this.webglCanvas.height);
45
+ this.gl.uniform1i(effectTypeLocation, {
46
+ grayscale: 0,
47
+ sepia: 1
48
+ }[this.colorConfig.effectType] || 0);
49
+ }
50
+ applyCanvas2DEffect(canvas) {
51
+ if (this.colorConfig.strength <= 0) {
52
+ const outputCanvas = this.createOutputCanvas(canvas);
53
+ return outputCanvas ? outputCanvas.canvas : null;
54
+ }
55
+ if (this.canUseCSSFilter()) return this.applyCSSFilter(canvas);
56
+ const outputCanvas = this.createOutputCanvas(canvas);
57
+ if (!outputCanvas) return null;
58
+ const {ctx: ctx} = outputCanvas;
59
+ try {
60
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height), currentTime = this.getAnimationTime();
61
+ let processedImageData;
62
+ switch (this.colorConfig.effectType) {
63
+ case "grayscale":
64
+ default:
65
+ processedImageData = this.applyGrayscaleEffect(imageData, this.colorConfig.strength, currentTime);
66
+ break;
67
+
68
+ case "sepia":
69
+ processedImageData = this.applySepiaEffect(imageData, this.colorConfig.strength, currentTime);
70
+ }
71
+ return ctx.clearRect(0, 0, canvas.width, canvas.height), ctx.putImageData(processedImageData, 0, 0),
72
+ outputCanvas.canvas;
73
+ } catch (error) {
74
+ return console.warn("Canvas 2D color effect failed:", error), null;
75
+ }
76
+ }
77
+ canUseCSSFilter() {
78
+ var _a;
79
+ return !!window.useFilterAPI && "undefined" != typeof CSS && (null === (_a = CSS.supports) || void 0 === _a ? void 0 : _a.call(CSS, "filter", "grayscale(1)"));
80
+ }
81
+ applyCSSFilter(canvas) {
82
+ try {
83
+ const outputCanvas = ImageProcessUtils_1.ImageProcessUtils.createTempCanvas(canvas.width, canvas.height), ctx = outputCanvas.getContext("2d");
84
+ if (!ctx) return null;
85
+ const currentTime = this.getAnimationTime(), dynamicStrength = ImageProcessUtils_1.ImageProcessUtils.calculateDynamicStrength(this.colorConfig.strength, currentTime);
86
+ let filterValue = "";
87
+ return "grayscale" === this.colorConfig.effectType ? filterValue = `grayscale(${Math.min(1, dynamicStrength)})` : "sepia" === this.colorConfig.effectType && (filterValue = `sepia(${Math.min(1, dynamicStrength)})`),
88
+ ctx.filter = filterValue, ctx.drawImage(canvas, 0, 0), ctx.filter = "none", outputCanvas;
89
+ } catch (error) {
90
+ return console.warn("CSS Filter API failed, falling back to pixel processing:", error),
91
+ null;
92
+ }
93
+ }
94
+ applyGrayscaleEffect(imageData, strength, time) {
95
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length), dynamicStrength = ImageProcessUtils_1.ImageProcessUtils.calculateDynamicStrength(strength, time);
96
+ for (let i = 0; i < data.length; i += 4) {
97
+ const r = data[i], g = data[i + 1], b = data[i + 2], a = data[i + 3], gray = ImageProcessUtils_1.ImageProcessUtils.getLuminance(r, g, b);
98
+ result[i] = Math.round(ImageProcessUtils_1.ImageProcessUtils.lerp(r, gray, dynamicStrength)),
99
+ result[i + 1] = Math.round(ImageProcessUtils_1.ImageProcessUtils.lerp(g, gray, dynamicStrength)),
100
+ result[i + 2] = Math.round(ImageProcessUtils_1.ImageProcessUtils.lerp(b, gray, dynamicStrength)),
101
+ result[i + 3] = a;
102
+ }
103
+ return new ImageData(result, width, height);
104
+ }
105
+ applySepiaEffect(imageData, strength, time) {
106
+ const {data: data, width: width, height: height} = imageData, result = new Uint8ClampedArray(data.length), dynamicStrength = ImageProcessUtils_1.ImageProcessUtils.calculateDynamicStrength(strength, time);
107
+ for (let i = 0; i < data.length; i += 4) {
108
+ const r = data[i], g = data[i + 1], b = data[i + 2], a = data[i + 3], [sepiaR, sepiaG, sepiaB] = ImageProcessUtils_1.ImageProcessUtils.applySepiaToPixel(r, g, b);
109
+ result[i] = Math.round(ImageProcessUtils_1.ImageProcessUtils.lerp(r, sepiaR, dynamicStrength)),
110
+ result[i + 1] = Math.round(ImageProcessUtils_1.ImageProcessUtils.lerp(g, sepiaG, dynamicStrength)),
111
+ result[i + 2] = Math.round(ImageProcessUtils_1.ImageProcessUtils.lerp(b, sepiaB, dynamicStrength)),
112
+ result[i + 3] = a;
113
+ }
114
+ return new ImageData(result, width, height);
115
+ }
116
+ afterStageRender(stage, canvas) {
117
+ if (this.canUseCSSFilter() && this.colorConfig.strength > 0) {
118
+ const cssResult = this.applyCSSFilter(canvas);
119
+ if (cssResult) return cssResult;
120
+ }
121
+ return super.afterStageRender(stage, canvas);
122
+ }
123
+ }
124
+
125
+ exports.Grayscale = Grayscale;
126
+ //# sourceMappingURL=grayscale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/custom/disappear/grayscale.ts"],"names":[],"mappings":"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","file":"grayscale.js","sourcesContent":["import type { EasingType } from '@visactor/vrender-core';\nimport { HybridEffectBase } from './base/CustomEffectBase';\nimport { ImageProcessUtils, ShaderLibrary } from './base/ImageProcessUtils';\n\nexport interface ColorEffectConfig {\n effectType: 'grayscale' | 'sepia';\n strength: number;\n useWebGL: boolean;\n}\n/**\n * 灰度/褐色调消失动画效果 - 重构版\n * 使用HybridEffectBase实现WebGL和Canvas 2D双重支持\n */\nexport class Grayscale extends HybridEffectBase {\n private colorConfig: Required<ColorEffectConfig>;\n\n constructor(from: null, to: null, duration: number, easing: EasingType, params: any) {\n super(from, to, duration, easing, params);\n\n // 获取strength并限制在0-1范围内\n const rawStrength = params?.options?.strength !== undefined ? params.options.strength : 1.0;\n const clampedStrength = Math.max(0, Math.min(1, rawStrength));\n\n this.colorConfig = {\n effectType: params?.options?.effectType || 'grayscale', // 'grayscale' | 'sepia'\n strength: clampedStrength, // 限制在 0.0 - 1.0 范围内\n useWebGL: params?.options?.useWebGL !== undefined ? params.options.useWebGL : true // 是否使用WebGL实现\n };\n }\n\n /**\n * WebGL实现:高性能着色器颜色转换\n */\n protected getShaderSources(): { vertex: string; fragment: string } | null {\n const vertexShader = ShaderLibrary.STANDARD_VERTEX_SHADER;\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_effectType;\n uniform vec2 u_resolution;\n varying vec2 v_texCoord;\n\n ${ShaderLibrary.SHADER_FUNCTIONS}\n\n void main() {\n vec2 uv = v_texCoord;\n vec4 originalColor = texture2D(u_texture, uv);\n vec3 color = originalColor.rgb;\n\n // 计算动态强度\n float dynamicStrength = calculateDynamicStrength(u_strength, u_time);\n\n if (u_effectType == 0) {\n // 灰度效果\n float gray = luminance(color);\n vec3 grayColor = vec3(gray);\n color = mix(color, grayColor, dynamicStrength);\n } else if (u_effectType == 1) {\n // 褐色调效果\n vec3 sepiaColor = sepia(color);\n color = mix(color, sepiaColor, dynamicStrength);\n }\n\n gl_FragColor = vec4(color, originalColor.a);\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.setColorUniforms();\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 setColorUniforms(): 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 effectTypeLocation = this.gl.getUniformLocation(this.program, 'u_effectType');\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.colorConfig.strength);\n this.gl.uniform2f(resolutionLocation, this.webglCanvas.width, this.webglCanvas.height);\n\n // 效果类型映射\n const effectTypeMap: { [key: string]: number } = {\n grayscale: 0,\n sepia: 1\n };\n this.gl.uniform1i(effectTypeLocation, effectTypeMap[this.colorConfig.effectType] || 0);\n }\n\n /**\n * Canvas 2D实现:软件颜色转换\n */\n protected applyCanvas2DEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null {\n // 如果强度为0,创建原图副本\n if (this.colorConfig.strength <= 0) {\n const outputCanvas = this.createOutputCanvas(canvas);\n return outputCanvas ? outputCanvas.canvas : null;\n }\n\n // 检查是否使用CSS Filter API(如果支持)\n if (this.canUseCSSFilter()) {\n return this.applyCSSFilter(canvas);\n }\n\n // 使用像素级处理\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 processedImageData: ImageData;\n\n switch (this.colorConfig.effectType) {\n case 'grayscale':\n processedImageData = this.applyGrayscaleEffect(imageData, this.colorConfig.strength, currentTime);\n break;\n case 'sepia':\n processedImageData = this.applySepiaEffect(imageData, this.colorConfig.strength, currentTime);\n break;\n default:\n processedImageData = this.applyGrayscaleEffect(imageData, this.colorConfig.strength, currentTime);\n }\n\n // 清空画布并绘制处理后的图像\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.putImageData(processedImageData, 0, 0);\n\n return outputCanvas.canvas;\n } catch (error) {\n console.warn('Canvas 2D color effect failed:', error);\n return null;\n }\n }\n\n /**\n * 检查是否可以使用CSS Filter API\n */\n private canUseCSSFilter(): boolean {\n // 检查全局配置或浏览器支持\n return !!(window as any).useFilterAPI && typeof CSS !== 'undefined' && CSS.supports?.('filter', 'grayscale(1)');\n }\n\n /**\n * 使用CSS Filter API应用颜色效果\n */\n private applyCSSFilter(canvas: HTMLCanvasElement): HTMLCanvasElement | null {\n try {\n const outputCanvas = ImageProcessUtils.createTempCanvas(canvas.width, canvas.height);\n const ctx = outputCanvas.getContext('2d');\n if (!ctx) {\n return null;\n }\n\n // 计算动态强度\n const currentTime = this.getAnimationTime();\n const dynamicStrength = ImageProcessUtils.calculateDynamicStrength(this.colorConfig.strength, currentTime);\n\n // 应用CSS滤镜\n let filterValue = '';\n if (this.colorConfig.effectType === 'grayscale') {\n filterValue = `grayscale(${Math.min(1, dynamicStrength)})`;\n } else if (this.colorConfig.effectType === 'sepia') {\n filterValue = `sepia(${Math.min(1, dynamicStrength)})`;\n }\n\n ctx.filter = filterValue;\n ctx.drawImage(canvas, 0, 0);\n ctx.filter = 'none';\n\n return outputCanvas;\n } catch (error) {\n console.warn('CSS Filter API failed, falling back to pixel processing:', error);\n return null;\n }\n }\n\n /**\n * Canvas 2D灰度效果实现\n */\n private applyGrayscaleEffect(imageData: ImageData, strength: number, time: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n\n // 计算动态强度\n const dynamicStrength = ImageProcessUtils.calculateDynamicStrength(strength, time);\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n const a = data[i + 3];\n\n // 使用标准亮度公式计算灰度值\n const gray = ImageProcessUtils.getLuminance(r, g, b);\n\n // 根据动态强度混合原色和灰度色\n result[i] = Math.round(ImageProcessUtils.lerp(r, gray, dynamicStrength));\n result[i + 1] = Math.round(ImageProcessUtils.lerp(g, gray, dynamicStrength));\n result[i + 2] = Math.round(ImageProcessUtils.lerp(b, gray, dynamicStrength));\n result[i + 3] = a;\n }\n\n return new ImageData(result, width, height);\n }\n\n /**\n * Canvas 2D褐色调效果实现\n */\n private applySepiaEffect(imageData: ImageData, strength: number, time: number): ImageData {\n const { data, width, height } = imageData;\n const result = new Uint8ClampedArray(data.length);\n\n // 计算动态强度\n const dynamicStrength = ImageProcessUtils.calculateDynamicStrength(strength, time);\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n const a = data[i + 3];\n\n // 使用工具类计算褐色调\n const [sepiaR, sepiaG, sepiaB] = ImageProcessUtils.applySepiaToPixel(r, g, b);\n\n // 根据动态强度混合原色和褐色调\n result[i] = Math.round(ImageProcessUtils.lerp(r, sepiaR, dynamicStrength));\n result[i + 1] = Math.round(ImageProcessUtils.lerp(g, sepiaG, dynamicStrength));\n result[i + 2] = Math.round(ImageProcessUtils.lerp(b, sepiaB, dynamicStrength));\n result[i + 3] = a;\n }\n\n return new ImageData(result, width, height);\n }\n\n /**\n * 重写主要渲染方法,添加CSS Filter快速路径\n */\n protected afterStageRender(stage: any, canvas: HTMLCanvasElement): HTMLCanvasElement | void | null | false {\n // 检查是否使用CSS Filter API作为快速路径\n if (this.canUseCSSFilter() && this.colorConfig.strength > 0) {\n const cssResult = this.applyCSSFilter(canvas);\n if (cssResult) {\n return cssResult;\n }\n }\n\n // 调用父类的智能渲染选择逻辑\n return super.afterStageRender(stage, canvas);\n }\n}\n"]}
@@ -0,0 +1,49 @@
1
+ import type { EasingType } from '@visactor/vrender-core';
2
+ import { HybridEffectBase } from './base/CustomEffectBase';
3
+ export interface ParticleConfig {
4
+ effectType?: 'explode' | 'vortex' | 'gravity';
5
+ count?: number;
6
+ size?: number;
7
+ strength?: number;
8
+ useWebGL: boolean;
9
+ }
10
+ export interface ParticleData {
11
+ x: number;
12
+ y: number;
13
+ originX: number;
14
+ originY: number;
15
+ vx: number;
16
+ vy: number;
17
+ r: number;
18
+ g: number;
19
+ b: number;
20
+ a: number;
21
+ life: number;
22
+ size: number;
23
+ }
24
+ export declare class Particle extends HybridEffectBase {
25
+ private particles;
26
+ private positionBuffer;
27
+ private colorBuffer;
28
+ private particleConfig;
29
+ constructor(from: null, to: null, duration: number, easing: EasingType, params: any);
30
+ protected getShaderSources(): {
31
+ vertex: string;
32
+ fragment: string;
33
+ } | null;
34
+ protected applyWebGLEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null;
35
+ protected applyCanvas2DEffect(canvas: HTMLCanvasElement): HTMLCanvasElement | null;
36
+ private extractParticles;
37
+ private updateParticles;
38
+ private applyParticleForces;
39
+ private applyGravityEffect;
40
+ private applyVortexEffect;
41
+ private updateParticleProperties;
42
+ private prepareAndDrawParticles;
43
+ private updateParticleBuffers;
44
+ private setParticleUniforms;
45
+ private cleanupTempBuffers;
46
+ private applyCanvas2DExplode;
47
+ private applyCanvas2DGravity;
48
+ private applyCanvas2DVortex;
49
+ }