| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- let _ = {
- MIN_LIMIT: 48, // Min size of zone
- DECIMAL_PLACES: 4 // Hotzone positioning decimal point limit number of digits
- }
- /**
- * Get a power result of 10 for the power of the constant
- * @return {Number}
- */
- _.getMultiple = (decimalPlaces = _.DECIMAL_PLACES) => {
- return Math.pow(10, decimalPlaces)
- }
- /**
- * Limit decimal places
- * @param {Number} num
- * @return {Number}
- */
- _.decimalPoint = (val = 0) => {
- return Math.round(val * _.getMultiple()) / _.getMultiple() || 0
- }
- /**
- * Get element width and height
- * @param {Object} elem
- * @return {Object}
- */
- _.getOffset = (elem = {}) => ({
- width: elem.clientWidth || 0,
- height: elem.clientHeight || 0
- })
- /**
- * Get pageX
- * @param {Object} e
- * @return {Number}
- */
- _.getPageX = (e) => ('pageX' in e) ? e.pageX : e.touches[0].pageX
- /**
- * Get pageY
- * @param {Object} e
- * @return {Number}
- */
- _.getPageY = (e) => ('pageY' in e) ? e.pageY : e.touches[0].pageY
- /**
- * Gets the abscissa value of the mouse click relative to the target node
- * @param {Object} e
- * @param {Object} container
- * @return {Number}
- */
- _.getDistanceX = (e, container) =>
- _.getPageX(e) - (container.getBoundingClientRect().left + window.pageXOffset)
- /**
- * Gets the ordinate value of the mouse click relative to the target node
- * @param {Object} e
- * @param {Object} container
- * @return {Number}
- */
- _.getDistanceY = (e, container) =>
- _.getPageY(e) - (container.getBoundingClientRect().top + window.pageYOffset)
- /**
- * Treatment of boundary conditions when changing the size of the hotzone
- * @param {Object} itemInfo
- * @param {Object} styleInfo
- * @param {Object} container
- */
- _.dealEdgeValue = (itemInfo, styleInfo, container) => {
- if (styleInfo.hasOwnProperty('left') && styleInfo.left < 0) {
- styleInfo.left = 0
- styleInfo.width = itemInfo.width + itemInfo.left
- }
- if (styleInfo.hasOwnProperty('top') && styleInfo.top < 0) {
- styleInfo.top = 0
- styleInfo.height = itemInfo.height + itemInfo.top
- }
- if (!styleInfo.hasOwnProperty('left') && styleInfo.hasOwnProperty('width')) {
- if (itemInfo.left + styleInfo.width > container.width) {
- styleInfo.width = container.width - itemInfo.left
- }
- }
- if (!styleInfo.hasOwnProperty('top') && styleInfo.hasOwnProperty('height')) {
- if (itemInfo.top + styleInfo.height > container.height) {
- styleInfo.height = container.height - itemInfo.top
- }
- }
- return Object.assign(itemInfo, styleInfo)
- }
- /**
- * Handle different drag points, capital letters mean: T-top,L-left,C-center,R-right,B-bottom
- * @param {Object} itemInfo
- * @param {Number} moveX
- * @param {Number} moveY
- * @return {Object}
- */
- _.dealTL = (itemInfo, moveX, moveY, minLimit = _.MIN_LIMIT) => {
- let styleInfo = {}
- let width = itemInfo.width - moveX
- let height = itemInfo.height - moveY
- if (width >= Math.min(minLimit, itemInfo.width)) {
- Object.assign(styleInfo, {
- width,
- left: itemInfo.left + moveX
- })
- }
- if (height >= Math.min(minLimit, itemInfo.height)) {
- Object.assign(styleInfo, {
- height,
- top: itemInfo.top + moveY
- })
- }
- return styleInfo
- }
- _.dealTC = (itemInfo, moveX, moveY, minLimit = _.MIN_LIMIT) => {
- let styleInfo = {}
- let height = itemInfo.height - moveY
- if (height >= Math.min(minLimit, itemInfo.height)) {
- styleInfo = {
- height,
- top: itemInfo.top + moveY
- }
- }
- return styleInfo
- }
- _.dealTR = (itemInfo, moveX, moveY, minLimit = _.MIN_LIMIT) => {
- let styleInfo = {}
- let width = itemInfo.width + moveX
- let height = itemInfo.height - moveY
- if (width >= Math.min(minLimit, itemInfo.width)) {
- Object.assign(styleInfo, {
- width
- })
- }
- if (height >= Math.min(minLimit, itemInfo.height)) {
- Object.assign(styleInfo, {
- height,
- top: itemInfo.top + moveY
- })
- }
- return styleInfo
- }
- _.dealCL = (itemInfo, moveX, moveY, minLimit = _.MIN_LIMIT) => {
- let styleInfo = {}
- let width = itemInfo.width - moveX
- if (width >= Math.min(minLimit, itemInfo.width)) {
- Object.assign(styleInfo, {
- width,
- left: itemInfo.left + moveX
- })
- }
- return styleInfo
- }
- _.dealCR = (itemInfo, moveX, moveY, minLimit = _.MIN_LIMIT) => {
- let styleInfo = {}
- let width = itemInfo.width + moveX
- if (width >= Math.min(minLimit, itemInfo.width)) {
- Object.assign(styleInfo, {
- width
- })
- }
- return styleInfo
- }
- _.dealBL = (itemInfo, moveX, moveY, minLimit = _.MIN_LIMIT) => {
- let styleInfo = {}
- let width = itemInfo.width - moveX
- let height = itemInfo.height + moveY
- if (width >= Math.min(minLimit, itemInfo.width)) {
- Object.assign(styleInfo, {
- width,
- left: itemInfo.left + moveX
- })
- }
- if (height >= Math.min(minLimit, itemInfo.height)) {
- Object.assign(styleInfo, {
- height
- })
- }
- return styleInfo
- }
- _.dealBC = (itemInfo, moveX, moveY, minLimit = _.MIN_LIMIT) => {
- let styleInfo = {}
- let height = itemInfo.height + moveY
- if (height >= Math.min(minLimit, itemInfo.height)) {
- Object.assign(styleInfo, {
- height
- })
- }
- return styleInfo
- }
- _.dealBR = (itemInfo, moveX, moveY, minLimit = _.MIN_LIMIT) => {
- let styleInfo = {}
- let width = itemInfo.width + moveX
- let height = itemInfo.height + moveY
- if (width >= Math.min(minLimit, itemInfo.width)) {
- Object.assign(styleInfo, {
- width
- })
- }
- if (height >= Math.min(minLimit, itemInfo.height)) {
- Object.assign(styleInfo, {
- height
- })
- }
- return styleInfo
- }
- let addItem = {
- bind: function (el, binding, vnode) {
- const MIN_LIMIT = _.MIN_LIMIT
- // 拖拽添加
- // el.addEventListener('mousedown', handleMouseDown)
- function handleMouseDown (e) {
- e && e.preventDefault()
- let itemInfo = {
- top: _.getDistanceY(e, el),
- left: _.getDistanceX(e, el),
- width: 0,
- height: 0
- }
- let container = _.getOffset(el)
- // Only used once at the beginning of init
- let setting = {
- topPer: _.decimalPoint(itemInfo.top / container.height),
- leftPer: _.decimalPoint(itemInfo.left / container.width),
- widthPer: 0,
- heightPer: 0
- }
- let preX = _.getPageX(e)
- let preY = _.getPageY(e)
- vnode.context.addhotZoneItem(setting)
- window.addEventListener('mousemove', handleChange)
- window.addEventListener('mouseup', handleMouseUp)
- function handleChange (e) {
- e && e.preventDefault()
- let moveX = _.getPageX(e) - preX
- let moveY = _.getPageY(e) - preY
- preX = _.getPageX(e)
- preY = _.getPageY(e)
- // Not consider the direction of movement first, consider only the lower right drag point
- let minLimit = 0
- let styleInfo = _.dealBR(itemInfo, moveX, moveY, minLimit)
- // Boundary value processing
- itemInfo = _.dealEdgeValue(itemInfo, styleInfo, container)
- Object.assign(el.lastElementChild.style, {
- top: `${itemInfo.top}px`,
- left: `${itemInfo.left}px`,
- width: `${itemInfo.width}px`,
- height: `${itemInfo.height}px`
- })
- }
- function handleMouseUp () {
- let perInfo = {
- topPer: _.decimalPoint(itemInfo.top / container.height),
- leftPer: _.decimalPoint(itemInfo.left / container.width),
- widthPer: _.decimalPoint(itemInfo.width / container.width),
- heightPer: _.decimalPoint(itemInfo.height / container.height)
- }
- if (vnode.context.isOverRange()) {
- vnode.context.overRange()
- } else if (container.height < MIN_LIMIT && itemInfo.width > MIN_LIMIT) {
- vnode.context.changeItem(Object.assign(perInfo, {
- topPer: 0,
- heightPer: 1
- }))
- } else if (container.width < MIN_LIMIT && itemInfo.height > MIN_LIMIT) {
- vnode.context.changeItem(Object.assign(perInfo, {
- leftper: 0,
- widthPer: 1
- }))
- } else if (itemInfo.width > MIN_LIMIT && itemInfo.height > MIN_LIMIT) {
- vnode.context.changeItem(perInfo)
- } else {
- vnode.context.eraseItem()
- }
- window.removeEventListener('mousemove', handleChange)
- window.removeEventListener('mouseup', handleMouseUp)
- }
- }
- el.$destroy = () => el.removeEventListener('mousedown', handleMouseDown)
- },
- unbind: function (el) {
- el.$destroy()
- }
- }
- let changeSize = {
- bind: function (el, binding, vnode) {
- el.addEventListener('mousedown', handleMouseDown)
- function handleMouseDown (e) {
- let pointer = e.target.dataset.pointer
- if (!pointer) {
- return
- }
- e && e.stopPropagation()
- let zone = el.parentNode
- let setting = vnode.context.setting
- let container = _.getOffset(zone.parentNode)
- let itemInfo = {
- width: _.getOffset(zone).width || 0,
- height: _.getOffset(zone).height || 0,
- top: setting.topPer * container.height || 0,
- left: setting.leftPer * container.width || 0
- }
- let preX = _.getPageX(e)
- let preY = _.getPageY(e)
- let flag
- // Hide the info displayed by hover
- vnode.context.handlehideZone(true)
- window.addEventListener('mousemove', handleChange)
- window.addEventListener('mouseup', handleMouseUp)
- function handleChange (e) {
- e && e.preventDefault()
- flag = true
- let moveX = _.getPageX(e) - preX
- let moveY = _.getPageY(e) - preY
- preX = _.getPageX(e)
- preY = _.getPageY(e)
- // Handling the situation when different dragging points are selected
- let styleInfo = _[pointer](itemInfo, moveX, moveY)
- // Boundary value processing
- itemInfo = _.dealEdgeValue(itemInfo, styleInfo, container)
- Object.assign(zone.style, {
- top: `${itemInfo.top}px`,
- left: `${itemInfo.left}px`,
- width: `${itemInfo.width}px`,
- height: `${itemInfo.height}px`
- })
- }
- function handleMouseUp () {
- if (flag) {
- flag = false
- let perInfo = {
- topPer: _.decimalPoint(itemInfo.top / container.height),
- leftPer: _.decimalPoint(itemInfo.left / container.width),
- widthPer: _.decimalPoint(itemInfo.width / container.width),
- heightPer: _.decimalPoint(itemInfo.height / container.height)
- }
- vnode.context.changeInfo(perInfo)
- // 兼容数据无变更情况下导致 computed 不更新,数据仍为 px 时 resize 出现的问题
- Object.assign(zone.style, {
- top: `${itemInfo.top}px`,
- left: `${itemInfo.left}px`,
- width: `${itemInfo.width}px`,
- height: `${itemInfo.height}px`
- })
- }
- // Show the info
- vnode.context.handlehideZone(false)
- window.removeEventListener('mousemove', handleChange)
- window.removeEventListener('mouseup', handleMouseUp)
- }
- }
- el.$destroy = () => el.removeEventListener('mousedown', handleMouseDown)
- },
- unbind: function (el) {
- el.$destroy()
- }
- }
- let dragItem = {
- bind: function (el, binding, vnode) {
- el.addEventListener('mousedown', handleMouseDown)
- function handleMouseDown (e) {
- e && e.stopPropagation()
- let container = _.getOffset(el.parentNode)
- let preX = _.getPageX(e)
- let preY = _.getPageY(e)
- let topPer
- let leftPer
- let flag
- window.addEventListener('mousemove', handleChange)
- window.addEventListener('mouseup', handleMouseUp)
- function handleChange (e) {
- e && e.preventDefault()
- flag = true
- // Hide the info displayed by hover
- vnode.context.handlehideZone(true)
- let setting = vnode.context.setting
- let moveX = _.getPageX(e) - preX
- let moveY = _.getPageY(e) - preY
- setting.topPer = setting.topPer || 0
- setting.leftPer = setting.leftPer || 0
- topPer = _.decimalPoint(moveY / container.height + setting.topPer)
- leftPer = _.decimalPoint(moveX / container.width + setting.leftPer)
- // Hotzone moving boundary processing
- if (topPer < 0) {
- topPer = 0
- moveY = -container.height * setting.topPer
- }
- if (leftPer < 0) {
- leftPer = 0
- moveX = -container.width * setting.leftPer
- }
- if (topPer + setting.heightPer > 1) {
- topPer = 1 - setting.heightPer
- moveY = container.height * (topPer - setting.topPer)
- }
- if (leftPer + setting.widthPer > 1) {
- leftPer = 1 - setting.widthPer
- moveX = container.width * (leftPer - setting.leftPer)
- }
- el.style.transform = `translate(${moveX}px, ${moveY}px)`
- }
- function handleMouseUp () {
- if (flag) {
- flag = false
- el.style.transform = 'translate(0, 0)'
- vnode.context.changeInfo({
- topPer,
- leftPer
- })
- }
- // Show the info
- vnode.context.handlehideZone(false)
- window.removeEventListener('mousemove', handleChange)
- window.removeEventListener('mouseup', handleMouseUp)
- }
- }
- el.$destroy = () => el.removeEventListener('mousedown', handleMouseDown)
- },
- unbind: function (el) {
- el.$destroy()
- }
- }
- // export default _
|