Working draggable modals

This commit is contained in:
euvl
2017-04-10 12:01:42 +01:00
parent d165145124
commit fb02b6be93
3 changed files with 42 additions and 56 deletions

View File

@@ -10,7 +10,7 @@
:class="modalClass" :class="modalClass"
:style="modalStyle" :style="modalStyle"
@mousedown.stop> @mousedown.stop>
<slot></slot> <slot/>
<resizer v-if="resizable" <resizer v-if="resizable"
:min-width="minWidth" :min-width="minWidth"
:min-height="minHeight" :min-height="minHeight"
@@ -24,6 +24,7 @@
import Vue from 'vue' import Vue from 'vue'
import Modal from './index' import Modal from './index'
import Resizer from './Resizer.vue' import Resizer from './Resizer.vue'
import { inRange } from './util'
export default { export default {
name: 'Modal', name: 'Modal',
@@ -149,18 +150,17 @@
this.onWindowResize() this.onWindowResize()
}, },
computed: { computed: {
center () {
return {
x: 0.5 * this.window.width
y: 0.5 * this.window.height
}
},
position () { position () {
let left = 0.5 * this.window.width - this.modal.width const { window, modal, shift } = this
let top = 0.5 * this.window.height - this.modal.height const maxLeft = window.width - modal.width
const maxTop = window.height - modal.height
const left = shift.left + this.pivotX * (window.width - modal.width)
const top = shift.top + this.pivotY * (window.height - modal.height)
return { return {
left: Math.max(/*this.shift.left + */ this.pivotX * (this.window.width - this.modal.width), 0), left: inRange(0, maxLeft, left),
top: Math.max(/*this.shift.top + */ this.pivotY * (this.window.height - this.modal.height), 0) top: inRange(0, maxTop, top)
} }
}, },
modalClass () { modalClass () {
@@ -181,12 +181,12 @@
this.window.height = window.innerHeight this.window.height = window.innerHeight
if (this.adaptive) { if (this.adaptive) {
this.modal.width = Math.min(this.window.width, this.modal.width) this.modal.width = inRange(0, this.window.width, this.modal.width)
this.modal.height = Math.min(this.window.height, this.modal.height) this.modal.height = inRange(0, this.window.height, this.modal.height)
} }
}, },
genEventObject (params) { genEventObject (params) {
//todo: clean this up //todo: clean this up (change to ...)
return Vue.util.extend({ return Vue.util.extend({
name: this.name, name: this.name,
ref: this.$refs.modal, ref: this.$refs.modal,
@@ -197,8 +197,8 @@
this.modal.width = event.size.width this.modal.width = event.size.width
this.modal.height = event.size.height this.modal.height = event.size.height
let { size } = this.modal const { size } = this.modal
let resizeEvent = this.genEventObject({ size }); const resizeEvent = this.genEventObject({ size });
this.$emit('resize', resizeEvent) this.$emit('resize', resizeEvent)
}, },
@@ -214,9 +214,9 @@
this.$emit(beforeEventName, beforeEvent) this.$emit(beforeEventName, beforeEvent)
if (!stopEventExecution) { if (!stopEventExecution) {
this.visible = !!state
const afterEvent = this.genEventObject({ state, params }) const afterEvent = this.genEventObject({ state, params })
this.visible = !!state
this.$emit(afterEventName, afterEvent) this.$emit(afterEventName, afterEvent)
} }
}, },
@@ -244,45 +244,33 @@
if (dragger) { if (dragger) {
let startX = 0 let startX = 0
let startY = 0 let startY = 0
let cachedShiftX = 0
let left = 0 let cachedShiftY = 0
let top = 0
let mousedown = (event) => { let mousedown = (event) => {
// left = this.position.left
// top = this.position.top
document.addEventListener('mousemove', mousemove) document.addEventListener('mousemove', mousemove)
document.addEventListener('mouseup', mouseup) document.addEventListener('mouseup', mouseup)
startX = event.clientX; startX = event.clientX
startY = event.clientY; startY = event.clientY
cachedShiftX = this.shift.left
cachedShiftY = this.shift.top
event.preventDefault() event.preventDefault()
} }
let mousemove = (event) => { let mousemove = (event) => {
this.shift.left = event.clientX - startX this.shift.left = cachedShiftX + event.clientX - startX
this.shift.top = event.clientY - startY this.shift.top = cachedShiftY + event.clientY - startY
console.log(this.shift)
event.preventDefault() event.preventDefault()
} }
let mouseup = (event) => { let mouseup = (event) => {
//dragger.removeEventListener('mousedown', mousedown)
document.removeEventListener('mousemove', mousemove) document.removeEventListener('mousemove', mousemove)
document.removeEventListener('mouseup', mouseup) document.removeEventListener('mouseup', mouseup)
// this.shiftX = shiftX
// this.shiftY = shiftY
// console.log(shiftX, shiftY)
event.preventDefault() event.preventDefault()
} }
dragger.addEventListener('mousedown', mousedown) dragger.addEventListener('mousedown', mousedown)
console.log(dragger)
} }
}, },

View File

@@ -2,6 +2,8 @@
<div :class="className"></div> <div :class="className"></div>
</template> </template>
<script> <script>
import { inRange } from './util'
export default { export default {
name: 'Resizer', name: 'Resizer',
props: { props: {
@@ -58,21 +60,8 @@ export default {
var width = event.clientX - el.offsetLeft var width = event.clientX - el.offsetLeft
var height = event.clientY - el.offsetTop var height = event.clientY - el.offsetTop
if (width < this.minWidth) { width = inRange(this.minWidth, window.innerWidth, width)
width = this.minWidth height = inRange(this.minHeight, window.innerHeight, height)
}
if (width > window.innerWidth) {
width = window.innerWidth
}
if (height < this.minHeight) {
height = this.minHeight
}
if (height > window.innerHeight) {
height = window.innerHeight
}
this.size = {width, height} this.size = {width, height}
el.style.width = width + 'px' el.style.width = width + 'px'

9
src/util.js Normal file
View File

@@ -0,0 +1,9 @@
export const inRange = (from, to, value) => {
if (value > to) {
return to
}
if (value < from) {
return from
}
return value
}