Merge pull request #4 from euvl/draggable

Draggable
This commit is contained in:
Yev Vlasenko
2017-04-10 12:08:55 +01:00
committed by GitHub
9 changed files with 369 additions and 274 deletions

View File

@@ -24,7 +24,7 @@ Create modal
Call it from anywhere in the app
```javascript
methods: {
show() {
show () {
this.$modal.show('hello-word');
},
hide () {

View File

@@ -13,15 +13,17 @@
ga('create', 'UA-80822945-4', 'auto');
ga('send', 'pageview');
</script>
</head>
<body>
<a href="https://github.com/euvl/vue-js-modal">
<img style="position: absolute; top: 0; right: 0; border: 0;"
src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67"
alt="Fork me on GitHub"
data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"></a>
<div style="position: absolute; right: 0; top: 20px">
<iframe
src="https://ghbtns.com/github-btn.html?user=euvl&repo=vue-js-modal&type=star&count=true"
frameborder="0"
scrolling="0"
width="94px"
height="20px"></iframe>
</div>
<div id="app"></div>
<script src="/dist/build.js"></script>
</body>

View File

@@ -16,7 +16,10 @@
</div>
</modal>
<h2>Vue.js Modal</h2>
<h2>Vue.js Modal
<a href="https://github.com/euvl/vue-js-modal/blob/master/README.md" target="readme">Readme</a>
<a href="https://github.com/euvl/vue-js-modal/issues" target="issues">Issues</a>
</h2>
<pre style="line-height: 1.5;">
npm install --save vue-js-modal
@@ -48,101 +51,35 @@
<tr>
<td><b>Mixed</b></td>
<td>
Is resizable, but if the size of the screen is changed modal will return to its initial size as well as it will try to adapt to the page size
Is resizable, but if the size of the screen is changed - modal will return to its initial size as well as it will try to adapt to the page size
</td>
</tr>
</table>
<div style="margin-top: 20px; margin-bottom: 20px;">
<button @click="show()">Simple</button>
<button @click="show(true)">Resizable</button>
<button @click="show(false, true)">Adaptive</button>
<button @click="show(true, true)">Mixed</button>
<button @click="show(false, false, true)">Draggable (under development)</button>
<button @click="show(false, false, false)">Simple</button>
<button @click="show(true, false, false)">Resizable</button>
<button @click="show(false, true, false)">Adaptive</button>
<button @click="show(true, true, false)">Mixed</button>
<button @click="show(false, false, true)">Draggable</button>
</div>
<table class="props">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr v-for="(prop, name) in props">
<td>
{{name}}
</td>
<td>
<template v-if="Array.isArray(prop.type)">
<span v-for="type in prop.type">
{{type.name}} /
</span>
</template>
<template v-else>
<span>{{prop.type.name}}</span>
</template>
</td>
<td>
{{prop.default}}
</td>
</tr>
</tbody>
</table>
<props-table />
</div>
</template>
<script>
import PropsTable from './PropsTable.vue'
//<props-table/>
export default {
name: 'app',
components: {PropsTable},
data() {
return {
resizable: false,
adaptive: false,
draggable: false,
props: {
name: {
required: true,
type: String,
},
delay: {
type: Number,
default: 0,
},
resizable: {
type: Boolean,
default: false
},
adaptive: {
type: Boolean,
default: false
},
transition: {
type: String,
},
classes: {
type: [String, Array],
default: 'nice-modal',
},
width: {
type: Number,
default: 600
},
height: {
type: Number,
default: 300
},
minWidth: {
type: Number,
default: 0
},
minHeight: {
type: Number,
default: 0
}
}
}
},
methods: {
@@ -165,56 +102,53 @@ export default {
<style lang="scss">
body {
margin: 0;
padding: 50px;
cursor: default;
box-sizing: border-box;
margin: 0;
padding: 50px;
cursor: default;
box-sizing: border-box;
}
pre {
color: #595959;
background-color: #f3f3f3;
border: 1px solid #eee;
color: #595959;
background-color: #f3f3f3;
border: 1px solid #eee;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
h1,
h2 {
font-weight: normal;
font-weight: normal;
a {
font-size: 12px;
}
}
a {
color: inherit;
}
button {
outline: none;
background: white;
border: 0;
padding: 6px 18px;
cursor: pointer;
border-radius: 3px;
outline: none;
background: white;
border: 0;
padding: 6px 18px;
cursor: pointer;
border-radius: 3px;
background: white;
background: white;
color: #4db3ff;
border: 1px solid #4db3ff;
&:hover {
color: #20a0ff;
border: 1px solid #20a0ff;
}
}
table.props {
width: 100%;
text-align: left;
border-collapse: collapse;
td, th {
border: 1px solid #eee;
padding: 4px 8px;
color: #4db3ff;
border: 1px solid #4db3ff;
&:hover {
color: #20a0ff;
border: 1px solid #20a0ff;
}
}
</style>

91
demo/src/PropsTable.vue Normal file
View File

@@ -0,0 +1,91 @@
<template>
<table class="props">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr v-for="(prop, name) in props">
<td>
{{name}}
</td>
<td>
<template v-if="Array.isArray(prop.type)">
{{prop.type.map(v => v.name).join(' / ')}}
</template>
<template v-else>
<span>{{prop.type.name}}</span>
</template>
</td>
<td>
{{prop.default}}
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
name: 'PropsTable',
data () {
return {
props: {
name: {
required: true,
type: String,
},
delay: {
type: Number,
default: 0,
},
resizable: {
type: Boolean,
default: false
},
adaptive: {
type: Boolean,
default: false
},
transition: {
type: String,
},
classes: {
type: [String, Array],
default: 'nice-modal',
},
width: {
type: Number,
default: 600
},
height: {
type: Number,
default: 300
},
minWidth: {
type: Number,
default: 0
},
minHeight: {
type: Number,
default: 0
}
}
}
}
}
</script>
<style lang="scss">
table.props {
width: 100%;
text-align: left;
border-collapse: collapse;
td, th {
border: 1px solid #eee;
padding: 4px 8px;
}
}
</style>

187
dist/index.js vendored
View File

@@ -73,11 +73,27 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 3);
/******/ return __webpack_require__(__webpack_require__.s = 4);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return inRange; });
var inRange = function inRange(from, to, value) {
if (value > to) {
return to;
}
if (value < from) {
return from;
}
return value;
};
/***/ }),
/* 1 */
/***/ (function(module, exports) {
/*
@@ -133,7 +149,7 @@ module.exports = function() {
/***/ }),
/* 1 */
/* 2 */
/***/ (function(module, exports) {
module.exports = function normalizeComponent (
@@ -186,7 +202,7 @@ module.exports = function normalizeComponent (
/***/ }),
/* 2 */
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
/*
@@ -205,7 +221,7 @@ if (typeof DEBUG !== 'undefined' && DEBUG) {
) }
}
var listToStyles = __webpack_require__(14)
var listToStyles = __webpack_require__(15)
/*
type StyleObject = {
@@ -422,12 +438,12 @@ function applyToTag (styleElement, obj) {
/***/ }),
/* 3 */
/* 4 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Modal_vue__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Modal_vue__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Modal_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__Modal_vue__);
@@ -462,18 +478,18 @@ var ModalPlugin = {
/* harmony default export */ __webpack_exports__["default"] = ModalPlugin;
/***/ }),
/* 4 */
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
/* styles */
__webpack_require__(12)
__webpack_require__(13)
var Component = __webpack_require__(1)(
var Component = __webpack_require__(2)(
/* script */
__webpack_require__(5),
__webpack_require__(6),
/* template */
__webpack_require__(10),
__webpack_require__(11),
/* scopeId */
"data-v-40dd3b1e",
/* cssModules */
@@ -484,15 +500,16 @@ module.exports = Component.exports
/***/ }),
/* 5 */
/* 6 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__index__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Resizer_vue__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__index__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Resizer_vue__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Resizer_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2__Resizer_vue__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util__ = __webpack_require__(0);
//
//
//
@@ -520,6 +537,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony default export */ __webpack_exports__["default"] = {
name: 'Modal',
props: {
@@ -587,6 +605,11 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
overlay: false
},
shift: {
left: 0,
top: 0
},
modal: {
width: this.width,
height: this.height
@@ -605,7 +628,6 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
visible: function visible(value) {
var _this = this;
// if (this.delay > 0) {
if (value) {
this.visibility.overlay = true;
@@ -624,15 +646,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
_this.removeDraggableListeners();
});
}, this.delay);
// this.removeDraggableHandlers()
}
// } else {
// this.visibility.overlay = value
// this.$nextTick(() => {
// this.visibility.modal = value
// })
// }
}
},
created: function created() {
@@ -655,9 +669,19 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
computed: {
position: function position() {
var window = this.window,
modal = this.modal,
shift = this.shift;
var maxLeft = window.width - modal.width;
var maxTop = window.height - modal.height;
var left = shift.left + this.pivotX * (window.width - modal.width);
var top = shift.top + this.pivotY * (window.height - modal.height);
return {
left: Math.max(this.pivotX * (this.window.width - this.modal.width), 0),
top: Math.max(this.pivotY * (this.window.height - this.modal.height), 0)
left: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util__["a" /* inRange */])(0, maxLeft, left),
top: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util__["a" /* inRange */])(0, maxTop, top)
};
},
modalClass: function modalClass() {
@@ -678,15 +702,12 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
this.window.height = window.innerHeight;
if (this.adaptive) {
var width = Math.min(this.window.width, this.modal.width);
var height = Math.min(this.window.height, this.modal.height);
this.modal.width = width; // Math.max(width, this.minWidth);
this.modal.height = height; // Math.max(height, this.minHeight);
this.modal.width = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util__["a" /* inRange */])(0, this.window.width, this.modal.width);
this.modal.height = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util__["a" /* inRange */])(0, this.window.height, this.modal.height);
}
},
genEventObject: function genEventObject(params) {
//todo: clean this up
//todo: clean this up (change to ...)
return __WEBPACK_IMPORTED_MODULE_0_vue__["a" /* default */].util.extend({
name: this.name,
ref: this.$refs.modal,
@@ -717,9 +738,9 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
this.$emit(beforeEventName, beforeEvent);
if (!stopEventExecution) {
this.visible = !!state;
var afterEvent = this.genEventObject({ state: state, params: params });
this.visible = !!state;
this.$emit(afterEventName, afterEvent);
}
},
@@ -734,6 +755,8 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
}
},
addDraggableListeners: function addDraggableListeners() {
var _this3 = this;
if (!this.draggable) {
return;
}
@@ -741,7 +764,37 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
var dragger = this.getDraggableElement();
if (dragger) {
console.log(dragger);
(function () {
var startX = 0;
var startY = 0;
var cachedShiftX = 0;
var cachedShiftY = 0;
var mousedown = function mousedown(event) {
document.addEventListener('mousemove', mousemove);
document.addEventListener('mouseup', mouseup);
startX = event.clientX;
startY = event.clientY;
cachedShiftX = _this3.shift.left;
cachedShiftY = _this3.shift.top;
event.preventDefault();
};
var mousemove = function mousemove(event) {
_this3.shift.left = cachedShiftX + event.clientX - startX;
_this3.shift.top = cachedShiftY + event.clientY - startY;
event.preventDefault();
};
var mouseup = function mouseup(event) {
document.removeEventListener('mousemove', mousemove);
document.removeEventListener('mouseup', mouseup);
event.preventDefault();
};
dragger.addEventListener('mousedown', mousedown);
})();
}
},
removeDraggableListeners: function removeDraggableListeners() {
@@ -751,15 +804,18 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
};
/***/ }),
/* 6 */
/* 7 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util__ = __webpack_require__(0);
//
//
//
/* harmony default export */ __webpack_exports__["default"] = {
name: 'Resizer',
props: {
@@ -817,21 +873,8 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
var width = event.clientX - el.offsetLeft;
var height = event.clientY - el.offsetTop;
if (width < this.minWidth) {
width = this.minWidth;
}
if (width > window.innerWidth) {
width = window.innerWidth;
}
if (height < this.minHeight) {
height = this.minHeight;
}
if (height > window.innerHeight) {
height = window.innerHeight;
}
width = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__util__["a" /* inRange */])(this.minWidth, window.innerWidth, width);
height = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__util__["a" /* inRange */])(this.minHeight, window.innerHeight, height);
this.size = { width: width, height: height };
el.style.width = width + 'px';
@@ -847,10 +890,10 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
};
/***/ }),
/* 7 */
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(0)();
exports = module.exports = __webpack_require__(1)();
// imports
@@ -861,10 +904,10 @@ exports.push([module.i, ".nice-modal-overlay[data-v-40dd3b1e]{position:fixed;lef
/***/ }),
/* 8 */
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(0)();
exports = module.exports = __webpack_require__(1)();
// imports
@@ -875,18 +918,18 @@ exports.push([module.i, ".vue-modal-resizer{overflow:hidden;width:12px;height:12
/***/ }),
/* 9 */
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
/* styles */
__webpack_require__(13)
__webpack_require__(14)
var Component = __webpack_require__(1)(
var Component = __webpack_require__(2)(
/* script */
__webpack_require__(6),
__webpack_require__(7),
/* template */
__webpack_require__(11),
__webpack_require__(12),
/* scopeId */
null,
/* cssModules */
@@ -897,7 +940,7 @@ module.exports = Component.exports
/***/ }),
/* 10 */
/* 11 */
/***/ (function(module, exports) {
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
@@ -939,7 +982,7 @@ module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c
},staticRenderFns: []}
/***/ }),
/* 11 */
/* 12 */
/***/ (function(module, exports) {
module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
@@ -949,17 +992,17 @@ module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c
},staticRenderFns: []}
/***/ }),
/* 12 */
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
// style-loader: Adds some css to the DOM by adding a <style> tag
// load the styles
var content = __webpack_require__(7);
var content = __webpack_require__(8);
if(typeof content === 'string') content = [[module.i, content, '']];
if(content.locals) module.exports = content.locals;
// add the styles to the DOM
var update = __webpack_require__(2)("3bb0039f", content, true);
var update = __webpack_require__(3)("3bb0039f", content, true);
// Hot Module Replacement
if(false) {
// When the styles change, update the <style> tags
@@ -975,17 +1018,17 @@ if(false) {
}
/***/ }),
/* 13 */
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
// style-loader: Adds some css to the DOM by adding a <style> tag
// load the styles
var content = __webpack_require__(8);
var content = __webpack_require__(9);
if(typeof content === 'string') content = [[module.i, content, '']];
if(content.locals) module.exports = content.locals;
// add the styles to the DOM
var update = __webpack_require__(2)("c392065e", content, true);
var update = __webpack_require__(3)("c392065e", content, true);
// Hot Module Replacement
if(false) {
// When the styles change, update the <style> tags
@@ -1001,7 +1044,7 @@ if(false) {
}
/***/ }),
/* 14 */
/* 15 */
/***/ (function(module, exports) {
/**
@@ -1034,7 +1077,7 @@ module.exports = function listToStyles (parentId, list) {
/***/ }),
/* 15 */
/* 16 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -10346,10 +10389,10 @@ Vue$3.compile = compileToFunctions;
/* harmony default export */ __webpack_exports__["a"] = Vue$3;
/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(16)))
/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(17)))
/***/ }),
/* 16 */
/* 17 */
/***/ (function(module, exports) {
var g;

View File

@@ -1,7 +1,7 @@
{
"name": "vue-js-modal",
"description": "Modal Component for Vue.js",
"version": "1.0.15",
"version": "1.0.16",
"author": "euvl <yev.vlasenko@gmail.com>",
"main": "dist/index.js",
"repository": {

View File

@@ -10,7 +10,7 @@
:class="modalClass"
:style="modalStyle"
@mousedown.stop>
<slot></slot>
<slot/>
<resizer v-if="resizable"
:min-width="minWidth"
:min-height="minHeight"
@@ -21,9 +21,10 @@
</transition>
</template>
<script>
import Vue from 'vue'
import Modal from './index'
import Resizer from './Resizer.vue'
import Vue from 'vue'
import Modal from './index'
import Resizer from './Resizer.vue'
import { inRange } from './util'
export default {
name: 'Modal',
@@ -83,7 +84,7 @@
components: {
Resizer
},
data() {
data () {
return {
visible: false,
@@ -92,6 +93,11 @@
overlay: false
},
shift: {
left: 0,
top: 0
},
modal: {
width: this.width,
height: this.height
@@ -107,7 +113,6 @@
},
watch: {
visible (value) {
// if (this.delay > 0) {
if (value) {
this.visibility.overlay = true
@@ -126,16 +131,8 @@
this.removeDraggableListeners()
})
}, this.delay)
// this.removeDraggableHandlers()
}
// } else {
// this.visibility.overlay = value
// this.$nextTick(() => {
// this.visibility.modal = value
// })
// }
},
}
},
created () {
Modal.event.$on('toggle', (name, state, params) => {
@@ -153,57 +150,59 @@
this.onWindowResize()
},
computed: {
position() {
position () {
const { window, modal, shift } = this
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 {
left: Math.max(this.pivotX * (this.window.width - this.modal.width), 0),
top: Math.max(this.pivotY * (this.window.height - this.modal.height), 0)
left: inRange(0, maxLeft, left),
top: inRange(0, maxTop, top)
}
},
modalClass() {
modalClass () {
return ['modal', this.classes]
},
modalStyle() {
modalStyle () {
return {
top: this.position.top + 'px',
left: this.position.left + 'px',
width: this.modal.width + 'px',
height: this.modal.height + 'px'
}
},
}
},
methods: {
onWindowResize() {
onWindowResize () {
this.window.width = window.innerWidth
this.window.height = window.innerHeight
if (this.adaptive) {
let width = Math.min(this.window.width, this.modal.width)
let height = Math.min(this.window.height, this.modal.height)
this.modal.width = width // Math.max(width, this.minWidth);
this.modal.height = height // Math.max(height, this.minHeight);
this.modal.width = inRange(0, this.window.width, this.modal.width)
this.modal.height = inRange(0, this.window.height, this.modal.height)
}
},
genEventObject(params) {
//todo: clean this up
return Vue.util.extend(
{
name: this.name,
ref: this.$refs.modal,
timestamp: Date.now()
},
params || {});
genEventObject (params) {
//todo: clean this up (change to ...)
return Vue.util.extend({
name: this.name,
ref: this.$refs.modal,
timestamp: Date.now()
}, params || {});
},
resize(event) {
resize (event) {
this.modal.width = event.size.width
this.modal.height = event.size.height
let { size } = this.modal
let resizeEvent = this.genEventObject({ size });
const { size } = this.modal
const resizeEvent = this.genEventObject({ size });
this.$emit('resize', resizeEvent)
},
toggle(state, params) {
toggle (state, params) {
const beforeEventName = this.visible ? 'before-close' : 'before-open'
const afterEventName = this.visible ? 'closed' : 'opened'
@@ -215,9 +214,9 @@
this.$emit(beforeEventName, beforeEvent)
if (!stopEventExecution) {
this.visible = !!state
const afterEvent = this.genEventObject({ state, params })
this.visible = !!state
this.$emit(afterEventName, afterEvent)
}
},
@@ -243,7 +242,35 @@
let dragger = this.getDraggableElement()
if (dragger) {
console.log(dragger)
let startX = 0
let startY = 0
let cachedShiftX = 0
let cachedShiftY = 0
let mousedown = (event) => {
document.addEventListener('mousemove', mousemove)
document.addEventListener('mouseup', mouseup)
startX = event.clientX
startY = event.clientY
cachedShiftX = this.shift.left
cachedShiftY = this.shift.top
event.preventDefault()
}
let mousemove = (event) => {
this.shift.left = cachedShiftX + event.clientX - startX
this.shift.top = cachedShiftY + event.clientY - startY
event.preventDefault()
}
let mouseup = (event) => {
document.removeEventListener('mousemove', mousemove)
document.removeEventListener('mouseup', mouseup)
event.preventDefault()
}
dragger.addEventListener('mousedown', mousedown)
}
},

View File

@@ -2,6 +2,8 @@
<div :class="className"></div>
</template>
<script>
import { inRange } from './util'
export default {
name: 'Resizer',
props: {
@@ -58,21 +60,8 @@ export default {
var width = event.clientX - el.offsetLeft
var height = event.clientY - el.offsetTop
if (width < this.minWidth) {
width = this.minWidth
}
if (width > window.innerWidth) {
width = window.innerWidth
}
if (height < this.minHeight) {
height = this.minHeight
}
if (height > window.innerHeight) {
height = window.innerHeight
}
width = inRange(this.minWidth, window.innerWidth, width)
height = inRange(this.minHeight, window.innerHeight, height)
this.size = {width, height}
el.style.width = width + 'px'
@@ -89,32 +78,32 @@ export default {
</script>
<style lang="scss">
.vue-modal-resizer {
display: block;
overflow: hidden;
position: absolute;
width: 12px;
height: 12px;
right: 0;
bottom: 0;
z-index: 9999999;
background: transparent;
cursor: se-resize;
&:after {
display: block;
overflow: hidden;
position: absolute;
width: 12px;
height: 12px;
right: 0;
bottom: 0;
z-index: 9999999;
content: '';
background: transparent;
cursor: se-resize;
left: 0;
top: 0;
width: 0;
height: 0;
border-bottom: 10px solid #ddd;
border-left: 10px solid transparent;
}
&:after {
display: block;
position: absolute;
content: '';
background: transparent;
left: 0;
top: 0;
width: 0;
height: 0;
border-bottom: 10px solid #ddd;
border-left: 10px solid transparent;
}
&.clicked:after {
border-bottom: 10px solid #369BE9;
}
&.clicked:after {
border-bottom: 10px solid #369BE9;
}
}
</style>

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
}