vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
2 lines (1 loc) • 13.3 kB
JavaScript
;const a=require("vue"),R=require("./BaseIcon-CObkWSlF.cjs"),ae=require("./ColorPicker-Czm9Mx_k.cjs"),O=require("./index-B7zOq_yO.cjs"),oe={class:"vue-ui-pen-and-paper-action",style:{padding:"0 !important"}},re=["disabled"],se={__name:"PenAndPaper",props:{svgRef:{type:[Object,null],required:!0},color:{type:String,default:"#2D353C"},backgroundColor:{type:String,default:"#FFFFFF"},active:{type:Boolean,default:!1},scale:{type:Number,default:1}},emits:["close"],setup(d,{emit:j}){const s=d,J=j,x=a.ref([]),k=a.ref([]),C=a.ref(s.color),N=a.ref(2),$=a.ref(!1),V=a.ref(""),r=a.ref(null),h=a.ref(null),D=a.ref(null),A=a.ref("draw"),T=a.ref(!1),f=a.ref(null),z=a.ref({x:0,y:0}),B=a.ref([""]),L=a.ref({row:0,col:0}),E=a.ref(16),I=a.ref("url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAABg2lDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TpSIVh2YQcchQnSyIijhKFYtgobQVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi6OSk6CIl/i8ptIjx4Lgf7+497t4BQrPKNKtnAtB020wn4lIuvyqFXhGGiAhCiMnMMpKZxSx8x9c9Any9i/Es/3N/jgG1YDEgIBHPMcO0iTeIZzZtg/M+scjKskp8Tjxu0gWJH7muePzGueSywDNFM5ueJxaJpVIXK13MyqZGPE0cVTWd8oWcxyrnLc5atc7a9+QvDBf0lQzXaY4ggSUkkYIEBXVUUIWNGK06KRbStB/38Q+7/hS5FHJVwMixgBo0yK4f/A9+d2sVpya9pHAc6H1xnI9RILQLtBqO833sOK0TIPgMXOkdf60JzH6S3uho0SNgcBu4uO5oyh5wuQMMPRmyKbtSkKZQLALvZ/RNeSByC/Sveb2193H6AGSpq+Ub4OAQGCtR9rrPu/u6e/v3TLu/H5C7crM1WjgWAAAABmJLR0QAqwB5AHWF+8OUAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH5gwUExIUagzGcQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAABfSURBVBjTldAxDoNQDIPhL0+q1L33P1AvAhN7xfK6WAgoLfSfrNiykpQtE+7RLzx2vgF9D3o8lWDmn1QVVMP0LZQGmNtqp1/cmou0XHdG/+sYeGZwFBqPCub8rkcvvAGvsi1VYarR8wAAAABJRU5ErkJggg==') 5 5, auto");function K(l){if(!r.value||A.value!=="text"||T.value)return;const{x:e,y:n}=M(l);z.value={x:e,y:n},B.value=[""],L.value={row:0,col:0};const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("x",e),t.setAttribute("y",n),t.setAttribute("fill",C.value),t.setAttribute("font-size",E.value*s.scale),t.setAttribute("font-family","sans-serif"),t.setAttribute("class","vue-data-ui-doodle"),t.setAttribute("dominant-baseline","hanging"),t.setAttribute("pointer-events","all");const o=document.createElementNS("http://www.w3.org/2000/svg","tspan");o.setAttribute("x",e),o.setAttribute("dy","0"),o.textContent="",t.appendChild(o),t.style.pointerEvents="none",t.style.userSelect="none",r.value.appendChild(t),f.value=t,T.value=!0,window.addEventListener("keydown",U),window.addEventListener("mousedown",H,!0),q(),G()}function U(l){if(!T.value)return;let{row:e,col:n}=L.value,t=B.value.slice(),o=!1;if(l.key==="Enter"){const u=t[e],i=u.slice(0,n),v=u.slice(n);t.splice(e,1,i,v),e+=1,n=0,o=!0,l.preventDefault()}else if(l.key==="Backspace"){if(n>0)t[e]=t[e].slice(0,n-1)+t[e].slice(n),n-=1,o=!0;else if(e>0){const u=t[e-1].length;t[e-1]+=t[e],t.splice(e,1),e-=1,n=u,o=!0}l.preventDefault()}else if(l.key==="Delete")n<t[e].length?(t[e]=t[e].slice(0,n)+t[e].slice(n+1),o=!0):e<t.length-1&&(t[e]+=t[e+1],t.splice(e+1,1),o=!0),l.preventDefault();else if(l.key==="ArrowLeft")n>0?n-=1:e>0&&(e-=1,n=t[e].length),o=!0,l.preventDefault();else if(l.key==="ArrowRight")n<t[e].length?n+=1:e<t.length-1&&(e+=1,n=0),o=!0,l.preventDefault();else if(l.key==="ArrowUp")e>0&&(e-=1,n=Math.min(n,t[e].length),o=!0),l.preventDefault();else if(l.key==="ArrowDown")e<t.length-1&&(e+=1,n=Math.min(n,t[e].length),o=!0),l.preventDefault();else if(l.key.length===1&&!l.ctrlKey&&!l.metaKey&&!l.altKey)t[e]=t[e].slice(0,n)+l.key+t[e].slice(n),n+=1,o=!0,l.preventDefault();else if(l.key==="Escape"){X(!0);return}else l.key==="Tab"&&l.preventDefault();o&&(B.value=t,L.value={row:e,col:n},q(),G())}function q(){const l=f.value,{x:e}=z.value;for(;l.firstChild;)l.removeChild(l.firstChild);B.value.forEach((n,t)=>{const o=document.createElementNS("http://www.w3.org/2000/svg","tspan");o.setAttribute("x",e),o.setAttribute("dy",t===0?"0":`${E.value*1.2*s.scale}`),o.textContent=n.length?n:"",l.appendChild(o)})}function G(){const l=r.value.querySelector(".vue-data-ui-svg-caret");l&&r.value.removeChild(l);const e=f.value;if(!e)return;const{x:n,y:t}=z.value,{row:o,col:u}=L.value,i=E.value*s.scale,v=e.childNodes[o];if(!v)return;let g=v.textContent.slice(0,u);g.endsWith(" ")&&(g+=" ");const c=document.createElementNS("http://www.w3.org/2000/svg","text");c.setAttribute("x",n),c.setAttribute("y",t),c.setAttribute("font-size",i),c.setAttribute("font-family","sans-serif"),c.textContent=g||"",r.value.appendChild(c);const m=c.getBBox();r.value.removeChild(c);let p=t+o*i*1.2,b=n+m.width;const w=document.createElementNS("http://www.w3.org/2000/svg","rect");w.setAttribute("x",b),w.setAttribute("y",p),w.setAttribute("width",2),w.setAttribute("height",i),w.setAttribute("fill",C.value),w.setAttribute("class","vue-data-ui-svg-caret"),r.value.appendChild(w)}function H(l){if(f.value&&!f.value.contains(l.target)){const e=f.value.children;e.length===1&&(e[0].textContent===""||e[0].textContent==="")&&f.value.remove(),X(!1)}}function X(l=!1){var o;window.removeEventListener("keydown",U),window.removeEventListener("mousedown",H,!0);const e=r.value.querySelector(".vue-data-ui-svg-caret");e&&r.value.removeChild(e);const n=(o=f.value)==null?void 0:o.children;let t=!1;if(n&&n.length===1){const u=n[0].textContent;t=!u||u===""}l||t?f.value&&r.value.contains(f.value)&&r.value.removeChild(f.value):f.value&&r.value.contains(f.value)&&x.value.push(f.value),T.value=!1,f.value=null,B.value=[""],L.value={row:0,col:0}}const y=a.computed(()=>O.lightenHexColor(s.color,.6));function Y(){if(!r.value)return;const l=r.value.querySelector(".vue-data-ui-mask");if(l&&r.value.removeChild(l),s.active){const e=document.createElementNS("http://www.w3.org/2000/svg","rect");e.setAttribute("class","vue-data-ui-mask"),e.setAttribute("width","100%"),e.setAttribute("height","100%"),e.setAttribute("fill","transparent"),e.setAttribute("pointer-events","all"),r.value.insertBefore(e,r.value.firstChild)}}function M(l){var o;const e=s.svgRef;if(!e)return{x:0,y:0};const n=e.createSVGPoint();n.x=l.clientX,n.y=l.clientY;const t=(o=e.getScreenCTM())==null?void 0:o.inverse();return t?n.matrixTransform(t):{x:0,y:0}}function Z(l){const e=l.trim().split(/\s+/);if(e.length<4)return l;const n=e.slice(1).map(Number);if(n.length%2!==0)return l;const t=_(n),o=[`M ${t[0]} ${t[1]}`];for(let v=2;v<t.length-2;v+=2){const g=t[v-2],c=t[v-1],m=t[v],p=t[v+1],b=(g+m)/2,w=(c+p)/2;o.push(`Q ${g} ${c} ${b} ${w}`)}const u=t[t.length-2],i=t[t.length-1];return o.push(`L ${u} ${i}`),o.join(" ")}function _(l,e=1){const n=[...l];for(let t=2;t<l.length-2;t+=2){const o=l[t],u=l[t+1],i=l[t-2],v=l[t-1],g=l[t+2],c=l[t+3];n[t]=o+e*((i+g)/2-o),n[t+1]=u+e*((v+c)/2-u)}return n}function ee(l){const e=l.trim().split(/\s+/);let n="",t="",o=null,u=null;for(let i=0;i<e.length;i+=1){const v=e[i];if(isNaN(v)){if(t=v,t==="M"||t==="L")o=parseFloat(e[++i]),u=parseFloat(e[++i]),n+=`${t}${o} ${u}`;else if(t==="Q"){const g=parseFloat(e[++i]),c=parseFloat(e[++i]),m=parseFloat(e[++i]),p=parseFloat(e[++i]);g===o&&c===u?n+=`t${m-o} ${p-u}`:n+=`q${g-o} ${c-u} ${m-o} ${p-u}`,o=m,u=p}}else{const g=parseFloat(v),c=parseFloat(e[++i]);if(t==="L"){const m=g-o,p=c-u;m===0?n+=`v${p}`:p===0?n+=`h${m}`:n+=`l${m} ${p}`,o=g,u=c}else if(t==="Q"){const m=g,p=c,b=parseFloat(e[++i]),w=parseFloat(e[++i]);m===o&&p===u?n+=`t${b-o} ${w-u}`:n+=`q${m-o} ${p-u} ${b-o} ${w-u}`,o=b,u=w}}}return n}function P(l){if(A.value!=="draw"||!s.active||!r.value)return;$.value=!0;const{x:e,y:n}=M(l);D.value={x:e,y:n},V.value=`M ${e} ${n}`,h.value=document.createElementNS("http://www.w3.org/2000/svg","path"),h.value.setAttribute("stroke",C.value),h.value.setAttribute("stroke-width",N.value*s.scale),h.value.setAttribute("fill","none"),h.value.setAttribute("stroke-linecap","round"),h.value.setAttribute("stroke-linejoin","round"),h.value.setAttribute("class","vue-data-ui-doodle"),r.value.appendChild(h.value)}function F(l){if(!$.value||!r.value||!h.value)return;const{x:e,y:n}=M(l);V.value+=` ${e} ${n}`,h.value.setAttribute("d",V.value)}function S(l){if($.value&&r.value&&h.value){const{x:e,y:n}=M(l);if(D.value&&D.value.x===e&&D.value.y===n){const t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("cx",e),t.setAttribute("cy",n),t.setAttribute("r",N.value*s.scale/2),t.setAttribute("fill",C.value),t.setAttribute("class","vue-data-ui-doodle"),r.value.appendChild(t),x.value.push(t)}else{const t=h.value;t.setAttribute("d",ee(Z(V.value))),x.value.push(t)}k.value=[],h.value=""}$.value=!1}function te(){if(x.value.length>0){const l=x.value.pop();k.value.push(l),r.value&&r.value.removeChild(l)}}function ne(){if(k.value.length>0){const l=k.value.pop();x.value.push(l),r.value&&r.value.appendChild(l)}}function le(){r.value&&(r.value.innerHTML=""),x.value=[],k.value=[],Y()}a.watch(A,()=>{s.active&&(Q(),W(),A.value==="text"?r.value.style.cursor="text":r.value.style.cursor=I.value)});function W(){!s.svgRef||!s.active||(A.value==="draw"?(s.svgRef.addEventListener("mousedown",P),s.svgRef.addEventListener("mousemove",F),s.svgRef.addEventListener("mouseup",S),s.svgRef.addEventListener("mouseleave",S),s.svgRef.addEventListener("touchstart",P,{passive:!1}),s.svgRef.addEventListener("touchmove",F,{passive:!1}),s.svgRef.addEventListener("touchend",S)):A.value==="text"&&s.svgRef.addEventListener("mousedown",K),r.value&&(r.value.style.pointerEvents="auto"))}function Q(){s.svgRef&&(s.svgRef.removeEventListener("mousedown",P),s.svgRef.removeEventListener("mousemove",F),s.svgRef.removeEventListener("mouseup",S),s.svgRef.removeEventListener("mouseleave",S),s.svgRef.removeEventListener("touchstart",P),s.svgRef.removeEventListener("touchmove",F),s.svgRef.removeEventListener("touchend",S),s.svgRef.removeEventListener("mousedown",K),r.value&&(r.value.style.pointerEvents="none"))}return a.watch(()=>s.active,l=>{l?W():Q()}),a.watch(()=>s.active,()=>{a.nextTick(()=>{Y()})}),a.onMounted(()=>{a.nextTick(()=>{s.svgRef&&(r.value=document.createElementNS("http://www.w3.org/2000/svg","g"),r.value.setAttribute("class","vue-data-ui-doodles"),r.value.style.cursor=I.value,s.svgRef.appendChild(r.value),Q())})}),a.onBeforeUnmount(()=>{r.value&&s.svgRef&&(s.svgRef.removeChild(r.value),Q())}),(l,e)=>d.active?(a.openBlock(),a.createElementBlock("div",{key:0,"data-dom-to-png-ignore":"",class:"vue-ui-pen-and-paper-actions",style:a.normalizeStyle({backgroundColor:d.backgroundColor})},[a.createElementVNode("button",{class:"vue-ui-pen-and-paper-action",onClick:e[0]||(e[0]=n=>J("close")),style:a.normalizeStyle({backgroundColor:d.backgroundColor,border:`1px solid ${y.value}`})},[a.createVNode(R.default,{name:"close",stroke:d.color},null,8,["stroke"])],4),a.createElementVNode("button",oe,[a.createVNode(ae.ColorPicker,{value:C.value,"onUpdate:value":e[1]||(e[1]=n=>C.value=n),backgroundColor:d.backgroundColor,buttonBorderColor:y.value},null,8,["value","backgroundColor","buttonBorderColor"])]),a.createElementVNode("button",{class:a.normalizeClass(["vue-ui-pen-and-paper-action",{"vue-ui-pen-and-paper-action-active":A.value==="text"}]),onClick:e[2]||(e[2]=n=>A.value=A.value==="text"?"draw":"text"),style:a.normalizeStyle({backgroundColor:d.backgroundColor,border:`1px solid ${y.value}`})},[a.createVNode(R.default,{name:A.value==="draw"?"annotator":"text",stroke:d.color},null,8,["name","stroke"]),a.createElementVNode("div",{style:a.normalizeStyle({position:"absolute",bottom:"-20px",color:y.value,width:"100%",textAlign:"center",fontSize:"12px",fontVariantNumeric:"tabular-nums"})},a.toDisplayString(a.unref(O.dataLabel)({v:A.value==="draw"?N.value:E.value,s:"px",r:1})),5)],6),a.createElementVNode("button",{class:a.normalizeClass(["vue-ui-pen-and-paper-action",{"vue-ui-pen-and-paper-action-disabled":!x.value.length}]),disabled:!x.value.length,onClick:te,style:a.normalizeStyle({backgroundColor:d.backgroundColor,border:`1px solid ${y.value}`,marginTop:"20px"})},[a.createVNode(R.default,{name:"restart",stroke:d.color},null,8,["stroke"])],14,re),a.createElementVNode("button",{class:a.normalizeClass(["vue-ui-pen-and-paper-action",{"vue-ui-pen-and-paper-action-disabled":!k.value.length}]),onClick:ne,style:a.normalizeStyle({backgroundColor:d.backgroundColor,border:`1px solid ${y.value}`})},[a.createVNode(R.default,{name:"restart",stroke:d.color,style:{transform:"scaleX(-1)"}},null,8,["stroke"])],6),a.createElementVNode("button",{class:a.normalizeClass(["vue-ui-pen-and-paper-action",{"vue-ui-pen-and-paper-action-disabled":!x.value.length}]),onClick:le,style:a.normalizeStyle({backgroundColor:d.backgroundColor,border:`1px solid ${y.value}`})},[a.createVNode(R.default,{name:"trash",stroke:d.color},null,8,["stroke"])],6),A.value==="draw"?a.withDirectives((a.openBlock(),a.createElementBlock("input",{key:0,ref:"range",type:"range",class:"vertical-range",min:.5,max:12,step:.1,"onUpdate:modelValue":e[3]||(e[3]=n=>N.value=n),style:a.normalizeStyle({accentColor:d.color})},null,4)),[[a.vModelText,N.value]]):a.createCommentVNode("",!0),A.value==="text"?a.withDirectives((a.openBlock(),a.createElementBlock("input",{key:1,ref:"range",type:"range",class:"vertical-range",min:3,max:48,step:.1,"onUpdate:modelValue":e[4]||(e[4]=n=>E.value=n),style:a.normalizeStyle({accentColor:d.color})},null,4)),[[a.vModelText,E.value]]):a.createCommentVNode("",!0)],4)):a.createCommentVNode("",!0)}};exports._sfc_main=se;