unlazy
Version:
Universal lazy loading library for placeholder images leveraging native browser APIs
12 lines (11 loc) • 7.71 kB
JavaScript
var UnLazy=function(g){"use strict";var pe;const te=new Uint8Array(128);for(let e=0;e<83;e++)te["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(e)]=e;const D=(e,t,n)=>{let o=0;for(;t<n;)o*=83,o+=te[e.charCodeAt(t++)];return o},re=Math.pow,G=Math.PI,we=G*2,ne=3294.6,oe=269.025,Ee=e=>e>10.31475?re(e/oe+.052132,2.4):e/ne,K=e=>~~(e>1227e-8?oe*re(e,.416666)-13.025:e*ne+1),T=e=>(e<0?-1:1)*e*e,se=e=>{for(e+=G/2;e>G;)e-=we;const t=1.27323954*e-.405284735*T(e);return .225*(T(t)-t)+t};function Se(e){const t=D(e,2,6);return[t>>16,t>>8&255,t&255]}function he(e,t,n,o){const c=D(e,0,1),s=c%9+1,i=~~(c/9)+1,d=s*i;let r=0,p=0,f=0,u=0,a=0,y=0,O=0,S=0,L=0,A=0,h=0,C=0;const P=(D(e,1,2)+1)/13446*(o|1),w=new Float64Array(d*3),m=Se(e);for(r=0;r<3;r++)w[r]=Ee(m[r]);for(r=1;r<d;r++)C=D(e,4+r*2,6+r*2),w[r*3]=T(~~(C/361)-9)*P,w[r*3+1]=T(~~(C/19)%19-9)*P,w[r*3+2]=T(C%19-9)*P;const Y=new Float64Array(i*n),$=new Float64Array(s*t);for(p=0;p<i;p++)for(u=0;u<n;u++)Y[p*n+u]=se(G*u*p/n);for(r=0;r<s;r++)for(f=0;f<t;f++)$[r*t+f]=se(G*f*r/t);const j=t*4,v=new Uint8ClampedArray(j*n);for(u=0;u<n;u++)for(f=0;f<t;f++){for(a=y=O=0,p=0;p<i;p++)for(L=Y[p*n+u],r=0;r<s;r++)S=$[r*t+f]*L,A=(r+p*s)*3,a+=w[A]*S,y+=w[A+1]*S,O+=w[A+2]*S;h=4*f+u*j,v[h]=K(a),v[h+1]=K(y),v[h+2]=K(O),v[h+3]=255}return v}const Q=32,ve="data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3C/svg%3E";/**
* Encodes an RGBA image to a PNG data URI. RGB should not be premultiplied by A.
*
* @remarks
* This is optimized for speed and simplicity and does not optimize for size
* at all. This does not do any compression (all values are stored uncompressed).
*
* @see https://github.com/evanw/thumbhash
* @author Evan Wallace
* @license MIT
*/function ce(e,t,n){const o=e*4+1,c=6+t*(5+o),s=[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,e>>8,e&255,0,0,t>>8,t&255,8,6,0,0,0,0,0,0,0,c>>>24,c>>16&255,c>>8&255,c&255,73,68,65,84,120,1],i=[0,498536548,997073096,651767980,1994146192,1802195444,1303535960,1342533948,-306674912,-267414716,-690576408,-882789492,-1687895376,-2032938284,-1609899400,-1111625188];let d=1,r=0;for(let f=0,u=0,a=o-1;f<t;f++,a+=o-1)for(s.push(f+1<t?0:1,o&255,o>>8,~o&255,o>>8^255,0),r=(r+d)%65521;u<a;u++){const y=n[u]&255;s.push(y),d=(d+y)%65521,r=(r+d)%65521}s.push(r>>8,r&255,d>>8,d&255,0,0,0,0,0,0,0,0,73,69,78,68,174,66,96,130);for(let[f,u]of[[12,29],[37,41+c]]){let a=-1;for(let y=f;y<u;y++)a^=s[y],a=a>>>4^i[a&15],a=a>>>4^i[a&15];a=~a,s[u++]=a>>>24,s[u++]=a>>16&255,s[u++]=a>>8&255,s[u++]=a&255}return`data:image/png;base64,${globalThis.btoa(String.fromCharCode(...s))}`}function ze(e,{ratio:t=1,size:n=Q}={}){const{width:o,height:c}=ge(t,n),s=he(e,o,c);return ce(o,c,s)}function ge(e,t){const n=e>=1;return{width:n?t:Math.round(t*e),height:n?Math.round(t/e):t}}function Le(e){let{PI:t,min:n,max:o,cos:c,round:s}=Math,i=e[0]|e[1]<<8|e[2]<<16,d=e[3]|e[4]<<8,r=(i&63)/63,p=(i>>6&63)/31.5-1,f=(i>>12&63)/31.5-1,u=(i>>18&31)/31,a=i>>23,y=(d>>3&63)/63,O=(d>>9&63)/63,S=d>>15,L=o(3,S?a?5:7:d&7),A=o(3,S?d&7:a?5:7),h=a?(e[5]&15)/15:1,C=(e[5]>>4)/15,P=a?6:5,w=0,m=(M,E,N)=>{let x=[];for(let z=0;z<E;z++)for(let U=z?0:1;U*E<M*(E-z);U++)x.push(((e[P+(w>>1)]>>((w++&1)<<2)&15)/7.5-1)*N);return x},Y=m(L,A,u),$=m(3,3,y*1.25),j=m(3,3,O*1.25),v=a&&m(5,5,C),Z=Ce(e),k=s(Z>1?32:32*Z),X=s(Z>1?32/Z:32),I=new Uint8Array(k*X*4),V=[],J=[];for(let M=0,E=0;M<X;M++)for(let N=0;N<k;N++,E+=4){let x=r,z=p,U=f,be=h;for(let l=0,b=o(L,a?5:3);l<b;l++)V[l]=c(t/k*(N+.5)*l);for(let l=0,b=o(A,a?5:3);l<b;l++)J[l]=c(t/X*(M+.5)*l);for(let l=0,b=0;l<A;l++)for(let _=l?0:1,R=J[l]*2;_*A<L*(A-l);_++,b++)x+=Y[b]*V[_]*R;for(let l=0,b=0;l<3;l++)for(let _=l?0:1,R=J[l]*2;_<3-l;_++,b++){let Ae=V[_]*R;z+=$[b]*Ae,U+=j[b]*Ae}if(a)for(let l=0,b=0;l<5;l++)for(let _=l?0:1,R=J[l]*2;_<5-l;_++,b++)be+=v[b]*V[_]*R;let ye=x-2/3*z,_e=(3*x-ye+U)/2,Ne=_e-U;I[E]=o(0,255*n(1,_e)),I[E+1]=o(0,255*n(1,Ne)),I[E+2]=o(0,255*n(1,ye)),I[E+3]=o(0,255*n(1,be))}return{w:k,h:X,rgba:I}}function Ce(e){let t=e[3],n=e[2]&128,o=e[4]&128,c=o?n?5:7:t&7,s=o?t&7:n?5:7;return c/s}function me(e){const t=xe(e),{w:n,h:o,rgba:c}=Le(t);return ce(n,o,c)}function xe(e){return Uint8Array.from(globalThis.atob(Ue(e)),t=>t.charCodeAt(0))}function Ue(e){return e.replaceAll("-","+").replaceAll("_","/")}const ae=typeof window>"u",Ge=!ae&&"loading"in HTMLImageElement.prototype,Te=!ae&&(!("onscroll"in window)||/(?:gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent));function le(e,t=document){return typeof e=="string"?[...t.querySelectorAll(e)]:e instanceof Element?[e]:[...e]}function Oe(e){const t=Date.now();return ve.replace(/\s/,` data-id='${t}-${e}' `)}function Pe(e,t){let n;return function(...o){n!=null&&clearTimeout(n),n=setTimeout(()=>{e(...o),n=void 0},t)}}function ee(e='img[loading="lazy"]',{hash:t=!0,hashType:n="blurhash",placeholderSize:o=Q,updateSizesOnResize:c=!1,onImageLoad:s}={}){const i=new Set;for(const[d,r]of le(e).entries()){const p=B(r,{updateOnResize:c});if(c&&p&&i.add(p),t){const u=Ie({image:r,hash:typeof t=="string"?t:void 0,hashType:n,size:o});u&&(r.src=u)}if(!r.dataset.src&&!r.dataset.srcset){(typeof __UNLAZY_LOGGING__>"u"||__UNLAZY_LOGGING__)&&console.error("[unlazy] Missing `data-src` or `data-srcset` attribute",r);continue}if(Te||!Ge){ue(r),W(r),F(r);continue}if(r.src||(r.src=Oe(d)),r.complete&&r.naturalWidth>0){H(r,s);continue}const f=()=>H(r,s);r.addEventListener("load",f,{once:!0}),i.add(()=>r.removeEventListener("load",f))}return()=>{for(const d of i)d();i.clear()}}function ie(e='img[data-sizes="auto"], source[data-sizes="auto"]'){for(const t of le(e))B(t)}function H(e,t){if(de(e)){ue(e),W(e),F(e),t==null||t(e);return}const n=new Image,{srcset:o,src:c,sizes:s}=e.dataset;if(s==="auto"){const i=fe(e);i&&(n.sizes=`${i}px`)}else e.sizes&&(n.sizes=e.sizes);o&&(n.srcset=o),c&&(n.src=c),n.addEventListener("load",()=>{W(e),F(e),t==null||t(e)},{once:!0})}function Ie({image:e,hash:t,hashType:n="blurhash",size:o=Q,ratio:c}={}){if(e&&!t){const{blurhash:s,thumbhash:i}=e.dataset;t=i||s,n=i?"thumbhash":"blurhash"}if(t)try{if(n==="blurhash"){if(e&&!c){const s=e.width||e.offsetWidth||o,i=e.height||e.offsetHeight||o;c=s/i}return ze(t,{ratio:c,size:o})}return me(t)}catch(s){(typeof __UNLAZY_LOGGING__>"u"||__UNLAZY_LOGGING__)&&console.error(`[unlazy] Failed to generate ${n} placeholder:`,s)}}const q=new WeakMap;function B(e,t){if(e.dataset.sizes!=="auto")return;const n=fe(e);if(n&&(e.sizes=`${n}px`),de(e)&&(t!=null&&t.processSourceElements))for(const o of[...e.parentElement.getElementsByTagName("source")])B(o,{processSourceElements:!0});if(t!=null&&t.updateOnResize){if(!q.has(e)){const o=Pe(()=>B(e),500),c=new ResizeObserver(o);q.set(e,c),c.observe(e)}return()=>{const o=q.get(e);o&&(o.disconnect(),q.delete(e))}}}function F(e){e.dataset.src&&(e.src=e.dataset.src,e.removeAttribute("data-src"))}function W(e){e.dataset.srcset&&(e.srcset=e.dataset.srcset,e.removeAttribute("data-srcset"))}function ue(e){const t=e.parentElement;(t==null?void 0:t.tagName.toLowerCase())==="picture"&&([...t.querySelectorAll("source[data-srcset]")].forEach(W),[...t.querySelectorAll("source[data-src]")].forEach(F))}function fe(e){var t,n;return e instanceof HTMLSourceElement?(n=(t=e.parentElement)==null?void 0:t.getElementsByTagName("img")[0])==null?void 0:n.offsetWidth:e.offsetWidth}function de(e){var t;return((t=e.parentElement)==null?void 0:t.tagName.toLowerCase())==="picture"}const Me=Object.freeze({autoSizes:ie,lazyLoad:ee,loadImage:H});return(pe=document.currentScript)!=null&&pe.hasAttribute("init")&&ee(),g.autoSizes=ie,g.default=Me,g.lazyLoad=ee,g.loadImage=H,Object.defineProperties(g,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),g}({});