@wix/showcase-react-components 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/dist/esm/SpatialImage/SpatialImage.js +8 -3
- package/dist/esm/SpatialImage/viewer/spatial-IC5HXWEQ.js +1 -1
- package/dist/esm/SpatialImage/viewer/spatial-QDMH4O6I.js +1 -1
- package/dist/esm/SpatialImage/viewer/spatial.bundle.d.ts +2 -2
- package/package.json +2 -2
- package/dist/esm/SpatialImage/viewer/workers/depth-gallery-fill-worker.mjs +0 -2
- package/dist/esm/SpatialImage/viewer/workers/depth-gallery-quality-worker.mjs +0 -2
- package/dist/esm/SpatialImage/viewer/workers/depth-gallery-subject-worker.mjs +0 -2
- package/dist/esm/SpatialImage/viewer/workers/depth-gallery-worker.mjs +0 -2
- package/dist/esm/SpatialImage/workers.js +0 -17
- package/dist/types/SpatialImage/workers.d.ts +0 -1
package/README.md
CHANGED
|
@@ -23,6 +23,5 @@ shouldRenderSpatialImage(image, spatialAsset, depthEnabled)
|
|
|
23
23
|
- `mediaId(uri)`: the Wix media id inside any of the editor's image forms.
|
|
24
24
|
|
|
25
25
|
The viewer under `src/SpatialImage/viewer` is a fixed, pre-minified bundle; see its `PATCHES.md`. The
|
|
26
|
-
package ships ESM only: the viewer loads its chunks with `import()
|
|
27
|
-
|
|
28
|
-
package) depends on it.
|
|
26
|
+
package ships ESM only: the viewer loads its chunks with `import()`. Published to public npm, because
|
|
27
|
+
editor-react-components (a public package) depends on it.
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createSpatialImage } from './viewer/spatial.bundle.js';
|
|
3
|
-
import { workerUrl } from './workers.js';
|
|
4
3
|
/*
|
|
5
4
|
* A photo with spatial depth (3D): the fixed, validated Spatial Image viewer bundle (./viewer) fed with
|
|
6
5
|
* the photo and its saved `spatialAsset`. The asset is always made by the showcase media service (the
|
|
7
6
|
* editor's Make 3D action), so the viewer never prepares depth in the browser, in the editor either: it
|
|
8
7
|
* would download the models and show its progress on the image, and the host has no way to keep the
|
|
9
|
-
* result.
|
|
8
|
+
* result. The preparation workers (and the remote model code they load) are not shipped, so
|
|
9
|
+
* `workerUrl` is never called.
|
|
10
10
|
*/
|
|
11
|
-
const Viewer = createSpatialImage({
|
|
11
|
+
const Viewer = createSpatialImage({
|
|
12
|
+
workerUrl: name => {
|
|
13
|
+
throw new Error(`Spatial Image does not prepare depth in the browser (${name}).`);
|
|
14
|
+
},
|
|
15
|
+
prepareInEditor: false,
|
|
16
|
+
});
|
|
12
17
|
export const SpatialImage = ({ id, className, image, spatialAsset, depthStrength, fit, role, }) => (React.createElement(Viewer, { id: id, className: className, image: image, spatialAsset: spatialAsset, depthEnabled: true, depthStrength: depthStrength, fit: fit, role: role }));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/* ARI Spatial Image viewer — Monty Alon */
|
|
2
|
-
import{a as U}from"./spatial-NBE3T2VB.js";import{a as M}from"./spatial-GZVXIGKN.js";var I=[{key:"enabled",label:"Depth",choices:[["off","Off"],["on","On"]],value:"off"},{key:"effect",label:"Presentation",choices:[["spatial","Spatial photo"],["dof","Depth of field only"],["parallax","Parallax"],["relief","3D relief"]],value:"spatial"},{key:"strength",label:"Depth strength",min:0,max:100,value:45},{key:"separation",label:"Layer separation",min:0,max:100,value:0},{key:"orbitRange",label:"Orbit range",min:0,max:8,value:3},{key:"orbitPeriod",label:"Orbit duration (seconds)",min:8,max:120,value:30},{key:"motion",label:"Automatic orbit",choices:[["on","On"],["off","Off"]],value:"on"},{key:"adaptive",label:"Protect fragile edges",choices:[["on","On"],["off","Off"]],value:"on"},{key:"background",label:"Background",choices:[["show","Show"],["remove","Remove"]],value:"show"},{key:"color",label:"Color",choices:[["color","Color"],["mono","Black & white"]],value:"color"},{key:"material",label:"Material",choices:[["photo","Photo"],["particles","Particles"]],value:"photo"},{key:"lens-enabled",label:"Lens blur",choices:[["off","Off"],["on","On"]],value:"off"},{key:"lens-look",label:"Lens look",choices:[["auto","Automatic"],["subtle","Subtle"],["cinematic","Cinematic"],["custom","Custom"]],value:"auto"},{key:"lens-mode",label:"Focus",choices:[["auto","Foreground"],["mouse","Follow mouse"],["manual","Manual"]],value:"auto"},{key:"lens-focus",label:"Focus: far to near",min:0,max:100,value:70},{key:"lens-bias",label:"Mouse focus: farther to nearer",min:-50,max:50,value:0},{key:"lens-blur",label:"Blur amount",min:0,max:100,value:26},{key:"lens-shape",label:"Bokeh shape",choices:[["round","Circular"],["hex","Hexagonal"],["oval","Anamorphic oval"]],value:"round"},{key:"lens-highlights",label:"Highlight glow",min:0,max:100,value:30}],j=e=>"spatial-"+e.replace(/[A-Z]/g,t=>"-"+t.toLowerCase()),ee=[{dataKey:"depth",key:"enabled"},{dataKey:"depthEnabled",key:"enabled"},{dataKey:"depthStrength",key:"strength"},{dataKey:"layerSeparation",key:"separation"},{dataKey:"orbitRange",key:"orbitRange"},{dataKey:"orbitPeriod",key:"orbitPeriod"},{dataKey:"background",key:"background"}];function A(e,t={},a={}){let i={...e.values},n=!1;for(let{dataKey:o,key:s}of ee){if(t[o]===void 0||t[o]===null||t[o]==="")continue;let l=I.find(c=>c.key===s),u=typeof t[o]=="boolean"?t[o]?"on":"off":t[o];i[s]=N(l,u,a[s]??l.value),n=!0}return n?V(o=>i[I.find(s=>j(s.key)===o)?.key],a):e}function N(e,t,a=e.value){let i=String(t??"").trim().replace(/^["']|["']$/g,"");if(!i)return a;if(e.choices)return e.choices.some(([o])=>o===i)?i:a;let n=Number(i);return Number.isFinite(n)?Math.max(e.min,Math.min(e.max,n)):a}function V(e,t={}){let a=Object.fromEntries(I.map(n=>[n.key,N(n,e(j(n.key)),t[n.key]??n.value)]));{let n=a.strength,o=Math.max(0,(n-45)/55);a.orbitRange=n<=45?n/15:3+o*5,a.separation=o*70}let i={lens:{}};for(let[n,o]of Object.entries(a)){if(n==="enabled")continue;let s=["motion","adaptive","lens-enabled"].includes(n)?o==="on":o;n==="background"?i.subjectView=o==="remove"?"foreground":"scene":n.startsWith("lens-")?i.lens[n.slice(5)]=s:i[n]=s}return{enabled:a.enabled==="on",settings:i,values:a}}function B(e,t,a){let i="",n=!1,o=()=>{if(n)return;let u=getComputedStyle(e),c=V(r=>u.getPropertyValue("--"+r),a),f=JSON.stringify(c);f!==i&&(i=f,t(c))},s=new MutationObserver(o);s.observe(e,{attributes:!0,attributeFilter:["class","style"]}),e.parentElement&&s.observe(e.parentElement,{attributes:!0,attributeFilter:["class","style"]});let l=setInterval(o,250);return o(),()=>{n=!0,clearInterval(l),s.disconnect()}}var R=e=>!e.crop||!(e.crop.x||e.crop.y||(e.crop.width??1)!==1||(e.crop.height??1)!==1);function te(e,t){if(!e?.uri||t?.sourceUri!==e.uri||!t.sourceVersion||!t.key||!R(e))return null;try{let a=new URL(t.url);return a.protocol!=="https:"||a.hostname!=="static.wixstatic.com"||!/^\/media\/[^/]+$/.test(a.pathname)||a.search||a.hash||a.username||a.password?null:{key:t.key,url:a.href}}catch{return null}}function T(e,{Image:t,loadHost:a,emptyState:i,defaults:n,prepare:o,onPrepared:s,isStale:l}){return function({id:c,className:f="",image:r,spatialAsset:L,wix:_,fit:ft="cover",role:rl,...D}){let x=e.useRef(null),v=e.useRef(null),S=e.useRef(null),[$,Q]=e.useState({enabled:!1,settings:{},values:{}}),Y=JSON.stringify(D,(b,p)=>b!==""&&(typeof p=="function"||p&&typeof p=="object")?void 0:p),h=e.useMemo(()=>A($,D,n),[$,Y]),[Z,q]=e.useState(!1),[y,O]=e.useState(null),[C,g]=e.useState(null),P=te(r,L),E=!!P&&!!l?.(L),w=!!o&&(!P||E)&&!!r?.uri&&R(r)&&h.enabled,m=(w&&y?.uri===r.uri&&y.key&&!(E&&y.partial)?{key:y.key,blob:y.blob,upgradeOf:y.upgradeOf}:null)||P;S.current={source:r,asset:m,enabled:h.enabled,status:m?"ready":"off",settings:h.settings},e.useEffect(()=>B(x.current,Q,n),[]),e.useEffect(()=>{if(!w||y?.uri===r.uri)return;let b=r.uri,p=!0;g("Preparing depth\u2026");let K=null;return o(r,d=>{p&&g(d)},d=>{p&&(K=d.key,O({uri:b,...d,partial:E}))}).then(d=>{p&&(O({uri:b,...d,upgradeOf:K}),g(null),s?.(d,{id:c,image:r}))},d=>{p&&(O({uri:b,error:d}),g(d.message||"Depth preparation failed."))}),()=>{p=!1}},[w,r?.uri]),e.useEffect(()=>{if(!m||!h.enabled)return;let b=!1;return a().then(({SpatialPhotoHost:p})=>{b||(v.current=new p({element:x.current,fit:ft,onRenderingChange:q}),v.current.update(S.current))}).catch(()=>{}),()=>{b=!0,v.current?.dispose(),v.current=null}},[!!m&&h.enabled,ft]),e.useEffect(()=>{v.current?.update(S.current)},[r?.uri,m?.key,m?.url,h]);let F=_?.presetsWrapperProps??{},G=r?.crop&&r.width&&r.height?{x:(r.crop.x||0)*r.width,y:(r.crop.y||0)*r.height,width:(r.crop.width??1)*r.width,height:(r.crop.height??1)*r.height}:void 0,X=r?.width&&r?.height?`${r.width} / ${r.height}`:"4 / 5";return e.createElement("div",{...F,style:{...F.style,display:"contents"}},e.createElement("div",{id:c,className:`wix-spatial-image ${f}`,ref:x,"data-depth-ready":!!m,style:{position:"relative",overflow:"hidden",boxSizing:"border-box",isolation:"isolate","--spatial-ratio":X}},e.createElement("style",null,".wix-spatial-image{aspect-ratio:var(--spatial-ratio,4 / 5)}"),r?.uri?e.createElement(t,{uri:r.uri,width:r.width||1,height:r.height||1,alt:r.alt||"",role:rl,name:r.name||"",crop:G,displayMode:ft==="contain"?"fit":"fill",shouldUseLQIP:!0,style:{position:"absolute",inset:0,display:"block",width:"100%",height:"100%",objectFit:ft,transform:h.enabled&&(h.settings.effect??"spatial")==="spatial"?"scale(1.12)":"none",transformOrigin:"50% 50%",opacity:Z?0:1}}):i?e.createElement(i):null,w&&C?e.createElement("div",{role:"status",style:{position:"absolute",left:12,bottom:12,zIndex:1,padding:"6px 10px",borderRadius:6,background:"rgba(20,22,28,.72)",color:"#fff",font:"12px/1.4 system-ui,sans-serif",pointerEvents:"none"}},C):null))}}import*as k from"react";var W={enabled:"on"};function z(e){let t=e?.uri??"",a=e?.url??"",i=t.replace(/#.*$/,"").replace(/^wix:image:\/\/v1\//,"").replace(/^wix:\/\/v1\//,"").replace(/\/.*$/,"");return i&&/^[\w.~-]+$/.test(i)?i:/^https:\/\/static\.wixstatic\.com\/media\/([\w.~-]+)/.exec(/^https?:/.test(t)?t:a)?.[1]??null}var H=e=>{let t=z(e);return t?"https://static.wixstatic.com/media/"+t:null};function re({uri:e,alt:t,role:r,style:a}){let i=H({uri:e});return i?k.createElement("img",{src:i,alt:t,role:r,loading:"lazy",decoding:"async",draggable:!1,style:a}):null}function ne(){return k.createElement("div",{role:"note",style:{position:"absolute",inset:0,display:"grid",placeItems:"center",padding:24,textAlign:"center",background:"#eef0f4",color:"#3b4252",font:"14px/1.5 system-ui,sans-serif",border:"2px dashed #b6bccb"}},"Spatial Image \u2014 choose a photo with Replace Image.")}function oe(e){let t=URL.createObjectURL(new Blob([`import ${JSON.stringify(e.href)};`],{type:"text/javascript"}));try{return new Worker(t,{type:"module"})}finally{setTimeout(()=>URL.revokeObjectURL(t),6e4)}}var ae=()=>typeof location<"u"&&/\.editor\.wix\.com$/.test(location.hostname);function J(e){let t;function a(){return t||(t=Promise.all([import("./spatial-CDWKCSGF.js"),import("./spatial-AL6PHL7B.js"),import("./spatial-2K3S733F.js"),import("./spatial-UQSQV6DC.js")]).then(([{SpatialAssetRegistry:i},{createSpatialStore:n},{createSpatialPreparer:o,preparationVersion:s},{createWorkerSessionPool:l}])=>{let u=l({createWorker:c=>oe(e(c.replace(/^\.\/|\.js$/g,"")))});return new i({siteId:"wix-dev-spatial-image",store:n("ari-wix-spatial-image"),prepare:o({pool:u,refine:!0}),pipeline:s("balanced",null,!0)})}).catch(i=>{throw t=null,i})),t}return async function(n,o,s){o("Loading photo\u2026");let l=await fetch(H(n));if(!l.ok)throw new Error(`Photo unavailable (${l.status}).`);let[{sourceFromFile:u},c]=await Promise.all([import("./spatial-2K3S733F.js"),l.blob()]),f=await(await a()).ensure(await u(c),o,s?r=>s({key:r.key,blob:r.blob}):null);return{key:f.key,blob:f.blob}}}function be({workerUrl:e,authorization:t}){let a=J(e);return async function(n,o){let{key:s,blob:l}=await a(n,o);o("Saving the 3D image to your site\u2026");let{uploadToSiteMedia:u,whenServed:c}=await import("./spatial-RRKAKJ56.js"),f=String(n.name||"photo").replace(/\.[^.]*$/,"").slice(0,80)+".spatial.png",{url:r}=await u(l,{fileName:f,authorization:await t()});return await c(r),{sourceUri:n.uri,sourceVersion:s,url:r,key:s}}}function ye({workerUrl:e,prepareInEditor:ie=!0}){let t=ie&&ae()?J(e):void 0,n=T(k,{Image:re,emptyState:ne,defaults:W,prepare:t,onPrepared:t?(o,s)=>import("./spatial-LSZJ6I7J.js").then(({saveFromEditor:l})=>l(o,s)).catch(l=>console.warn("Spatial Image: the 3D version was not saved for visitors.",l)):void 0,isStale:t?o=>![M,U].every(s=>String(o?.key??"").includes(s)):void 0,loadHost:()=>import("./spatial-WDCZLPPJ.js")});return function({image:s,...l}){let u=z(s);return k.createElement(n,{...l,image:u?{...s,uri:u}:void 0})}}export{I as a,j as b,N as c,V as d,te as e,z as f,be as g,ye as h};
|
|
2
|
+
import{a as U}from"./spatial-NBE3T2VB.js";import{a as M}from"./spatial-GZVXIGKN.js";var I=[{key:"enabled",label:"Depth",choices:[["off","Off"],["on","On"]],value:"off"},{key:"effect",label:"Presentation",choices:[["spatial","Spatial photo"],["dof","Depth of field only"],["parallax","Parallax"],["relief","3D relief"]],value:"spatial"},{key:"strength",label:"Depth strength",min:0,max:100,value:45},{key:"separation",label:"Layer separation",min:0,max:100,value:0},{key:"orbitRange",label:"Orbit range",min:0,max:8,value:3},{key:"orbitPeriod",label:"Orbit duration (seconds)",min:8,max:120,value:30},{key:"motion",label:"Automatic orbit",choices:[["on","On"],["off","Off"]],value:"on"},{key:"adaptive",label:"Protect fragile edges",choices:[["on","On"],["off","Off"]],value:"on"},{key:"background",label:"Background",choices:[["show","Show"],["remove","Remove"]],value:"show"},{key:"color",label:"Color",choices:[["color","Color"],["mono","Black & white"]],value:"color"},{key:"material",label:"Material",choices:[["photo","Photo"],["particles","Particles"]],value:"photo"},{key:"lens-enabled",label:"Lens blur",choices:[["off","Off"],["on","On"]],value:"off"},{key:"lens-look",label:"Lens look",choices:[["auto","Automatic"],["subtle","Subtle"],["cinematic","Cinematic"],["custom","Custom"]],value:"auto"},{key:"lens-mode",label:"Focus",choices:[["auto","Foreground"],["mouse","Follow mouse"],["manual","Manual"]],value:"auto"},{key:"lens-focus",label:"Focus: far to near",min:0,max:100,value:70},{key:"lens-bias",label:"Mouse focus: farther to nearer",min:-50,max:50,value:0},{key:"lens-blur",label:"Blur amount",min:0,max:100,value:26},{key:"lens-shape",label:"Bokeh shape",choices:[["round","Circular"],["hex","Hexagonal"],["oval","Anamorphic oval"]],value:"round"},{key:"lens-highlights",label:"Highlight glow",min:0,max:100,value:30}],j=e=>"spatial-"+e.replace(/[A-Z]/g,t=>"-"+t.toLowerCase()),ee=[{dataKey:"depth",key:"enabled"},{dataKey:"depthEnabled",key:"enabled"},{dataKey:"depthStrength",key:"strength"},{dataKey:"layerSeparation",key:"separation"},{dataKey:"orbitRange",key:"orbitRange"},{dataKey:"orbitPeriod",key:"orbitPeriod"},{dataKey:"background",key:"background"}];function A(e,t={},a={}){let i={...e.values},n=!1;for(let{dataKey:o,key:s}of ee){if(t[o]===void 0||t[o]===null||t[o]==="")continue;let l=I.find(c=>c.key===s),u=typeof t[o]=="boolean"?t[o]?"on":"off":t[o];i[s]=N(l,u,a[s]??l.value),n=!0}return n?V(o=>i[I.find(s=>j(s.key)===o)?.key],a):e}function N(e,t,a=e.value){let i=String(t??"").trim().replace(/^["']|["']$/g,"");if(!i)return a;if(e.choices)return e.choices.some(([o])=>o===i)?i:a;let n=Number(i);return Number.isFinite(n)?Math.max(e.min,Math.min(e.max,n)):a}function V(e,t={}){let a=Object.fromEntries(I.map(n=>[n.key,N(n,e(j(n.key)),t[n.key]??n.value)]));{let n=a.strength,o=Math.max(0,(n-45)/55);a.orbitRange=n<=45?n/15:3+o*5,a.separation=o*70}let i={lens:{}};for(let[n,o]of Object.entries(a)){if(n==="enabled")continue;let s=["motion","adaptive","lens-enabled"].includes(n)?o==="on":o;n==="background"?i.subjectView=o==="remove"?"foreground":"scene":n.startsWith("lens-")?i.lens[n.slice(5)]=s:i[n]=s}return{enabled:a.enabled==="on",settings:i,values:a}}function B(e,t,a){let i="",n=!1,o=()=>{if(n)return;let u=getComputedStyle(e),c=V(r=>u.getPropertyValue("--"+r),a),f=JSON.stringify(c);f!==i&&(i=f,t(c))},s=new MutationObserver(o);s.observe(e,{attributes:!0,attributeFilter:["class","style"]}),e.parentElement&&s.observe(e.parentElement,{attributes:!0,attributeFilter:["class","style"]});let l=null,g=!0,d=()=>{clearInterval(l),l=g&&!document.hidden?(o(),setInterval(o,250)):null},j=typeof IntersectionObserver<"u"?new IntersectionObserver(x=>{g=x[x.length-1].isIntersecting,d()}):null;return j?.observe(e),document.addEventListener("visibilitychange",d),d(),o(),()=>{n=!0,clearInterval(l),j?.disconnect(),document.removeEventListener("visibilitychange",d),s.disconnect()}}var R=e=>!e.crop||!(e.crop.x||e.crop.y||(e.crop.width??1)!==1||(e.crop.height??1)!==1);function te(e,t){if(!e?.uri||t?.sourceUri!==e.uri||!t.sourceVersion||!t.key||!R(e))return null;try{let a=new URL(t.url);return a.protocol!=="https:"||a.hostname!=="static.wixstatic.com"||!/^\/media\/[^/]+$/.test(a.pathname)||a.search||a.hash||a.username||a.password?null:{key:t.key,url:a.href}}catch{return null}}function T(e,{Image:t,loadHost:a,emptyState:i,defaults:n,prepare:o,onPrepared:s,isStale:l}){return function({id:c,className:f="",image:r,spatialAsset:L,wix:_,fit:ft="cover",role:rl,...D}){let x=e.useRef(null),v=e.useRef(null),S=e.useRef(null),[$,Q]=e.useState({enabled:!1,settings:{},values:{}}),Y=JSON.stringify(D,(b,p)=>b!==""&&(typeof p=="function"||p&&typeof p=="object")?void 0:p),h=e.useMemo(()=>A($,D,n),[$,Y]),[Z,q]=e.useState(!1),[y,O]=e.useState(null),[C,g]=e.useState(null),P=te(r,L),E=!!P&&!!l?.(L),w=!!o&&(!P||E)&&!!r?.uri&&R(r)&&h.enabled,m=(w&&y?.uri===r.uri&&y.key&&!(E&&y.partial)?{key:y.key,blob:y.blob,upgradeOf:y.upgradeOf}:null)||P;S.current={source:r,asset:m,enabled:h.enabled,status:m?"ready":"off",settings:h.settings},e.useEffect(()=>B(x.current,Q,n),[]),e.useEffect(()=>{if(!w||y?.uri===r.uri)return;let b=r.uri,p=!0;g("Preparing depth\u2026");let K=null;return o(r,d=>{p&&g(d)},d=>{p&&(K=d.key,O({uri:b,...d,partial:E}))}).then(d=>{p&&(O({uri:b,...d,upgradeOf:K}),g(null),s?.(d,{id:c,image:r}))},d=>{p&&(O({uri:b,error:d}),g(d.message||"Depth preparation failed."))}),()=>{p=!1}},[w,r?.uri]),e.useEffect(()=>{if(!m||!h.enabled)return;let b=!1;return a().then(({SpatialPhotoHost:p})=>{b||(v.current=new p({element:x.current,fit:ft,onRenderingChange:q}),v.current.update(S.current))}).catch(()=>{}),()=>{b=!0,v.current?.dispose(),v.current=null}},[!!m&&h.enabled,ft]),e.useEffect(()=>{v.current?.update(S.current)},[r?.uri,m?.key,m?.url,h]);let F=_?.presetsWrapperProps??{},G=r?.crop&&r.width&&r.height?{x:(r.crop.x||0)*r.width,y:(r.crop.y||0)*r.height,width:(r.crop.width??1)*r.width,height:(r.crop.height??1)*r.height}:void 0,X=r?.width&&r?.height?`${r.width} / ${r.height}`:"4 / 5";return e.createElement("div",{...F,style:{...F.style,display:"contents"}},e.createElement("div",{id:c,className:`wix-spatial-image ${f}`,ref:x,"data-depth-ready":!!m,style:{position:"relative",overflow:"hidden",boxSizing:"border-box",isolation:"isolate","--spatial-ratio":X}},e.createElement("style",null,".wix-spatial-image{aspect-ratio:var(--spatial-ratio,4 / 5)}"),r?.uri?e.createElement(t,{uri:r.uri,width:r.width||1,height:r.height||1,alt:r.alt||"",role:rl,name:r.name||"",crop:G,displayMode:ft==="contain"?"fit":"fill",shouldUseLQIP:!0,style:{position:"absolute",inset:0,display:"block",width:"100%",height:"100%",objectFit:ft,transform:h.enabled&&(h.settings.effect??"spatial")==="spatial"?"scale(1.12)":"none",transformOrigin:"50% 50%",opacity:Z?0:1}}):i?e.createElement(i):null,w&&C?e.createElement("div",{role:"status",style:{position:"absolute",left:12,bottom:12,zIndex:1,padding:"6px 10px",borderRadius:6,background:"rgba(20,22,28,.72)",color:"#fff",font:"12px/1.4 system-ui,sans-serif",pointerEvents:"none"}},C):null))}}import*as k from"react";var W={enabled:"on"};function z(e){let t=e?.uri??"",a=e?.url??"",i=t.replace(/#.*$/,"").replace(/^wix:image:\/\/v1\//,"").replace(/^wix:\/\/v1\//,"").replace(/\/.*$/,"");return i&&/^\w[\w.~-]*$/.test(i)?i:/^https:\/\/static\.wixstatic\.com\/media\/(\w[\w.~-]*)/.exec(/^https?:/.test(t)?t:a)?.[1]??null}var H=e=>{let t=z(e);return t?"https://static.wixstatic.com/media/"+t:null};var se=[320,480,640,800,1024,1280,1600,1920,2560,3200,3840];function re({uri:e,width:w,height:h,alt:t,role:r,style:a}){let i=H({uri:e}),c=k.useRef(null),[z2,y2]=k.useState("auto, 100vw"),q=w>1&&h>1?w/h:0,f=a?.objectFit,n=i&&/\.(jpe?g|png|webp)$/i.test(i)?i.slice(i.lastIndexOf("/")+1):null,v=n?se.filter(x=>!q||x<w).concat(q&&w<=3840?[w]:[]):[],u=x=>`${i}/v1/fit/w_${x},h_${q?Math.round(x/q):x*8},q_90/${n}`,p=v.length?u(v.filter(x=>x<=1280).pop()??v[0]):i;k.useEffect(()=>{let o=c.current;if(!o||!v.length||typeof ResizeObserver>"u")return;let b=new ResizeObserver(()=>{let{width:W,height:L}=o.getBoundingClientRect();if(!W||!L)return;let m=q?f==="contain"?Math.min(W,L*q):Math.max(W,L*q):W;y2(Math.ceil(m)+"px")});return b.observe(o),()=>b.disconnect()},[p,f]);return i?k.createElement("img",{ref:c,srcSet:v.length?v.map(x=>`${u(x)} ${x}w`).join(", "):void 0,sizes:v.length?z2:void 0,src:p,alt:t,role:r,loading:"lazy",decoding:"async",draggable:!1,style:a}):null}function ne(){return k.createElement("div",{role:"note",style:{position:"absolute",inset:0,display:"grid",placeItems:"center",padding:24,textAlign:"center",background:"#eef0f4",color:"#3b4252",font:"14px/1.5 system-ui,sans-serif",border:"2px dashed #b6bccb"}},"Spatial Image \u2014 choose a photo with Replace Image.")}function oe(e){let t=URL.createObjectURL(new Blob([`import ${JSON.stringify(e.href)};`],{type:"text/javascript"}));try{return new Worker(t,{type:"module"})}finally{setTimeout(()=>URL.revokeObjectURL(t),6e4)}}var ae=()=>typeof location<"u"&&/\.editor\.wix\.com$/.test(location.hostname);function J(e){let t;function a(){return t||(t=Promise.all([import("./spatial-CDWKCSGF.js"),import("./spatial-AL6PHL7B.js"),import("./spatial-2K3S733F.js"),import("./spatial-UQSQV6DC.js")]).then(([{SpatialAssetRegistry:i},{createSpatialStore:n},{createSpatialPreparer:o,preparationVersion:s},{createWorkerSessionPool:l}])=>{let u=l({createWorker:c=>oe(e(c.replace(/^\.\/|\.js$/g,"")))});return new i({siteId:"wix-dev-spatial-image",store:n("ari-wix-spatial-image"),prepare:o({pool:u,refine:!0}),pipeline:s("balanced",null,!0)})}).catch(i=>{throw t=null,i})),t}return async function(n,o,s){o("Loading photo\u2026");let l=await fetch(H(n));if(!l.ok)throw new Error(`Photo unavailable (${l.status}).`);let[{sourceFromFile:u},c]=await Promise.all([import("./spatial-2K3S733F.js"),l.blob()]),f=await(await a()).ensure(await u(c),o,s?r=>s({key:r.key,blob:r.blob}):null);return{key:f.key,blob:f.blob}}}function be({workerUrl:e,authorization:t}){let a=J(e);return async function(n,o){let{key:s,blob:l}=await a(n,o);o("Saving the 3D image to your site\u2026");let{uploadToSiteMedia:u,whenServed:c}=await import("./spatial-RRKAKJ56.js"),f=String(n.name||"photo").replace(/\.[^.]*$/,"").slice(0,80)+".spatial.png",{url:r}=await u(l,{fileName:f,authorization:await t()});return await c(r),{sourceUri:n.uri,sourceVersion:s,url:r,key:s}}}function ye({workerUrl:e,prepareInEditor:ie=!1}){let t=ie&&ae()?J(e):void 0,n=T(k,{Image:re,emptyState:ne,defaults:W,prepare:t,onPrepared:t?(o,s)=>import("./spatial-LSZJ6I7J.js").then(({saveFromEditor:l})=>l(o,s)).catch(l=>console.warn("Spatial Image: the 3D version was not saved for visitors.",l)):void 0,isStale:t?o=>![M,U].every(s=>String(o?.key??"").includes(s)):void 0,loadHost:()=>import("./spatial-WDCZLPPJ.js")});return function({image:s,...l}){let u=z(s);return k.createElement(n,{...l,image:u?{...s,uri:u}:void 0})}}export{I as a,j as b,N as c,V as d,te as e,z as f,be as g,ye as h};
|
|
@@ -179,4 +179,4 @@ float scatterWeight(float sourcePx, float coc, float compactness) {
|
|
|
179
179
|
float compact = 1.0 - scatterRamp(allowed * 0.75, allowed * 1.25, max(1.0, sourcePx));
|
|
180
180
|
return focus * compact;
|
|
181
181
|
}`;function Lt(t,e,o,n,r){let a=r.threshold??le,s=r.maxCount??he,c=r.isolation??ue,i=r.maxExtentPx??fe,f=r.compactness??pe,l=o*n,p=new Uint8Array(l),d=[],g=(x,u)=>u*o+x,w=(x,u)=>x>=0&&u>=0&&x<o&&u<n;for(let x=0;x<n;x++)for(let u=0;u<o;u++){let m=g(u,x);if(p[m])continue;let h=m*4;if($(t[h],t[h+1],t[h+2])<=a){p[m]=1;continue}let M=[m];p[m]=1;let b=[],C=u,P=u,E=x,D=x,_=0,j=0,tt=0,et=0,ot=0,nt=0;for(;M.length;){let A=M.pop(),S=A%o,L=A/o|0;b.push(A);let k=A*4,N=$(t[k],t[k+1],t[k+2]);_+=N,j+=S*N,tt+=L*N;let q=J(N,a);et+=t[k]*q,ot+=t[k+1]*q,nt+=t[k+2]*q,S<C&&(C=S),S>P&&(P=S),L<E&&(E=L),L>D&&(D=L);let Nt=[A-1,A+1,A-o,A+o],it=[[S-1,L],[S+1,L],[S,L-1],[S,L+1]];for(let I=0;I<4;I++){let Ut=it[I][0],Ht=it[I][1];if(!w(Ut,Ht))continue;let z=Nt[I];if(p[z])continue;let Z=z*4;if($(t[Z],t[Z+1],t[Z+2])<=a){p[z]=1;continue}p[z]=1,M.push(z)}}let Dt=P-C+1,Rt=D-E+1,at=Math.max(Dt,Rt),rt=_>0?j/_:u,ct=_>0?tt/_:x,_t=e[g(Math.round(rt),Math.round(ct))]??e[m];if(at>i)continue;let O=4,st=0,W=0,It=new Set(b);for(let A=E-O;A<=D+O;A++)for(let S=C-O;S<=P+O;S++){if(!w(S,A))continue;let L=g(S,A);if(It.has(L))continue;let k=L*4;st+=$(t[k],t[k+1],t[k+2]),W++}let zt=b.reduce((A,S)=>{let L=S*4;return Math.max(A,$(t[L],t[L+1],t[L+2]))},0),Gt=W?st/W:0;if(zt<c*Math.max(Gt,1e-4))continue;let Ot=b.length;d.push({uv:[(rt+.5)/o,(ct+.5)/n],rgb:[et,ot,nt],z:_t,sourcePx:Math.max(1,Math.sqrt(Ot)),extentPx:at,footprint:b})}return d.sort((x,u)=>$(u.rgb[0],u.rgb[1],u.rgb[2])-$(x.rgb[0],x.rgb[1],x.rgb[2])),d.slice(0,s)}var me={encoding:"unit",source:"depth",channel:"r",near:1,far:8,nearIs:"white"},xe={enabled:!1,mode:"auto",look:"auto",focus:70,bias:0,blur:26,shape:"round",highlights:30},ge=8,je=.065,to=1.15,eo=36e3;function At(t={}){t||(t={});let e=n=>Math.max(0,Math.min(100,Number.isFinite(t[n])?t[n]:xe[n])),o=t.look==null;return{enabled:t.enabled===!0,mode:o&&t.mode!=="manual"?"auto":["mouse","auto","manual"].includes(t.mode)?t.mode:"auto",look:["auto","subtle","cinematic","custom"].includes(t.look)?t.look:"auto",focus:e("focus"),bias:Math.max(-50,Math.min(50,Number.isFinite(t.bias)?t.bias:0)),blur:e("blur"),highlights:e("highlights"),shape:["round","hex","oval"].includes(t.shape)?t.shape:"round"}}function oo(t,e,o){if(t.mode==="manual")return t.focus/100;let n=t.mode==="mouse"&&e!=null?e:o;return Math.max(0,Math.min(1,n+(t.mode==="mouse"?(t.bias||0)/100:0)))}function no(t,e,o){let n=new Float32Array(e*o*4),r=new Float32Array(e*o).fill(4);for(let i=0;i<t.length;i+=4){let f=t[i+3]/255;for(let l=0;l<3;l++){let p=t[i+l]/255;n[i+l]=(p<=.04045?p/12.92:((p+.055)/1.055)**2.4)*f}n[i+3]=f}let a=.55,s=Lt(n,r,e,o,{focusDistance:2,focalLength:.05,aperture:.05,threshold:a,isolation:2.5,maxExtentPx:12,maxCount:256}),c=new Uint8Array(e*o);for(let i of s)for(let f of i.footprint){let l=f*4,p=n[l]*.2126+n[l+1]*.7152+n[l+2]*.0722;c[f]=Math.round(255*J(p,a))}return{mask:c,highlights:s,width:e,height:o}}function ao(t={},e,o,n="auto"){let r=(p,d,g)=>Math.max(d,Math.min(g,p)),a=(e?.highlights||[]).filter(p=>{if(!o?.usable)return!0;let d=Math.min(o.width-1,Math.floor(p.uv[0]*o.width)),g=Math.min(o.height-1,Math.floor(p.uv[1]*o.height));return o.mask[g*o.width+d]<128}).length,s=r((t.soft||0)*1.4+(t.border||0)*.4+(t.detail||0)*2,0,1),c=r((t.gap||t.span||0)/.35,.45,1);return{blur:Math.round((n==="subtle"?16:n==="cinematic"?52:a?30:24)*(1-s*.4)*c),highlights:a?n==="subtle"?18:n==="cinematic"?75:42:0,backgroundLights:a}}function ro(t){return St(me,[Math.max(0,Math.min(1,t)),0,0,1])}function co(t,e,o=!1){if(!t)return .7;let n=[],r=Math.max(1,Math.ceil(Math.sqrt(t.width*t.height/8e3)));for(let s=0;s<t.height;s+=r)for(let c=0;c<t.width;c+=r){if(e?.usable){let f=Math.min(e.width-1,Math.floor(c/t.width*e.width)),l=Math.min(e.height-1,Math.floor(s/t.height*e.height));if(e.mask[l*e.width+f]<240)continue}else if(c<t.width*.3||c>t.width*.7||s<t.height*.3||s>t.height*.7)continue;let i=t.values[s*t.width+c];Number.isFinite(i)&&n.push(i)}n.sort((s,c)=>s-c);let a=n.length?n[Math.floor(n.length/2)]:.7;return o?1-a:a}function so(t){let e=ge,o=dt({radiusPx:e,blades:t==="hex"?6:9,anamorphic:t==="oval"?1.8:1,supersample:4}),n=o.data.reduce((a,s)=>a+s,0),r=[];for(let a=0;a<o.height;a++)for(let s=0;s<o.width;s++){let c=o.data[a*o.width+s]/n;c>0&&r.push([(s-o.cx)/e,(a-o.cy)/e,c])}return r}var Et=`ARI-SPATIAL-PNG:1
|
|
182
|
-
`,y=32;function Q(t={}){t||(t={});let e=(n,r,a,s)=>Math.max(a,Math.min(s,Number.isFinite(t[n])?t[n]:r)),o=(n,r,a)=>r.includes(t[n])?t[n]:a;return{effect:o("effect",["spatial","dof","relief","parallax","flat"],"spatial"),material:o("material",["photo","particles"],"photo"),color:o("color",["color","mono"],"color"),strength:e("strength",35,0,100),separation:e("separation",0,0,100),orbitRange:e("orbitRange",3,0,75),orbitPeriod:e("orbitPeriod",30,8,120),size:e("size",2,.5,5),density:e("density",260,80,500),edge:e("edge",50,0,100),invert:t.invert===!0,motion:t.motion!==!1,adaptive:t.adaptive!==!1,cleanEdges:t.cleanEdges!==!1,subjectView:o("subjectView",["scene","foreground","background","off"],"scene"),lens:At(t.effect==="dof"?{...t.lens,enabled:!0}:t.lens),compare:"animated",frozen:!1,map:!1}}function ve(t,e,o){if(t?.format!=="ari-spatial-photo"||t.version!==1||t.depthEncoding!=="rg16-near-white")throw new Error("Unsupported spatial PNG version.");if(t.width!==e||t.height!==o||e<64||e>8192||o>8192||e*o>32e6)throw new Error("Spatial PNG dimensions changed or exceed the supported size. Use the original file.");if(t.foregroundRefined!==void 0&&(t.foregroundRefined!==!0||!t.tiles?.mask))throw new Error("Invalid refined foreground metadata.");let n=Object.entries(t.tiles||{});if(!t.tiles?.photo||!t.tiles?.depth||n.some(([a])=>!["photo","depth","mask","background"].includes(a)))throw new Error("Spatial PNG is missing its photo or depth.");for(let[,a]of n)if(!a||![a.x,a.y,a.width,a.height].every(Number.isSafeInteger)||a.x<0||a.y<y||a.width<1||a.height<1||a.x+a.width>e||a.y+a.height>o)throw new Error("Invalid spatial PNG tile bounds.");for(let a=0;a<n.length;a++)for(let s=a+1;s<n.length;s++){let c=n[a][1],i=n[s][1];if(c.x<i.x+i.width&&c.x+c.width>i.x&&c.y<i.y+i.height&&c.y+c.height>i.y)throw new Error("Spatial PNG tiles overlap.")}if(t.tiles.background&&(!t.tiles.mask||t.tiles.background.width!==t.tiles.mask.width||t.tiles.background.height!==t.tiles.mask.height))throw new Error("Background and mask dimensions differ.");let r=t.tiles.photo.width/t.tiles.photo.height;for(let[,a]of n)if(Math.abs(a.width/a.height/r-1)>.02)throw new Error("Spatial PNG layers use different crops.");if(!t.hashes||!/^[a-f0-9]{64}$/.test(t.hashes.depth)||t.tiles.mask&&!/^[a-f0-9]{64}$/.test(t.hashes.mask))throw new Error("Spatial PNG is missing map integrity checks.");return t}function Ct(t,e){let o=new TextEncoder().encode(Et),n=new TextEncoder().encode(JSON.stringify(t)),r=new Uint8Array(o.length+4+n.length);if(r.set(o),new DataView(r.buffer).setUint32(o.length,n.length),r.set(n,o.length+4),r.length>e*y*3)throw new Error("Spatial PNG metadata is too large.");let a=new Uint8ClampedArray(e*y*4);for(let s=0;s<e*y;s++){a[s*4+3]=255;for(let c=0;c<3;c++)a[s*4+c]=r[s*3+c]||0}return a}function Pt(t,e,o){let n=new Uint8Array(Math.floor(t.length/4)*3);for(let c=0;c<t.length/4;c++)n.set(t.subarray(c*4,c*4+3),c*3);let r=new TextEncoder().encode(Et);if(!r.every((c,i)=>n[i]===c))return null;let a=new DataView(n.buffer).getUint32(r.length);if(a<2||a>n.length-r.length-4)throw new Error("Spatial PNG header is damaged.");let s=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(n.subarray(r.length+4,r.length+4+a)));return ve(s,e,o)}function kt(t){let e=new Uint8ClampedArray(t.length*4),o=[0,0];return t.forEach((n,r)=>{if(!Number.isFinite(n)||n<0||n>1)throw new Error("Spatial depth must be finite and normalized.");Y(n,o),e.set([Math.round(o[0]*255),Math.round(o[1]*255),0,255],r*4)}),e}function Tt(t){return Float32Array.from({length:t.length/4},(e,o)=>H(t[o*4]/255,t[o*4+1]/255))}var F=(t,e)=>{let o=document.createElement("canvas");return o.width=t,o.height=e,o},$t=t=>new Promise((e,o)=>t.toBlob(n=>n?e(n):o(new Error("Could not encode spatial PNG.")),"image/png")),B=async t=>Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256",t))).map(e=>e.toString(16).padStart(2,"0")).join("");async function xo({photo:t,depth:e,subject:o,fill:n,settings:r,name:a="Spatial photo"}){if(!t||!e)throw new Error("Load a photo and its depth first.");let s=Q(r),c=Math.max(32,t.width,e.width,o?.width||0),i=Math.max(t.height,e.height,o?.height||0),f=c*2,l=y+i*(o?2:1);if(f>8192||l>8192||f*l>32e6)throw new Error("This photo is too large for a spatial PNG.");let p=F(f,l),d=p.getContext("2d"),g={photo:{x:0,y,width:t.width,height:t.height},depth:{x:c,y,width:e.width,height:e.height}},w=!!o?.foreground;if(w){if(o.foreground.length!==o.width*o.height*4)throw Error("Refined foreground dimensions do not match.");let h=F(o.width,o.height);h.getContext("2d").putImageData(new ImageData(new Uint8ClampedArray(o.foreground),o.width,o.height),0,0),d.drawImage(h,0,y,t.width,t.height)}else d.drawImage(t,0,y);let x=kt(e.values);d.putImageData(new ImageData(x,e.width,e.height),c,y);let u={depth:await B(x)};if(o){let{width:h,height:v}=o,M=new Uint8ClampedArray(h*v*4);o.mask.forEach((b,C)=>M.set([b,b,b,255],C*4)),g.mask={x:0,y:y+i,width:h,height:v},d.putImageData(new ImageData(M,h,v),0,y+i),u.mask=await B(M),o.usable&&(g.background={x:c,y:y+i,width:h,height:v},d.putImageData(new ImageData(new Uint8ClampedArray(n?.background||o.background),h,v),c,y+i))}let m={format:"ari-spatial-photo",version:1,name:String(a).slice(0,200),width:f,height:l,tiles:g,hashes:u,depthEncoding:"rg16-near-white",settings:s,fillRadius:n?.radius||0,...w?{foregroundRefined:!0}:{}};return d.putImageData(new ImageData(Ct(m,f),f,y),0,0),{blob:await $t(p),manifest:m}}async function spatialSplit(t){let n=new Uint8Array(await t.arrayBuffer());if(![137,80,78,71,13,10,26,10].every((e,o)=>n[o]===e))return[t,null];let r=new DataView(n.buffer,n.byteOffset,n.byteLength),o=8;for(;o+12<=n.length;){let e=r.getUint32(o),a=String.fromCharCode(n[o+4],n[o+5],n[o+6],n[o+7]);if(a==="spAt")return[new Blob([n.subarray(o+8,o+8+e)],{type:"image/png"}),t];if(a==="IEND")break;o+=12+e}return[t,null]}async function spatialPhotoTile(t,e){let n=await createImageBitmap(t,{colorSpaceConversion:"none",premultiplyAlpha:"none"});try{let r=F(e.width,e.height);return r.getContext("2d").drawImage(n,0,0,e.width,e.height),r}finally{n.close()}}async function Me(t,{required:e=!1}={}){if(t.size>50*1024*1024)throw new Error("Spatial PNG must be smaller than 50 MB.");let[tg,tp]=await spatialSplit(t);t=tg;let o=new Uint8Array(await t.slice(0,24).arrayBuffer());if(![137,80,78,71,13,10,26,10].every((i,f)=>o[f]===i)){if(e)throw new Error("Use the original spatial PNG file.");return null}if(o.length<24)throw new Error("Incomplete PNG file.");let r=new DataView(o.buffer),a=r.getUint32(16),s=r.getUint32(20);if(a>8192||s>8192||a*s>32e6){if(e)throw new Error("Spatial PNG dimensions exceed the supported size.");return null}if(a<64||s<y){if(e)throw new Error("This is not a spatial PNG.");return null}let c=await createImageBitmap(t,{colorSpaceConversion:"none",premultiplyAlpha:"none"});try{let i=F(a,y),f=i.getContext("2d",{willReadFrequently:!0});f.drawImage(c,0,0);let l=Pt(f.getImageData(0,0,a,y).data,a,s);if(!l){if(e)throw new Error("Spatial data is missing. Use the exported PNG without resizing or image optimization.");return null}let p=h=>{let v=F(h.width,h.height);return v.getContext("2d",{willReadFrequently:!0}).drawImage(c,h.x,h.y,h.width,h.height,0,0,h.width,h.height),v},d=h=>h.getContext("2d",{willReadFrequently:!0}).getImageData(0,0,h.width,h.height).data,g=tp?await spatialPhotoTile(tp,l.tiles.photo):p(l.tiles.photo),w=d(p(l.tiles.depth));if(await B(w)!==l.hashes.depth)throw new Error("Depth pixels changed. Load the original lossless spatial PNG.");let x={key:`spatial-depth-${l.hashes.depth}`,width:l.tiles.depth.width,height:l.tiles.depth.height,values:Tt(w),source:"import",name:l.name,device:"asset",inferenceMs:0,tier:"spatial"},u=null,m=null;if(l.tiles.mask){let h=d(p(l.tiles.mask));if(await B(h)!==l.hashes.mask)throw new Error("Mask pixels changed. Load the original lossless spatial PNG.");let{width:v,height:M}=l.tiles.mask,b=F(v,M);b.getContext("2d").drawImage(g,0,0,v,M);let C=d(b),P=Uint8Array.from({length:v*M},(E,D)=>h[D*4]);if(u={...ht(P,C,v,M),key:`spatial-mask-${l.hashes.mask}`,mask:P,width:v,height:M,device:"asset",inferenceMs:0,edited:!0},l.foregroundRefined&&(u.foreground=C),l.tiles.background&&u.usable){let E=Math.max(0,Math.min(64,Number.isInteger(l.fillRadius)?l.fillRadius:0));m={key:"spatial-background",background:d(p(l.tiles.background)),backgroundDonors:E?G(P,v,M,E).donors:u.backgroundDonors,width:v,height:M,radius:E,device:"asset",inferenceMs:0,tier:"spatial"}}}return{manifest:l,photo:g,photoBlob:await $t(g),depth:x,subject:u,fill:m,settings:Q(l.settings)}}finally{c.close()}}async function go(t){let e=new URL(t,location.href);if(!["https:","http:","blob:"].includes(e.protocol))throw new Error("Use an HTTP(S) spatial PNG URL.");let o=await fetch(e,{credentials:"omit"});if(!o.ok)throw new Error(`Could not load spatial PNG (${o.status}).`);let n=o.body.getReader(),r=[],a=0;try{for(;;){let{value:c,done:i}=await n.read();if(i)break;if(a+=c.length,a>50*1024*1024)throw new Error("Spatial PNG must be smaller than 50 MB.");r.push(c)}}finally{await n.cancel()}let s=new Blob(r,{type:"image/png"});return{blob:s,asset:await Me(s,{required:!0})}}function vo(t,e){if(!t||t.width===e.width&&t.height===e.height)return t;let o=F(t.width,t.height),n=F(e.width,e.height);o.getContext("2d").putImageData(new ImageData(new Uint8ClampedArray(t.background),t.width,t.height),0,0);let r=n.getContext("2d");r.drawImage(o,0,0,n.width,n.height);let a=Math.max(2,Math.ceil((t.radius||0)*n.width/t.width));return{...t,key:t.key+"|"+e.key,width:n.width,height:n.height,radius:a,background:r.getImageData(0,0,n.width,n.height).data,backgroundDonors:G(e.mask,n.width,n.height,a).donors}}function bo(t,e,o){let n=Math.min(e*.8,t*.8/o),r=n*o;return{x:(t-r)/2,y:(e-n)/2,width:r,height:n}}function yo(t){let e=Uint8Array.from(t.mask,o=>o<240?255:0);try{return G(e,t.width,t.height,Math.max(1,Math.ceil(Math.max(t.width,t.height)*.002))).donors}catch{return t.foregroundDonors}}function So(t,e){if(!t)return{gap:0,span:0,detail:0,soft:0,border:0,separated:!1};let o=e?.usable?e.width:t.width,n=e?.usable?e.height:t.height,r=Math.max(1,Math.ceil(Math.sqrt(o*n/4e4))),a=[],s=[],c=[],i=0,f=0,l=0,p=0,d=0,g=0;for(let m=0;m<n;m+=r)for(let h=0;h<o;h+=r){let v=t.values[Math.min(t.height-1,Math.floor(m/n*t.height))*t.width+Math.min(t.width-1,Math.floor(h/o*t.width))];if(!Number.isFinite(v))continue;if(c.push(v),h+r<o){let b=t.values[Math.min(t.height-1,Math.floor(m/n*t.height))*t.width+Math.min(t.width-1,Math.floor((h+r)/o*t.width))];Number.isFinite(b)&&(g++,Math.abs(v-b)>.12&&d++)}let M=e?.usable?e.mask[m*o+h]:0;M>4&&(f++,M<240&&i++),M>=240?a.push(v):M<=4&&s.push(v),(h<r||h>=o-r||m<r||m>=n-r)&&(p++,M>127&&l++)}let w=(m,h)=>(m.sort((v,M)=>v-M),m[Math.min(m.length-1,Math.floor(m.length*h))]||0),x=!!e?.usable&&a.length>0&&s.length>0;return{gap:x?Math.abs(w(a,.5)-w(s,.5)):w(c,.9)-w(c,.1),span:w(c,.9)-w(c,.1),detail:d/Math.max(1,g),soft:i/Math.max(1,f),border:l/Math.max(1,p),separated:x}}function Lo(t,e=!1,o=1){let n=(p,d,g)=>Math.max(d,Math.min(g,p)),r=n(t.soft*1.4+t.border*.65+(t.detail||0)*2.5,0,1),a=t.span??t.gap,s=Math.round(n(44/Math.max(.3,a),32,64)*(1-r*.22)*(t.separated?1:.9)),c=n(Math.sqrt(Math.max(.1,o)),.72,1.05),i=(t.separated?e?4.2:2.6:2.2)*(1-r*.35)*c,f=Math.round(n(Math.min(i,Ft(t,s,e)),.8,4.4)*10)/10,l=Math.round(28+r*10+(o<.85?3:0));return{strength:s,orbitRange:f,orbitPeriod:l}}function Ao({phase:t,time:e,scale:o,pointer:n,tilt:r,interacting:a,motion:s,reduced:c}){if(c)return[0,0];let i=1-Math.exp(-Math.max(0,e)/1800),f=a||Math.hypot(...r)>.04;return(s?[Math.sin(t)*.65,Math.cos(t)*.65]:[0,0]).map((p,d)=>Math.max(-1,Math.min(1,n[d]+r[d]+p*i*(f?.15:1)))*o)}function Ft(t,e,o=!1,n=0){let r=(o?.055:.024)*(1-.65*t.soft)*(1-.7*t.border)/(1+4*(t.detail||0)),a=t.gap+(t.separated?Math.max(0,Math.min(100,n))/100*.7:0),s=Math.max(.001,a*Math.max(0,e)/100*1.6*.7),c=Math.asin(Math.min(1,r/s))*180/Math.PI;return Math.max(.25,Math.floor(Math.min(t.separated?8:3,c)*100)/100)}function Eo(t,{strength:e=35,separation:o=0,orbitRange:n=3,effect:r="spatial",aspect:a=1,filled:s=!1}={}){let c=Math.max(0,Math.min(100,e))/100,i=r==="spatial"?Math.max(0,Math.min(100,o)):0,f=Math.min(Math.max(0,n),8,Ft(t,e,s,i)),l=1.16;if(r==="parallax"){let g=f*Math.PI/180/.23*.055*1.6*c;return{range:f,zoom:Math.min(l,1/(1-g))}}let p=1.5*(.8+c*(.6+.7*i/100))/Math.min(1,Math.max(.25,a)),d=Math.asin(Math.min(1,(l-1)/p))*180/Math.PI;return f=Math.min(f,d),{range:f,zoom:Math.min(l,1+Math.sin(f*Math.PI/180)*p)}}export{We as a,qe as b,be as c,me as d,ge as e,je as f,to as g,eo as h,At as i,oo as j,no as k,ao as l,ro as m,co as n,so as o,Q as p,xo as q,Me as r,go as s,vo as t,bo as u,yo as v,So as w,Lo as x,Ao as y,Ft as z,Eo as A};
|
|
182
|
+
`,y=32;function Q(t={}){t||(t={});let e=(n,r,a,s)=>Math.max(a,Math.min(s,Number.isFinite(t[n])?t[n]:r)),o=(n,r,a)=>r.includes(t[n])?t[n]:a;return{effect:o("effect",["spatial","dof","relief","parallax","flat"],"spatial"),material:o("material",["photo","particles"],"photo"),color:o("color",["color","mono"],"color"),strength:e("strength",35,0,100),separation:e("separation",0,0,100),orbitRange:e("orbitRange",3,0,75),orbitPeriod:e("orbitPeriod",30,8,120),size:e("size",2,.5,5),density:e("density",260,80,500),edge:e("edge",50,0,100),invert:t.invert===!0,motion:t.motion!==!1,adaptive:t.adaptive!==!1,cleanEdges:t.cleanEdges!==!1,subjectView:o("subjectView",["scene","foreground","background","off"],"scene"),lens:At(t.effect==="dof"?{...t.lens,enabled:!0}:t.lens),compare:"animated",frozen:!1,map:!1}}function ve(t,e,o){if(t?.format!=="ari-spatial-photo"||t.version!==1||t.depthEncoding!=="rg16-near-white")throw new Error("Unsupported spatial PNG version.");if(t.width!==e||t.height!==o||e<64||e>8192||o>8192||e*o>32e6)throw new Error("Spatial PNG dimensions changed or exceed the supported size. Use the original file.");if(t.foregroundRefined!==void 0&&(t.foregroundRefined!==!0||!t.tiles?.mask))throw new Error("Invalid refined foreground metadata.");let n=Object.entries(t.tiles||{});if(!t.tiles?.photo||!t.tiles?.depth||n.some(([a])=>!["photo","depth","mask","background"].includes(a)))throw new Error("Spatial PNG is missing its photo or depth.");for(let[,a]of n)if(!a||![a.x,a.y,a.width,a.height].every(Number.isSafeInteger)||a.x<0||a.y<y||a.width<1||a.height<1||a.x+a.width>e||a.y+a.height>o)throw new Error("Invalid spatial PNG tile bounds.");for(let a=0;a<n.length;a++)for(let s=a+1;s<n.length;s++){let c=n[a][1],i=n[s][1];if(c.x<i.x+i.width&&c.x+c.width>i.x&&c.y<i.y+i.height&&c.y+c.height>i.y)throw new Error("Spatial PNG tiles overlap.")}if(t.tiles.background&&(!t.tiles.mask||t.tiles.background.width!==t.tiles.mask.width||t.tiles.background.height!==t.tiles.mask.height))throw new Error("Background and mask dimensions differ.");let r=t.tiles.photo.width/t.tiles.photo.height;for(let[,a]of n)if(Math.abs(a.width/a.height/r-1)>.02)throw new Error("Spatial PNG layers use different crops.");if(!t.hashes||!/^[a-f0-9]{64}$/.test(t.hashes.depth)||t.tiles.mask&&!/^[a-f0-9]{64}$/.test(t.hashes.mask))throw new Error("Spatial PNG is missing map integrity checks.");return t}function Ct(t,e){let o=new TextEncoder().encode(Et),n=new TextEncoder().encode(JSON.stringify(t)),r=new Uint8Array(o.length+4+n.length);if(r.set(o),new DataView(r.buffer).setUint32(o.length,n.length),r.set(n,o.length+4),r.length>e*y*3)throw new Error("Spatial PNG metadata is too large.");let a=new Uint8ClampedArray(e*y*4);for(let s=0;s<e*y;s++){a[s*4+3]=255;for(let c=0;c<3;c++)a[s*4+c]=r[s*3+c]||0}return a}function Pt(t,e,o){let n=new Uint8Array(Math.floor(t.length/4)*3);for(let c=0;c<t.length/4;c++)n.set(t.subarray(c*4,c*4+3),c*3);let r=new TextEncoder().encode(Et);if(!r.every((c,i)=>n[i]===c))return null;let a=new DataView(n.buffer).getUint32(r.length);if(a<2||a>n.length-r.length-4)throw new Error("Spatial PNG header is damaged.");let s=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(n.subarray(r.length+4,r.length+4+a)));return ve(s,e,o)}function kt(t){let e=new Uint8ClampedArray(t.length*4),o=[0,0];return t.forEach((n,r)=>{if(!Number.isFinite(n)||n<0||n>1)throw new Error("Spatial depth must be finite and normalized.");Y(n,o),e.set([Math.round(o[0]*255),Math.round(o[1]*255),0,255],r*4)}),e}function Tt(t){return Float32Array.from({length:t.length/4},(e,o)=>H(t[o*4]/255,t[o*4+1]/255))}var F=(t,e)=>{let o=document.createElement("canvas");return o.width=t,o.height=e,o},$t=t=>new Promise((e,o)=>t.toBlob(n=>n?e(n):o(new Error("Could not encode spatial PNG.")),"image/png")),B=async t=>Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256",t))).map(e=>e.toString(16).padStart(2,"0")).join("");async function xo({photo:t,depth:e,subject:o,fill:n,settings:r,name:a="Spatial photo"}){if(!t||!e)throw new Error("Load a photo and its depth first.");let s=Q(r),c=Math.max(32,t.width,e.width,o?.width||0),i=Math.max(t.height,e.height,o?.height||0),f=c*2,l=y+i*(o?2:1);if(f>8192||l>8192||f*l>32e6)throw new Error("This photo is too large for a spatial PNG.");let p=F(f,l),d=p.getContext("2d"),g={photo:{x:0,y,width:t.width,height:t.height},depth:{x:c,y,width:e.width,height:e.height}},w=!!o?.foreground;if(w){if(o.foreground.length!==o.width*o.height*4)throw Error("Refined foreground dimensions do not match.");let h=F(o.width,o.height);h.getContext("2d").putImageData(new ImageData(new Uint8ClampedArray(o.foreground),o.width,o.height),0,0),d.drawImage(h,0,y,t.width,t.height)}else d.drawImage(t,0,y);let x=kt(e.values);d.putImageData(new ImageData(x,e.width,e.height),c,y);let u={depth:await B(x)};if(o){let{width:h,height:v}=o,M=new Uint8ClampedArray(h*v*4);o.mask.forEach((b,C)=>M.set([b,b,b,255],C*4)),g.mask={x:0,y:y+i,width:h,height:v},d.putImageData(new ImageData(M,h,v),0,y+i),u.mask=await B(M),o.usable&&(g.background={x:c,y:y+i,width:h,height:v},d.putImageData(new ImageData(new Uint8ClampedArray(n?.background||o.background),h,v),c,y+i))}let m={format:"ari-spatial-photo",version:1,name:String(a).slice(0,200),width:f,height:l,tiles:g,hashes:u,depthEncoding:"rg16-near-white",settings:s,fillRadius:n?.radius||0,...w?{foregroundRefined:!0}:{}};return d.putImageData(new ImageData(Ct(m,f),f,y),0,0),{blob:await $t(p),manifest:m}}async function spatialSplit(t){let n=new Uint8Array(await t.arrayBuffer());if(![137,80,78,71,13,10,26,10].every((e,o)=>n[o]===e))return[t,null];let r=new DataView(n.buffer,n.byteOffset,n.byteLength),o=8;for(;o+12<=n.length;){let e=r.getUint32(o),a=String.fromCharCode(n[o+4],n[o+5],n[o+6],n[o+7]);if(a==="spAt")return[new Blob([n.subarray(o+8,o+8+e)],{type:"image/png"}),t];if(a==="IEND")break;o+=12+e}return[t,null]}async function spatialPhotoTile(t,e){let h=new DataView(await t.slice(0,24).arrayBuffer());if(h.byteLength<24||h.getUint32(12)!==1229472850||h.getUint32(16)!==e.width||h.getUint32(20)!==e.height)throw new Error("Spatial PNG photo and layers differ in size.");let n=await createImageBitmap(t,{colorSpaceConversion:"none",premultiplyAlpha:"none"});try{let r=F(e.width,e.height);return r.getContext("2d").drawImage(n,0,0,e.width,e.height),r}finally{n.close()}}async function Me(t,{required:e=!1}={}){if(t.size>50*1024*1024)throw new Error("Spatial PNG must be smaller than 50 MB.");let[tg,tp]=await spatialSplit(t);t=tg;let o=new Uint8Array(await t.slice(0,24).arrayBuffer());if(![137,80,78,71,13,10,26,10].every((i,f)=>o[f]===i)){if(e)throw new Error("Use the original spatial PNG file.");return null}if(o.length<24)throw new Error("Incomplete PNG file.");let r=new DataView(o.buffer),a=r.getUint32(16),s=r.getUint32(20);if(a>8192||s>8192||a*s>32e6){if(e)throw new Error("Spatial PNG dimensions exceed the supported size.");return null}if(a<64||s<y){if(e)throw new Error("This is not a spatial PNG.");return null}let c=await createImageBitmap(t,{colorSpaceConversion:"none",premultiplyAlpha:"none"});try{let i=F(a,y),f=i.getContext("2d",{willReadFrequently:!0});f.drawImage(c,0,0);let l=Pt(f.getImageData(0,0,a,y).data,a,s);if(!l){if(e)throw new Error("Spatial data is missing. Use the exported PNG without resizing or image optimization.");return null}let p=h=>{let v=F(h.width,h.height);return v.getContext("2d",{willReadFrequently:!0}).drawImage(c,h.x,h.y,h.width,h.height,0,0,h.width,h.height),v},d=h=>h.getContext("2d",{willReadFrequently:!0}).getImageData(0,0,h.width,h.height).data,g=tp?await spatialPhotoTile(tp,l.tiles.photo):p(l.tiles.photo),w=d(p(l.tiles.depth));if(await B(w)!==l.hashes.depth)throw new Error("Depth pixels changed. Load the original lossless spatial PNG.");let x={key:`spatial-depth-${l.hashes.depth}`,width:l.tiles.depth.width,height:l.tiles.depth.height,values:Tt(w),source:"import",name:l.name,device:"asset",inferenceMs:0,tier:"spatial"},u=null,m=null;if(l.tiles.mask){let h=d(p(l.tiles.mask));if(await B(h)!==l.hashes.mask)throw new Error("Mask pixels changed. Load the original lossless spatial PNG.");let{width:v,height:M}=l.tiles.mask,b=F(v,M);b.getContext("2d").drawImage(g,0,0,v,M);let C=d(b),P=Uint8Array.from({length:v*M},(E,D)=>h[D*4]);if(u={...ht(P,C,v,M),key:`spatial-mask-${l.hashes.mask}`,mask:P,width:v,height:M,device:"asset",inferenceMs:0,edited:!0},l.foregroundRefined&&(u.foreground=C),l.tiles.background&&u.usable){let E=Math.max(0,Math.min(64,Number.isInteger(l.fillRadius)?l.fillRadius:0));m={key:"spatial-background",background:d(p(l.tiles.background)),backgroundDonors:E?G(P,v,M,E).donors:u.backgroundDonors,width:v,height:M,radius:E,device:"asset",inferenceMs:0,tier:"spatial"}}}return{manifest:l,photo:g,photoBlob:await $t(g),depth:x,subject:u,fill:m,settings:Q(l.settings)}}finally{c.close()}}async function go(t){let e=new URL(t,location.href);if(!["https:","http:","blob:"].includes(e.protocol))throw new Error("Use an HTTP(S) spatial PNG URL.");let o=await fetch(e,{credentials:"omit"});if(!o.ok)throw new Error(`Could not load spatial PNG (${o.status}).`);let n=o.body.getReader(),r=[],a=0;try{for(;;){let{value:c,done:i}=await n.read();if(i)break;if(a+=c.length,a>50*1024*1024)throw new Error("Spatial PNG must be smaller than 50 MB.");r.push(c)}}finally{await n.cancel()}let s=new Blob(r,{type:"image/png"});return{blob:s,asset:await Me(s,{required:!0})}}function vo(t,e){if(!t||t.width===e.width&&t.height===e.height)return t;let o=F(t.width,t.height),n=F(e.width,e.height);o.getContext("2d").putImageData(new ImageData(new Uint8ClampedArray(t.background),t.width,t.height),0,0);let r=n.getContext("2d");r.drawImage(o,0,0,n.width,n.height);let a=Math.max(2,Math.ceil((t.radius||0)*n.width/t.width));return{...t,key:t.key+"|"+e.key,width:n.width,height:n.height,radius:a,background:r.getImageData(0,0,n.width,n.height).data,backgroundDonors:G(e.mask,n.width,n.height,a).donors}}function bo(t,e,o){let n=Math.min(e*.8,t*.8/o),r=n*o;return{x:(t-r)/2,y:(e-n)/2,width:r,height:n}}function yo(t){let e=Uint8Array.from(t.mask,o=>o<240?255:0);try{return G(e,t.width,t.height,Math.max(1,Math.ceil(Math.max(t.width,t.height)*.002))).donors}catch{return t.foregroundDonors}}function So(t,e){if(!t)return{gap:0,span:0,detail:0,soft:0,border:0,separated:!1};let o=e?.usable?e.width:t.width,n=e?.usable?e.height:t.height,r=Math.max(1,Math.ceil(Math.sqrt(o*n/4e4))),a=[],s=[],c=[],i=0,f=0,l=0,p=0,d=0,g=0;for(let m=0;m<n;m+=r)for(let h=0;h<o;h+=r){let v=t.values[Math.min(t.height-1,Math.floor(m/n*t.height))*t.width+Math.min(t.width-1,Math.floor(h/o*t.width))];if(!Number.isFinite(v))continue;if(c.push(v),h+r<o){let b=t.values[Math.min(t.height-1,Math.floor(m/n*t.height))*t.width+Math.min(t.width-1,Math.floor((h+r)/o*t.width))];Number.isFinite(b)&&(g++,Math.abs(v-b)>.12&&d++)}let M=e?.usable?e.mask[m*o+h]:0;M>4&&(f++,M<240&&i++),M>=240?a.push(v):M<=4&&s.push(v),(h<r||h>=o-r||m<r||m>=n-r)&&(p++,M>127&&l++)}let w=(m,h)=>(m.sort((v,M)=>v-M),m[Math.min(m.length-1,Math.floor(m.length*h))]||0),x=!!e?.usable&&a.length>0&&s.length>0;return{gap:x?Math.abs(w(a,.5)-w(s,.5)):w(c,.9)-w(c,.1),span:w(c,.9)-w(c,.1),detail:d/Math.max(1,g),soft:i/Math.max(1,f),border:l/Math.max(1,p),separated:x}}function Lo(t,e=!1,o=1){let n=(p,d,g)=>Math.max(d,Math.min(g,p)),r=n(t.soft*1.4+t.border*.65+(t.detail||0)*2.5,0,1),a=t.span??t.gap,s=Math.round(n(44/Math.max(.3,a),32,64)*(1-r*.22)*(t.separated?1:.9)),c=n(Math.sqrt(Math.max(.1,o)),.72,1.05),i=(t.separated?e?4.2:2.6:2.2)*(1-r*.35)*c,f=Math.round(n(Math.min(i,Ft(t,s,e)),.8,4.4)*10)/10,l=Math.round(28+r*10+(o<.85?3:0));return{strength:s,orbitRange:f,orbitPeriod:l}}function Ao({phase:t,time:e,scale:o,pointer:n,tilt:r,interacting:a,motion:s,reduced:c}){if(c)return[0,0];let i=1-Math.exp(-Math.max(0,e)/1800),f=a||Math.hypot(...r)>.04;return(s?[Math.sin(t)*.65,Math.cos(t)*.65]:[0,0]).map((p,d)=>Math.max(-1,Math.min(1,n[d]+r[d]+p*i*(f?.15:1)))*o)}function Ft(t,e,o=!1,n=0){let r=(o?.055:.024)*(1-.65*t.soft)*(1-.7*t.border)/(1+4*(t.detail||0)),a=t.gap+(t.separated?Math.max(0,Math.min(100,n))/100*.7:0),s=Math.max(.001,a*Math.max(0,e)/100*1.6*.7),c=Math.asin(Math.min(1,r/s))*180/Math.PI;return Math.max(.25,Math.floor(Math.min(t.separated?8:3,c)*100)/100)}function Eo(t,{strength:e=35,separation:o=0,orbitRange:n=3,effect:r="spatial",aspect:a=1,filled:s=!1}={}){let c=Math.max(0,Math.min(100,e))/100,i=r==="spatial"?Math.max(0,Math.min(100,o)):0,f=Math.min(Math.max(0,n),8,Ft(t,e,s,i)),l=1.16;if(r==="parallax"){let g=f*Math.PI/180/.23*.055*1.6*c;return{range:f,zoom:Math.min(l,1/(1-g))}}let p=1.5*(.8+c*(.6+.7*i/100))/Math.min(1,Math.max(.25,a)),d=Math.asin(Math.min(1,(l-1)/p))*180/Math.PI;return f=Math.min(f,d),{range:f,zoom:Math.min(l,1+Math.sin(f*Math.PI/180)*p)}}export{We as a,qe as b,be as c,me as d,ge as e,je as f,to as g,eo as h,At as i,oo as j,no as k,ao as l,ro as m,co as n,so as o,Q as p,xo as q,Me as r,go as s,vo as t,bo as u,yo as v,So as w,Lo as x,Ao as y,Ft as z,Eo as A};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import type {FC} from 'react';
|
|
3
3
|
/**
|
|
4
4
|
* `workerUrl(name)` = the URL of preparation worker `name` (depth-gallery-worker, -subject-worker, -fill-worker, -quality-worker).
|
|
5
|
-
* `prepareInEditor` (default
|
|
6
|
-
* `spatialAsset`, showing progress on the image.
|
|
5
|
+
* `prepareInEditor` (default false): on an editor host, prepare depth in the browser when the photo has no current
|
|
6
|
+
* `spatialAsset`, showing progress on the image. Opting in needs the preparation workers, which this package does not ship.
|
|
7
7
|
*/
|
|
8
8
|
export function createSpatialImage(options: {workerUrl(name: string): URL | string; prepareInEditor?: boolean}): FC<Record<string, unknown>>;
|
|
9
9
|
/** The saved 3D version the component loads instead of preparing (its `spatialAsset` data item). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/showcase-react-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Showcase React components for other Wix hosts. SpatialImage: a photo with spatial depth (3D), rendered from the spatialAsset the showcase media service made for it.",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"registry": "https://registry.npmjs.org/",
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
|
-
"falconPackageHash": "
|
|
50
|
+
"falconPackageHash": "62cdecd8d150117f7b14f7cc904306dd6810a7d32714bea98f35664c"
|
|
51
51
|
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/* ARI Spatial Image viewer — Monty Alon */
|
|
2
|
-
function z(c,r,s,a){if(c.length!==r*s)throw new Error("Mask dimensions do not match.");let e=new Int32Array(c.length).fill(-1),n=new Int32Array(c.length),g=0,m=0;for(let t=0;t<c.length;t++)(a?c[t]>=240:c[t]<=4)&&(e[t]=t,n[m++]=t);if(!m)return null;for(;g<m;){let t=n[g++],i=t%r,l=o=>{e[o]<0&&(e[o]=e[t],n[m++]=o)};i&&l(t-1),i+1<r&&l(t+1),t>=r&&l(t-r),t+r<c.length&&l(t+r)}return e}var D="andraniksargsyan/migan",F="406830d0fa60666da0071c342ad2fbc8f30c5c64",H="migan.onnx",V="593eba0b7e04730f1b61c0a3cbca68d97d8d6a7ff5c6a44a7b9d7fcd880fc5ae";function G(c,r,s,a=Math.max(2,Math.ceil(Math.max(r,s)*.004))){if(c.length!==r*s)throw new Error("Mask dimensions do not match.");let e=r+1,n=new Uint32Array(e*(s+1));for(let t=0;t<s;t++){let i=0;for(let l=0;l<r;l++)i+=c[t*r+l]>4?1:0,n[(t+1)*e+l+1]=n[t*e+l+1]+i}let g=new Uint8Array(c.length);for(let t=0;t<s;t++)for(let i=0;i<r;i++){let l=Math.max(0,i-a),o=Math.min(r,i+a+1),p=Math.max(0,t-a),d=Math.min(s,t+a+1);n[d*e+o]-n[p*e+o]-n[d*e+l]+n[p*e+l]&&(g[t*r+i]=255)}let m=z(g,r,s,!1);if(!m)throw new Error("Not enough visible background to reconstruct. Use Fast fill or a wider photo.");return{hole:g,donors:m,radius:a}}function J(c,r,s,a){if(c.length!==s.length*4||r.length!==c.length||a.length!==s.length)throw new Error("Fill dimensions do not match.");let e=new Uint8ClampedArray(c);for(let n=0;n<s.length;n++)s[n]&&(e.set(r.subarray(n*4,n*4+3),n*4),e[n*4+3]=c[a[n]*4+3]);return e}var K="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/",y,u,x;async function q(c){let r=`https://huggingface.co/${D}/resolve/${F}/${H}`,s;try{s=await caches.open("ari-depth-fill-models-v1")}catch{}let a=await s?.match(r),e=!!a;if(a||(a=await fetch(r)),!a.ok)throw new Error(`Model download failed (${a.status}).`);let n=a.clone(),g=a.body.getReader(),m=Number(a.headers.get("content-length"))||29546882,t=[],i=0;for(;;){let{value:d,done:h}=await g.read();if(h)break;t.push(d),i+=d.length,c(`${e?"Loading saved":"Downloading"} background model \xB7 ${Math.min(100,Math.round(i/m*100))}%`)}let l=new Uint8Array(i),o=0;for(let d of t)l.set(d,o),o+=d.length;if([...new Uint8Array(await crypto.subtle.digest("SHA-256",l))].map(d=>d.toString(16).padStart(2,"0")).join("")!==V)throw await s?.delete(r),new Error("Background model integrity check failed. Retry the download.");if(!e)try{await s?.put(r,n)}catch{}return l}self.onmessage=async({data:c})=>{let r=(a,e={})=>self.postMessage({id:c.id,type:a,...e}),s=a=>r("progress",{message:a});try{let a=performance.now(),{width:e,height:n}=c,g=new Uint8ClampedArray(c.rgba),m=new Uint8Array(c.mask),{hole:t,donors:i,radius:l}=G(m,e,n);if(!u){y||(y=await import(`${K}ort.webgpu.min.mjs`)),y.env.wasm.wasmPaths=K,y.env.wasm.numThreads=self.crossOriginIsolated?Math.min(4,navigator.hardwareConcurrency||1):1;let f=await q(s);if(s("Preparing background model\u2026"),navigator.gpu)try{u=await y.InferenceSession.create(f,{executionProviders:["webgpu"],graphOptimizationLevel:"all"}),x="webgpu"}catch{s("Using compatible CPU background processing\u2026")}u||(u=await y.InferenceSession.create(f,{executionProviders:["wasm"],graphOptimizationLevel:"all"}),x="wasm")}let o=512,p=o*o,d=Math.min(o/e,o/n),h=Math.max(1,Math.round(e*d)),b=Math.max(1,Math.round(n*d)),C=Math.floor((o-h)/2),A=Math.floor((o-b)/2),S=new OffscreenCanvas(e,n);S.getContext("2d").putImageData(new ImageData(g,e,n),0,0);let Q=new OffscreenCanvas(h,b),$=Q.getContext("2d");$.drawImage(S,0,0,h,b);let W=$.getImageData(0,0,h,b).data,O=new Uint8Array(3*p),P=new Uint8Array(p);for(let f=0;f<o;f++)for(let w=0;w<o;w++){let M=Math.max(0,Math.min(h-1,w-C)),j=Math.max(0,Math.min(b-1,f-A)),ee=Math.min(n-1,Math.floor((j+.5)/b*n))*e+Math.min(e-1,Math.floor((M+.5)/h*e)),te=t[ee]?0:1,B=f*o+w,ne=(j*h+M)*4;P[B]=te*255;for(let I=0;I<3;I++)O[I*p+B]=W[ne+I]}s(`Reconstructing hidden background \xB7 ${x==="webgpu"?"GPU":"CPU"}\u2026`);let X=performance.now(),L=new y.Tensor("uint8",O,[1,3,o,o]),U=new y.Tensor("uint8",P,[1,1,o,o]),v;try{try{v=await u.run({image:L,mask:U})}catch(f){if(x!=="webgpu")throw f;await u.release().catch(()=>{}),u=null,s("GPU fill unavailable. Reconstructing on CPU\u2026"),u=await y.InferenceSession.create(await q(s),{executionProviders:["wasm"],graphOptimizationLevel:"all"}),x="wasm",v=await u.run({image:L,mask:U})}}finally{L.dispose(),U.dispose()}let k=v[u.outputNames[0]],T=k.data;if(T.length!==3*p||k.dims[2]!==o||k.dims[3]!==o)throw new Error("Unexpected background model output.");let E=new ImageData(o,o);for(let f=0;f<p;f++){for(let w=0;w<3;w++){let M=T[w*p+f];if(!Number.isFinite(M))throw new Error("Background model returned invalid pixels.");E.data[f*4+w]=M}E.data[f*4+3]=255}for(let f of Object.values(v))f.dispose();let _=new OffscreenCanvas(o,o);_.getContext("2d").putImageData(E,0,0);let Y=new OffscreenCanvas(e,n),N=Y.getContext("2d");N.drawImage(_,C,A,h,b,0,0,e,n);let R=J(g,N.getImageData(0,0,e,n).data,t,i),Z={background:R,backgroundDonors:i,width:e,height:n,radius:l,device:x,inferenceMs:performance.now()-X,totalMs:performance.now()-a,model:D,revision:F,created:Date.now()};await u.release(),u=null,self.postMessage({id:c.id,type:"result",result:Z},[R.buffer,i.buffer])}catch(a){u&&await u.release().catch(()=>{}),u=null,r("error",{message:a.message||String(a)})}};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/* ARI Spatial Image viewer — Monty Alon */
|
|
2
|
-
function U(e,t,n,a){if(e.length!==t*n)throw new Error("Mask dimensions do not match.");let i=new Int32Array(e.length).fill(-1),c=new Int32Array(e.length),x=0,l=0;for(let o=0;o<e.length;o++)(a?e[o]>=240:e[o]<=4)&&(i[o]=o,c[l++]=o);if(!l)return null;for(;x<l;){let o=c[x++],f=o%t,u=r=>{i[r]<0&&(i[r]=i[o],c[l++]=r)};f&&u(o-1),f+1<t&&u(o+1),o>=t&&u(o-t),o+t<e.length&&u(o+t)}return i}function N(e,t,n,a){if(t.length!==n*a*4)throw new Error("Image dimensions do not match.");let i=0;for(let r of e)r>127&&i++;let c=i/e.length;if(c<.003||c>.985)return{usable:!1,coverage:c,reason:"No clear foreground/background split. Use the full image, or try a photo with a distinct subject."};let x=U(e,n,a,!0),l=U(e,n,a,!1);if(!x||!l)return{usable:!1,coverage:c,reason:"The subject boundary is uncertain. The full image is still available."};let o=new Uint8ClampedArray(t.length);for(let r=0;r<e.length;r++){let h=l[r]*4;o.set(t.subarray(h,h+4),r*4)}let f=o,u=new Uint8ClampedArray(o.length);for(let r=0;r<8;r++){u.set(f);for(let h=1;h<a-1;h++)for(let p=1;p<n-1;p++){let s=h*n+p;if(!(e[s]<=4))for(let m=0;m<3;m++)u[s*4+m]=(f[(s-1)*4+m]+f[(s+1)*4+m]+f[(s-n)*4+m]+f[(s+n)*4+m])/4}[f,u]=[u,f]}return{usable:!0,coverage:c,foregroundDonors:x,backgroundDonors:l,background:f}}var C=(e,t=0,n=1)=>Math.max(t,Math.min(n,e));function v(e,t,n,a=1){if(!Number.isSafeInteger(e)||!Number.isSafeInteger(t)||e<1||t<1||e*t>16e6||n!==e*t*a)throw Error("Quality input dimensions do not match.")}function k(e,t,n,a,{radius:i=24,amount:c=.7}={}){if(v(n,a,e.length),v(n,a,t.length,4),!Number.isFinite(i)||i<1||!Number.isFinite(c)||c<0||c>1)throw Error("Invalid edge refinement.");let x=U(e,n,a,!0),l=U(e,n,a,!1),o=new Uint8Array(e),f=new Uint8ClampedArray(t),u=0;if(!x||!l)return{mask:o,foreground:f,changed:u};for(let r=0;r<e.length;r++){let h=e[r]/255;if(h<=4/255||h>=240/255)continue;let p=x[r],s=l[r],m=r%n,D=Math.floor(r/n);if(Math.hypot(p%n-m,Math.floor(p/n)-D)>i||Math.hypot(s%n-m,Math.floor(s/n)-D)>i)continue;let g=0,y=0;for(let d=0;d<3;d++){let I=(t[p*4+d]-t[s*4+d])/255;g+=I*I,y+=(t[r*4+d]-t[s*4+d])/255*I}let A=C((g-.015)/.12),S=C((y+.035*h)/(g+.035)),M=C(h+C(S-h,-.2,.2)*c*A,0,t[r*4+3]/255);o[r]=Math.round(M*255),o[r]!==e[r]&&u++;for(let d=0;d<3;d++){let I=(t[r*4+d]-t[s*4+d]*(1-M))/Math.max(.15,M),W=t[p*4+d],E=C(M/.35),F=C(I*E+W*(1-E),0,255);f[r*4+d]=t[r*4+d]+(F-t[r*4+d])*c*A}}return{mask:o,foreground:f,changed:u}}function T(e,t,n,a,i){if(v(a,i,e.length),v(a,i,t.length),v(a,i,n.length,4),e.some(l=>!Number.isFinite(l)||l<0||l>1))throw Error("Depth must be finite and normalized.");let c=new Float32Array(e),x=0;for(let l=0;l<i;l++)for(let o=0;o<a;o++){let f=l*a+o,u=e[f],r=u*2,h=2;for(let p=-2;p<=2;p++)for(let s=-2;s<=2;s++){if(!s&&!p)continue;let m=o+s,D=l+p;if(m<0||m>=a||D<0||D>=i)continue;let g=D*a+m,y=e[g]-u;if(t[f]>=128!=t[g]>=128||Math.abs(y)>.08)continue;let A=0;for(let M=0;M<3;M++)A+=((n[f*4+M]-n[g*4+M])/255)**2;let S=Math.exp(-(s*s+p*p)/4-y*y/.0025-A/.06);r+=e[g]*S,h+=S}c[f]=C(u*.25+r/h*.75),Math.abs(c[f]-u)>1e-4&&x++}return{values:c,changed:x}}self.onmessage=({data:e})=>{try{let{width:t,height:n}=e,a=new Uint8ClampedArray(e.rgba),i=performance.now(),c=new OffscreenCanvas(e.maskWidth,e.maskHeight),x=new Uint8ClampedArray(e.mask.length*4);e.mask.forEach((g,y)=>x.set([g,g,g,255],y*4)),c.getContext("2d").putImageData(new ImageData(x,e.maskWidth,e.maskHeight),0,0);let l=new OffscreenCanvas(t,n),o=l.getContext("2d");o.drawImage(c,0,0,t,n);let f=o.getImageData(0,0,t,n).data,u=Uint8Array.from({length:t*n},(g,y)=>Math.min(f[y*4],a[y*4+3])),r=k(u,a,t,n,{radius:Math.max(12,Math.ceil(Math.max(t,n)*.025))}),h=new Float32Array(t*n);for(let g=0;g<n;g++)for(let y=0;y<t;y++){let A=Math.max(0,Math.min(e.depthWidth-1,(y+.5)/t*e.depthWidth-.5)),S=Math.max(0,Math.min(e.depthHeight-1,(g+.5)/n*e.depthHeight-.5)),M=Math.floor(A),d=Math.floor(S),I=Math.min(e.depthWidth-1,M+1),W=Math.min(e.depthHeight-1,d+1),E=A-M,F=S-d;h[g*t+y]=(e.depth[d*e.depthWidth+M]*(1-E)+e.depth[d*e.depthWidth+I]*E)*(1-F)+(e.depth[W*e.depthWidth+M]*(1-E)+e.depth[W*e.depthWidth+I]*E)*F}let p=T(h,r.mask,a,t,n),s={...N(r.mask,a,t,n),mask:r.mask,foreground:r.foreground,width:t,height:n,key:e.key+"|edges-v1"},m={subject:s,depth:{values:p.values,width:t,height:n,key:e.key+"|depth-v1"},stats:{edgePixels:r.changed,depthPixels:p.changed,prepareMs:Math.round(performance.now()-i)}},D=[s.mask.buffer,s.foreground.buffer,m.depth.values.buffer];s.usable&&D.push(s.foregroundDonors.buffer,s.backgroundDonors.buffer,s.background.buffer),self.postMessage({id:e.id,type:"result",result:m},D)}catch(t){self.postMessage({id:e.id,type:"error",message:t.message})}};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/* ARI Spatial Image viewer — Monty Alon */
|
|
2
|
-
var M="studioludens/birefnet-lite-512",v="962e67969ec6acec9c19fab76acee4f5e22e990c";function I(e,r,n,s,c={}){for(let o=0;o<e.length;o++)e[o]=Math.round(e[o]*r[o*4+3]/255);return{...T(e,r,n,s),mask:e,width:n,height:s,...c,created:Date.now()}}function U(e,r,n,s){if(e.length!==r*n)throw new Error("Mask dimensions do not match.");let c=new Int32Array(e.length).fill(-1),o=new Int32Array(e.length),p=0,l=0;for(let t=0;t<e.length;t++)(s?e[t]>=240:e[t]<=4)&&(c[t]=t,o[l++]=t);if(!l)return null;for(;p<l;){let t=o[p++],i=t%r,u=a=>{c[a]<0&&(c[a]=c[t],o[l++]=a)};i&&u(t-1),i+1<r&&u(t+1),t>=r&&u(t-r),t+r<e.length&&u(t+r)}return c}function T(e,r,n,s){if(r.length!==n*s*4)throw new Error("Image dimensions do not match.");let c=0;for(let a of e)a>127&&c++;let o=c/e.length;if(o<.003||o>.985)return{usable:!1,coverage:o,reason:"No clear foreground/background split. Use the full image, or try a photo with a distinct subject."};let p=U(e,n,s,!0),l=U(e,n,s,!1);if(!p||!l)return{usable:!1,coverage:o,reason:"The subject boundary is uncertain. The full image is still available."};let t=new Uint8ClampedArray(r.length);for(let a=0;a<e.length;a++){let f=l[a]*4;t.set(r.subarray(f,f+4),a*4)}let i=t,u=new Uint8ClampedArray(t.length);for(let a=0;a<8;a++){u.set(i);for(let f=1;f<s-1;f++)for(let w=1;w<n-1;w++){let m=f*n+w;if(!(e[m]<=4))for(let g=0;g<3;g++)u[m*4+g]=(i[(m-1)*4+g]+i[(m+1)*4+g]+i[(m-n)*4+g]+i[(m+n)*4+g])/4}[i,u]=[u,i]}return{usable:!0,coverage:o,foregroundDonors:p,backgroundDonors:l,background:i}}var h,d,x,y;self.onmessage=async({data:e})=>{let r=(n,s={})=>self.postMessage({id:e.id,type:n,...s});try{h||(h=await import("https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.8.1/dist/transformers.min.js")),h.env.allowLocalModels=!1,h.env.backends.onnx.wasm.numThreads=self.crossOriginIsolated?Math.min(4,navigator.hardwareConcurrency||1):1;let n=performance.now(),s=async(A,_)=>{let C=E=>{E.status==="progress"&&r("progress",{message:`Downloading subject model \xB7 ${Math.round(E.progress||0)}%`})};r("progress",{message:"Loading general subject model\u2026"}),d=await h.AutoModel.from_pretrained(M,{device:A,dtype:_,revision:v,progress_callback:C}),y=A},o=e.device==="webgpu"&&!!navigator.gpu&&!!await navigator.gpu.requestAdapter()?"webgpu":"wasm",p=e.dtype??"fp32",l=o+":"+p;d&&y!==l&&(await d.dispose().catch(()=>{}),d=null),d||(await s(o,p),y=l),x||(x=await h.AutoProcessor.from_pretrained(M,{revision:v})),r("progress",{message:`Finding foreground \xB7 ${y.startsWith("webgpu")?"GPU":"CPU"}\u2026`});let t=new Uint8ClampedArray(e.rgba),i=new h.RawImage(t,e.width,e.height,4),u=performance.now(),{pixel_values:a}=await x(i),f=await d({input_image:a}),w=f.logits||f.output_image;if(!w)throw new Error("Subject model returned no mask.");let m=w[0].sigmoid().mul(255).to("uint8"),g=await h.RawImage.fromTensor(m).resize(e.width,e.height),S=performance.now()-u;r("progress",{message:"Preparing separate layers and filling hidden background\u2026"});let b=I(new Uint8Array(g.data),t,e.width,e.height,{model:M,revision:v,device:y.split(":")[0],dtype:y.split(":")[1],inferenceMs:S,totalMs:performance.now()-n}),D=[b.mask.buffer];b.usable&&D.push(b.foregroundDonors.buffer,b.backgroundDonors.buffer,b.background.buffer),self.postMessage({id:e.id,type:"result",result:b},D)}catch(n){d&&await d.dispose().catch(()=>{}),d=null,x=null,r("error",{message:n.message||String(n)})}};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/* ARI Spatial Image viewer — Monty Alon */
|
|
2
|
-
var l="onnx-community/depth-anything-v2-small",p="4472b7362082ad9968fee890ca0f1e5aca36b93d",c={fast:{label:"Fast",size:322},balanced:{label:"Balanced",size:518},detail:{label:"Detail",size:770},local:{label:"Local HQ",size:1536}};function y(e){let t=1/0,r=-1/0;for(let s of e)Number.isFinite(s)&&(t=Math.min(t,s),r=Math.max(r,s));if(!Number.isFinite(t))throw new Error("The model returned no valid depth values.");let a=r-t;return Float32Array.from(e,s=>Number.isFinite(s)&&a>1e-8?(s-t)/a:.5)}var o,n,d;self.onmessage=async({data:e})=>{let t=(r,a={})=>self.postMessage({id:e.id,type:r,...a});try{t("progress",{message:"Loading depth engine\u2026"}),o||(o=await import("https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.8.1/dist/transformers.min.js")),o.env.allowLocalModels=!1,o.env.backends.onnx.wasm.numThreads=self.crossOriginIsolated?Math.min(4,navigator.hardwareConcurrency||1):1;let r=e.device!=="wasm"&&navigator.gpu?await navigator.gpu.requestAdapter():null;if(e.device==="webgpu"&&!r)throw new Error("WebGPU is unavailable. Select Auto or CPU.");let a=r?"webgpu":"wasm",s=e.dtype??(a==="webgpu"?"fp32":"q8"),m=`${a}:${s}`,v=performance.now();d!==m&&(n&&await n.dispose(),n=null,d=null,n=await o.pipeline("depth-estimation",l,{device:a,dtype:s,revision:p,progress_callback:h=>{h.status==="progress"&&t("progress",{message:`Downloading model \xB7 ${Math.round(h.progress||0)}%`})}}),d=m);let f=n.processor.image_processor||n.processor.feature_extractor;if(!f)throw new Error("Unsupported model processor.");f.size={width:c[e.tier].size,height:c[e.tier].size};let b=new o.RawImage(new Uint8ClampedArray(e.rgba),e.width,e.height,4);t("progress",{message:`Estimating depth \xB7 ${a==="webgpu"?"GPU":"CPU"}\u2026`});let E=performance.now(),u=await n(b),i=Float32Array.from(u.predicted_depth.data,Number),g=u.predicted_depth.dims,w=y(i);self.postMessage({id:e.id,type:"result",result:{values:w,raw:i,width:g.at(-1),height:g.at(-2),device:a,dtype:s,model:l,revision:p,tier:e.tier,inferenceMs:performance.now()-E,totalMs:performance.now()-v,created:Date.now()}},[w.buffer,i.buffer])}catch(r){t("error",{message:r.message||String(r)})}};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// The viewer bundle asks for these only when it prepares depth in the browser, which `SpatialImage` never
|
|
2
|
-
// does (it passes `prepareInEditor: false`): depth is made by the showcase media service and
|
|
3
|
-
// arrives as `spatialAsset`. The bundle still requires the map; it is kept complete in case in-editor
|
|
4
|
-
// preparation is ever enabled for this host.
|
|
5
|
-
const WORKERS = {
|
|
6
|
-
'depth-gallery-worker': new URL('./viewer/workers/depth-gallery-worker.mjs', import.meta.url),
|
|
7
|
-
'depth-gallery-subject-worker': new URL('./viewer/workers/depth-gallery-subject-worker.mjs', import.meta.url),
|
|
8
|
-
'depth-gallery-fill-worker': new URL('./viewer/workers/depth-gallery-fill-worker.mjs', import.meta.url),
|
|
9
|
-
'depth-gallery-quality-worker': new URL('./viewer/workers/depth-gallery-quality-worker.mjs', import.meta.url),
|
|
10
|
-
};
|
|
11
|
-
export const workerUrl = (name) => {
|
|
12
|
-
const url = WORKERS[name];
|
|
13
|
-
if (!url) {
|
|
14
|
-
throw new Error(`Unknown preparation worker: ${name}`);
|
|
15
|
-
}
|
|
16
|
-
return url;
|
|
17
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const workerUrl: (name: string) => URL;
|