vue-img-mapper
Version:
Vue Component to highlight interactive zones in images
2 lines (1 loc) • 9.56 kB
JavaScript
var __defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(e,t,i)=>t in e?__defProp(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i,__spreadValues=(e,t)=>{for(var i in t||(t={}))__hasOwnProp.call(t,i)&&__defNormalProp(e,i,t[i]);if(__getOwnPropSymbols)for(var i of __getOwnPropSymbols(t))__propIsEnum.call(t,i)&&__defNormalProp(e,i,t[i]);return e},__spreadProps=(e,t)=>__defProps(e,__getOwnPropDescs(t));!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("vue")):"function"==typeof define&&define.amd?define(["vue"],t):(e="undefined"!=typeof globalThis?globalThis:e||self)["vue-img-mapper"]=t(e.Vue)}(this,(function(e){"use strict";const t={inheritAttrs:!1,props:{area:{type:Object,required:!0},index:{type:Number,required:!0},extendedArea:{type:Function,required:!0},hoverOff:{type:Function,required:!0},hoverOn:{type:Function,required:!0},click:{type:Function,required:!0}},methods:{mouseMove:(e,t,i,a)=>{a.$attrs.onMousemove&&(i.preventDefault(),i.stopImmediatePropagation(),a.$emit("mousemove",e,t,i))},mouseDown:(e,t,i,a)=>{a.$attrs.onMousedown&&(i.preventDefault(),i.stopImmediatePropagation(),a.$emit("mousedown",e,t,i))},mouseUp:(e,t,i,a)=>{a.$attrs.onMouseup&&(i.preventDefault(),i.stopImmediatePropagation(),a.$emit("mouseup",e,t,i))},touchStart:(e,t,i,a)=>{a.$attrs.onTouchstart&&(i.preventDefault(),i.stopImmediatePropagation(),a.$emit("touchstart",e,t,i))},touchEnd:(e,t,i,a)=>{a.$attrs.onTouchend&&(i.preventDefault(),i.stopImmediatePropagation(),a.$emit("touchend",e,t,i))}}},i=["coords","shape","href"];t.render=function(t,a,s,r,o,n){return s.area.disabled?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("area",{key:0,coords:s.extendedArea(s.area).scaledCoords.join(","),shape:s.area.shape,href:s.area.href,alt:"map",onMouseenter:a[0]||(a[0]=e=>s.hoverOn(s.extendedArea(s.area),s.index,e)),onMouseleave:a[1]||(a[1]=e=>s.hoverOff(s.extendedArea(s.area),s.index,e)),onMousemove:a[2]||(a[2]=e=>n.mouseMove(s.extendedArea(s.area),s.index,e,this)),onMousedown:a[3]||(a[3]=e=>n.mouseDown(s.extendedArea(s.area),s.index,e,this)),onMouseup:a[4]||(a[4]=e=>n.mouseUp(s.extendedArea(s.area),s.index,e,this)),onTocuhstart:a[5]||(a[5]=e=>n.touchStart(s.extendedArea(s.area),s.index,e,this)),onTouchend:a[6]||(a[6]=e=>n.touchEnd(s.extendedArea(s.area),s.index,e,this)),onClick:a[7]||(a[7]=e=>s.click(s.extendedArea(s.area),s.index,e))},null,40,i))};const a={position:"absolute",top:0,left:0},s=__spreadProps(__spreadValues({},a),{zIndex:1,userSelect:"none"}),r=__spreadProps(__spreadValues({},s),{width:"100%",height:"auto"}),o={position:"relative"},n=__spreadProps(__spreadValues({},a),{pointerEvents:"none",zIndex:2}),l={src:{type:String,required:!0},map:{type:Object,required:!0},areaKeyName:{type:String,default:"id"},active:{type:Boolean,default:!0},disabled:{type:Boolean,default:!1},fillColor:{type:String,default:"rgba(255, 255, 255, 0.5)"},strokeColor:{type:String,default:"rgba(0, 0, 0, 0.5)"},lineWidth:{type:Number,default:1},imgWidth:{type:Number,default:0},width:{type:Number,default:0},height:{type:Number,default:0},natural:{type:Boolean,default:!1},stayHighlighted:{type:Boolean,default:!1},stayMultiHighlighted:{type:Boolean,default:!1},toggleHighlighted:{type:Boolean,default:!1},responsive:{type:Boolean,default:!1},parentWidth:{type:Number,default:0}},h=(e,t,i,a,s,r,o)=>(console.log(),"rect"===e&&r?((e,t,i,a,s)=>{const[r,o,n,l]=e;s.fillStyle=t,s.lineWidth=i,s.strokeStyle=a,s.strokeRect(r,o,n-r,l-o),s.fillRect(r,o,n-r,l-o)})(t,i,a,s,o):"circle"===e&&r?((e,t,i,a,s)=>{s.fillStyle=t,s.beginPath(),s.lineWidth=i,s.strokeStyle=a,s.arc(e[0],e[1],e[2],0,2*Math.PI),s.closePath(),s.stroke(),s.fill()})(t,i,a,s,o):!("poly"!==e||!r)&&((e,t,i,a,s)=>{const r=e.reduce(((e,t,i,a)=>i%2?e:[...e,a.slice(i,i+2)]),[]);s.fillStyle=t,s.beginPath(),s.lineWidth=i,s.strokeStyle=a,r.forEach((e=>s.lineTo(e[0],e[1]))),s.closePath(),s.stroke(),s.fill()})(t,i,a,s,o)),d=e.defineComponent({name:"ImageMapper",components:{RenderAreas:t},props:l,data(){return{mapState:this.map,storedMap:this.mapState,isRendered:!1,imgRef:null,ctx:null}},computed:{containerStyle:()=>o,canvasStyle:()=>n,mapStyle(){return this.onClick&&{cursor:"pointer"}||void 0},imgStyle(){return this.responsive?r:s}},watch:{parentWidth(){this.responsive&&this.initCanvas()}},updated(){!this.isRendered&&this.map.areas.length&&(this.ctx=this.$refs.canvas.getContext("2d"),this.updateCacheMap(),this.isRendered=!0),JSON.stringify(this.mapState)===JSON.stringify(this.map)&&(this.updateCacheMap(),this.initCanvas(),this.updateCanvas())},methods:{imageMouseMove:(e,t)=>{t.$attrs.onImageMouseMove&&(e.preventDefault(),e.stopImmediatePropagation(),t.$emit("imageMouseMove",e))},imageClick:(e,t)=>{t.$attrs.onImageClick&&(e.preventDefault(),e.stopImmediatePropagation(),t.$emit("imageClick",e))},clearHighlightedArea(){this.mapState=this.storedMap,this.initCanvas()},extendedArea(e){const t=this.scaleCoords(e.coords),i=this.computeCenter(e);return __spreadProps(__spreadValues({},e),{scaledCoords:t,center:i})},updateCacheMap(){this.mapState=this.map,this.storedMap=this.map},getDimensions(e){return"function"==typeof this[e]?this[e](this.$refs.img):this[e]},getValues(e,t,i="area"){const{naturalWidth:a,naturalHeight:s,clientWidth:r,clientHeight:o}=this.$refs.img;return"width"===e?this.responsive?this.parentWidth:this.natural?a:this.width||"image"===i?t:r:"height"===e?this.responsive?o:this.natural?s:this.height||"image"===i?t:o:0},initCanvas(e=!1){const t=this.getDimensions("width"),i=this.getDimensions("height"),a=this.getValues("width",t),s=this.getValues("height",i);(this.width||this.responsive)&&(this.$refs.img.width=this.getValues("width",t,"image")),(this.height||this.responsive)&&(this.$refs.img.height=this.getValues("height",i,"image")),this.$refs.canvas.width=a,this.$refs.canvas.height=s,this.$refs.container.style.width=`${a}px`,this.$refs.container.style.height=`${s}px`,this.ctx=this.$refs.canvas.getContext("2d"),this.ctx.fillStyle=this.fillColor,this.$attrs.onLoad&&e&&this.$emit("load",this.$refs.img,{width:a,height:s}),this.imgRef=this.$refs.img,this.renderPrefilledAreas()},hoverOn(e,t,i){const{shape:a,scaledCoords:s,fillColor:r,lineWidth:o,strokeColor:n,active:l}=e;this.active&&h(a,s,r||this.fillColor,o||this.lineWidth,n||this.strokeColor,null==l||l,this.ctx),this.$attrs.onMouseenter&&(i.preventDefault(),i.stopImmediatePropagation(),this.$emit("mouseenter",e,t,i))},hoverOff(e,t,i){this.active&&(this.ctx.clearRect(0,0,this.$refs.canvas.width,this.$refs.canvas.height),this.renderPrefilledAreas()),this.$attrs.onMouseleave&&(i.preventDefault(),i.stopImmediatePropagation(),this.$emit("mouseleave",e,t,i))},click(e,t,i){var a;if((null==(a=e.active)||a)&&(this.stayHighlighted||this.stayMultiHighlighted||this.toggleHighlighted)){const t=__spreadValues({},e),i=this.stayMultiHighlighted?this.mapState:this.storedMap;this.toggleHighlighted&&t.preFillColor?delete t.preFillColor:(this.stayHighlighted||this.stayMultiHighlighted)&&(t.preFillColor=e.fillColor||this.fillColor);const a=i.areas.map((i=>i[this.areaKeyName]===e[this.areaKeyName]?t:i));this.mapState=__spreadProps(__spreadValues({},this.mapState),{areas:a})}this.$attrs.onClick&&(i.preventDefault(),i.stopImmediatePropagation(),this.$emit("click",e,t,i))},scaleCoords(e){const t=this.width&&this.imgWidth&&this.imgWidth>0?this.width/this.imgWidth:1;return this.responsive&&this.parentWidth?e.map((e=>e/(this.imgRef.naturalWidth/this.parentWidth))):e.map((e=>e*t))},renderPrefilledAreas(e=this.mapState){e.areas.map((e=>!!e.preFillColor&&(h(e.shape,this.scaleCoords(e.coords),e.preFillColor,e.lineWidth||this.lineWidth,e.strokeColor||this.strokeColor,!0,this.ctx),!0)))},computeCenter(e){if(!e)return[0,0];const t=this.scaleCoords(e.coords);switch(e.shape){case"circle":return[t[0],t[1]];case"poly":case"rect":default:{const e=t.length/2,{y:i,x:a}=t.reduce((({y:t,x:i},a,s)=>s%2?{y:t+a/e,x:i}:{y:t,x:i+a/e}),{y:0,x:0});return[a,i]}}},updateCanvas(){this.ctx.clearRect(0,0,this.$refs.canvas.width,this.$refs.canvas.height),this.renderPrefilledAreas(this.map)}}}),p=["src","useMap"],c=["name"];return d.render=function(t,i,a,s,r,o){const n=e.resolveComponent("RenderAreas");return e.openBlock(),e.createElementBlock("div",{id:"img-mapper",ref:"container",style:e.normalizeStyle(t.containerStyle)},[e.createElementVNode("img",{ref:"img",role:"presentation",class:"img-mapper-img",style:e.normalizeStyle(t.imgStyle),src:t.src,useMap:`#${t.mapState.name}`,alt:"map",onLoad:i[0]||(i[0]=e=>t.initCanvas(!0)),onClick:i[1]||(i[1]=e=>t.imageClick(e,this)),onMousemove:i[2]||(i[2]=e=>t.imageMouseMove(e,this))},null,44,p),e.createElementVNode("canvas",{ref:"canvas",class:"img-mapper-canvas",style:e.normalizeStyle(t.canvasStyle)},null,4),t.isRendered&&!t.disabled?(e.openBlock(),e.createElementBlock("map",{key:0,class:"img-mapper-map",name:t.mapState.name,style:e.normalizeStyle(t.mapStyle)},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.mapState.areas,((i,a)=>(e.openBlock(),e.createBlock(n,e.mergeProps({key:i[t.areaKeyName]||a.toString(),area:i,index:a,"extended-area":t.extendedArea,"hover-on":t.hoverOn,"hover-off":t.hoverOff,click:t.click},t.$attrs),null,16,["area","index","extended-area","hover-on","hover-off","click"])))),128))],12,c)):e.createCommentVNode("",!0)],4)},d}));