@hirasso/thumbhash-custom-element
Advanced tools
Comparing version 0.0.2 to 0.1.0
@@ -1,2 +0,2 @@ | ||
import{thumbHashToRGBA as t}from"thumbhash";class e extends HTMLElement{constructor(){super()}static init(){window.customElements.get("thumb-hash")||customElements.define("thumb-hash",e)}connectedCallback(){const t=this.value.trim();t&&this.render(t)}get value(){return this.getAttribute("value")||""}render(e){const a=Uint8Array.from(atob(e),t=>t.charCodeAt(0)),{w:s,h:n,rgba:r}=t(a),h=function(t,e,a){const s=document.createElement("canvas"),n=s.getContext("2d");if(!n)return;s.width=t,s.height=e;const r=n.createImageData(t,e);return r.data.set(a),n.putImageData(r,0,0),s}(s,n,r);h&&(h.style.width="100%",h.style.height="100%",h.setAttribute("data-thumb-hash-canvas",""),this.appendChild(h))}}export{e as default}; | ||
import{thumbHashToRGBA as t,thumbHashToAverageRGBA as e}from"thumbhash";function a(e){const a=Uint8Array.from(atob(e),t=>t.charCodeAt(0)),{w:s,h,rgba:i}=t(a);return{width:s,height:h,pixels:i}}class s extends HTMLElement{constructor(){super(),this.canvas=void 0,this.shadowRoot=void 0,this.shadowRoot=this.attachShadow({mode:"open"}),this.canvas=document.createElement("canvas"),this.canvas.style.width="100%",this.canvas.style.height="100%",this.setAttribute("aria-hidden","true")}static init(){window.customElements.get("thumb-hash")||customElements.define("thumb-hash",s)}connectedCallback(){const t=this.value.trim();t&&(this.average?this.renderAverage(t):this.renderCanvas(t))}get value(){return this.getAttribute("value")||""}get average(){return!!this.getAttribute("average")}renderCanvas(t){const{width:e,height:s,pixels:h}=a(t),i=this.canvas.getContext("2d");if(!i)return;this.canvas.width=e,this.canvas.height=s;const n=i.createImageData(e,s);n.data.set(h),i.putImageData(n,0,0),this.shadowRoot.appendChild(this.canvas)}renderAverage(t){const s=function(t){const{pixels:s}=a(t),{r:h,g:i,b:n}=e(s);return`rgb(${Math.round(255*h)} ${Math.round(255*i)} ${Math.round(255*n)})`}(t),h=document.createElement("div");h.style.width="100%",h.style.height="100%",h.style.background=s,this.shadowRoot.appendChild(h)}}export{s as default}; | ||
//# sourceMappingURL=index.modern.js.map |
@@ -1,2 +0,2 @@ | ||
import{thumbHashToRGBA as t}from"thumbhash";class e extends HTMLElement{constructor(){super()}static init(){window.customElements.get("thumb-hash")||customElements.define("thumb-hash",e)}connectedCallback(){const t=this.value.trim();t&&this.render(t)}get value(){return this.getAttribute("value")||""}render(e){const a=Uint8Array.from(atob(e),t=>t.charCodeAt(0)),{w:s,h:n,rgba:r}=t(a),h=function(t,e,a){const s=document.createElement("canvas"),n=s.getContext("2d");if(!n)return;s.width=t,s.height=e;const r=n.createImageData(t,e);return r.data.set(a),n.putImageData(r,0,0),s}(s,n,r);h&&(h.style.width="100%",h.style.height="100%",h.setAttribute("data-thumb-hash-canvas",""),this.appendChild(h))}}export{e as default}; | ||
import{thumbHashToRGBA as t,thumbHashToAverageRGBA as e}from"thumbhash";function a(e){const a=Uint8Array.from(atob(e),t=>t.charCodeAt(0)),{w:s,h:h,rgba:i}=t(a);return{width:s,height:h,pixels:i}}class s extends HTMLElement{constructor(){super(),this.canvas=void 0,this.shadowRoot=void 0,this.shadowRoot=this.attachShadow({mode:"open"}),this.canvas=document.createElement("canvas"),this.canvas.style.width="100%",this.canvas.style.height="100%",this.setAttribute("aria-hidden","true")}static init(){window.customElements.get("thumb-hash")||customElements.define("thumb-hash",s)}connectedCallback(){const t=this.value.trim();t&&(this.average?this.renderAverage(t):this.renderCanvas(t))}get value(){return this.getAttribute("value")||""}get average(){return!!this.getAttribute("average")}renderCanvas(t){const{width:e,height:s,pixels:h}=a(t),i=this.canvas.getContext("2d");if(!i)return;this.canvas.width=e,this.canvas.height=s;const n=i.createImageData(e,s);n.data.set(h),i.putImageData(n,0,0),this.shadowRoot.appendChild(this.canvas)}renderAverage(t){const s=function(t){const{pixels:s}=a(t),{r:h,g:i,b:n}=e(s);return`rgb(${Math.round(255*h)} ${Math.round(255*i)} ${Math.round(255*n)})`}(t),h=document.createElement("div");h.style.width="100%",h.style.height="100%",h.style.background=s,this.shadowRoot.appendChild(h)}}export{s as default}; | ||
//# sourceMappingURL=index.module.js.map |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t||self).ThumbhashCustomElement=e()}(this,function(){class t extends HTMLElement{constructor(){super()}static init(){window.customElements.get("thumb-hash")||customElements.define("thumb-hash",t)}connectedCallback(){const t=this.value.trim();t&&this.render(t)}get value(){return this.getAttribute("value")||""}render(t){const e=Uint8Array.from(atob(t),t=>t.charCodeAt(0)),{w:n,h:r,rgba:o}=function(t){let{PI:e,min:n,max:r,cos:o,round:a}=Math,l=t[0]|t[1]<<8|t[2]<<16,s=t[3]|t[4]<<8,i=(63&l)/63,u=(l>>6&63)/31.5-1,f=(l>>12&63)/31.5-1,h=(l>>18&31)/31,c=l>>23,d=(s>>3&63)/63,m=(s>>9&63)/63,b=s>>15,g=r(3,b?c?5:7:7&s),p=r(3,b?7&s:c?5:7),y=c?(15&t[5])/15:1,w=(t[5]>>4)/15,v=c?6:5,x=0,A=(e,n,r)=>{let o=[];for(let a=0;a<n;a++)for(let l=a?0:1;l*n<e*(n-a);l++)o.push(((t[v+(x>>1)]>>((1&x++)<<2)&15)/7.5-1)*r);return o},C=A(g,p,h),E=A(3,3,1.25*d),T=A(3,3,1.25*m),I=c&&A(5,5,w),D=function(t){let e=t[3],n=128&t[2],r=128&t[4];return(r?n?5:7:7&e)/(r?7&e:n?5:7)}(t),M=a(D>1?32:32*D),U=a(D>1?32/D:32),j=new Uint8Array(M*U*4),k=[],H=[];for(let t=0,a=0;t<U;t++)for(let l=0;l<M;l++,a+=4){let s=i,h=u,d=f,m=y;for(let t=0,n=r(g,c?5:3);t<n;t++)k[t]=o(e/M*(l+.5)*t);for(let n=0,a=r(p,c?5:3);n<a;n++)H[n]=o(e/U*(t+.5)*n);for(let t=0,e=0;t<p;t++)for(let n=t?0:1,r=2*H[t];n*p<g*(p-t);n++,e++)s+=C[e]*k[n]*r;for(let t=0,e=0;t<3;t++)for(let n=t?0:1,r=2*H[t];n<3-t;n++,e++){let t=k[n]*r;h+=E[e]*t,d+=T[e]*t}if(c)for(let t=0,e=0;t<5;t++)for(let n=t?0:1,r=2*H[t];n<5-t;n++,e++)m+=I[e]*k[n]*r;let b=s-2/3*h,w=(3*s-b+d)/2,v=w-d;j[a]=r(0,255*n(1,w)),j[a+1]=r(0,255*n(1,v)),j[a+2]=r(0,255*n(1,b)),j[a+3]=r(0,255*n(1,m))}return{w:M,h:U,rgba:j}}(e),a=function(t,e,n){const r=document.createElement("canvas"),o=r.getContext("2d");if(!o)return;r.width=t,r.height=e;const a=o.createImageData(t,e);return a.data.set(n),o.putImageData(a,0,0),r}(n,r,o);a&&(a.style.width="100%",a.style.height="100%",a.setAttribute("data-thumb-hash-canvas",""),this.appendChild(a))}}return t}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t||self).ThumbhashCustomElement=e()}(this,function(){function t(t){const e=Uint8Array.from(atob(t),t=>t.charCodeAt(0)),{w:n,h:a,rgba:r}=function(t){let{PI:e,min:n,max:a,cos:r,round:o}=Math,s=t[0]|t[1]<<8|t[2]<<16,i=t[3]|t[4]<<8,h=(63&s)/63,d=(s>>6&63)/31.5-1,l=(s>>12&63)/31.5-1,u=(s>>18&31)/31,c=s>>23,f=(i>>3&63)/63,g=(i>>9&63)/63,m=i>>15,v=a(3,m?c?5:7:7&i),b=a(3,m?7&i:c?5:7),p=c?(15&t[5])/15:1,w=(t[5]>>4)/15,y=c?6:5,x=0,A=(e,n,a)=>{let r=[];for(let o=0;o<n;o++)for(let s=o?0:1;s*n<e*(n-o);s++)r.push(((t[y+(x>>1)]>>((1&x++)<<2)&15)/7.5-1)*a);return r},C=A(v,b,u),E=A(3,3,1.25*f),M=A(3,3,1.25*g),R=c&&A(5,5,w),T=function(t){let e=t[3],n=128&t[2],a=128&t[4];return(a?n?5:7:7&e)/(a?7&e:n?5:7)}(t),I=o(T>1?32:32*T),$=o(T>1?32/T:32),k=new Uint8Array(I*$*4),D=[],U=[];for(let t=0,o=0;t<$;t++)for(let s=0;s<I;s++,o+=4){let i=h,u=d,f=l,g=p;for(let t=0,n=a(v,c?5:3);t<n;t++)D[t]=r(e/I*(s+.5)*t);for(let n=0,o=a(b,c?5:3);n<o;n++)U[n]=r(e/$*(t+.5)*n);for(let t=0,e=0;t<b;t++)for(let n=t?0:1,a=2*U[t];n*b<v*(b-t);n++,e++)i+=C[e]*D[n]*a;for(let t=0,e=0;t<3;t++)for(let n=t?0:1,a=2*U[t];n<3-t;n++,e++){let t=D[n]*a;u+=E[e]*t,f+=M[e]*t}if(c)for(let t=0,e=0;t<5;t++)for(let n=t?0:1,a=2*U[t];n<5-t;n++,e++)g+=R[e]*D[n]*a;let m=i-2/3*u,w=(3*i-m+f)/2,y=w-f;k[o]=a(0,255*n(1,w)),k[o+1]=a(0,255*n(1,y)),k[o+2]=a(0,255*n(1,m)),k[o+3]=a(0,255*n(1,g))}return{w:I,h:$,rgba:k}}(e);return{width:n,height:a,pixels:r}}class e extends HTMLElement{constructor(){super(),this.canvas=void 0,this.shadowRoot=void 0,this.shadowRoot=this.attachShadow({mode:"open"}),this.canvas=document.createElement("canvas"),this.canvas.style.width="100%",this.canvas.style.height="100%",this.setAttribute("aria-hidden","true")}static init(){window.customElements.get("thumb-hash")||customElements.define("thumb-hash",e)}connectedCallback(){const t=this.value.trim();t&&(this.average?this.renderAverage(t):this.renderCanvas(t))}get value(){return this.getAttribute("value")||""}get average(){return!!this.getAttribute("average")}renderCanvas(e){const{width:n,height:a,pixels:r}=t(e),o=this.canvas.getContext("2d");if(!o)return;this.canvas.width=n,this.canvas.height=a;const s=o.createImageData(n,a);s.data.set(r),o.putImageData(s,0,0),this.shadowRoot.appendChild(this.canvas)}renderAverage(e){const n=function(e){const{pixels:n}=t(e),{r:a,g:r,b:o}=function(t){let{min:e,max:n}=Math,a=t[0]|t[1]<<8|t[2]<<16,r=(63&a)/63,o=(a>>12&63)/31.5-1,s=a>>23?(15&t[5])/15:1,i=r-2/3*((a>>6&63)/31.5-1),h=(3*r-i+o)/2,d=h-o;return{r:n(0,e(1,h)),g:n(0,e(1,d)),b:n(0,e(1,i)),a:s}}(n);return`rgb(${Math.round(255*a)} ${Math.round(255*r)} ${Math.round(255*o)})`}(e),a=document.createElement("div");a.style.width="100%",a.style.height="100%",a.style.background=n,this.shadowRoot.appendChild(a)}}return e}); | ||
//# sourceMappingURL=index.umd.js.map |
@@ -1,3 +0,3 @@ | ||
import { ThumbHashElement } from "./ThumbhashElement.js"; | ||
import { ThumbHashElement } from "./ThumbHashElement.js"; | ||
export default ThumbHashElement; | ||
//# sourceMappingURL=index.d.ts.map |
{ | ||
"name": "@hirasso/thumbhash-custom-element", | ||
"amdName": "ThumbhashCustomElement", | ||
"version": "0.0.2", | ||
"version": "0.1.0", | ||
"description": "A custom element that renders a thumbhash placeholder for your lazy-loaded images 🎨", | ||
@@ -33,17 +33,2 @@ "author": { | ||
], | ||
"scripts": { | ||
"clean": "rm -rf ./dist", | ||
"format": "npx prettier 'src/**/*.{js,ts,mjs}' --write", | ||
"prepublishOnly": "npm run build", | ||
"build": "npm run clean && npm run build:module && npm run build:bundle", | ||
"build:module": "BROWSERSLIST_ENV=modern microbundle src/index.ts --format modern,esm,cjs", | ||
"build:bundle": "BROWSERSLIST_ENV=production microbundle src/index.ts --format umd --external none", | ||
"watch": "BROWSERSLIST_ENV=development microbundle src/index.ts --watch --format modern", | ||
"docs:dev": "astro dev --root docs", | ||
"docs:build": "astro build --root docs", | ||
"docs:serve": "astro build --root docs && astro preview --root docs", | ||
"test": "npm run test:e2e", | ||
"test:e2e": "npx playwright test --config ./tests/e2e/config.playwright.ts", | ||
"test:e2e:dev": "PLAYWRIGHT_ENV=dev npm run test:e2e -- --ui" | ||
}, | ||
"dependencies": { | ||
@@ -61,3 +46,18 @@ "thumbhash": "^0.1.1" | ||
"typescript": "^5.3.2" | ||
}, | ||
"scripts": { | ||
"preinstall": "npx only-allow pnpm", | ||
"clean": "rm -rf ./dist", | ||
"format": "npx prettier 'src/**/*.{js,ts,mjs}' --write", | ||
"build": "pnpm clean && pnpm build:module && pnpm build:bundle", | ||
"build:module": "BROWSERSLIST_ENV=modern microbundle src/index.ts --format modern,esm,cjs", | ||
"build:bundle": "BROWSERSLIST_ENV=production microbundle src/index.ts --format umd --external none", | ||
"watch": "BROWSERSLIST_ENV=development microbundle src/index.ts --watch --format modern", | ||
"docs:dev": "astro dev --root docs", | ||
"docs:build": "astro build --root docs", | ||
"docs:serve": "astro build --root docs && astro preview --root docs", | ||
"test": "pnpm test:e2e", | ||
"test:e2e": "npx playwright test --config ./tests/e2e/config.playwright.ts", | ||
"test:e2e:dev": "PLAYWRIGHT_ENV=dev pnpm test:e2e -- --ui" | ||
} | ||
} | ||
} |
@@ -42,3 +42,3 @@ # <thumb-hash> | ||
<figure> | ||
+ <thumb-hash value="YTkGJwaRhWUIt4lbgnhZl3ath2BUBGYA" aria-hidden="true"></thumb-hash> | ||
+ <thumb-hash value="YTkGJwaRhWUIt4lbgnhZl3ath2BUBGYA" /> | ||
<img src="https://example.com/image.jpg" loading="lazy" width="32" height="32" alt="My large lazy-loaded image"> | ||
@@ -52,4 +52,5 @@ </figure> | ||
<figure> | ||
+ <thumb-hash value="YTkGJwaRhWUIt4lbgnhZl3ath2BUBGYA" aria-hidden="true"> | ||
+ <canvas width="32" height="32" data-thumb-hash-canvas style="width: 100%; height: 100%;"></canvas> | ||
+ <thumb-hash value="YTkGJwaRhWUIt4lbgnhZl3ath2BUBGYA"> | ||
+ ⇩#shadow-root (open) | ||
+ <canvas width="32" height="32" style="width: 100%; height: 100%;"></canvas> | ||
+ </thumb-hash> | ||
@@ -76,2 +77,25 @@ <img src="https://example.com/image.jpg" loading="lazy" width="32" height="32" alt="My large lazy-loaded image"> | ||
} | ||
``` | ||
### Average color | ||
If you add the boolean attribute `average` to your `<thumb-hash />`, the average color of the image will be rendered instead of the blurry thumbhash image: | ||
```diff | ||
<figure> | ||
+ <thumb-hash average value="YTkGJwaRhWUIt4lbgnhZl3ath2BUBGYA" /> | ||
<img src="https://example.com/image.jpg" loading="lazy" width="32" height="32" alt="My large lazy-loaded image"> | ||
</figure> | ||
``` | ||
The custom element will automatically create a canvas with the thumbhash image for you: | ||
```diff | ||
<figure> | ||
+ <thumb-hash average value="YTkGJwaRhWUIt4lbgnhZl3ath2BUBGYA"> | ||
+ ⇩#shadow-root (open) | ||
+ <div style="width: 100%; height: 100%; background: rgb(111, 51, 0);"></div> | ||
+ </thumb-hash> | ||
<img src="https://example.com/image.jpg" loading="lazy" width="32" height="32" alt="My large lazy-loaded image"> | ||
</figure> | ||
``` |
@@ -1,3 +0,3 @@ | ||
import { ThumbHashElement } from "./ThumbhashElement.js"; | ||
import { ThumbHashElement } from "./ThumbHashElement.js"; | ||
export default ThumbHashElement; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
86340
163
98
1
1