vue-progressive-image
Version:
Vue progressive image loading plugin
1 lines • 3.34 kB
JavaScript
import{Transition as e,computed as t,createBlock as n,createCommentVNode as r,createElementBlock as i,createElementVNode as a,createVNode as o,defineComponent as s,inject as c,nextTick as l,normalizeClass as u,normalizeStyle as d,onMounted as f,onUnmounted as p,openBlock as m,reactive as h,ref as g,renderSlot as _,unref as v,vShow as y,watch as b,withCtx as x,withDirectives as S}from"vue";const C=`success`,w=`error`,T=Symbol(`globalOptions`);function E(e){let n=new Image,r=g(0),i=g(0),a=t(()=>r.value?i.value/r.value:.5625),o=setInterval(()=>{n?.width&&(clearInterval(o),r.value=n.width,i.value=n.height)},10),s=e=>{let t=document.createElement(`canvas`);t.width=1,t.height=1,t.setAttribute(`hidden`,`true`),document.body.appendChild(t),t.getContext(`2d`)?.drawImage(e,0,0),document.body.removeChild(t)};async function c(){let t=v(e);if(t&&(n.src=t.src,!n.complete))return new Promise((e,r)=>{n.onload=()=>{s(t),l(()=>e())},n.onerror=r})}return{width:r,height:i,aspectRatio:a,loadImage:c}}function D(e){let t=g(!1),n=new IntersectionObserver(e=>{e[0].isIntersecting&&(t.value=!0,n.disconnect())},{threshold:.2});return f(()=>{let t=v(e);t&&n.observe(t)}),p(()=>{n.disconnect()}),{watchIntersectionOnce:e=>{let n=b(t,t=>{t&&(l().then(e),n())},{immediate:!0})},isIntersected:t}}const O=[`src`,`alt`,`title`],k=[`alt`,`loading`,`src`],A={key:1,class:`v-progressive-image-slot-default`};var j=s({__name:`ProgressiveImage`,props:{src:{},placeholderSrc:{},fallbackSrc:{},alt:{},title:{},customClass:{},blur:{},lazyPlaceholder:{type:Boolean},delay:{},objectCover:{type:Boolean}},emits:[C,w],setup(s,{emit:l}){let p=s,b=c(T,{}),j=h({...p,...b}),M=l,N=g(null),P=g(null),F=g(!1),I=g(!1),L=t(()=>I.value?j.fallbackSrc:j.src),{isIntersected:R,watchIntersectionOnce:z}=D(N),{loadImage:B,aspectRatio:V,width:H}=E(P),U=t(()=>!F.value),W=t(()=>({paddingBottom:`${V.value*100}%`})),G=t(()=>{if(!(j.objectCover||H.value===0))return{maxWidth:`${H.value}px`}}),K=t(()=>[j.customClass,{"v-progressive-image-object-cover":j.objectCover,"v-progressive-image-loading":U.value}]);function q(e){let t=0;return typeof e==`string`?t=Number.parseInt(e):typeof e==`number`&&(t=e),t}function J(){B().then(()=>{setTimeout(()=>{F.value=!0,M(C)},q(j.delay))}).catch(e=>{F.value=!0,I.value=!0,M(w,e)})}return f(()=>{j.placeholderSrc&&j.blur&&document.documentElement.style.setProperty(`--progressive-image-blur`,`${q(j.blur)}px`),j.src&&z(J)}),(t,s)=>(m(),i(`div`,{ref_key:`rootRef`,ref:N,class:u([`v-progressive-image`,K.value]),style:d(G.value)},[a(`div`,{style:d(W.value)},[o(e,{css:!j.placeholderSrc,name:`v-progressive-image-main-fade`,appear:``},{default:x(()=>[v(R)?S((m(),i(`img`,{key:0,ref_key:`imageRef`,ref:P,class:`v-progressive-image-main`,src:L.value,alt:j.alt,title:j.title},null,8,O)),[[y,F.value]]):r(`v-if`,!0)]),_:1},8,[`css`]),j.placeholderSrc?(m(),n(e,{key:0,name:`v-progressive-image-placeholder-fade`,appear:``},{default:x(()=>[U.value?(m(),i(`img`,{key:0,alt:j.alt,class:`v-progressive-image-placeholder`,loading:j.lazyPlaceholder?`lazy`:`eager`,src:j.placeholderSrc},null,8,k)):r(`v-if`,!0)]),_:1})):r(`v-if`,!0),t.$slots.default?(m(),i(`div`,A,[_(t.$slots,`default`,{isLoading:U.value})])):r(`v-if`,!0)],4)],6))}});function M(e,t){e.provide(T,t),e.component(`ProgressiveImage`,j)}var N=M;export{j as ProgressiveImage,N as default,M as install};