planit
Version:
Interactive markers on an image or blank canvas
1 lines • 18.8 kB
JavaScript
var Planit,bind=function(t,i){return function(){return t.apply(i,arguments)}};Planit=function(){function t(){}return t.containerClass="planit-container",t.draggingClass="is-dragging",t.imageContainer="planit-image-container",t.infoboxClass="planit-infobox",t.infoboxContainerClass="planit-infobox-container",t.markerClass="planit-marker",t.markerContainerClass="planit-markers-container",t.markerContentClass="planit-marker-content",t.prototype["new"]=function(i){return this.options=null!=i?i:{},new t.Plan(this.options)},t.randomString=function(t){var i;return null==t&&(t=16),i=Math.random().toString(36).slice(2),i+=Math.random().toString(36).slice(2),i.substring(0,t-1)},t}(),Planit.Plan=function(){function t(t){var i,n,a,o;for(this.options=null!=t?t:{},this.allMarkers=bind(this.allMarkers,this),this.addMarker=bind(this.addMarker,this),this.zoomOut=bind(this.zoomOut,this),this.zoomIn=bind(this.zoomIn,this),this.calc=bind(this.calc,this),this.zoomTo=bind(this.zoomTo,this),this.centerOn=bind(this.centerOn,this),this.resetImage=bind(this.resetImage,this),o=b(),i=0,n=o.length;n>i;i++)a=o[i],a.call(this)}var i,n,a,o,s,r,e,h,l,c,f,d,m,u,g,p,P,b,x,k,C,v,I,w,y,M,z,D,F,H,O,W;return b=function(){return[x,u,p,m,g]},x=function(){return this.options.container?this.options.container=$("#"+this.options.container):this.options.container=$("#planit"),this.container=this.options.container},u=function(){return this.container.addClass(Planit.containerClass),this.container.append('<div class="'+Planit.infoboxContainerClass+'"></div>\n<div class="'+Planit.markerContainerClass+'"></div>'),this.markersContainer=this.container.find("."+Planit.markerContainerClass).first()},p=function(){return this.options.image&&this.options.image.url?(this.container.prepend('<div class="'+Planit.imageContainer+'">\n <img src="'+this.options.image.url+'">\n</div>'),this.image=this.container.find("img").first(),this.image.load(function(t){return function(){return t.container.css({height:t.image.height()}),C.call(t),P.call(t)}}(this))):void 0},C=function(){return this.zoomId=Planit.randomString(),this.markersContainer.attr("data-zoom-id",this.zoomId),this.resetImage(),this.options.image.zoom?k.call(this):void 0},k=function(){return this.container.prepend('<div class="planit-controls">\n <a href="#" class="zoom" data-action="in">+</a>\n <a href="#" class="zoom" data-action="out">-</a>\n</div>'),this.container.find(".zoom[data-action='in']").click(function(t){return function(i){return i.preventDefault(),t.zoomIn()}}(this)),this.container.find(".zoom[data-action='out']").click(function(t){return function(i){return i.preventDefault(),t.zoomOut()}}(this)),this.container.on("dblclick",function(t){return function(i){return D.call(t,i)}}(this)),this.container.on("mousedown",function(t){return function(i){return H.call(t,i)}}(this)),$(document).on("mousemove",function(t){return function(i){return O.call(t,i)}}(this)),$(document).on("mouseup",function(t){return function(i){return W.call(t,i)}}(this))},m=function(){return this.options.image&&this.options.image.url?void 0:P.call(this)},P=function(){var t,i,n,a,o;if(this.options.markers&&this.options.markers.length>0){for(a=this.options.markers,o=[],t=0,i=a.length;i>t;t++)n=a[t],n.plan=this,o.push(Planit.Marker.create(n));return o}},g=function(){return this.container.find("."+Planit.imageContainer+" > img").length>0&&(this.image=this.container.find("."+Planit.imageContainer+" > img").first()),$(document).on("mousemove",function(t){return function(i){return v.call(t,i)}}(this)),$(document).on("mouseup",function(t){return function(i){return I.call(t,i)}}(this)),$(window).resize(function(t){return function(i){return y.call(t,i)}}(this))},t.prototype.resetImage=function(){return this.imagePosition={leftPx:0,topPx:0,width:this.image.width(),height:this.image.height(),scale:1,increment:.5},M.call(this),!0},M=function(){return this.image.css({left:this.imagePosition.leftPx+"px",top:this.imagePosition.topPx+"px",width:100*this.imagePosition.scale+"%",height:"auto"}),z.call(this)},i=function(){return this.image.animate({left:this.imagePosition.leftPx+"px",top:this.imagePosition.topPx+"px",width:100*this.imagePosition.scale+"%",height:"auto"},250),n.call(this)},z=function(){var t,i,n,a,o,s;if(o=this.container.find("."+Planit.markerClass),o.length>0){for(t=0,n=o.length;n>t;t++)a=o[t],i=this.calc(f)*($(a).attr("data-xPc")/100)+this.imagePosition.leftPx-$(a).outerWidth()/2,s=this.calc(e)*($(a).attr("data-yPc")/100)+this.imagePosition.topPx-$(a).outerHeight()/2,$(a).css({left:i+"px",top:s+"px"});return w.call(this)}},n=function(){var t,i,n,a,o,s,r,h;if(s=this.container.find("."+Planit.markerClass),s.length>0){for(r=[],t=0,n=s.length;n>t;t++)o=s[t],a=new Planit.Marker(this,$(o).attr("data-marker")),a.hideInfobox(),i=this.calc(f)*($(o).attr("data-xPc")/100)+this.imagePosition.leftPx-$(o).outerWidth()/2,h=this.calc(e)*($(o).attr("data-yPc")/100)+this.imagePosition.topPx-$(o).outerHeight()/2,r.push(function(t){return $(o).animate({left:i+"px",top:h+"px"},250,function(i){return function(){return t.positionInfobox(),t.unhideInfobox()}}(this))}(a));return r}},w=function(){var t,i,n,a,o;for(o=this.container.find("."+Planit.markerClass),t=0,i=o.length;i>t;t++)a=o[t],n=new Planit.Marker(this,$(a).attr("data-marker")),n.positionInfobox();return!0},t.prototype.centerOn=function(t){var n,s,r,h;for(r=t[0]>=50?100-t[0]:t[0],h=t[1]>=50?100-t[1]:t[1],s=50*(this.calc(o)/r),n=50*(this.calc(a)/h),this.container.find("."+Planit.infoboxClass).removeClass("active"),this.imagePosition.leftPx=-(this.calc(f)*(t[0]/100)-this.calc(o)/2),this.imagePosition.topPx=-(this.calc(e)*(t[1]/100)-this.calc(a)/2);this.calc(f)<s||this.calc(e)<n;)this.imagePosition.scale=this.imagePosition.scale+this.imagePosition.increment,this.imagePosition.leftPx=-(this.calc(f)*(t[0]/100)-this.calc(o)/2),this.imagePosition.topPx=-(this.calc(e)*(t[1]/100)-this.calc(a)/2);return i.call(this),t},t.prototype.zoomTo=function(t){var i;return i=this.imagePosition.increment,t*i+1!==this.imagePosition.scale&&(this.imagePosition.scale=t*i+1+i,this.zoomOut()),t},t.prototype.calc=function(t){return t.call(this)},f=function(){return parseFloat(this.imagePosition.width*this.imagePosition.scale)},d=function(){return parseFloat(this.imagePosition.width*this.imagePosition.increment)},o=function(){return parseFloat(this.markersContainer.width())},l=function(){return Math.abs(parseFloat(this.image.css("left")))},e=function(){return parseFloat(this.imagePosition.height*this.imagePosition.scale)},h=function(){return parseFloat(this.imagePosition.height*this.imagePosition.increment)},a=function(){return parseFloat(this.markersContainer.height())},c=function(){return Math.abs(parseFloat(this.image.css("top")))},F=function(t){return{left:(t.pageX-this.container.offset().left)/this.calc(o),top:(t.pageY-this.container.offset().top)/this.calc(a)}},D=function(t){var i;return $(t.target).attr("data-zoom-id")===this.zoomId?(i=F.call(this,t),this.zoomIn("click",i.left,i.top)):void 0},H=function(t){var i;return $(t.target).attr("data-zoom-id")===this.zoomId&&1===t.which&&(this.isDragging=!0,i=F.call(this,t),this.dragCoords={pointRef:i,imgRef:{left:0-this.calc(l),top:0-this.calc(c)},max:{right:i.left*this.calc(o)+this.calc(l),left:i.left*this.calc(o)-(this.calc(f)-(this.calc(o)+this.calc(l))),bottom:i.top*this.calc(a)+this.calc(c),top:i.top*this.calc(a)-(this.calc(e)-(this.calc(a)+this.calc(c)))}}),!0},O=function(t){var i,n,s,r,h;return this.isDragging&&(i=F.call(this,t),n=i.left*this.calc(o),s=i.top*this.calc(a),n>=this.dragCoords.max.left&&n<=this.dragCoords.max.right?(r=(i.left-this.dragCoords.pointRef.left)*this.calc(o),this.imagePosition.leftPx=this.dragCoords.imgRef.left+r):n<this.dragCoords.max.left?this.imagePosition.leftPx=this.calc(o)-this.calc(f):n>this.dragCoords.max.right&&(this.imagePosition.leftPx=0),s>=this.dragCoords.max.top&&s<=this.dragCoords.max.bottom?(h=(i.top-this.dragCoords.pointRef.top)*this.calc(a),this.imagePosition.topPx=this.dragCoords.imgRef.top+h):s<this.dragCoords.max.top?this.imagePosition.topPx=this.calc(a)-this.calc(e):s>this.dragCoords.max.bottom&&(this.imagePosition.topPx=0),M.call(this)),!0},W=function(t){return this.isDragging=!1,w.call(this),!0},t.prototype.zoomIn=function(){return this.imagePosition.scale=this.imagePosition.scale+this.imagePosition.increment,this.imagePosition.leftPx=-this.calc(l)-this.calc(d)/2,this.imagePosition.topPx=-this.calc(c)-this.calc(h)/2,i.call(this),!0},t.prototype.zoomOut=function(){var t,n;return this.imagePosition.scale>1?(this.imagePosition.scale=this.imagePosition.scale-this.imagePosition.increment,t=-this.calc(l)+this.calc(d)/2,n=-this.calc(c)+this.calc(h)/2,t>0?this.imagePosition.leftPx=0:t<this.calc(o)-this.calc(f)?this.imagePosition.leftPx=this.calc(o)-this.calc(f):this.imagePosition.leftPx=t,n>0?this.imagePosition.topPx=0:n<this.calc(a)-this.calc(e)?this.imagePosition.topPx=this.calc(a)-this.calc(e):this.imagePosition.topPx=n,i.call(this),!0):!1},s=function(){return this.markersContainer.find("."+Planit.markerClass+"."+Planit.draggingClass)},r=function(t){var i,n,s,r,e,h,l,c;return this.image?(e=t.pageX-this.container.offset().left,c=t.pageY-this.container.offset().top,n=this.image.width(),i=this.image.height(),s=parseInt(this.image.css("left")),h=parseInt(this.image.css("top")),r=(e+Math.abs(s))/n*100,l=(c+Math.abs(h))/i*100):(r=(t.pageX-this.container.offset().left)/this.calc(o),l=(t.pageY-this.container.offset().top)/this.calc(a)),[r,l]},I=function(t){var i,n;return n=this.markersContainer.find("."+Planit.draggingClass).first(),s.call(this).length>0&&(i=new Planit.Marker(this,n.attr("data-marker")),this.options.markerDragEnd&&this.options.markerDragEnd(t,i),i.savePosition(),i.positionInfobox(),s.call(this).removeClass(Planit.draggingClass)),$(t.target).hasClass(Planit.markerContainerClass)&&this.options.canvasClick&&this.options.canvasClick(t,r.call(this,t)),($(t.target).hasClass(Planit.markerClass)||$(t.target).parents("."+Planit.markerClass).length>0)&&(n=$(t.target).hasClass(Planit.markerClass)?$(t.target):$(t.target).parents("."+Planit.markerClass).first(),i=new Planit.Marker(this,n.attr("data-marker")),this.options.markerClick&&this.options.markerClick(t,i)),!0},v=function(t){var i,n,a,o,s,r,e,h,l,c,f,d,m,u;return c=this.markersContainer.find("."+Planit.markerClass+"."+Planit.draggingClass),c.length>0?(i=c.first(),(Math.abs(t.pageX-i.attr("data-drag-start-x"))>0||Math.abs(t.pageY-i.attr("data-drag-start-y"))>0)&&this.container.find("#"+i.attr("data-infobox")).removeClass("active"),f=t.pageX-this.container.offset().left,d=t.pageY-this.container.offset().top,u=this.container.width(),m=this.container.height(),o=f-i.outerWidth()/2,r=d-i.outerHeight()/2,s=f+i.outerWidth()/2,n=d+i.outerHeight()/2,e=i.outerWidth(),a=i.outerHeight(),h=0>=o?0:u>s?o:u-e,l=0>=r?0:m>n?r:m-a,i.css({left:h,top:l})):void 0},y=function(t){var i,n,a,o,s,r;for(this.image&&(this.resetImage(),this.container.height(this.image.height())),s=this.markersContainer.find(".planit-marker"),r=[],i=0,n=s.length;n>i;i++)o=s[i],a=new Planit.Marker(this,$(o).attr("data-marker")),r.push(a.set());return r},t.prototype.addMarker=function(t){var i;return null==t&&(t={}),t.plan=this,i=Planit.Marker.create(t)},t.prototype.allMarkers=function(){var t,i,n,a,o;for(a=[],o=this.container.find("."+Planit.markerClass),t=0,i=o.length;i>t;t++)n=o[t],a.push(new Planit.Marker(this,$(n).attr("data-marker")));return a},t}(),Planit.Marker=function(){function t(t,i){this.plan=t,this.remove=bind(this.remove,this),this.update=bind(this.update,this),this.savePosition=bind(this.savePosition,this),this.set=bind(this.set,this),this.animateInfobox=bind(this.animateInfobox,this),this.positionInfobox=bind(this.positionInfobox,this),this.infoboxCoords=bind(this.infoboxCoords,this),this.unhideInfobox=bind(this.unhideInfobox,this),this.showInfobox=bind(this.showInfobox,this),this.hideInfobox=bind(this.hideInfobox,this),this.infoboxVisible=bind(this.infoboxVisible,this),this.infoboxHTML=bind(this.infoboxHTML,this),this.infobox=bind(this.infobox,this),this.isDraggable=bind(this.isDraggable,this),this.id=bind(this.id,this),this.planitID=bind(this.planitID,this),this.color=bind(this.color,this),this.relativePosition=bind(this.relativePosition,this),this.position=bind(this.position,this),this.enableDragging=bind(this.enableDragging,this),this.container=this.plan.container,this.markersContainer=this.container.find("."+Planit.markerContainerClass),this.container.find("."+Planit.imageContainer+" > img").length>0&&(this.image=this.container.find("."+Planit.imageContainer+" > img").first()),this.marker=this.markersContainer.find("."+Planit.markerClass+"[data-marker='"+i+"']").first()}return t.create=function(t){var i,n,a,o,s,r,e,h,l,c,f,d,m,u;return d=t.plan,s=d.container,f=s.find("."+Planit.markerContainerClass).first(),t.planitID||(t.planitID=Planit.randomString(20)),o=t.color?t.color:"#FC5B3F",h=parseFloat(t.coords[0])/100*s.width()-15,u=parseFloat(t.coords[1])/100*s.height()-15,f.append($("<div></div>").addClass(Planit.markerClass).attr({"data-marker":t.planitID,"data-xPc":t.coords[0],"data-yPc":t.coords[1]}).css({left:h+"px",top:u+"px",backgroundColor:o})),l=f.find("."+Planit.markerClass).last(),c=new Planit.Marker(d,t.planitID),t.id&&l.attr({"data-id":t.id}),t["class"]&&l.addClass(t["class"]),t.html&&l.html(t.html),t.size&&l.css({width:t.size+"px",height:t.size+"px"}),t.draggable&&(l.addClass("draggable"),c.enableDragging(l)),d.options.markerMouseOver&&l.on("mouseover",function(t){return function(t){return d.options.markerMouseOver(t,c),!0}}(this)),d.options.markerMouseOut&&l.on("mouseout",function(t){return function(t){return d.options.markerMouseOut(t,c),!0}}(this)),t.infobox&&(r=Planit.randomString(16),e=t.infobox,m=e.position?e.position:"top",i=e.arrow?!0:!1,n=i===!0?"arrow":"",a=Planit.infoboxClass+" "+m+" "+n,s.find("."+Planit.infoboxContainerClass).append('<div class="'+a+'" id="info-'+r+'"\n data-position="'+m+'">\n '+e.html+"\n</div>"),e.offsetX&&s.find("."+Planit.infoboxClass).last().attr({"data-offset-x":e.offsetX}),e.offsetY&&s.find("."+Planit.infoboxClass).last().attr({"data-offset-y":e.offsetY}),l.attr("data-infobox","info-"+r),c.positionInfobox()),c},t.prototype.enableDragging=function(t){return t.on("mousedown",function(i){return function(i){return 1===i.which?(t=$(i.target).closest("."+Planit.markerClass),t.addClass(Planit.draggingClass),t.attr({"data-drag-start-x":i.pageX,"data-drag-start-y":i.pageY})):void 0}}(this))},t.prototype.position=function(){var t,i,n,a,o,s,r,e;return o=this.marker.position().left+this.marker.outerWidth()/2,e=this.marker.position().top+this.marker.outerHeight()/2,this.image?(i=this.image.width(),t=this.image.height(),n=parseInt(this.image.css("left")),s=parseInt(this.image.css("top")),a=(o+Math.abs(n))/i*100,r=(e+Math.abs(s))/t*100):(a=o/this.container.width()*100,r=e/this.container.height()*100),[a,r]},t.prototype.relativePosition=function(){var t,i,n,a;return i=this.marker.position().left+this.marker.outerWidth()/2,a=this.marker.position().top+this.marker.outerHeight()/2,t=i/this.container.width()*100,n=a/this.container.height()*100,[t,n]},t.prototype.color=function(){return this.marker.css("backgroundColor")},t.prototype.planitID=function(){return this.marker.attr("data-marker")},t.prototype.id=function(){return this.marker.attr("data-id")},t.prototype.isDraggable=function(){return this.marker.hasClass("draggable")},t.prototype.infobox=function(){var t;return t=this.container.find("#"+this.marker.attr("data-infobox")),t.length>0?t:null},t.prototype.infoboxHTML=function(){return this.infobox()&&this.infobox().length>0?this.infobox().html():null},t.prototype.infoboxVisible=function(){return this.infobox()&&this.infobox().hasClass("active")},t.prototype.hideInfobox=function(){return this.infoboxVisible()?(this.infobox().addClass("hidden"),!0):!1},t.prototype.showInfobox=function(){return this.infobox()&&!this.infoboxVisible()?(this.infobox().addClass("active"),this.unhideInfobox(),!0):!1},t.prototype.unhideInfobox=function(){return this.infoboxVisible()?(this.infobox().removeClass("hidden"),!0):!1},t.prototype.infoboxCoords=function(){var t,i,n,a,o,s,r,e,h,l,c,f,d,m,u,g,p,P;switch(l=this.container.find("#"+this.marker.attr("data-infobox")),u=parseFloat(this.relativePosition()[0]/100)*this.container.width(),g=parseFloat(this.relativePosition()[1]/100)*this.container.height(),r=l.outerWidth(),o=r/2,s=l.outerHeight(),a=s/2,n=this.container.width(),i=this.container.height(),m=this.marker.outerWidth(),f=m/2,d=this.marker.outerHeight(),c=d/2,t=5,p=parseInt(l.attr("data-offset-x")),p||(p=0),P=parseInt(l.attr("data-offset-y")),P||(P=0),l.attr("data-position")){case"top":e=u-o,h=g-s-c-t;break;case"right":e=u+f+t,h=g-a;break;case"bottom":e=u-o,h=g+c+t;break;case"left":e=u-r-f-t,h=g-a;break;case"top-left":e=u-r-f+t,h=g-s-c+t;break;case"top-right":e=u+f-t,h=g-s-c+t;break;case"bottom-left":e=u-r-f+t,h=g+c-t;break;case"bottom-right":e=u+f-t,h=g+c-t}return{left:e+p,top:h+P}},t.prototype.positionInfobox=function(){var t;return t=this.infoboxCoords(),this.container.find("#"+this.marker.attr("data-infobox")).css({left:t.left+"px",top:t.top+"px"}),this.position()},t.prototype.animateInfobox=function(){var t;return t=this.infoboxCoords(),this.container.find("#"+this.marker.attr("data-infobox")).animate({left:t.left+"px",top:t.top+"px"},250,function(t){return function(){return t.position()}}(this))},t.prototype.set=function(){var t,i;return this.image?(t=this.image.width()*(this.marker.attr("data-xPc")/100)+parseFloat(this.image.css("left"))-this.marker.outerWidth()/2,i=this.image.height()*(this.marker.attr("data-yPc")/100)+parseFloat(this.image.css("top"))-this.marker.outerHeight()/2):(t=this.container.width()*(this.marker.attr("data-xPc")/100)-this.marker.outerWidth()/2,i=this.container.height()*(this.marker.attr("data-yPc")/100)-this.marker.outerHeight()/2),this.marker.css({left:t+"px",top:i+"px"}),this.positionInfobox(),[t,i]},t.prototype.savePosition=function(){var t;return t=this.position(),this.marker.attr({"data-xPc":t[0],"data-yPc":t[1]}),t},t.prototype.update=function(t){var i,n;return t.color&&this.marker.css({backgroundColor:t.color}),t.infobox&&(this.marker.find("."+Planit.infoboxClass).html(t.infobox),this.positionInfobox()),void 0!==t.draggable&&(t.draggable===!0?(this.marker.addClass("draggable"),this.enableDragging(this.marker)):(this.marker.removeClass("draggable"),this.marker.off("mousedown"))),t.coords&&(i=parseFloat(t.coords[0])/100*this.container.width()-15,n=parseFloat(t.coords[1])/100*this.container.height()-15,this.marker.css({left:i+"px",top:n+"px"})),!0},t.prototype.remove=function(){return this.infobox()&&this.infobox().remove(),this.marker.remove(),!0},t}(),window.planit=new Planit;