@hirasso/thumbhash-custom-element
Advanced tools
Comparing version 0.1.0 to 0.1.1
@@ -1,2 +0,2 @@ | ||
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}; | ||
import{thumbHashToRGBA as t,thumbHashToAverageRGBA as e}from"thumbhash";function a(t){return Uint8Array.from(atob(t),t=>t.charCodeAt(0))}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(e){const{width:s,height:h,pixels:n}=function(e){const{w:s,h,rgba:n}=t(a(e));return{width:s,height:h,pixels:n}}(e),i=this.canvas.getContext("2d");if(!i)return;this.canvas.width=s,this.canvas.height=h;const r=i.createImageData(s,h);r.data.set(n),i.putImageData(r,0,0),this.shadowRoot.appendChild(this.canvas)}renderAverage(t){const s=function(t){const{r:s,g:h,b:n}=e(a(t));return`rgb(${Math.round(255*s)} ${Math.round(255*h)} ${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,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}; | ||
import{thumbHashToRGBA as t,thumbHashToAverageRGBA as e}from"thumbhash";function a(t){return Uint8Array.from(atob(t),t=>t.charCodeAt(0))}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(e){const{width:s,height:h,pixels:n}=function(e){const{w:s,h:h,rgba:n}=t(a(e));return{width:s,height:h,pixels:n}}(e),i=this.canvas.getContext("2d");if(!i)return;this.canvas.width=s,this.canvas.height=h;const r=i.createImageData(s,h);r.data.set(n),i.putImageData(r,0,0),this.shadowRoot.appendChild(this.canvas)}renderAverage(t){const s=function(t){const{r:s,g:h,b:n}=e(a(t));return`rgb(${Math.round(255*s)} ${Math.round(255*h)} ${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(){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}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t||self).ThumbhashCustomElement={})}(this,function(t){function e(t){return Uint8Array.from(atob(t),t=>t.charCodeAt(0))}class n 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",n)}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:n,height:a,pixels:r}=function(t){const{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,m=(i>>9&63)/63,g=i>>15,v=a(3,g?c?5:7:7&i),b=a(3,g?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*m),T=c&&A(5,5,w),R=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(R>1?32:32*R),$=o(R>1?32/R:32),k=new Uint8Array(I*$*4),D=[],H=[];for(let t=0,o=0;t<$;t++)for(let s=0;s<I;s++,o+=4){let i=h,u=d,f=l,m=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++)H[n]=r(e/$*(t+.5)*n);for(let t=0,e=0;t<b;t++)for(let n=t?0:1,a=2*H[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*H[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*H[t];n<5-t;n++,e++)m+=T[e]*D[n]*a;let g=i-2/3*u,w=(3*i-g+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,g)),k[o+3]=a(0,255*n(1,m))}return{w:I,h:$,rgba:k}}(e(t));return{width:n,height:a,pixels:r}}(t),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(t){const n=function(t){const{r:n,g:a,b:r}=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}}(e(t));return`rgb(${Math.round(255*n)} ${Math.round(255*a)} ${Math.round(255*r)})`}(t),a=document.createElement("div");a.style.width="100%",a.style.height="100%",a.style.background=n,this.shadowRoot.appendChild(a)}}t.ThumbHashElement=n}); | ||
//# sourceMappingURL=index.umd.js.map |
{ | ||
"name": "@hirasso/thumbhash-custom-element", | ||
"amdName": "ThumbhashCustomElement", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"description": "A custom element that renders a thumbhash placeholder for your lazy-loaded images 🎨", | ||
@@ -37,10 +37,15 @@ "author": { | ||
"devDependencies": { | ||
"@astrojs/mdx": "^1.1.5", | ||
"@playwright/test": "^1.40.1", | ||
"astro": "^3.6.4", | ||
"astro-expressive-code": "^0.29.2", | ||
"@astrojs/mdx": "^3.1.7", | ||
"@changesets/cli": "^2.27.9", | ||
"@playwright/test": "^1.47.2", | ||
"astro": "^4.15.9", | ||
"astro-expressive-code": "^0.37.0", | ||
"astro-feather": "^1.0.0", | ||
"canvas": "^2.11.2", | ||
"jsdom": "^25.0.1", | ||
"microbundle": "^0.15.1", | ||
"prettier": "^3.1.0", | ||
"typescript": "^5.3.2" | ||
"prettier": "^3.3.3", | ||
"sharp": "^0.33.5", | ||
"typescript": "^5.6.2", | ||
"vitest": "^2.1.1" | ||
}, | ||
@@ -50,6 +55,6 @@ "scripts": { | ||
"clean": "rm -rf ./dist", | ||
"format": "npx prettier 'src/**/*.{js,ts,mjs}' --write", | ||
"build": "pnpm clean && pnpm build:module && pnpm build:bundle", | ||
"format": "pnpm exec prettier 'src/**/*.{js,ts,mjs}' --write", | ||
"build": "pnpm run clean && pnpm run build:module && pnpm 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", | ||
"build:bundle": "BROWSERSLIST_ENV=production microbundle src/ThumbHashElement.ts --format umd --external none", | ||
"watch": "BROWSERSLIST_ENV=development microbundle src/index.ts --watch --format modern", | ||
@@ -59,6 +64,9 @@ "docs:dev": "astro dev --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" | ||
"test": "pnpm run test:unit && pnpm run test:e2e", | ||
"test:unit": "vitest run --config ./tests/unit/vitest.config.ts", | ||
"test:unit:watch": "vitest --config ./tests/unit/vitest.config.ts", | ||
"test:e2e": "pnpm exec playwright test --config ./tests/e2e/config.playwright.ts", | ||
"test:e2e:dev": "PLAYWRIGHT_ENV=dev pnpm run test:e2e --ui", | ||
"test:e2e:install": "pnpm exec playwright install --with-deps" | ||
} | ||
} |
import { thumbHashToAverageRGBA, thumbHashToRGBA } from "thumbhash"; | ||
/** | ||
* Get the bytes from a hash | ||
*/ | ||
function getBytes(hash: string) { | ||
return Uint8Array.from(atob(hash), (c) => c.charCodeAt(0)); | ||
} | ||
/** | ||
* Get the width, height and pixels from a thumbhash | ||
*/ | ||
export function decodeThumbHash(hash: string) { | ||
const bytes = Uint8Array.from(atob(hash), (c) => c.charCodeAt(0)); | ||
const { w: width, h: height, rgba: pixels } = thumbHashToRGBA(bytes); | ||
const { w: width, h: height, rgba: pixels } = thumbHashToRGBA(getBytes(hash)); | ||
return { width, height, pixels }; | ||
@@ -16,4 +22,3 @@ } | ||
export function getAverageColor(hash: string) { | ||
const { pixels } = decodeThumbHash(hash); | ||
const { r, g, b, a } = thumbHashToAverageRGBA(pixels); | ||
const { r, g, b, a } = thumbHashToAverageRGBA(getBytes(hash)); | ||
@@ -20,0 +25,0 @@ // Scale r, g, b from 0-1 to 0-255 and round to the nearest integer |
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
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
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
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
87060
167
0
13