vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
3 lines (2 loc) • 11.9 kB
JavaScript
;const a=require("vue");require("../button/index.cjs");require("../icon/index.cjs");require("../spin/index.cjs");require("../tooltip/index.cjs");require("../form/index.cjs");require("../renderer/index.cjs");require("./captcha-slider.vue.cjs");const c=require("@vexip-ui/config"),ue=require("@vexip-ui/hooks"),g=require("@vexip-ui/utils"),He=require("./props.cjs"),B=require("./hollow-paths.cjs"),Xe=require("../form/helper.cjs"),Ae=require("./captcha-slider.vue2.cjs"),I=require("../renderer/renderer.cjs"),Ee=require("../icon/icon.cjs"),Oe=require("../spin/spin.vue2.cjs"),je=require("../button/button.cjs"),Ge=require("../tooltip/tooltip.cjs");function de(L){return typeof L=="function"||Object.prototype.toString.call(L)==="[object Object]"&&!a.isVNode(L)}const Je=a.defineComponent({name:"Captcha",props:He.captchaProps,emits:["update:visible"],setup(L,{slots:T,expose:fe}){const{idFor:ge,labelId:he,disabled:ve,loading:pe,validateField:me,setFieldValue:be}=Xe.useFieldStore(Pe),t=c.useProps("captcha",L,{type:"slide",slideTarget:{default:null,validator:e=>g.isNull(e)?!0:Array.isArray(e)?e[0]>=0&&e[0]<=100&&e[1]>=0&&e[1]<=100:e>=0&&e<=100},title:null,tip:null,successTip:null,failTip:null,image:null,tolerance:{default:1,validator:e=>e>=0},canvasSize:()=>[1e3,600],refreshIcon:c.createIconProp(),disabled:()=>ve.value,loading:()=>pe.value,loadingIcon:c.createIconProp(),loadingEffect:null,onBeforeTest:{default:null,isFunc:!0},texts:{default:()=>[],validator:e=>!e.find(r=>r.length>1)},failLimit:0,remotePoint:!1,useTrigger:!1,triggerSize:c.createSizeProp(),triggerText:null,transfer:!1,hideDelay:{default:3e3,validator:e=>e>=0},hollowShape:{default:B.squarePath,isFunc:!0},slots:()=>({})}),n=c.useNameHelper("captcha"),N=c.useLocale("captcha"),E=c.useIcons(),{timer:te}=ue.useSetTimeout(),q=a.ref(Z(t.slideTarget)),D=a.ref(!1),d=a.reactive([]),O=a.ref(!1),_=a.ref(!1),P=a.ref(!1),W=a.ref(0),b=a.ref(!1),j=a.ref(),w=a.ref(),G=a.ref(),v=a.ref(),ae=a.computed(()=>{var e;return(e=v.value)==null?void 0:e.track}),l=a.computed(()=>{var e;return!!((e=v.value)!=null&&e.isSuccess)||_.value}),we=a.computed(()=>{var e;return((e=v.value)==null?void 0:e.currentLeft)||0}),re=a.computed(()=>{var e;return(e=v.value)==null?void 0:e.resetting}),ye=a.computed(()=>q.value[0]),Y=a.ref(!1),F=a.shallowRef(Promise.resolve()),J=[],ne=.108;let $=!1,f,y;const M=a.computed(()=>t.loading||Y.value||O.value),ie=a.computed(()=>t.failLimit>0&&W.value>=t.failLimit),xe=a.computed(()=>[n.b(),n.bs("vars"),n.bm(t.type),{[n.bm("success")]:l.value,[n.bm("fail")]:!l.value&&P.value,[n.bm("dragging")]:D.value,[n.bm("disabled")]:t.disabled,[n.bm("loading")]:M.value,[n.bm("fail-locked")]:ie.value}]),Se=a.computed(()=>({left:`${we.value}%`,[n.cv("trigger-transition")]:re.value?"left 250ms ease":void 0})),K=a.computed(()=>[t.canvasSize[0]||1e3,t.canvasSize[1]||600]),R=a.computed(()=>t.disabled||l.value||M.value);a.watch(()=>t.slideTarget,e=>{q.value=Z(e)}),a.watch([()=>t.image,j],async()=>{f=void 0,await(F.value=H()),X()}),a.watch([q,()=>t.canvasSize[0],()=>t.canvasSize[1],()=>t.hollowShape],X),a.watch([()=>t.type,()=>t.remotePoint],()=>{t.type!=="slide"&&t.remotePoint&&typeof t.onBeforeTest!="function"&&console.warn("[vexip-ui:Captcha] You should specify 'on-before-test' prop to valid the captcha if you are using the 'point' type in remote")},{immediate:!0}),a.watch([()=>t.type,()=>t.texts,()=>t.texts.length,()=>t.remotePoint],()=>{t.type==="point"&&t.texts.length&&!t.remotePoint&&f&&X()}),a.watch(b,async e=>{e&&(await(F.value=H()),X())}),a.watch(l,e=>{e&&t.useTrigger&&b.value&&(clearTimeout(te.hideTrigger),te.hideTrigger=setTimeout(()=>{b.value=!1},t.hideDelay))}),a.onMounted(async()=>{await(F.value=H()),U()}),fe({dragging:D,resetting:re,isSuccess:l,imageLoading:Y,imagePromise:F,wrapper:j,canvas:w,subCanvas:G,slider:v,reset:Ne});let Q;async function H(){if(f)return;Y.value=!0,Q=`${Date.now()}${Math.round(Math.random()*1e7)}`;const e=Q,r=typeof t.image=="function"?await t.image():t.image;await new Promise(i=>{if(!g.isClient||e!==Q||!r){i();return}f=new Image,$=!1,f.src=r,r.trim().startsWith("data:image")?($=!0,i()):f.onload=()=>{$=!0,i()}}).finally(()=>{Y.value=!1})}function le(){var C;const e=w.value,r=(C=e==null?void 0:e.getContext)==null?void 0:C.call(e,"2d");if(!f||!e||!r)return;const{width:i,height:s}=e;if(r.drawImage(f,0,0,i,s),!t.texts.length||t.remotePoint)return;J.length=0;const o=Math.max(i,s)*ne;r.textBaseline="middle",r.textAlign="center",r.font=`bold ${o}px sans-serif`,r.lineWidth=2,r.strokeStyle="#fff";const z=(m,u,h,A=0,ee=g.randomHardColor())=>{r.save(),r.translate(u,h),A&&r.rotate(A*Math.PI),r.fillStyle=ee,r.fillText(m,0,0),r.strokeText(m,0,0),r.restore()},V=r.measureText(t.texts[0]),p=Math.max(o,V.width)*1.2,k=Math.max(o,V.fontBoundingBoxAscent+V.fontBoundingBoxDescent)*1.2;let x=-2*o,S=-2*o;for(const m of t.texts){let u=x,h=S;for(;Math.abs(u-x)<p&&Math.abs(h-S)<k;)u=i*.1+Math.random()*i*.8,h=s*.1+Math.random()*s*.8;x=u,S=h,J.push([u/i*100,h/s*100]),z(m,u,h,Math.random()*2)}}function Te(){if(typeof t.hollowShape=="function")return t.hollowShape;switch(t.hollowShape){case"puzzle":return B.puzzlePath;case"shield":return B.shieldPath;case"heart":return B.heartPath;default:return B.squarePath}}function U(){var se,ce;const e=w.value,r=(se=e==null?void 0:e.getContext)==null?void 0:se.call(e,"2d"),i=G.value,s=(ce=i==null?void 0:i.getContext)==null?void 0:ce.call(i,"2d");if(!f||!$||!e||!r||!t.image)return;if(t.type==="point"){le();return}if(!i||!s||!ae.value)return;if(!y){if(!g.isClient)return;y=document.createElement("canvas")}y.width=e.width,y.height=e.height;const o=y.getContext("2d");if(!o)return;r.clearRect(0,0,e.width,e.height),s.clearRect(0,0,i.width,i.height),o.clearRect(0,0,y.width,y.height);const z=e.getBoundingClientRect(),V=ae.value.getBoundingClientRect(),p=(z.width-V.width)/z.width*e.width,k=p/2+q.value[0]*(e.width-p)*.01,x=q.value[1]*e.height*.01,S=Te();o.beginPath(),o.strokeStyle="rgba(255, 255, 255, 0.5)",o.lineWidth=4;const[C,m,u,h]=S({ctx:o,x:k,y:x,width:t.canvasSize[0],height:t.canvasSize[1]});o.stroke(),o.clip(),o.drawImage(f,0,0,e.width,e.height);const A=k-C,ee=(u*.5-A)/u*100;i.style.transform=`translate3d(${ee-50}%, 0, 0)`,i.width=u,s.drawImage(y,C,m,u,h,0,m,u,h),r.save(),r.beginPath(),r.fillStyle="rgba(255, 255, 255, 0.75)",r.strokeStyle="rgba(255, 255, 255, 0.5)",r.lineWidth=10,S({ctx:r,x:k,y:x,width:t.canvasSize[0],height:t.canvasSize[1]}),r.stroke(),r.fill(),r.restore(),r.globalCompositeOperation="destination-over",r.drawImage(f,0,0,e.width,e.height)}function X(){g.nextFrameOnce(U)}async function Ne(e){var r;e&&(f=void 0,await(F.value=H()),U()),_.value=!1,P.value=!1,W.value=0,q.value=Z(),d.length=0,(r=v.value)==null||r.reset(),t.type==="point"&&le()}function Z(e=t.slideTarget){if(g.isNull(e))return[g.random(75,25),g.random(75,25)];const[r=g.random(75,25),i=g.random(75,25)]=g.ensureArray(e);return[r,i]}function Pe(e){var r;(r=v.value)==null||r.focus(e)}function Ve(e){D.value=!0,c.emitEvent(t.onDragStart,e)}function ke(e){c.emitEvent(t.onDrag,e)}function Ce(e){D.value=!1,c.emitEvent(t.onDragEnd,e)}function Ie(e){_.value=!0,P.value=!1,c.emitEvent(t.onSuccess,e),be(e),me()}function qe(){P.value=!0,++W.value,c.emitEvent(t.onFail)}function ze(){!R.value&&c.emitEvent(t.onRefresh)}function Le(e){e.stopPropagation()}async function _e(){if(M.value)return;d.length=t.texts.length;let e=t.remotePoint,r;if(!t.remotePoint&&w.value){const{width:i,height:s}=w.value,o=Math.max(i,s)*ne,z=o/i*50+t.tolerance,V=o/s*50+t.tolerance;e=!0;for(let p=0,k=d.length;p<k;++p){const[x,S]=d[p],[C,m]=J[p];if(Math.abs(x-C)>z||Math.abs(S-m)>V){e=!1;break}}}typeof t.onBeforeTest=="function"&&(a.nextTick(()=>{O.value=!0}),r=await t.onBeforeTest(d.flat()),a.nextTick(()=>{O.value=!1})),!e||r===!1?(_.value=!1,d.length=0,P.value=!0,++W.value,c.emitEvent(t.onFail)):(_.value=!0,P.value=!1,c.emitEvent(t.onSuccess,d.flat()))}function Fe(e){if(t.type!=="point"||R.value||!w.value)return;const{clientWidth:r,clientHeight:i}=w.value,{offsetX:s,offsetY:o}=e;d.push([s/r*100,o/i*100]),d.length>=t.texts.length&&a.nextTick(_e)}function Me(e,r){r.stopPropagation(),!(R.value||e!==d.length-1)&&d.pop()}function Re(){l.value||(b.value=!0)}function Be(){let e;return a.createVNode("div",{class:[n.be("image"),R.value&&n.bem("image","locked")],onClick:Fe},[t.image&&a.createVNode("div",{class:n.be("image-inner")},[a.createVNode("canvas",{ref:w,class:n.be("canvas"),width:K.value[0],height:K.value[1]},null),t.type==="slide"&&a.createVNode("div",{class:n.be("sub-image")},[a.createVNode("canvas",{ref:G,class:n.be("sub-canvas"),height:K.value[1],style:Se.value},null)])]),t.type==="point"&&a.createVNode(a.TransitionGroup,{name:n.ns("fade"),appear:!0},de(e=d.map(([r,i],s)=>a.createVNode("span",{key:s,class:n.be("pointer"),style:{top:`${i}%`,left:`${r}%`},onClick:Me.bind(null,s)},[s+1])))?e:{default:()=>[e]}),a.createVNode(a.Transition,{name:n.ns("fade")},{default:()=>[(l.value||P.value)&&a.createVNode("div",{class:[n.be("image-tip"),n.bem("image-tip",l.value?"success":"fail")],onClick:Le},[l.value?t.successTip??N.value.success:t.failTip??N.value.fail])]})])}function De(){return a.createVNode(Ae,{ref:v,class:n.bem("slider","inner"),target:ye.value,tolerance:t.tolerance,loading:M.value,"loading-icon":t.loadingIcon,"loading-lock":!0,"loading-effect":t.loadingEffect,disabled:t.disabled||ie.value,onBeforeTest:t.onBeforeTest,onSuccess:Ie,onFail:qe,onDragStart:Ve,onDrag:ke,onDragEnd:Ce},{tip:()=>a.renderSlot(T,"tip",{success:l.value},()=>[a.createVNode(I,{renderer:t.slots.tip,data:{success:l.value}},{default:()=>[t.tip??N.value.slide]})])})}function We(){return a.createVNode("div",{class:n.be("text-list")},[a.createVNode("div",{class:n.be("tip")},[a.renderSlot(T,"tip",{success:l.value},()=>[a.createVNode(I,{renderer:t.slots.tip,data:{success:l.value}},{default:()=>[t.tip??N.value.pointInOrder]})])]),a.createVNode("span",null,[":"]),a.renderSlot(T,"texts",{texts:a.toRef(t,"texts")},()=>{let e;return[a.createVNode(I,{renderer:t.slots.texts,data:{texts:a.toRef(t,"texts")}},de(e=t.texts.map((r,i)=>a.createVNode("span",{key:i,class:n.be("text")},[r])))?e:{default:()=>[e]})]})])}function Ye(){return t.type==="slide"?De():t.type==="point"?We():null}function oe(){var e;return a.createVNode("div",{ref:j,id:ge.value,class:xe.value,tabindex:-1,role:"application","aria-labelledby":he.value},[a.createVNode("div",{class:n.be("header")},[a.createVNode("div",{class:n.be("title")},[a.renderSlot(T,"title",{success:l.value},()=>[a.createVNode(I,{renderer:t.slots.title,data:{success:l.value}},{default:()=>[t.title??N.value.doCaptcha]})])]),a.createVNode("span",{role:"none",style:"flex: auto"},null),a.createVNode("button",{class:[n.be("action"),n.be("refresh"),R.value&&n.bem("action","disabled")],type:"button",onClick:ze},[a.renderSlot(T,"refresh",void 0,()=>[a.createVNode(I,{renderer:t.slots.refresh},{default:()=>[a.createVNode(Ee,a.mergeProps(E.value.refresh,{icon:t.refreshIcon||E.value.refresh.icon}),null)]})])])]),a.createVNode(Oe,{active:M.value||((e=v.value)==null?void 0:e.isLoading),delay:!1},{default:Be,icon:ue.createSlotRender(T,["loading-icon","loadingIcon"],()=>a.createVNode(I,{renderer:t.slots.loadingIcon},null))}),Ye()])}function $e(){return a.renderSlot(T,"trigger",{visible:b.value,success:l.value},()=>[a.createVNode(I,{renderer:t.slots.trigger,data:{visible:b.value,success:l.value}},{default:()=>[a.createVNode(je,{class:[n.be("button"),l.value&&n.bem("button","success")],type:l.value?"success":"primary",size:t.triggerSize,block:!0,loading:b.value&&!l.value,icon:l.value?E.value.success.icon:null,onClick:Re},{default:()=>[t.triggerText??(l.value?N.value.completed:N.value.trigger)]})]})])}return()=>t.useTrigger?a.createVNode(Ge,{class:n.bs("wrapper"),visible:b.value,trigger:"custom",raw:!0,wrapper:!0,transfer:t.transfer},{trigger:$e,default:oe}):oe()}});module.exports=Je;
//# sourceMappingURL=captcha.cjs.map