UNPKG

vue-drag-drop-snap

Version:
2 lines (1 loc) 21.3 kB
var VueDragDropSnap=function(t){"use strict";function e(){var t=document.head||document.getElementsByTagName("head")[0],n=e.styles||(e.styles={}),i="undefined"!=typeof navigator&&/msie [6-9]\\b/.test(navigator.userAgent.toLowerCase());return function(e,o){if(!document.querySelector('style[data-vue-ssr-id~="'+e+'"]')){var r=i?o.media||"default":e,s=n[r]||(n[r]={ids:[],parts:[],element:void 0});if(!s.ids.includes(e)){var h=o.source,a=s.ids.length;if(s.ids.push(e),i&&(s.element=s.element||document.querySelector("style[data-group="+r+"]")),!s.element){var p=s.element=document.createElement("style");p.type="text/css",o.media&&p.setAttribute("media",o.media),i&&(p.setAttribute("data-group",r),p.setAttribute("data-next-index","0")),t.appendChild(p)}if(i&&(a=parseInt(s.element.getAttribute("data-next-index")),s.element.setAttribute("data-next-index",a+1)),s.element.styleSheet)s.parts.push(h),s.element.styleSheet.cssText=s.parts.filter(Boolean).join("\n");else{var l=document.createTextNode(h),f=s.element.childNodes;f[a]&&s.element.removeChild(f[a]),f.length?s.element.insertBefore(l,f[a]):s.element.appendChild(l)}}}}}function n(t){n.installed||(n.installed=!0,t.component("DragDropSnap",s))}var i={name:"drag-drop-snap",props:{width:{type:Number,default:0},height:{type:Number,default:0},parentSelector:{type:String,default:""},parentWidth:{type:Number,default:0},parentHeight:{type:Number,default:0},startingPosition:{type:String,default:null},autoSnap:{type:Boolean,default:!0},snapOptions:{type:Object,default:function(){return{"top-left":{left:10,top:10},"top-right":{right:10,top:10},"bottom-left":{left:10,bottom:10},"bottom-right":{right:10,bottom:10}}}},noStyle:{type:Boolean,default:!1},noAnimation:{type:Boolean,default:!1}},data:function(){return{shiftY:null,shiftX:null,left:0,top:0,elem:null,isIos:!1,parent:{width:0,height:0},parentElem:null,isDragging:!1,onLeft:!1,onTop:!1,currentPosition:"",events:[]}},watch:{width:function(t,e){if(!(t<e)&&0!==this.left&&(this.calculateParent(),t>this.parent.width-this.left)){var n=this.parent.width-t;this.left=n<0?0:n,this.elem.style.left=this.left+"px"}},height:function(t,e){if(!(t<e)&&0!==this.top&&(this.calculateParent(),t>this.parent.height-this.top)){var n=this.parent.height-this.height;this.top=n,this.elem.style.top=this.top+"px"}}},destroyed:function(){window.removeEventListener("resize",this.update)},mounted:function(){this.isIos=/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,this.elem=this.$el,this.parentElem=this.parentSelector&&document.body.querySelector(this.parentSelector)||this.elem.parentNode,this.calculateArea(),this.startingPosition&&(this.currentPosition=this.startingPosition,this.update()),window.addEventListener("resize",this.update)},methods:{iosMove:function(t){this.isIos&&this.elementMove(t)},elementMove:function(t){"dragging"!==this.events.slice(-1)[0]&&(this.$emit("dragging"),this.events.push("dragging")),t.preventDefault(),t.pageX||(document.body.style.overflow="hidden");var e=t.pageX||t.changedTouches[0].pageX,n=t.pageY||t.changedTouches[0].pageY,i=e-this.shiftX,o=n-this.shiftY,r=e-this.shiftX+this.elem.offsetWidth,s=n-this.shiftY+this.elem.offsetHeight;i=i<0?0:r>this.parent.width?this.parent.width-this.elem.offsetWidth:e-this.shiftX,o=o<0?0:s>this.parent.height?this.parent.height-this.elem.offsetHeight:n-this.shiftY,this.elem.style.left=i+"px",this.left=i,this.elem.style.top=o+"px",this.top=o},hang:function(t){this.events=[],this.events.push("activated"),this.$emit("activated"),this.isDragging=!0,this.calculateParent(),this.shiftX=t.pageX?t.pageX-this.elem.offsetLeft:t.changedTouches[0].pageX-this.elem.offsetLeft,this.shiftY=t.pageY?t.pageY-this.elem.offsetTop:t.changedTouches[0].pageY-this.elem.offsetTop,t.pageX?this.isIos?this.parentElem.addEventListener("touchmove",this.elementMove):(this.parentElem.addEventListener("mousemove",this.elementMove),this.parentElem.addEventListener("mouseleave",this.drop)):this.parentElem.addEventListener("touchmove",this.elementMove)},drop:function(){this.$emit("dropped"),this.isDragging=!1,document.body.style.overflow=null,this.parentElem.removeEventListener("mousemove",this.elementMove,!1),this.parentElem.removeEventListener("touchmove",this.elementMove,!1),this.parentElem.onmouseup=null,this.parentElem.ontouchend=null,this.autoSnap&&(this.calculateArea(),this.onLeft&&this.onTop?this.getSnapOption("top-left")?this.autoSnapMoveTL():this.getSnapOption("top-right")?this.autoSnapMoveTR():this.getSnapOption("bottom-left")?this.autoSnapMoveBL():this.autoSnapMoveTL():!this.onLeft&&this.onTop?this.getSnapOption("top-right")?this.autoSnapMoveTR():this.getSnapOption("top-left")?this.autoSnapMoveTL():this.getSnapOption("bottom-right")?this.autoSnapMoveBR():this.autoSnapMoveTL():this.onLeft&&!this.onTop?this.getSnapOption("bottom-left")?this.autoSnapMoveBL():this.getSnapOption("bottom-right")?this.autoSnapMoveBR():(this.getSnapOption("top-left"),this.autoSnapMoveTL()):this.onLeft||this.onTop||(this.getSnapOption("bottom-right")?this.autoSnapMoveBR():this.getSnapOption("bottom-left")?this.autoSnapMoveBL():this.getSnapOption("top-right")?this.autoSnapMoveTR():this.autoSnapMoveTL()))},getSnapOption:function(t){return!!this.snapOptions[t]&&{top:this.snapOptions[t]&&this.snapOptions[t].top,left:this.snapOptions[t]&&this.snapOptions[t].left,bottom:this.snapOptions[t]&&this.snapOptions[t].bottom,right:this.snapOptions[t]&&this.snapOptions[t].right}},autoSnapMoveTL:function(){var t=this.getSnapOption("top-left").left||0,e=this.getSnapOption("top-left").top||0;this.moveLeft(t),this.moveTop(e)},autoSnapMoveTR:function(){var t=this.getSnapOption("top-right").right||0,e=this.getSnapOption("top-right").top||0;this.moveLeft(this.parent.width-this.elem.offsetWidth-t),this.moveTop(e)},autoSnapMoveBL:function(){var t=this.getSnapOption("bottom-left").left||0,e=this.getSnapOption("bottom-left").bottom||0,n=this.parent.height-this.elem.offsetHeight-e;this.moveLeft(t),this.moveTop(n)},autoSnapMoveBR:function(){var t=this.getSnapOption("bottom-right").right||0,e=this.getSnapOption("bottom-right").bottom||0,n=this.parent.width-this.elem.offsetWidth-t,i=this.parent.height-this.elem.offsetHeight-e;this.moveLeft(n),this.moveTop(i)},moveLeft:function(t){this.left=t,this.elem.style.left=t+"px"},moveTop:function(t){this.top=t,this.elem.style.top=t+"px"},calculateParent:function(){this.parent.width=this.parentWidth||this.parentSelector&&document.body.querySelector(this.parentSelector)&&document.body.querySelector(this.parentSelector).offsetWidth||this.elem.parentNode.offsetWidth,this.parent.height=this.parentHeight||this.parentSelector&&document.body.querySelector(this.parentSelector)&&document.body.querySelector(this.parentSelector).offsetHeight||this.elem.parentNode.offsetHeight},calculateArea:function(){this.onLeft=this.left+this.elem.offsetWidth/2<this.parent.width/2,this.onTop=this.top+this.elem.offsetHeight/2<this.parent.height/2,this.onLeft&&this.onTop?this.currentPosition="TL":!this.onLeft&&this.onTop?this.currentPosition="TR":this.onLeft&&!this.onTop?this.currentPosition="BL":this.onLeft||this.onTop||(this.currentPosition="BR")},changePosition:function(t){var e=["TL","TR","BL","BR"];this.currentPosition=e.includes(t)?t:"TL",this.update()},update:function(){this.calculateParent(),this.currentPosition&&this["autoSnapMove"+this.currentPosition]()}}},o=function(){var t=this,e=t.$createElement;return(t._self._c||e)("div",{staticClass:"drag-drop-snap",class:{dragging:t.isDragging,dropped:!t.isDragging,"with-style":!t.noStyle,"with-animation":!t.noAnimation},on:{touchstart:function(e){return e.stopPropagation(),t.hang.apply(null,arguments)},touchend:function(e){return e.stopPropagation(),t.drop.apply(null,arguments)},mousedown:function(e){return e.stopPropagation(),t.hang.apply(null,arguments)},mouseup:function(e){return e.stopPropagation(),t.drop.apply(null,arguments)},touchmove:function(e){return e.stopPropagation(),t.iosMove.apply(null,arguments)}}},[t._t("default")],2)},r=[];o._withStripped=!0;var s=function(t,e,n,i,o,r,s,h){var a=("function"==typeof n?n.options:n)||{};a.__file="C:\\Users\\Enes\\Desktop\\çalışmalar\\vue-drag-drop-snap\\src\\DragDropSnap.vue",a.render||(a.render=t.render,a.staticRenderFns=t.staticRenderFns,a._compiled=!0,o&&(a.functional=!0)),a._scopeId=i;var p;if(e&&(p=function(t){e.call(this,s(t))}),void 0!==p)if(a.functional){var l=a.render;a.render=function(t,e){return p.call(e),l(t,e)}}else{var f=a.beforeCreate;a.beforeCreate=f?[].concat(f,p):[p]}return a}({render:o,staticRenderFns:r},function(t){t&&t("data-v-4efc33f3_0",{source:"\n.drag-drop-snap[data-v-4efc33f3] {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n z-index: 9;\r\n cursor: move;\n}\n.drag-drop-snap.with-style[data-v-4efc33f3] {\r\n width: 8em;\r\n height: 4.5em;\r\n background: #ccc;\r\n border-radius: 2em;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.drag-drop-snap.active[data-v-4efc33f3] {\r\n visibility: visible;\n}\n.drag-drop-snap.dropped.with-animation[data-v-4efc33f3] {\r\n transition: left 500ms, top 500ms;\r\n transition-timing-function: cubic-bezier(0.35, 1.16, 0.63, 1.17), cubic-bezier(0.35, 1.16, 0.63, 1.17);\n}\r\n",map:{version:3,sources:["C:\\Users\\Enes\\Desktop\\çalışmalar\\vue-drag-drop-snap/C:\\Users\\Enes\\Desktop\\çalışmalar\\vue-drag-drop-snap\\src\\DragDropSnap.vue"],names:[],mappings:";AA0VA;EACA,mBAAA;EACA,OAAA;EACA,SAAA;EACA,WAAA;EACA,aAAA;CACA;AAEA;EACA,WAAA;EACA,cAAA;EACA,iBAAA;EACA,mBAAA;EACA,cAAA;EACA,wBAAA;EACA,oBAAA;EACA,yEAAA;CACA;AAEA;EACA,oBAAA;CACA;AAEA;EACA,kCAAA;EACA,uGAAA;CACA",file:"DragDropSnap.vue",sourcesContent:["<template>\r\n <div\r\n :class=\"{ dragging: isDragging, dropped: !isDragging, 'with-style': !noStyle, 'with-animation': !noAnimation }\"\r\n class=\"drag-drop-snap\"\r\n @touchstart.stop=\"hang\"\r\n @touchend.stop=\"drop\"\r\n @mousedown.stop=\"hang\"\r\n @mouseup.stop=\"drop\"\r\n @touchmove.stop=\"iosMove\"\r\n >\r\n <slot></slot>\r\n </div>\r\n</template>\r\n\r\n<script>\r\nexport default {\r\n name: 'drag-drop-snap',\r\n props: {\r\n width: {\r\n type: Number,\r\n default: 0\r\n },\r\n height: {\r\n type: Number,\r\n default: 0\r\n },\r\n parentSelector: {\r\n type: String,\r\n default: ''\r\n },\r\n parentWidth: {\r\n type: Number,\r\n default: 0\r\n },\r\n parentHeight: {\r\n type: Number,\r\n default: 0\r\n },\r\n startingPosition: {\r\n type: String,\r\n default: null\r\n },\r\n autoSnap: {\r\n type: Boolean,\r\n default: true\r\n },\r\n snapOptions: {\r\n type: Object,\r\n default () {\r\n return {\r\n 'top-left': {\r\n left: 10,\r\n top: 10\r\n },\r\n 'top-right': {\r\n right: 10,\r\n top: 10\r\n },\r\n 'bottom-left': {\r\n left: 10,\r\n bottom: 10\r\n },\r\n 'bottom-right': {\r\n right: 10,\r\n bottom: 10\r\n }\r\n }\r\n }\r\n },\r\n noStyle: {\r\n type: Boolean,\r\n default: false\r\n },\r\n noAnimation: {\r\n type: Boolean,\r\n default: false\r\n },\r\n },\r\n data: () => ({\r\n shiftY: null,\r\n shiftX: null,\r\n left: 0,\r\n top: 0,\r\n elem: null,\r\n isIos: false,\r\n parent: {\r\n width: 0,\r\n height: 0\r\n },\r\n parentElem: null,\r\n isDragging: false,\r\n onLeft: false,\r\n onTop: false,\r\n currentPosition: '',\r\n events: []\r\n }),\r\n watch: {\r\n width (newWidth, oldWidth) {\r\n if (newWidth < oldWidth) return\r\n if (this.left === 0) return\r\n\r\n this.calculateParent()\r\n\r\n if (newWidth > this.parent.width - this.left) {\r\n const newLeft = this.parent.width - newWidth\r\n this.left = newLeft < 0 ? 0 : newLeft\r\n this.elem.style.left = `${this.left}px`\r\n }\r\n },\r\n\r\n height (newHeight, oldHeight) {\r\n if (newHeight < oldHeight) return\r\n if (this.top === 0) return\r\n\r\n this.calculateParent()\r\n\r\n if (newHeight > this.parent.height - this.top) {\r\n const newTop = this.parent.height - this.height\r\n this.top = newTop\r\n this.elem.style.top = `${this.top}px`\r\n }\r\n }\r\n },\r\n destroyed () {\r\n window.removeEventListener('resize', this.update)\r\n },\r\n mounted () {\r\n this.isIos = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream\r\n this.elem = this.$el\r\n\r\n this.parentElem = (this.parentSelector && document.body.querySelector(this.parentSelector)) || this.elem.parentNode\r\n\r\n this.calculateArea()\r\n\r\n if (this.startingPosition) {\r\n this.currentPosition = this.startingPosition\r\n this.update()\r\n }\r\n\r\n window.addEventListener('resize', this.update)\r\n },\r\n methods: {\r\n iosMove (e) {\r\n if (this.isIos) this.elementMove(e)\r\n },\r\n\r\n elementMove (e) {\r\n if (this.events.slice(-1)[0] !== 'dragging') {\r\n this.$emit('dragging')\r\n this.events.push('dragging')\r\n }\r\n \r\n e.preventDefault()\r\n if (!e.pageX)\r\n document.body.style.overflow = 'hidden'\r\n\r\n const x = e.pageX || e.changedTouches[0].pageX\r\n const y = e.pageY || e.changedTouches[0].pageY\r\n let newLeft = x - this.shiftX\r\n let newTop = y - this.shiftY\r\n const newRight = x - this.shiftX + this.elem.offsetWidth\r\n const newBottom = y - this.shiftY + this.elem.offsetHeight\r\n if (newLeft < 0)\r\n newLeft = 0\r\n else if (newRight > this.parent.width)\r\n newLeft = this.parent.width - this.elem.offsetWidth\r\n else\r\n newLeft = x - this.shiftX\r\n\r\n if (newTop < 0)\r\n newTop = 0\r\n else if (newBottom > this.parent.height)\r\n newTop = this.parent.height - this.elem.offsetHeight\r\n else\r\n newTop = y - this.shiftY\r\n\r\n this.elem.style.left = `${newLeft}px`\r\n this.left = newLeft\r\n this.elem.style.top = `${newTop}px`\r\n this.top = newTop\r\n },\r\n\r\n hang (e) {\r\n this.events = []\r\n this.events.push('activated')\r\n this.$emit('activated')\r\n\r\n this.isDragging = true\r\n this.calculateParent()\r\n\r\n this.shiftX = e.pageX\r\n ? e.pageX - this.elem.offsetLeft\r\n : e.changedTouches[0].pageX - this.elem.offsetLeft\r\n this.shiftY = e.pageY\r\n ? e.pageY - this.elem.offsetTop\r\n : e.changedTouches[0].pageY - this.elem.offsetTop\r\n\r\n if (e.pageX) {\r\n if (this.isIos) {\r\n this.parentElem.addEventListener('touchmove', this.elementMove)\r\n } else {\r\n this.parentElem.addEventListener('mousemove', this.elementMove)\r\n this.parentElem.addEventListener('mouseleave', this.drop)\r\n }\r\n } else {\r\n this.parentElem.addEventListener('touchmove', this.elementMove)\r\n }\r\n },\r\n\r\n drop () {\r\n this.$emit('dropped')\r\n\r\n this.isDragging = false\r\n document.body.style.overflow = null\r\n this.parentElem.removeEventListener('mousemove', this.elementMove, false)\r\n this.parentElem.removeEventListener('touchmove', this.elementMove, false)\r\n this.parentElem.onmouseup = null\r\n this.parentElem.ontouchend = null\r\n\r\n if (this.autoSnap) {\r\n this.calculateArea()\r\n\r\n // Top - Left\r\n if (this.onLeft && this.onTop)\r\n if (this.getSnapOption('top-left')) this.autoSnapMoveTL()\r\n else if (this.getSnapOption('top-right')) this.autoSnapMoveTR()\r\n else if (this.getSnapOption('bottom-left')) this.autoSnapMoveBL()\r\n else this.autoSnapMoveTL()\r\n\r\n // Top - Right\r\n else if (!this.onLeft && this.onTop)\r\n if (this.getSnapOption('top-right')) this.autoSnapMoveTR()\r\n else if (this.getSnapOption('top-left')) this.autoSnapMoveTL()\r\n else if (this.getSnapOption('bottom-right')) this.autoSnapMoveBR()\r\n else this.autoSnapMoveTL()\r\n\r\n // Bottom - Left\r\n else if (this.onLeft && !this.onTop)\r\n if (this.getSnapOption('bottom-left')) this.autoSnapMoveBL()\r\n else if (this.getSnapOption('bottom-right')) this.autoSnapMoveBR()\r\n else if (this.getSnapOption('top-left')) this.autoSnapMoveTL()\r\n else this.autoSnapMoveTL()\r\n\r\n // Bottom - Right\r\n else if (!this.onLeft && !this.onTop)\r\n if (this.getSnapOption('bottom-right')) this.autoSnapMoveBR()\r\n else if (this.getSnapOption('bottom-left')) this.autoSnapMoveBL()\r\n else if (this.getSnapOption('top-right')) this.autoSnapMoveTR()\r\n else this.autoSnapMoveTL()\r\n }\r\n },\r\n\r\n getSnapOption(option) {\r\n if (!this.snapOptions[option])\r\n return false\r\n\r\n return {\r\n top: this.snapOptions[option] && this.snapOptions[option].top,\r\n left: this.snapOptions[option] && this.snapOptions[option].left,\r\n bottom: this.snapOptions[option] && this.snapOptions[option].bottom,\r\n right: this.snapOptions[option] && this.snapOptions[option].right\r\n }\r\n },\r\n\r\n autoSnapMoveTL () {\r\n const left = this.getSnapOption('top-left').left || 0\r\n const top = this.getSnapOption('top-left').top || 0\r\n\r\n this.moveLeft(left)\r\n this.moveTop(top)\r\n },\r\n\r\n autoSnapMoveTR () {\r\n const right = this.getSnapOption('top-right').right || 0\r\n const top = this.getSnapOption('top-right').top || 0\r\n\r\n this.moveLeft(this.parent.width - this.elem.offsetWidth - right)\r\n this.moveTop(top)\r\n },\r\n\r\n autoSnapMoveBL () {\r\n const left = this.getSnapOption('bottom-left').left || 0\r\n const bottom = this.getSnapOption('bottom-left').bottom || 0\r\n\r\n const r = this.parent.height - this.elem.offsetHeight - bottom\r\n\r\n this.moveLeft(left)\r\n this.moveTop(r)\r\n },\r\n\r\n autoSnapMoveBR () {\r\n const right = this.getSnapOption('bottom-right').right || 0\r\n const bottom = this.getSnapOption('bottom-right').bottom || 0\r\n\r\n const l = this.parent.width - this.elem.offsetWidth - right\r\n const r = this.parent.height - this.elem.offsetHeight - bottom\r\n\r\n this.moveLeft(l)\r\n this.moveTop(r)\r\n },\r\n\r\n moveLeft (left) {\r\n this.left = left\r\n this.elem.style.left = `${left}px`\r\n },\r\n\r\n moveTop (top) {\r\n this.top = top\r\n this.elem.style.top = `${top}px`\r\n },\r\n\r\n calculateParent () {\r\n this.parent.width = this.parentWidth || (this.parentSelector && document.body.querySelector(this.parentSelector) &&document.body.querySelector(this.parentSelector).offsetWidth) || this.elem.parentNode.offsetWidth\r\n this.parent.height = this.parentHeight || (this.parentSelector && document.body.querySelector(this.parentSelector) &&document.body.querySelector(this.parentSelector).offsetHeight) || this.elem.parentNode.offsetHeight\r\n },\r\n\r\n calculateArea () {\r\n this.onLeft = this.left + this.elem.offsetWidth / 2 < this.parent.width / 2\r\n this.onTop = this.top + this.elem.offsetHeight / 2 < this.parent.height / 2\r\n\r\n if (this.onLeft && this.onTop)\r\n this.currentPosition = 'TL'\r\n else if (!this.onLeft && this.onTop)\r\n this.currentPosition = 'TR'\r\n else if (this.onLeft && !this.onTop)\r\n this.currentPosition = 'BL'\r\n else if (!this.onLeft && !this.onTop)\r\n this.currentPosition = 'BR'\r\n },\r\n\r\n changePosition (position) {\r\n const positions = ['TL', 'TR', 'BL', 'BR']\r\n this.currentPosition = positions.includes(position) ? position : 'TL'\r\n this.update()\r\n },\r\n\r\n update () {\r\n this.calculateParent()\r\n if (this.currentPosition)\r\n this['autoSnapMove' + this.currentPosition]()\r\n }\r\n }\r\n}\r\n<\/script>\r\n\r\n<style scoped>\r\n.drag-drop-snap {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n z-index: 9;\r\n cursor: move;\r\n}\r\n\r\n.drag-drop-snap.with-style {\r\n width: 8em;\r\n height: 4.5em;\r\n background: #ccc;\r\n border-radius: 2em;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\r\n}\r\n\r\n.drag-drop-snap.active {\r\n visibility: visible;\r\n}\r\n\r\n.drag-drop-snap.dropped.with-animation {\r\n transition: left 500ms, top 500ms;\r\n transition-timing-function: cubic-bezier(0.35, 1.16, 0.63, 1.17), cubic-bezier(0.35, 1.16, 0.63, 1.17);\r\n}\r\n</style>\r\n"]},media:void 0})},i,"data-v-4efc33f3",!1,void 0,e,void 0),h={install:n},a=null;return"undefined"!=typeof window?a=window.Vue:"undefined"!=typeof global&&(a=global.Vue),a&&a.use(h),t.default=s,t}({});