(effects, seed, targetWidth, targetHeight)
| 1241 | } |
| 1242 | |
| 1243 | render(effects, seed, targetWidth, targetHeight) { |
| 1244 | if (!this.image) return; |
| 1245 | |
| 1246 | const width = targetWidth || this.imageWidth; |
| 1247 | const height = targetHeight || this.imageHeight; |
| 1248 | |
| 1249 | this.canvas.width = width; |
| 1250 | this.canvas.height = height; |
| 1251 | |
| 1252 | this.ctx.drawImage(this.image, 0, 0, width, height); |
| 1253 | |
| 1254 | const enabledEffects = effects.filter(e => e.enabled); |
| 1255 | if (enabledEffects.length === 0) return; |
| 1256 | |
| 1257 | this.imageData = this.ctx.getImageData(0, 0, width, height); |
| 1258 | const data = this.imageData.data; |
| 1259 | |
| 1260 | for (const effect of enabledEffects) { |
| 1261 | switch (effect.type) { |
| 1262 | case EFFECT_TYPES.NOISE: |
| 1263 | this._applyNoise(data, width, height, effect.params, seed); |
| 1264 | break; |
| 1265 | case EFFECT_TYPES.DITHER: |
| 1266 | this._applyDither(data, width, height, effect.params); |
| 1267 | break; |
| 1268 | case EFFECT_TYPES.HALFTONE: |
| 1269 | this._applyHalftone(data, width, height, effect.params); |
| 1270 | break; |
| 1271 | case EFFECT_TYPES.ASCII: |
| 1272 | this._applyAscii(width, height, effect.params); |
| 1273 | return; |
| 1274 | case EFFECT_TYPES.OVERLAY: |
| 1275 | break; |
| 1276 | } |
| 1277 | } |
| 1278 | |
| 1279 | this.ctx.putImageData(this.imageData, 0, 0); |
| 1280 | } |
| 1281 | |
| 1282 | _hash(x, y, seed) { |
| 1283 | const n = Math.sin(x * 12.9898 + y * 78.233 + seed) * 43758.5453; |
no test coverage detected