glitch-canvas
Version:
JavaScript library for applying a glitch effect to a canvas element
1 lines • 6.18 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).glitch=e()}(this,function(){"use strict";var t={amount:35,iterations:20,quality:30,seed:25};function e(e){var a,n,i;return"object"!=typeof(e=function(t){let e=!1;if(void 0!==t)try{e=JSON.parse(JSON.stringify(t))}catch(t){}return e}(e))&&(e={}),Object.keys(t).filter(t=>"iterations"!==t).forEach(s=>{"number"!=typeof e[s]||isNaN(e[s])?e[s]=t[s]:e[s]=(a=e[s],i=100,a<(n=0)?n:a>i?i:a),e[s]=Math.round(e[s])}),("number"!=typeof e.iterations||isNaN(e.iterations)||e.iterations<=0)&&(e.iterations=t.iterations),e.iterations=Math.round(e.iterations),e}class a{constructor(t=300,e=150){"undefined"==typeof window?(this.canvasEl={width:t,height:e},this.ctx=null):(this.canvasEl=document.createElement("canvas"),this.canvasEl.width=t,this.canvasEl.height=e,this.ctx=this.canvasEl.getContext("2d"))}getContext(){return this.ctx}toDataURL(t,e,a){if("function"!=typeof a)return this.canvasEl.toDataURL(t,e);a(this.canvasEl.toDataURL(t,e))}get width(){return this.canvasEl.width}set width(t){this.canvasEl.width=t}get height(){return this.canvasEl.height}set height(t){this.canvasEl.height=t}}function n(t){if(t instanceof HTMLImageElement){if(!t.naturalWidth||!t.naturalHeight||!1===t.complete)throw new Error("This this image hasn't finished loading: "+t.src);const e=new a(t.naturalWidth,t.naturalHeight),n=e.getContext("2d");n.drawImage(t,0,0,e.width,e.height);const i=n.getImageData(0,0,e.width,e.height);return i.data&&i.data.length&&(void 0===i.width&&(i.width=t.naturalWidth),void 0===i.height&&(i.height=t.naturalHeight)),i}throw new Error("This object does not seem to be an image.")}"undefined"!=typeof window&&(a.Image=Image);const i=a.Image;function s(t){return new Promise((e,a)=>{const n=new i;n.onload=(()=>{e(n)}),n.onerror=a;try{n.src=t}catch(t){a(t)}})}function r(t,e,a,n){s(t).then(a,n)}function o(t){return{width:t.width||t.naturalWidth,height:t.height||t.naturalHeight}}function h(t,e,n,i){s(t).then(t=>{const e=o(t),i=function(t){const e=o(t),n=new a(e.width,e.height),i=n.getContext("2d");return i.drawImage(t,0,0,e.width,e.height),{canvas:n,ctx:i}}(t).ctx.getImageData(0,0,e.width,e.height);i.width||(i.width=e.width),i.height||(i.height=e.height),n(i)},i)}const c=Object.assign;return function(t){let i,s;t=e(t);const o=new Worker(URL.createObjectURL(new Blob(['function isImageData(a){return a&&"number"==typeof a.width&&"number"==typeof a.height&&a.data&&"number"==typeof a.data.length&&"object"==typeof a.data}const base64Chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",base64Map$1=base64Chars.split(""),reversedBase64Map$1={};base64Map$1.forEach((a,e)=>{reversedBase64Map$1[a]=e});var maps={base64Map:base64Map$1,reversedBase64Map:reversedBase64Map$1};const reversedBase64Map=maps.reversedBase64Map;function base64ToByteArray(a){const e=[];let s;const t=a.replace("data:image/jpeg;base64,","");for(var r=0,i=t.length;r<i;r++){t[r];const a=reversedBase64Map[t[r]];switch(r%4){case 1:e.push(s<<2|a>>4);break;case 2:e.push((15&s)<<4|a>>2);break;case 3:e.push((3&s)<<6|a)}s=a}return e}function jpgHeaderLength(a){let e=417;for(let s=0,t=a.length;s<t;s++)if(255===a[s]&&218===a[s+1]){e=s+2;break}return e}function glitchByteArray(a,e,s,t){const r=jpgHeaderLength(a),i=a.length-r-4,n=s/100,p=e/100;for(var o=0;o<t;o++){const e=i/t*o|0;let s=e+((i/t*(o+1)|0)-e)*p|0;s>i&&(s=i),a[~~(r+s)]=~~(256*n)}return a}const base64Map=maps.base64Map;function byteArrayToBase64(a){const e=["data:image/jpeg;base64,"];let s,t;for(let r=0,i=a.length;r<i;r++){const i=a[r];switch(s=r%3){case 0:e.push(base64Map[i>>2]);break;case 1:e.push(base64Map[(3&t)<<4|i>>4]);break;case 2:e.push(base64Map[(15&t)<<2|i>>6]),e.push(base64Map[63&i])}t=i}return 0===s?(e.push(base64Map[(3&t)<<4]),e.push("==")):1===s&&(e.push(base64Map[(15&t)<<2]),e.push("=")),e.join("")}function glitchImageData(a,e,s){if(isImageData(a)){return byteArrayToBase64(glitchByteArray(base64ToByteArray(e),s.seed,s.amount,s.iterations))}throw new Error("glitchImageData: imageData seems to be corrupt.")}function fail(a){self.postMessage({err:a.message||a})}function success(a){self.postMessage({base64URL:a})}onmessage=(a=>{const e=a.data.imageData,s=a.data.params,t=a.data.base64URL;if(e&&t&&s)try{void 0===e.width&&"number"==typeof a.data.imageDataWidth&&(e.width=a.data.imageDataWidth),void 0===e.height&&"number"==typeof a.data.imageDataHeight&&(e.height=a.data.imageDataHeight),success(glitchImageData(e,t,s))}catch(a){fail(a)}else a.data.imageData?fail("Parameters are missing."):fail("ImageData is missing.");self.close()});'],{type:"text/javascript"}))),u={getParams:function(){return t},getInput:f,getOutput:m},g={fromImageData:function(t){return l(p,t)},fromImage:function(t){return l(n,t)}},d={toImage:function(t){return b(r,t,!0)},toDataURL:function(t){return b(p)},toImageData:function(t){return b(h,t,!0)}};function f(){const t=c({},u);return i||c(t,g),t}function m(){const t=c({},u);return s||c(t,d),t}function p(t){return t}function l(t,e,a){return i=(()=>new Promise((n,i)=>{if(a)t(e,n,i);else if(t===p)n(e);else try{n(t(e,n,i))}catch(t){i(t)}})),w()?y():m()}function b(t,e,a){return s=(n=>new Promise((i,s)=>{a?t(n,e,i,s):t===p?i(n):t(n,e).then(i,s)})),w()?y():f()}function w(){return i&&s}function y(){return new Promise((e,n)=>{i().then(e=>(function(t,e){return new Promise((n,i)=>{(function(t,e){return new Promise((n,i)=>{if(function(t){return t&&"number"==typeof t.width&&"number"==typeof t.height&&t.data&&"number"==typeof t.data.length&&"object"==typeof t.data}(t)){const i=new a(t.width,t.height);i.getContext("2d").putImageData(t,0,0),n(i.toDataURL("image/jpeg",e/100))}else i(new Error("object is not valid imageData"))})})(t,e.quality).then(a=>(function(t,e,a){return new Promise((n,i)=>{o.addEventListener("message",t=>{t.data&&t.data.base64URL?n(t.data.base64URL):t.data&&t.data.err?i(t.data.err):i(t)}),o.postMessage({params:a,base64URL:e,imageData:t,imageDataWidth:t.width,imageDataHeight:t.height})})})(t,a,e),i).then(n,i)})})(e,t),n).then(t=>{s(t).then(e,n)},n)})}return f()}});