forked from github/dataease
feat:画板优化
This commit is contained in:
parent
e20607d911
commit
7efac43e55
@ -26,14 +26,14 @@ public class PanelViewLinkageController {
|
||||
@Resource
|
||||
private PanelViewLinkageService panelViewLinkageService;
|
||||
|
||||
@ApiOperation("获取仪表板视图联动信息")
|
||||
@ApiOperation("获取仪表板所有视图联动信息")
|
||||
@PostMapping("/getViewLinkageGather")
|
||||
public Map getViewLinkageGather(@RequestBody PanelLinkageRequest request){
|
||||
return panelViewLinkageService.getViewLinkageGather(request);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("获取仪表板视图联动信息")
|
||||
@ApiOperation("保存仪表板视图联动信息")
|
||||
@PostMapping("/saveLinkage")
|
||||
public void saveLinkage(@RequestBody PanelLinkageRequest request){
|
||||
panelViewLinkageService.saveLinkage(request);
|
||||
|
@ -45,14 +45,15 @@
|
||||
"vue-codemirror": "^4.0.6",
|
||||
"vue-fullscreen": "^2.5.2",
|
||||
"vue-i18n": "7.3.2",
|
||||
"vue-power-drag": "^0.2.0",
|
||||
"vue-router": "3.0.6",
|
||||
"vue-to-pdf": "^1.0.0",
|
||||
"vue-uuid": "2.0.2",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuex": "3.1.0",
|
||||
"webpack": "^4.46.0",
|
||||
"xlsx": "^0.17.0"
|
||||
"xlsx": "^0.17.0",
|
||||
"lodash": "^4.17.4",
|
||||
"jquery": "^3.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.4.0-0",
|
||||
|
948
frontend/src/components/DeDrag/drag.js
Normal file
948
frontend/src/components/DeDrag/drag.js
Normal file
@ -0,0 +1,948 @@
|
||||
import _ from 'lodash'
|
||||
import $ from 'jquery'
|
||||
|
||||
let positionBox = []
|
||||
let coordinates = [] // 坐标点集合
|
||||
|
||||
let lastTask
|
||||
let isOverlay = false // 是否正在交换位置
|
||||
let moveTime = 80 // 移动动画时间
|
||||
|
||||
let itemMaxY = 0
|
||||
let itemMaxX = 0
|
||||
|
||||
function debounce(func, time) {
|
||||
if (!isOverlay) {
|
||||
(function(t) {
|
||||
isOverlay = true
|
||||
setTimeout(function() {
|
||||
t()
|
||||
setTimeout(function() {
|
||||
isOverlay = false
|
||||
if (lastTask !== undefined) {
|
||||
debounce(lastTask, time)
|
||||
}
|
||||
}, moveTime)
|
||||
}, time)
|
||||
})(func)
|
||||
lastTask = undefined
|
||||
} else {
|
||||
lastTask = func
|
||||
}
|
||||
}
|
||||
|
||||
function scrollScreen(e) {
|
||||
if (e.clientY + 50 >= window.innerHeight) {
|
||||
const body = $(document.body)
|
||||
body.scrollTop(body.scrollTop() + 20)
|
||||
} else if (e.clientY <= 150) {
|
||||
const body = $(document.body)
|
||||
body.scrollTop(body.scrollTop() - 20)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置位置盒子
|
||||
*
|
||||
*/
|
||||
function resetPositionBox() {
|
||||
// 根据当前容器的宽度来决定多少列
|
||||
itemMaxX = this.maxCell
|
||||
const rows = 1 // 初始100行,后面根据需求会自动增加
|
||||
for (let i = 0; i < rows; i++) {
|
||||
const row = []
|
||||
|
||||
for (let j = 0; j < this.maxCell; j++) {
|
||||
row.push({
|
||||
el: false
|
||||
})
|
||||
}
|
||||
|
||||
positionBox.push(row)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充位置盒子
|
||||
*
|
||||
* @param {any} item
|
||||
*/
|
||||
function addItemToPositionBox(item) {
|
||||
const pb = positionBox
|
||||
if (item.x <= 0 || item.y <= 0) return
|
||||
|
||||
for (let i = item.x - 1; i < item.x - 1 + item.sizex; i++) {
|
||||
for (let j = item.y - 1; j < item.y - 1 + item.sizey; j++) {
|
||||
if (pb[j][i]) {
|
||||
pb[j][i].el = item
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fillPositionBox(maxY) {
|
||||
const pb = positionBox
|
||||
maxY += 2
|
||||
for (let j = 0; j < maxY; j++) {
|
||||
if (pb[j] === undefined) {
|
||||
const row = []
|
||||
for (let i = 0; i < itemMaxX; i++) {
|
||||
row.push({
|
||||
el: false
|
||||
})
|
||||
}
|
||||
pb.push(row)
|
||||
}
|
||||
}
|
||||
|
||||
itemMaxY = maxY
|
||||
|
||||
$(this.$el).css('height', ((itemMaxY + 2) * this.cellHeight) + 'px')
|
||||
}
|
||||
|
||||
function removeItemFromPositionBox(item) {
|
||||
const pb = positionBox
|
||||
if (item.x <= 0 || item.y <= 0) return
|
||||
for (let i = item.x - 1; i < item.x - 1 + item.sizex; i++) {
|
||||
for (let j = item.y - 1; j < item.y - 1 + item.sizey; j++) {
|
||||
if (pb[j][i]) {
|
||||
pb[j][i].el = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新计算宽度,使最小单元格能占满整个容器
|
||||
*
|
||||
*/
|
||||
function recalcCellWidth() {
|
||||
const containerNode = this.$refs['container']
|
||||
const containerWidth = containerNode.offsetWidth
|
||||
|
||||
const cells = Math.round(containerWidth / this.cellWidth)
|
||||
this.maxCell = cells
|
||||
|
||||
// if (containerWidth % this.cellWidth !=== 0) {
|
||||
// this.cellWidth += containerWidth % this.cellWidth / cells;
|
||||
// }
|
||||
}
|
||||
|
||||
function init() {
|
||||
this.cellWidth = this.baseWidth + this.baseMarginLeft
|
||||
this.cellHeight = this.baseHeight + this.baseMarginTop
|
||||
|
||||
positionBox = []
|
||||
coordinates = [] // 坐标点集合
|
||||
|
||||
lastTask = undefined
|
||||
isOverlay = false // 是否正在交换位置
|
||||
moveTime = 80 // 移动动画时间
|
||||
|
||||
itemMaxY = 0
|
||||
itemMaxX = 0
|
||||
|
||||
const vm = this
|
||||
|
||||
recalcCellWidth.call(this)
|
||||
|
||||
resetPositionBox.call(this)
|
||||
|
||||
let i = 0
|
||||
const timeid = setInterval(function() {
|
||||
if (i >= vm.yourList.length) {
|
||||
clearInterval(timeid)
|
||||
vm.$nextTick(function() {
|
||||
vm.moveAnimate = true
|
||||
})
|
||||
} else {
|
||||
const item = vm.yourList[i]
|
||||
addItem.call(vm, item, i)
|
||||
i++
|
||||
}
|
||||
}, 1)
|
||||
vm.renderOk = true
|
||||
}
|
||||
|
||||
function resizePlayer(item, newSize) {
|
||||
const vm = this
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
const canGoUpRows = canItemGoUp(upItem)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
}
|
||||
})
|
||||
|
||||
item.sizex = newSize.sizex
|
||||
item.sizey = newSize.sizey
|
||||
|
||||
if (item.sizex + item.x - 1 > itemMaxX) {
|
||||
item.sizex = itemMaxX - item.x + 1
|
||||
}
|
||||
|
||||
if (item.sizey + item.y > itemMaxY) {
|
||||
fillPositionBox.call(this, item.y + item.sizey)
|
||||
}
|
||||
|
||||
emptyTargetCell.call(this, item)
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
|
||||
const canGoUpRows = canItemGoUp(item)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(this, item, canGoUpRows)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查移动的位置,如果不合法,会自动修改
|
||||
*
|
||||
* @param {any} item
|
||||
* @param {any} position
|
||||
*/
|
||||
function checkItemPosition(item, position) {
|
||||
position = position || {}
|
||||
position.x = position.x || item.x
|
||||
position.y = position.y || item.y
|
||||
|
||||
// 检查位置
|
||||
if (item.x < 1) {
|
||||
item.x = 1
|
||||
}
|
||||
|
||||
// 检查大小
|
||||
if (item.sizex > itemMaxX) {
|
||||
item.sizex = itemMaxX
|
||||
}
|
||||
|
||||
if (item.sizex < 1) {
|
||||
item.sizex = 1
|
||||
}
|
||||
|
||||
if (item.x + item.sizex - 1 > itemMaxX) {
|
||||
item.x = itemMaxX - item.sizex + 1
|
||||
if (item.x < 1) {
|
||||
item.x = 1
|
||||
}
|
||||
}
|
||||
|
||||
if (item.y < 1) {
|
||||
item.y = 1
|
||||
}
|
||||
|
||||
if (item.sizey < 1) {
|
||||
item.sizey = 1
|
||||
}
|
||||
|
||||
if (item.y + item.sizey > itemMaxY - 1) {
|
||||
fillPositionBox.call(this, item.y + item.sizey - 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动正在拖动的元素
|
||||
*
|
||||
* @param {any} item
|
||||
* @param {any} position
|
||||
*/
|
||||
function movePlayer(item, position) {
|
||||
const vm = this
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
const canGoUpRows = canItemGoUp(upItem)
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
}
|
||||
})
|
||||
|
||||
item.x = position.x
|
||||
item.y = position.y
|
||||
|
||||
checkItemPosition.call(this, item, position)
|
||||
|
||||
emptyTargetCell.call(this, item)
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
|
||||
const canGoUpRows = canItemGoUp(item)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(this, item, canGoUpRows)
|
||||
}
|
||||
}
|
||||
|
||||
function removeItem(index) {
|
||||
const vm = this
|
||||
const item = this.yourList[index]
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
|
||||
// $(this.$refs['item' + item._dragId][0]).remove();
|
||||
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
const canGoUpRows = canItemGoUp(upItem)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
}
|
||||
})
|
||||
|
||||
this.yourList.splice(index, 1, {})
|
||||
}
|
||||
|
||||
function addItem(item, index) {
|
||||
if (index < 0) {
|
||||
index = this.yourList.length
|
||||
}
|
||||
item._dragId = index
|
||||
|
||||
checkItemPosition.call(this, item, {
|
||||
x: item.x,
|
||||
y: item.y
|
||||
})
|
||||
|
||||
emptyTargetCell.call(this, item)
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
const canGoUpRows = canItemGoUp(item)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(this, item, canGoUpRows)
|
||||
}
|
||||
|
||||
// 生成坐标点
|
||||
// makeCoordinate.call(this, item);
|
||||
}
|
||||
|
||||
function changeToCoord(left, top, width, height) {
|
||||
return {
|
||||
x1: left,
|
||||
x2: left + width,
|
||||
y1: top,
|
||||
y2: top + height,
|
||||
c1: left + width / 2,
|
||||
c2: top + height / 2
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测有无碰撞,并作出处理
|
||||
*
|
||||
* @param {any} tCoord 比对对象的坐标
|
||||
*/
|
||||
function findClosetCoords(item, tCoord) {
|
||||
if (isOverlay) return
|
||||
let i = coordinates.length
|
||||
let collisionsItem = []
|
||||
while (i--) {
|
||||
const nowCoord = coordinates[i]
|
||||
if (item._dragId === nowCoord.el._dragId) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (tCoord.x2 < nowCoord.x1 || tCoord.x1 > nowCoord.x2 || tCoord.y2 < nowCoord.y1 || tCoord.y1 > nowCoord.y2) {
|
||||
continue
|
||||
} else {
|
||||
collisionsItem.push({
|
||||
centerDistance: Math.sqrt(Math.pow(tCoord.c1 - nowCoord.c1, 2) + Math.pow(tCoord.c2 - nowCoord.c2, 2)),
|
||||
coord: nowCoord
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (collisionsItem.length <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
isOverlay = true
|
||||
|
||||
collisionsItem = _.sortBy(collisionsItem, 'area')
|
||||
|
||||
movePlayer.call(this, item, {
|
||||
x: collisionsItem[0].coord.el.x,
|
||||
y: collisionsItem[0].coord.el.y
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
isOverlay = false
|
||||
}, 200)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成坐标点
|
||||
*
|
||||
* @param {any} item
|
||||
*/
|
||||
function makeCoordinate(item) {
|
||||
const width = this.cellWidth * (item.sizex) - this.baseMarginLeft
|
||||
const height = this.cellHeight * (item.sizey) - this.baseMarginTop
|
||||
const left = this.cellWidth * (item.x - 1) + this.baseMarginLeft
|
||||
const top = this.cellHeight * (item.y - 1) + this.baseMarginTop
|
||||
|
||||
const coord = {
|
||||
x1: left,
|
||||
x2: left + width,
|
||||
y1: top,
|
||||
y2: top + height,
|
||||
c1: left + width / 2,
|
||||
c2: top + height / 2,
|
||||
el: item
|
||||
}
|
||||
|
||||
coordinates.push(coord)
|
||||
}
|
||||
|
||||
function changeItemCoord(item) {
|
||||
const width = this.cellWidth * (item.sizex) - this.baseMarginLeft
|
||||
const height = this.cellHeight * (item.sizey) - this.baseMarginTop
|
||||
const left = this.cellWidth * (item.x - 1) + this.baseMarginLeft
|
||||
const top = this.cellHeight * (item.y - 1) + this.baseMarginTop
|
||||
|
||||
const coord = {
|
||||
x1: left,
|
||||
x2: left + width,
|
||||
y1: top,
|
||||
y2: top + height,
|
||||
c1: left + width / 2,
|
||||
c2: top + height / 2,
|
||||
el: item
|
||||
}
|
||||
|
||||
const index = _.findIndex(coordinates, function(o) {
|
||||
return o.el._dragId === item._dragId
|
||||
})
|
||||
if (index !== -1) {
|
||||
coordinates.splice(index, 1, coord)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空目标位置的元素
|
||||
*
|
||||
* @param {any} item
|
||||
*/
|
||||
function emptyTargetCell(item) {
|
||||
const vm = this
|
||||
const belowItems = findBelowItems(item)
|
||||
|
||||
_.forEach(belowItems, function(downItem, index) {
|
||||
if (downItem._dragId === item._dragId) return
|
||||
const moveSize = item.y + item.sizey - downItem.y
|
||||
if (moveSize > 0) {
|
||||
moveItemDown.call(vm, downItem, moveSize)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前位置的item能否上浮
|
||||
*
|
||||
* @param {any} item
|
||||
* @returns
|
||||
*/
|
||||
function canItemGoUp(item) {
|
||||
let upperRows = 0
|
||||
for (let row = item.y - 2; row >= 0; row--) {
|
||||
for (let cell = item.x - 1; cell < item.x - 1 + item.sizex; cell++) {
|
||||
if (positionBox[row][cell] && positionBox[row][cell].el) {
|
||||
return upperRows
|
||||
}
|
||||
}
|
||||
upperRows++
|
||||
}
|
||||
|
||||
return upperRows
|
||||
}
|
||||
|
||||
/**
|
||||
* 在移动之前,找到当前下移的元素的下面的元素(递归)
|
||||
*
|
||||
* @param {any} items
|
||||
* @param {any} size
|
||||
*/
|
||||
function moveItemDown(item, size) {
|
||||
const vm = this
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems(item)
|
||||
|
||||
_.forEach(belowItems, function(downItem, index) {
|
||||
if (downItem._dragId === item._dragId) return
|
||||
const moveSize = calcDiff(item, downItem, size)
|
||||
if (moveSize > 0) {
|
||||
moveItemDown.call(vm, downItem, moveSize)
|
||||
}
|
||||
})
|
||||
|
||||
const targetPosition = {
|
||||
y: item.y + size
|
||||
}
|
||||
setPlayerPosition.call(this, item, targetPosition)
|
||||
checkItemPosition.call(this, item, targetPosition)
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
}
|
||||
|
||||
function setPlayerPosition(item, position) {
|
||||
const vm = this
|
||||
position = position || {}
|
||||
|
||||
const targetX = position.x || item.x
|
||||
const targetY = position.y || item.y
|
||||
|
||||
item.x = targetX
|
||||
item.y = targetY
|
||||
|
||||
if (item.y + item.sizey > itemMaxY) {
|
||||
itemMaxY = item.y + item.sizey
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 寻找子元素到父元素的最大距离
|
||||
*
|
||||
* @param {any} parent
|
||||
* @param {any} son
|
||||
* @param {any} size
|
||||
*/
|
||||
function calcDiff(parent, son, size) {
|
||||
const diffs = []
|
||||
|
||||
for (let i = son.x - 1; i < son.x - 1 + son.sizex; i++) {
|
||||
let temp_y = 0
|
||||
|
||||
for (let j = parent.y - 1 + parent.sizey; j < son.y - 1; j++) {
|
||||
if (positionBox[j][i] && positionBox[j][i].el === false) {
|
||||
temp_y++
|
||||
}
|
||||
}
|
||||
diffs.push(temp_y)
|
||||
}
|
||||
|
||||
const max_diff = Math.max.apply(Math, diffs)
|
||||
size = size - max_diff
|
||||
|
||||
return size > 0 ? size : 0
|
||||
}
|
||||
|
||||
function moveItemUp(item, size) {
|
||||
// console.log('moveItemUp')
|
||||
const vm = this
|
||||
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
|
||||
// item.y -= size;
|
||||
setPlayerPosition.call(this, item, {
|
||||
y: item.y - size
|
||||
})
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
|
||||
_.forEach(belowItems, function(upItem, index) {
|
||||
const moveSize = canItemGoUp(upItem)
|
||||
if (moveSize > 0) {
|
||||
moveItemUp.call(vm, upItem, moveSize)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function findBelowItems(item) {
|
||||
const belowItems = {}
|
||||
for (let cell = item.x - 1; cell < item.x - 1 + item.sizex; cell++) {
|
||||
for (let row = item.y - 1; row < positionBox.length; row++) {
|
||||
const target = positionBox[row][cell]
|
||||
if (target && target.el) {
|
||||
belowItems[target.el._dragId] = target.el
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _.sortBy(_.values(belowItems), 'y')
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'vue-power-drag',
|
||||
props: {
|
||||
yourList: {
|
||||
required: true,
|
||||
type: Array // String,Number,Boolean,Function,Object,Array
|
||||
},
|
||||
baseWidth: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
baseHeight: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: 50
|
||||
},
|
||||
baseMarginLeft: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
baseMarginTop: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
draggable: {
|
||||
required: false,
|
||||
default: true,
|
||||
type: Boolean
|
||||
},
|
||||
dragStart: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
dragging: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
dragEnd: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
resizable: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
resizeStart: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
resizing: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
resizeEnd: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
renderOk: false,
|
||||
moveAnimate: false,
|
||||
list: [],
|
||||
cellWidth: 0,
|
||||
cellHeight: 0,
|
||||
maxCell: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
positionBox() {
|
||||
return positionBox
|
||||
},
|
||||
coordinates() {
|
||||
return coordinates
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
removeItem: removeItem,
|
||||
startResize(e, item, index) {
|
||||
console.log('startResize:' + index)
|
||||
if (!this.resizable) return
|
||||
this.resizeStart.call(null, e, item, index)
|
||||
|
||||
// e.preventDefault();
|
||||
const target = $(e.target)
|
||||
|
||||
if (!this.infoBox) {
|
||||
this.infoBox = {}
|
||||
}
|
||||
|
||||
const itemNode = target.parents('.item')
|
||||
|
||||
this.infoBox.resizeItem = item
|
||||
this.infoBox.resizeItemIndex = index
|
||||
},
|
||||
containerMouseDown(e) {
|
||||
console.log('containerMouseDown:')
|
||||
|
||||
// e.preventDefault();
|
||||
if (!this.infoBox) {
|
||||
this.infoBox = {}
|
||||
}
|
||||
|
||||
this.infoBox.startX = e.pageX
|
||||
this.infoBox.startY = e.pageY
|
||||
},
|
||||
startMove(e, item, index) {
|
||||
console.log('startMove:' + index)
|
||||
const vm = this
|
||||
// e.preventDefault();
|
||||
|
||||
if (!this.infoBox) {
|
||||
this.infoBox = {}
|
||||
}
|
||||
const infoBox = this.infoBox
|
||||
const target = $(e.target)
|
||||
|
||||
let className = target.attr('class')
|
||||
className = className || ''
|
||||
if (className.indexOf('dragHandle') === -1 && className.indexOf('item') === -1 && className.indexOf('resizeHandle') === -1) {
|
||||
return
|
||||
}
|
||||
|
||||
if (className.includes('resizeHandle')) {
|
||||
|
||||
} else if (this.draggable && (className.includes('dragHandle') || className.includes('item'))) {
|
||||
this.dragStart.call(null, e, item, index)
|
||||
infoBox.moveItem = item
|
||||
infoBox.moveItemIndex = index
|
||||
}
|
||||
|
||||
infoBox.cloneItem = null
|
||||
infoBox.nowItemNode = null
|
||||
|
||||
if (target.attr('class') && target.attr('class').indexOf('item') !== -1) {
|
||||
infoBox.nowItemNode = target
|
||||
infoBox.cloneItem = target.clone()
|
||||
} else {
|
||||
infoBox.nowItemNode = target.parents('.item')
|
||||
infoBox.cloneItem = infoBox.nowItemNode.clone()
|
||||
}
|
||||
infoBox.cloneItem.addClass('cloneNode')
|
||||
|
||||
$(this.$el).append(infoBox.cloneItem)
|
||||
|
||||
infoBox.orignX = infoBox.cloneItem.position().left // 克隆对象原始X位置
|
||||
infoBox.orignY = infoBox.cloneItem.position().top
|
||||
infoBox.oldX = item.x // 实际对象原始X位置
|
||||
infoBox.oldY = item.y
|
||||
infoBox.oldSizeX = item.sizex
|
||||
infoBox.oldSizeY = item.sizey
|
||||
infoBox.orignWidth = infoBox.cloneItem.prop('offsetWidth')
|
||||
infoBox.orignHeight = infoBox.cloneItem.prop('offsetHeight')
|
||||
|
||||
function itemMouseMove(e) {
|
||||
// console.log('itemMouseMove')
|
||||
const moveItem = _.get(infoBox, 'moveItem')
|
||||
const resizeItem = _.get(infoBox, 'resizeItem')
|
||||
|
||||
if (resizeItem) { // 调整大小时
|
||||
console.log('resizeItem')
|
||||
vm.resizing.call(null, e, resizeItem, resizeItem._dragId)
|
||||
|
||||
vm.$set(resizeItem, 'isPlayer', true)
|
||||
const nowItemIndex = infoBox.resizeItemIndex
|
||||
const cloneItem = infoBox.cloneItem
|
||||
const startX = infoBox.startX
|
||||
const startY = infoBox.startY
|
||||
const oldSizeX = infoBox.oldSizeX
|
||||
const oldSizeY = infoBox.oldSizeY
|
||||
const orignWidth = infoBox.orignWidth
|
||||
const orignHeight = infoBox.orignHeight
|
||||
|
||||
const moveXSize = e.pageX - startX // X方向移动的距离
|
||||
const moveYSize = e.pageY - startY // Y方向移动的距离
|
||||
|
||||
const addSizex = (moveXSize) % vm.cellWidth > (vm.cellWidth / 4 * 1) ? parseInt(((moveXSize) / vm.cellWidth + 1)) : parseInt(((moveXSize) / vm.cellWidth))
|
||||
const addSizey = (moveYSize) % vm.cellHeight > (vm.cellHeight / 4 * 1) ? parseInt(((moveYSize) / vm.cellHeight + 1)) : parseInt(((moveYSize) / vm.cellHeight))
|
||||
|
||||
const nowX = oldSizeX + addSizex > 0 ? oldSizeX + addSizex : 1
|
||||
const nowY = oldSizeY + addSizey > 0 ? oldSizeY + addSizey : 1
|
||||
|
||||
debounce((function(addSizex, addSizey) {
|
||||
return function() {
|
||||
resizePlayer.call(vm, resizeItem, {
|
||||
sizex: nowX,
|
||||
sizey: nowY
|
||||
})
|
||||
}
|
||||
})(addSizex, addSizey), 10)
|
||||
|
||||
let nowWidth = orignWidth + moveXSize
|
||||
nowWidth = nowWidth <= vm.baseWidth ? vm.baseWidth : nowWidth
|
||||
let nowHeight = orignHeight + moveYSize
|
||||
nowHeight = nowHeight <= vm.baseHeight ? vm.baseHeight : nowHeight
|
||||
// 克隆元素实时改变大小
|
||||
cloneItem.css({
|
||||
width: nowWidth,
|
||||
height: nowHeight
|
||||
})
|
||||
} else if (moveItem) {
|
||||
console.log('moveItem')
|
||||
|
||||
scrollScreen(e)
|
||||
if (!vm.draggable) return
|
||||
vm.dragging.call(null, e, moveItem, moveItem._dragId)
|
||||
|
||||
vm.$set(moveItem, 'isPlayer', true)
|
||||
// this.$set(moveItem, "show", false);
|
||||
const nowItemIndex = infoBox.moveItemIndex
|
||||
const cloneItem = infoBox.cloneItem
|
||||
const startX = infoBox.startX
|
||||
const startY = infoBox.startY
|
||||
const orignX = infoBox.orignX
|
||||
const orignY = infoBox.orignY
|
||||
const oldX = infoBox.oldX
|
||||
const oldY = infoBox.oldY
|
||||
|
||||
const moveXSize = e.pageX - startX // X方向移动的距离
|
||||
const moveYSize = e.pageY - startY // Y方向移动的距离
|
||||
|
||||
const nowCloneItemX = orignX + moveXSize
|
||||
const nowCloneItemY = orignY + moveYSize
|
||||
|
||||
let newX = parseInt((nowCloneItemX + (cloneItem.width() / 12) - vm.baseMarginLeft) / vm.cellWidth + 1)
|
||||
let newY = parseInt((nowCloneItemY + (cloneItem.height() / 12) - vm.baseMarginTop) / vm.cellHeight + 1)
|
||||
newX = newX > 0 ? newX : 1
|
||||
newY = newY > 0 ? newY : 1
|
||||
|
||||
debounce((function(newX, oldX, newY, oldY) {
|
||||
return function() {
|
||||
if (newX !== oldX || oldY !== newY) {
|
||||
// console.log("move");
|
||||
movePlayer.call(vm, moveItem, {
|
||||
x: newX,
|
||||
y: newY
|
||||
})
|
||||
|
||||
infoBox.oldX = newX
|
||||
infoBox.oldY = newY
|
||||
}
|
||||
}
|
||||
})(newX, oldX, newY, oldY), 10)
|
||||
|
||||
cloneItem.css({
|
||||
left: nowCloneItemX + 'px',
|
||||
top: nowCloneItemY + 'px'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(window).mousemove(itemMouseMove)
|
||||
|
||||
$(window).mouseup(function itemMouseUp(e) {
|
||||
if (_.isEmpty(vm.infoBox)) return
|
||||
if (vm.infoBox.cloneItem) {
|
||||
vm.infoBox.cloneItem.remove()
|
||||
}
|
||||
if (vm.infoBox.resizeItem) {
|
||||
vm.$delete(vm.infoBox.resizeItem, 'isPlayer')
|
||||
vm.resizeEnd.call(null, e, vm.infoBox.resizeItem, vm.infoBox.resizeItem._dragId)
|
||||
}
|
||||
if (vm.infoBox.moveItem) {
|
||||
vm.dragEnd.call(null, e, vm.infoBox.moveItem, vm.infoBox.moveItem._dragId)
|
||||
vm.$set(vm.infoBox.moveItem, 'show', true)
|
||||
vm.$delete(vm.infoBox.moveItem, 'isPlayer')
|
||||
}
|
||||
vm.infoBox = {}
|
||||
|
||||
$(this).off('mousemove', itemMouseMove)
|
||||
$(this).off('mouseup', itemMouseUp)
|
||||
})
|
||||
},
|
||||
endMove(e) {
|
||||
|
||||
},
|
||||
moving(e) {
|
||||
|
||||
},
|
||||
/**
|
||||
* 计算当前item的位置和大小
|
||||
*
|
||||
* @param {any} item
|
||||
* @returns
|
||||
*/
|
||||
nowItemStyle(item, index) {
|
||||
return {
|
||||
width: (this.cellWidth * (item.sizex) - this.baseMarginLeft) + 'px',
|
||||
height: (this.cellHeight * (item.sizey) - this.baseMarginTop) + 'px',
|
||||
left: (this.cellWidth * (item.x - 1) + this.baseMarginLeft) + 'px',
|
||||
top: (this.cellHeight * (item.y - 1) + this.baseMarginTop) + 'px'
|
||||
}
|
||||
},
|
||||
getList() {
|
||||
console.log('getList:')
|
||||
|
||||
const returnList = _.sortBy(_.cloneDeep(this.yourList), 'y')
|
||||
const finalList = []
|
||||
_.forEach(returnList, function(item, index) {
|
||||
if (_.isEmpty(item)) return
|
||||
delete item['_dragId']
|
||||
delete item['show']
|
||||
finalList.push(item)
|
||||
})
|
||||
return finalList
|
||||
},
|
||||
/**
|
||||
* 获取x最大值
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
getMaxCell() {
|
||||
console.log('getMaxCell:')
|
||||
|
||||
return this.maxCell
|
||||
},
|
||||
/**
|
||||
* 获取渲染状态
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
getRenderState() {
|
||||
console.log('getRenderState:')
|
||||
|
||||
return this.moveAnimate
|
||||
},
|
||||
addItem: addItem,
|
||||
init: init,
|
||||
afterInitOk(func) {
|
||||
const timeid = setInterval(() => {
|
||||
if (this.moveAnimate) {
|
||||
clearInterval(timeid)
|
||||
func()
|
||||
}
|
||||
}, 100)
|
||||
},
|
||||
addItemBox(item) {
|
||||
this.yourList.push(item)
|
||||
|
||||
this.$nextTick(function() {
|
||||
addItem.call(this, item, this.yourList.length - 1)
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
updated() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
// init.call(this);
|
||||
}
|
||||
}
|
112
frontend/src/components/DeDrag/drag.less
Normal file
112
frontend/src/components/DeDrag/drag.less
Normal file
@ -0,0 +1,112 @@
|
||||
.dragAndResize
|
||||
{
|
||||
position: relative;
|
||||
|
||||
user-select: none;
|
||||
|
||||
*
|
||||
{
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.item
|
||||
{
|
||||
position: absolute;
|
||||
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
|
||||
cursor: move;
|
||||
|
||||
border: 1px solid;
|
||||
background-color: #fff;
|
||||
|
||||
.resizeHandle
|
||||
{
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
bottom: 2px;
|
||||
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
||||
cursor: nw-resize;
|
||||
|
||||
opacity: .5;
|
||||
border-bottom: 10px solid black;
|
||||
border-left: 10px solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.moveAnimation
|
||||
{
|
||||
transition: top 80ms ease;
|
||||
}
|
||||
|
||||
.canNotDrag
|
||||
{
|
||||
cursor: default!important;
|
||||
}
|
||||
|
||||
.cloneNode
|
||||
{
|
||||
z-index: 3;
|
||||
|
||||
transition: none;
|
||||
|
||||
background-color: #bec1c9;
|
||||
opacity: 0.5;
|
||||
|
||||
}
|
||||
|
||||
.movingItem
|
||||
{
|
||||
position: absolute;
|
||||
|
||||
border: none;
|
||||
&:before
|
||||
{
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
content: 'movingItem';
|
||||
|
||||
background-color: #3d66e7;
|
||||
}
|
||||
}
|
||||
|
||||
.positionBox
|
||||
{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 100px;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.coords
|
||||
{
|
||||
position: fixed;
|
||||
right: 100px;
|
||||
bottom: 200px;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
|
||||
border: 1px solid;
|
||||
}
|
||||
}
|
986
frontend/src/components/DeDrag/drag.vue
Normal file
986
frontend/src/components/DeDrag/drag.vue
Normal file
@ -0,0 +1,986 @@
|
||||
<template>
|
||||
<div ref="container" class="dragAndResize" @mousedown="containerMouseDown($event)" @mouseup="endMove($event)" @mousemove="moving($event)">
|
||||
<div
|
||||
v-for="(item,index) in yourList"
|
||||
v-if="item.sizex!==undefined"
|
||||
:ref="'item'+index"
|
||||
:key="'item'+index"
|
||||
:class="{item:true,moveAnimation:moveAnimate,movingItem:item.isPlayer}"
|
||||
:style="nowItemStyle(item,index)"
|
||||
@mousedown="startMove($event,item,index)"
|
||||
>
|
||||
<slot :name="'slot'+index" />
|
||||
<span v-show="resizable" class="resizeHandle" @mousedown="startResize($event,item,index)" />
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import $ from 'jquery'
|
||||
|
||||
let positionBox = []
|
||||
let coordinates = [] // 坐标点集合
|
||||
|
||||
let lastTask
|
||||
let isOverlay = false // 是否正在交换位置
|
||||
let moveTime = 80 // 移动动画时间
|
||||
|
||||
let itemMaxY = 0
|
||||
let itemMaxX = 0
|
||||
|
||||
function debounce(func, time) {
|
||||
if (!isOverlay) {
|
||||
(function(t) {
|
||||
isOverlay = true
|
||||
setTimeout(function() {
|
||||
t()
|
||||
setTimeout(function() {
|
||||
isOverlay = false
|
||||
if (lastTask !== undefined) {
|
||||
debounce(lastTask, time)
|
||||
}
|
||||
}, moveTime)
|
||||
}, time)
|
||||
})(func)
|
||||
lastTask = undefined
|
||||
} else {
|
||||
lastTask = func
|
||||
}
|
||||
}
|
||||
|
||||
function scrollScreen(e) {
|
||||
if (e.clientY + 50 >= window.innerHeight) {
|
||||
const body = $(document.body)
|
||||
body.scrollTop(body.scrollTop() + 20)
|
||||
} else if (e.clientY <= 150) {
|
||||
const body = $(document.body)
|
||||
body.scrollTop(body.scrollTop() - 20)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置位置盒子
|
||||
*
|
||||
*/
|
||||
function resetPositionBox() {
|
||||
// 根据当前容器的宽度来决定多少列
|
||||
itemMaxX = this.maxCell
|
||||
const rows = 1 // 初始100行,后面根据需求会自动增加
|
||||
for (let i = 0; i < rows; i++) {
|
||||
const row = []
|
||||
|
||||
for (let j = 0; j < this.maxCell; j++) {
|
||||
row.push({
|
||||
el: false
|
||||
})
|
||||
}
|
||||
|
||||
positionBox.push(row)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充位置盒子
|
||||
*
|
||||
* @param {any} item
|
||||
*/
|
||||
function addItemToPositionBox(item) {
|
||||
const pb = positionBox
|
||||
if (item.x <= 0 || item.y <= 0) return
|
||||
|
||||
for (let i = item.x - 1; i < item.x - 1 + item.sizex; i++) {
|
||||
for (let j = item.y - 1; j < item.y - 1 + item.sizey; j++) {
|
||||
if (pb[j][i]) {
|
||||
pb[j][i].el = item
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fillPositionBox(maxY) {
|
||||
const pb = positionBox
|
||||
maxY += 2
|
||||
for (let j = 0; j < maxY; j++) {
|
||||
if (pb[j] === undefined) {
|
||||
const row = []
|
||||
for (let i = 0; i < itemMaxX; i++) {
|
||||
row.push({
|
||||
el: false
|
||||
})
|
||||
}
|
||||
pb.push(row)
|
||||
}
|
||||
}
|
||||
|
||||
itemMaxY = maxY
|
||||
|
||||
$(this.$el).css('height', ((itemMaxY + 2) * this.cellHeight) + 'px')
|
||||
}
|
||||
|
||||
function removeItemFromPositionBox(item) {
|
||||
const pb = positionBox
|
||||
if (item.x <= 0 || item.y <= 0) return
|
||||
for (let i = item.x - 1; i < item.x - 1 + item.sizex; i++) {
|
||||
for (let j = item.y - 1; j < item.y - 1 + item.sizey; j++) {
|
||||
if (pb[j][i]) {
|
||||
pb[j][i].el = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新计算宽度,使最小单元格能占满整个容器
|
||||
*
|
||||
*/
|
||||
function recalcCellWidth() {
|
||||
const containerNode = this.$refs['container']
|
||||
const containerWidth = containerNode.offsetWidth
|
||||
|
||||
const cells = Math.round(containerWidth / this.cellWidth)
|
||||
this.maxCell = cells
|
||||
|
||||
// if (containerWidth % this.cellWidth !=== 0) {
|
||||
// this.cellWidth += containerWidth % this.cellWidth / cells;
|
||||
// }
|
||||
}
|
||||
|
||||
function init() {
|
||||
this.cellWidth = this.baseWidth + this.baseMarginLeft
|
||||
this.cellHeight = this.baseHeight + this.baseMarginTop
|
||||
|
||||
positionBox = []
|
||||
coordinates = [] // 坐标点集合
|
||||
|
||||
lastTask = undefined
|
||||
isOverlay = false // 是否正在交换位置
|
||||
moveTime = 80 // 移动动画时间
|
||||
|
||||
itemMaxY = 0
|
||||
itemMaxX = 0
|
||||
|
||||
const vm = this
|
||||
|
||||
recalcCellWidth.call(this)
|
||||
|
||||
resetPositionBox.call(this)
|
||||
|
||||
let i = 0
|
||||
const timeid = setInterval(function() {
|
||||
if (i >= vm.yourList.length) {
|
||||
clearInterval(timeid)
|
||||
vm.$nextTick(function() {
|
||||
vm.moveAnimate = true
|
||||
})
|
||||
} else {
|
||||
const item = vm.yourList[i]
|
||||
addItem.call(vm, item, i)
|
||||
i++
|
||||
}
|
||||
}, 1)
|
||||
vm.renderOk = true
|
||||
}
|
||||
|
||||
function resizePlayer(item, newSize) {
|
||||
const vm = this
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
const canGoUpRows = canItemGoUp(upItem)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
}
|
||||
})
|
||||
|
||||
item.sizex = newSize.sizex
|
||||
item.sizey = newSize.sizey
|
||||
|
||||
if (item.sizex + item.x - 1 > itemMaxX) {
|
||||
item.sizex = itemMaxX - item.x + 1
|
||||
}
|
||||
|
||||
if (item.sizey + item.y > itemMaxY) {
|
||||
fillPositionBox.call(this, item.y + item.sizey)
|
||||
}
|
||||
|
||||
emptyTargetCell.call(this, item)
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
|
||||
const canGoUpRows = canItemGoUp(item)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(this, item, canGoUpRows)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查移动的位置,如果不合法,会自动修改
|
||||
*
|
||||
* @param {any} item
|
||||
* @param {any} position
|
||||
*/
|
||||
function checkItemPosition(item, position) {
|
||||
position = position || {}
|
||||
position.x = position.x || item.x
|
||||
position.y = position.y || item.y
|
||||
|
||||
// 检查位置
|
||||
if (item.x < 1) {
|
||||
item.x = 1
|
||||
}
|
||||
|
||||
// 检查大小
|
||||
if (item.sizex > itemMaxX) {
|
||||
item.sizex = itemMaxX
|
||||
}
|
||||
|
||||
if (item.sizex < 1) {
|
||||
item.sizex = 1
|
||||
}
|
||||
|
||||
if (item.x + item.sizex - 1 > itemMaxX) {
|
||||
item.x = itemMaxX - item.sizex + 1
|
||||
if (item.x < 1) {
|
||||
item.x = 1
|
||||
}
|
||||
}
|
||||
|
||||
if (item.y < 1) {
|
||||
item.y = 1
|
||||
}
|
||||
|
||||
if (item.sizey < 1) {
|
||||
item.sizey = 1
|
||||
}
|
||||
|
||||
if (item.y + item.sizey > itemMaxY - 1) {
|
||||
fillPositionBox.call(this, item.y + item.sizey - 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动正在拖动的元素
|
||||
*
|
||||
* @param {any} item
|
||||
* @param {any} position
|
||||
*/
|
||||
function movePlayer(item, position) {
|
||||
const vm = this
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
const canGoUpRows = canItemGoUp(upItem)
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
}
|
||||
})
|
||||
|
||||
item.x = position.x
|
||||
item.y = position.y
|
||||
|
||||
checkItemPosition.call(this, item, position)
|
||||
|
||||
emptyTargetCell.call(this, item)
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
|
||||
const canGoUpRows = canItemGoUp(item)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(this, item, canGoUpRows)
|
||||
}
|
||||
}
|
||||
|
||||
function removeItem(index) {
|
||||
const vm = this
|
||||
const item = this.yourList[index]
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
|
||||
// $(this.$refs['item' + item._dragId][0]).remove();
|
||||
|
||||
_.forEach(belowItems, function(upItem) {
|
||||
const canGoUpRows = canItemGoUp(upItem)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(vm, upItem, canGoUpRows)
|
||||
}
|
||||
})
|
||||
|
||||
this.yourList.splice(index, 1, {})
|
||||
}
|
||||
|
||||
function addItem(item, index) {
|
||||
if (index < 0) {
|
||||
index = this.yourList.length
|
||||
}
|
||||
item._dragId = index
|
||||
|
||||
checkItemPosition.call(this, item, {
|
||||
x: item.x,
|
||||
y: item.y
|
||||
})
|
||||
|
||||
emptyTargetCell.call(this, item)
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
const canGoUpRows = canItemGoUp(item)
|
||||
|
||||
if (canGoUpRows > 0) {
|
||||
moveItemUp.call(this, item, canGoUpRows)
|
||||
}
|
||||
|
||||
// 生成坐标点
|
||||
// makeCoordinate.call(this, item);
|
||||
}
|
||||
|
||||
function changeToCoord(left, top, width, height) {
|
||||
return {
|
||||
x1: left,
|
||||
x2: left + width,
|
||||
y1: top,
|
||||
y2: top + height,
|
||||
c1: left + width / 2,
|
||||
c2: top + height / 2
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测有无碰撞,并作出处理
|
||||
*
|
||||
* @param {any} tCoord 比对对象的坐标
|
||||
*/
|
||||
function findClosetCoords(item, tCoord) {
|
||||
if (isOverlay) return
|
||||
let i = coordinates.length
|
||||
let collisionsItem = []
|
||||
while (i--) {
|
||||
const nowCoord = coordinates[i]
|
||||
if (item._dragId === nowCoord.el._dragId) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (tCoord.x2 < nowCoord.x1 || tCoord.x1 > nowCoord.x2 || tCoord.y2 < nowCoord.y1 || tCoord.y1 > nowCoord.y2) {
|
||||
continue
|
||||
} else {
|
||||
collisionsItem.push({
|
||||
centerDistance: Math.sqrt(Math.pow(tCoord.c1 - nowCoord.c1, 2) + Math.pow(tCoord.c2 - nowCoord.c2, 2)),
|
||||
coord: nowCoord
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (collisionsItem.length <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
isOverlay = true
|
||||
|
||||
collisionsItem = _.sortBy(collisionsItem, 'area')
|
||||
|
||||
movePlayer.call(this, item, {
|
||||
x: collisionsItem[0].coord.el.x,
|
||||
y: collisionsItem[0].coord.el.y
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
isOverlay = false
|
||||
}, 200)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成坐标点
|
||||
*
|
||||
* @param {any} item
|
||||
*/
|
||||
function makeCoordinate(item) {
|
||||
const width = this.cellWidth * (item.sizex) - this.baseMarginLeft
|
||||
const height = this.cellHeight * (item.sizey) - this.baseMarginTop
|
||||
const left = this.cellWidth * (item.x - 1) + this.baseMarginLeft
|
||||
const top = this.cellHeight * (item.y - 1) + this.baseMarginTop
|
||||
|
||||
const coord = {
|
||||
x1: left,
|
||||
x2: left + width,
|
||||
y1: top,
|
||||
y2: top + height,
|
||||
c1: left + width / 2,
|
||||
c2: top + height / 2,
|
||||
el: item
|
||||
}
|
||||
|
||||
coordinates.push(coord)
|
||||
}
|
||||
|
||||
function changeItemCoord(item) {
|
||||
const width = this.cellWidth * (item.sizex) - this.baseMarginLeft
|
||||
const height = this.cellHeight * (item.sizey) - this.baseMarginTop
|
||||
const left = this.cellWidth * (item.x - 1) + this.baseMarginLeft
|
||||
const top = this.cellHeight * (item.y - 1) + this.baseMarginTop
|
||||
|
||||
const coord = {
|
||||
x1: left,
|
||||
x2: left + width,
|
||||
y1: top,
|
||||
y2: top + height,
|
||||
c1: left + width / 2,
|
||||
c2: top + height / 2,
|
||||
el: item
|
||||
}
|
||||
|
||||
const index = _.findIndex(coordinates, function(o) {
|
||||
return o.el._dragId === item._dragId
|
||||
})
|
||||
if (index !== -1) {
|
||||
coordinates.splice(index, 1, coord)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空目标位置的元素
|
||||
*
|
||||
* @param {any} item
|
||||
*/
|
||||
function emptyTargetCell(item) {
|
||||
const vm = this
|
||||
const belowItems = findBelowItems(item)
|
||||
|
||||
_.forEach(belowItems, function(downItem, index) {
|
||||
if (downItem._dragId === item._dragId) return
|
||||
const moveSize = item.y + item.sizey - downItem.y
|
||||
if (moveSize > 0) {
|
||||
moveItemDown.call(vm, downItem, moveSize)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前位置的item能否上浮
|
||||
*
|
||||
* @param {any} item
|
||||
* @returns
|
||||
*/
|
||||
function canItemGoUp(item) {
|
||||
let upperRows = 0
|
||||
for (let row = item.y - 2; row >= 0; row--) {
|
||||
for (let cell = item.x - 1; cell < item.x - 1 + item.sizex; cell++) {
|
||||
if (positionBox[row][cell] && positionBox[row][cell].el) {
|
||||
return upperRows
|
||||
}
|
||||
}
|
||||
upperRows++
|
||||
}
|
||||
|
||||
return upperRows
|
||||
}
|
||||
|
||||
/**
|
||||
* 在移动之前,找到当前下移的元素的下面的元素(递归)
|
||||
*
|
||||
* @param {any} items
|
||||
* @param {any} size
|
||||
*/
|
||||
function moveItemDown(item, size) {
|
||||
const vm = this
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems(item)
|
||||
|
||||
_.forEach(belowItems, function(downItem, index) {
|
||||
if (downItem._dragId === item._dragId) return
|
||||
const moveSize = calcDiff(item, downItem, size)
|
||||
if (moveSize > 0) {
|
||||
moveItemDown.call(vm, downItem, moveSize)
|
||||
}
|
||||
})
|
||||
|
||||
const targetPosition = {
|
||||
y: item.y + size
|
||||
}
|
||||
setPlayerPosition.call(this, item, targetPosition)
|
||||
checkItemPosition.call(this, item, targetPosition)
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
}
|
||||
|
||||
function setPlayerPosition(item, position) {
|
||||
const vm = this
|
||||
position = position || {}
|
||||
|
||||
const targetX = position.x || item.x
|
||||
const targetY = position.y || item.y
|
||||
|
||||
item.x = targetX
|
||||
item.y = targetY
|
||||
|
||||
if (item.y + item.sizey > itemMaxY) {
|
||||
itemMaxY = item.y + item.sizey
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 寻找子元素到父元素的最大距离
|
||||
*
|
||||
* @param {any} parent
|
||||
* @param {any} son
|
||||
* @param {any} size
|
||||
*/
|
||||
function calcDiff(parent, son, size) {
|
||||
const diffs = []
|
||||
|
||||
for (let i = son.x - 1; i < son.x - 1 + son.sizex; i++) {
|
||||
let temp_y = 0
|
||||
|
||||
for (let j = parent.y - 1 + parent.sizey; j < son.y - 1; j++) {
|
||||
if (positionBox[j][i] && positionBox[j][i].el === false) {
|
||||
temp_y++
|
||||
}
|
||||
}
|
||||
diffs.push(temp_y)
|
||||
}
|
||||
|
||||
const max_diff = Math.max.apply(Math, diffs)
|
||||
size = size - max_diff
|
||||
|
||||
return size > 0 ? size : 0
|
||||
}
|
||||
|
||||
function moveItemUp(item, size) {
|
||||
// console.log('moveItemUp')
|
||||
const vm = this
|
||||
|
||||
removeItemFromPositionBox(item)
|
||||
|
||||
const belowItems = findBelowItems.call(this, item)
|
||||
|
||||
// item.y -= size;
|
||||
setPlayerPosition.call(this, item, {
|
||||
y: item.y - size
|
||||
})
|
||||
|
||||
addItemToPositionBox.call(this, item)
|
||||
|
||||
changeItemCoord.call(this, item)
|
||||
|
||||
_.forEach(belowItems, function(upItem, index) {
|
||||
const moveSize = canItemGoUp(upItem)
|
||||
if (moveSize > 0) {
|
||||
moveItemUp.call(vm, upItem, moveSize)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function findBelowItems(item) {
|
||||
const belowItems = {}
|
||||
for (let cell = item.x - 1; cell < item.x - 1 + item.sizex; cell++) {
|
||||
for (let row = item.y - 1; row < positionBox.length; row++) {
|
||||
const target = positionBox[row][cell]
|
||||
if (target && target.el) {
|
||||
belowItems[target.el._dragId] = target.el
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _.sortBy(_.values(belowItems), 'y')
|
||||
}
|
||||
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'VuePowerDrag',
|
||||
props: {
|
||||
yourList: {
|
||||
required: true,
|
||||
type: Array // String,Number,Boolean,Function,Object,Array
|
||||
},
|
||||
baseWidth: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
baseHeight: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: 50
|
||||
},
|
||||
baseMarginLeft: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
baseMarginTop: {
|
||||
required: false,
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
draggable: {
|
||||
required: false,
|
||||
default: true,
|
||||
type: Boolean
|
||||
},
|
||||
dragStart: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
dragging: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
dragEnd: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
resizable: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
resizeStart: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
resizing: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
},
|
||||
resizeEnd: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: function() {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
renderOk: false,
|
||||
moveAnimate: false,
|
||||
list: [],
|
||||
cellWidth: 0,
|
||||
cellHeight: 0,
|
||||
maxCell: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
positionBox() {
|
||||
return positionBox
|
||||
},
|
||||
coordinates() {
|
||||
return coordinates
|
||||
},
|
||||
...mapState([
|
||||
'componentData',
|
||||
'curComponent',
|
||||
'canvasStyleData',
|
||||
'editor',
|
||||
'linkageSettingStatus',
|
||||
'curLinkageView'
|
||||
])
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
updated() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
// init.call(this);
|
||||
},
|
||||
methods: {
|
||||
removeItem: removeItem,
|
||||
startResize(e, item, index) {
|
||||
console.log('startResize:' + index)
|
||||
if (!this.resizable) return
|
||||
this.resizeStart.call(null, e, item, index)
|
||||
|
||||
// e.preventDefault();
|
||||
const target = $(e.target)
|
||||
|
||||
if (!this.infoBox) {
|
||||
this.infoBox = {}
|
||||
}
|
||||
|
||||
const itemNode = target.parents('.item')
|
||||
|
||||
this.infoBox.resizeItem = item
|
||||
this.infoBox.resizeItemIndex = index
|
||||
},
|
||||
containerMouseDown(e) {
|
||||
// console.log('containerMouseDown:')
|
||||
|
||||
// e.preventDefault();
|
||||
if (!this.infoBox) {
|
||||
this.infoBox = {}
|
||||
}
|
||||
|
||||
this.infoBox.startX = e.pageX
|
||||
this.infoBox.startY = e.pageY
|
||||
},
|
||||
startMove(e, item, index) {
|
||||
console.log('startMove:' + index)
|
||||
const vm = this
|
||||
// e.preventDefault();
|
||||
|
||||
if (!this.infoBox) {
|
||||
this.infoBox = {}
|
||||
}
|
||||
const infoBox = this.infoBox
|
||||
const target = $(e.target)
|
||||
|
||||
let className = target.attr('class')
|
||||
className = className || ''
|
||||
if (className.indexOf('dragHandle') === -1 && className.indexOf('item') === -1 && className.indexOf('resizeHandle') === -1) {
|
||||
return
|
||||
}
|
||||
|
||||
if (className.includes('resizeHandle')) {
|
||||
|
||||
} else if (this.draggable && (className.includes('dragHandle') || className.includes('item'))) {
|
||||
this.dragStart.call(null, e, item, index)
|
||||
infoBox.moveItem = item
|
||||
infoBox.moveItemIndex = index
|
||||
}
|
||||
|
||||
infoBox.cloneItem = null
|
||||
infoBox.nowItemNode = null
|
||||
|
||||
if (target.attr('class') && target.attr('class').indexOf('item') !== -1) {
|
||||
infoBox.nowItemNode = target
|
||||
infoBox.cloneItem = target.clone()
|
||||
} else {
|
||||
infoBox.nowItemNode = target.parents('.item')
|
||||
infoBox.cloneItem = infoBox.nowItemNode.clone()
|
||||
}
|
||||
infoBox.cloneItem.addClass('cloneNode')
|
||||
|
||||
$(this.$el).append(infoBox.cloneItem)
|
||||
|
||||
infoBox.orignX = infoBox.cloneItem.position().left // 克隆对象原始X位置
|
||||
infoBox.orignY = infoBox.cloneItem.position().top
|
||||
infoBox.oldX = item.x // 实际对象原始X位置
|
||||
infoBox.oldY = item.y
|
||||
infoBox.oldSizeX = item.sizex
|
||||
infoBox.oldSizeY = item.sizey
|
||||
infoBox.orignWidth = infoBox.cloneItem.prop('offsetWidth')
|
||||
infoBox.orignHeight = infoBox.cloneItem.prop('offsetHeight')
|
||||
|
||||
function itemMouseMove(e) {
|
||||
// console.log('itemMouseMove')
|
||||
const moveItem = _.get(infoBox, 'moveItem')
|
||||
const resizeItem = _.get(infoBox, 'resizeItem')
|
||||
|
||||
if (resizeItem) { // 调整大小时
|
||||
console.log('resizeItem')
|
||||
vm.resizing.call(null, e, resizeItem, resizeItem._dragId)
|
||||
|
||||
vm.$set(resizeItem, 'isPlayer', true)
|
||||
const nowItemIndex = infoBox.resizeItemIndex
|
||||
const cloneItem = infoBox.cloneItem
|
||||
const startX = infoBox.startX
|
||||
const startY = infoBox.startY
|
||||
const oldSizeX = infoBox.oldSizeX
|
||||
const oldSizeY = infoBox.oldSizeY
|
||||
const orignWidth = infoBox.orignWidth
|
||||
const orignHeight = infoBox.orignHeight
|
||||
|
||||
const moveXSize = e.pageX - startX // X方向移动的距离
|
||||
const moveYSize = e.pageY - startY // Y方向移动的距离
|
||||
|
||||
const addSizex = (moveXSize) % vm.cellWidth > (vm.cellWidth / 4 * 1) ? parseInt(((moveXSize) / vm.cellWidth + 1)) : parseInt(((moveXSize) / vm.cellWidth))
|
||||
const addSizey = (moveYSize) % vm.cellHeight > (vm.cellHeight / 4 * 1) ? parseInt(((moveYSize) / vm.cellHeight + 1)) : parseInt(((moveYSize) / vm.cellHeight))
|
||||
|
||||
const nowX = oldSizeX + addSizex > 0 ? oldSizeX + addSizex : 1
|
||||
const nowY = oldSizeY + addSizey > 0 ? oldSizeY + addSizey : 1
|
||||
|
||||
debounce((function(addSizex, addSizey) {
|
||||
return function() {
|
||||
resizePlayer.call(vm, resizeItem, {
|
||||
sizex: nowX,
|
||||
sizey: nowY
|
||||
})
|
||||
}
|
||||
})(addSizex, addSizey), 10)
|
||||
|
||||
let nowWidth = orignWidth + moveXSize
|
||||
nowWidth = nowWidth <= vm.baseWidth ? vm.baseWidth : nowWidth
|
||||
let nowHeight = orignHeight + moveYSize
|
||||
nowHeight = nowHeight <= vm.baseHeight ? vm.baseHeight : nowHeight
|
||||
// 克隆元素实时改变大小
|
||||
cloneItem.css({
|
||||
width: nowWidth,
|
||||
height: nowHeight
|
||||
})
|
||||
} else if (moveItem) {
|
||||
console.log('moveItem')
|
||||
|
||||
scrollScreen(e)
|
||||
if (!vm.draggable) return
|
||||
vm.dragging.call(null, e, moveItem, moveItem._dragId)
|
||||
|
||||
vm.$set(moveItem, 'isPlayer', true)
|
||||
// this.$set(moveItem, "show", false);
|
||||
const nowItemIndex = infoBox.moveItemIndex
|
||||
const cloneItem = infoBox.cloneItem
|
||||
const startX = infoBox.startX
|
||||
const startY = infoBox.startY
|
||||
const orignX = infoBox.orignX
|
||||
const orignY = infoBox.orignY
|
||||
const oldX = infoBox.oldX
|
||||
const oldY = infoBox.oldY
|
||||
|
||||
const moveXSize = e.pageX - startX // X方向移动的距离
|
||||
const moveYSize = e.pageY - startY // Y方向移动的距离
|
||||
|
||||
const nowCloneItemX = orignX + moveXSize
|
||||
const nowCloneItemY = orignY + moveYSize
|
||||
|
||||
let newX = parseInt((nowCloneItemX + (cloneItem.width() / 12) - vm.baseMarginLeft) / vm.cellWidth + 1)
|
||||
let newY = parseInt((nowCloneItemY + (cloneItem.height() / 12) - vm.baseMarginTop) / vm.cellHeight + 1)
|
||||
newX = newX > 0 ? newX : 1
|
||||
newY = newY > 0 ? newY : 1
|
||||
|
||||
debounce((function(newX, oldX, newY, oldY) {
|
||||
return function() {
|
||||
if (newX !== oldX || oldY !== newY) {
|
||||
// console.log("move");
|
||||
movePlayer.call(vm, moveItem, {
|
||||
x: newX,
|
||||
y: newY
|
||||
})
|
||||
|
||||
infoBox.oldX = newX
|
||||
infoBox.oldY = newY
|
||||
}
|
||||
}
|
||||
})(newX, oldX, newY, oldY), 10)
|
||||
|
||||
cloneItem.css({
|
||||
left: nowCloneItemX + 'px',
|
||||
top: nowCloneItemY + 'px'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(window).mousemove(itemMouseMove)
|
||||
|
||||
$(window).mouseup(function itemMouseUp(e) {
|
||||
if (_.isEmpty(vm.infoBox)) return
|
||||
if (vm.infoBox.cloneItem) {
|
||||
vm.infoBox.cloneItem.remove()
|
||||
}
|
||||
if (vm.infoBox.resizeItem) {
|
||||
vm.$delete(vm.infoBox.resizeItem, 'isPlayer')
|
||||
vm.resizeEnd.call(null, e, vm.infoBox.resizeItem, vm.infoBox.resizeItem._dragId)
|
||||
}
|
||||
if (vm.infoBox.moveItem) {
|
||||
vm.dragEnd.call(null, e, vm.infoBox.moveItem, vm.infoBox.moveItem._dragId)
|
||||
vm.$set(vm.infoBox.moveItem, 'show', true)
|
||||
vm.$delete(vm.infoBox.moveItem, 'isPlayer')
|
||||
}
|
||||
vm.infoBox = {}
|
||||
|
||||
$(this).off('mousemove', itemMouseMove)
|
||||
$(this).off('mouseup', itemMouseUp)
|
||||
})
|
||||
},
|
||||
endMove(e) {
|
||||
|
||||
},
|
||||
moving(e) {
|
||||
|
||||
},
|
||||
/**
|
||||
* 计算当前item的位置和大小
|
||||
*
|
||||
* @param {any} item
|
||||
* @returns
|
||||
*/
|
||||
nowItemStyle(item, index) {
|
||||
const style = {
|
||||
width: (this.cellWidth * (item.sizex) - this.baseMarginLeft) + 'px',
|
||||
height: (this.cellHeight * (item.sizey) - this.baseMarginTop) + 'px',
|
||||
left: (this.cellWidth * (item.x - 1) + this.baseMarginLeft) + 'px',
|
||||
top: (this.cellHeight * (item.y - 1) + this.baseMarginTop) + 'px'
|
||||
}
|
||||
console.log('nowItemStyle:' + JSON.stringify(style))
|
||||
return style
|
||||
},
|
||||
getList() {
|
||||
console.log('getList:')
|
||||
|
||||
const returnList = _.sortBy(_.cloneDeep(this.yourList), 'y')
|
||||
const finalList = []
|
||||
_.forEach(returnList, function(item, index) {
|
||||
if (_.isEmpty(item)) return
|
||||
delete item['_dragId']
|
||||
delete item['show']
|
||||
finalList.push(item)
|
||||
})
|
||||
return finalList
|
||||
},
|
||||
/**
|
||||
* 获取x最大值
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
getMaxCell() {
|
||||
console.log('getMaxCell:')
|
||||
|
||||
return this.maxCell
|
||||
},
|
||||
/**
|
||||
* 获取渲染状态
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
getRenderState() {
|
||||
console.log('getRenderState:')
|
||||
|
||||
return this.moveAnimate
|
||||
},
|
||||
addItem: addItem,
|
||||
init: init,
|
||||
afterInitOk(func) {
|
||||
const timeid = setInterval(() => {
|
||||
if (this.moveAnimate) {
|
||||
clearInterval(timeid)
|
||||
func()
|
||||
}
|
||||
}, 100)
|
||||
},
|
||||
addItemBox(item) {
|
||||
this.yourList.push(item)
|
||||
|
||||
this.$nextTick(function() {
|
||||
addItem.call(this, item, this.yourList.length - 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "./drag.less";
|
||||
|
||||
</style>
|
@ -434,6 +434,7 @@ export default {
|
||||
}
|
||||
},
|
||||
style() {
|
||||
// console.log('style-top:' + this.y + '--' + this.top)
|
||||
return {
|
||||
transform: `translate(${this.left}px, ${this.top}px) rotate(${this.rotate}deg)`,
|
||||
width: this.computedWidth,
|
||||
@ -482,7 +483,7 @@ export default {
|
||||
return 'auto'
|
||||
}
|
||||
}
|
||||
if (this.canvasStyleData.auxiliaryMatrix) {
|
||||
if (this.element.auxiliaryMatrix) {
|
||||
const width = Math.round(this.width / this.curCanvasScale.matrixStyleWidth) * this.curCanvasScale.matrixStyleWidth
|
||||
return width + 'px'
|
||||
} else {
|
||||
@ -496,7 +497,7 @@ export default {
|
||||
return 'auto'
|
||||
}
|
||||
}
|
||||
if (this.canvasStyleData.auxiliaryMatrix) {
|
||||
if (this.element.auxiliaryMatrix) {
|
||||
const height = Math.round(this.height / this.curCanvasScale.matrixStyleHeight) * this.curCanvasScale.matrixStyleHeight
|
||||
return height + 'px'
|
||||
} else {
|
||||
@ -594,13 +595,15 @@ export default {
|
||||
this.maxH = val
|
||||
},
|
||||
w(val) {
|
||||
console.log('changeWidthCK:' + this.resizing)
|
||||
|
||||
if (this.resizing || this.dragging) {
|
||||
return
|
||||
}
|
||||
if (this.parent) {
|
||||
this.bounds = this.calcResizeLimits()
|
||||
}
|
||||
// console.log('changeWidth:' + val)
|
||||
console.log('changeWidth:' + val)
|
||||
this.changeWidth(val)
|
||||
},
|
||||
h(val) {
|
||||
@ -696,6 +699,8 @@ export default {
|
||||
}
|
||||
// 阻止冒泡事件
|
||||
e.stopPropagation()
|
||||
// 此处阻止冒泡 但是外层需要获取pageX pageY
|
||||
this.element.auxiliaryMatrix && this.$emit('elementMouseDown', e)
|
||||
this.$store.commit('setCurComponent', { component: this.element, index: this.index })
|
||||
eventsFor = events.mouse
|
||||
this.elementDown(e)
|
||||
@ -707,6 +712,8 @@ export default {
|
||||
}
|
||||
const target = e.target || e.srcElement
|
||||
if (this.$el.contains(target)) {
|
||||
// 挤压式画布设计 drag start 通知
|
||||
this.element.auxiliaryMatrix && this.$emit('onDragStart', e, this.element, this.index)
|
||||
if (this.onDragStart(e) === false) {
|
||||
return
|
||||
}
|
||||
@ -800,6 +807,7 @@ export default {
|
||||
if (e instanceof MouseEvent && e.which !== 1) {
|
||||
return false
|
||||
}
|
||||
this.element.auxiliaryMatrix && this.$emit('onResizeStart', e, this.element, this.index)
|
||||
if (this.onResizeStart(handle, e) === false) {
|
||||
return false
|
||||
}
|
||||
@ -982,6 +990,10 @@ export default {
|
||||
this.bottom = bottom
|
||||
await this.snapCheck()
|
||||
this.$emit('dragging', this.left, this.top)
|
||||
// 如果当前视图遵循矩阵设计则 进行位置挤压检查
|
||||
if (this.element.auxiliaryMatrix) {
|
||||
this.$emit('onDragging', e, this.element)
|
||||
}
|
||||
|
||||
// private 记录当前样式
|
||||
this.recordCurStyle()
|
||||
@ -1156,7 +1168,8 @@ export default {
|
||||
// console.log('width2:' + this.width)
|
||||
this.height = newH
|
||||
|
||||
this.$emit('resizing', this.left, this.top, this.width, this.height)
|
||||
// this.$emit('resizing', this.left, this.top, this.width, this.height)
|
||||
this.element.auxiliaryMatrix && this.$emit('onResizing', e, this.element)
|
||||
|
||||
// private 记录当前组件样式
|
||||
this.recordCurStyle()
|
||||
@ -1179,7 +1192,7 @@ export default {
|
||||
this.right = right
|
||||
this.bottom = bottom
|
||||
this.width = width
|
||||
// console.log('width3:' + this.width)
|
||||
console.log('width3:' + this.width)
|
||||
this.height = height
|
||||
},
|
||||
changeHeight(val) {
|
||||
@ -1201,7 +1214,7 @@ export default {
|
||||
this.height = height
|
||||
},
|
||||
// 从控制柄松开
|
||||
async handleUp(e) {
|
||||
handleUp(e) {
|
||||
this.handle = null
|
||||
// 初始化辅助线数据
|
||||
const temArr = new Array(3).fill({ display: false, position: '', origin: '', lineLength: '' })
|
||||
@ -1215,7 +1228,8 @@ export default {
|
||||
this.lastMouseY = mouseY
|
||||
if (this.resizing) {
|
||||
this.resizing = false
|
||||
await this.conflictCheck()
|
||||
console.log('resizing2:' + this.resizing)
|
||||
this.conflictCheck()
|
||||
this.$emit('refLineParams', refLine)
|
||||
// this.$emit('resizestop', this.left, this.top, this.width, this.height)
|
||||
// private
|
||||
@ -1223,7 +1237,7 @@ export default {
|
||||
}
|
||||
if (this.dragging) {
|
||||
this.dragging = false
|
||||
await this.conflictCheck()
|
||||
this.conflictCheck()
|
||||
this.$emit('refLineParams', refLine)
|
||||
this.$emit('dragstop', this.left, this.top)
|
||||
}
|
||||
@ -1235,8 +1249,9 @@ export default {
|
||||
// private 记录snapshot
|
||||
|
||||
// 如果辅助设计 需要最后调整矩阵
|
||||
if (this.canvasStyleData.auxiliaryMatrix) {
|
||||
this.recordMatrixCurStyle()
|
||||
if (this.element.auxiliaryMatrix) {
|
||||
// this.recordMatrixCurStyle()
|
||||
this.recordMatrixCurShadowStyle()
|
||||
}
|
||||
this.hasMove && this.$store.commit('recordSnapshot', 'handleUp')
|
||||
// 记录snapshot后 移动已记录设置为false
|
||||
@ -1246,6 +1261,9 @@ export default {
|
||||
|
||||
// private 删除handle Up事件 防止重复recordSnapshot
|
||||
removeEvent(document.documentElement, eventsFor.stop, this.handleUp)
|
||||
|
||||
// 挤占式画布设计 handleUp
|
||||
this.element.auxiliaryMatrix && this.$emit('onHandleUp', e)
|
||||
},
|
||||
// 新增方法 ↓↓↓
|
||||
// 设置属性
|
||||
@ -1549,11 +1567,38 @@ export default {
|
||||
// this.hasMove = true
|
||||
this.$store.commit('setShapeStyle', style)
|
||||
|
||||
// resize
|
||||
self.$emit('resizeView')
|
||||
// const self = this
|
||||
// setTimeout(function() {
|
||||
// self.$emit('resizeView')
|
||||
// }, 200)
|
||||
},
|
||||
// 记录当前样式 跟随阴影位置 矩阵处理
|
||||
recordMatrixCurShadowStyle() {
|
||||
console.log('recordMatrixCurShadowStyle')
|
||||
// debugger
|
||||
const left = (this.element.x - 1) * this.curCanvasScale.matrixStyleWidth
|
||||
const top = (this.element.y - 1) * this.curCanvasScale.matrixStyleHeight
|
||||
const width = this.element.sizex * this.curCanvasScale.matrixStyleWidth
|
||||
const height = this.element.sizey * this.curCanvasScale.matrixStyleHeight
|
||||
const style = {
|
||||
...this.defaultStyle
|
||||
}
|
||||
style.left = left
|
||||
style.top = top
|
||||
style.width = width
|
||||
style.height = height
|
||||
style.rotate = this.rotate
|
||||
// this.hasMove = true
|
||||
this.$store.commit('setShapeStyle', style)
|
||||
|
||||
// resize
|
||||
const self = this
|
||||
setTimeout(function() {
|
||||
self.$emit('resizeView')
|
||||
}, 200)
|
||||
self.$emit('resizeView')
|
||||
// setTimeout(function() {
|
||||
// self.$emit('resizeView')
|
||||
// }, 200)
|
||||
},
|
||||
mountedFunction() {
|
||||
// private 冲突检测 和水平设计值保持一致
|
||||
|
@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<div style="z-index:-1" :style="styleInfo" />
|
||||
<div style="z-index:-1" :style="styleInfo">
|
||||
<!-- {{ curComponent }}-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -16,27 +18,42 @@ export default {
|
||||
let top = 0
|
||||
let width = 0
|
||||
let height = 0
|
||||
// if (this.dragComponentInfo && !this.dragComponentInfo.auxiliaryMatrix) {
|
||||
if (this.dragComponentInfo) {
|
||||
console.log('shadowDrag=')
|
||||
// 组件移入
|
||||
left = this.dragComponentInfo.shadowStyle.x
|
||||
top = this.dragComponentInfo.shadowStyle.y
|
||||
width = this.dragComponentInfo.style.width
|
||||
height = this.dragComponentInfo.style.height
|
||||
if (this.dragComponentInfo.auxiliaryMatrix) {
|
||||
left = (this.dragComponentInfo.x - 1) * this.curCanvasScale.matrixStyleWidth
|
||||
top = (this.dragComponentInfo.y - 1) * this.curCanvasScale.matrixStyleHeight
|
||||
|
||||
width = this.dragComponentInfo.sizex * this.curCanvasScale.matrixStyleWidth
|
||||
height = this.dragComponentInfo.sizey * this.curCanvasScale.matrixStyleHeight
|
||||
} else {
|
||||
left = this.dragComponentInfo.shadowStyle.x
|
||||
top = this.dragComponentInfo.shadowStyle.y
|
||||
width = this.dragComponentInfo.style.width
|
||||
height = this.dragComponentInfo.style.height
|
||||
}
|
||||
|
||||
// console.log('left:' + left + 'top:' + top + 'width:' + width + 'height:' + height)
|
||||
} else {
|
||||
left = this.curComponent.style.left * this.curCanvasScale.scaleWidth / 100
|
||||
top = this.curComponent.style.top * this.curCanvasScale.scaleHeight / 100
|
||||
width = this.curComponent.style.width * this.curCanvasScale.scaleWidth / 100
|
||||
height = this.curComponent.style.height * this.curCanvasScale.scaleHeight / 100
|
||||
// temp 临时测试
|
||||
// left = this.curComponent.style.left * this.curCanvasScale.scaleWidth / 100
|
||||
// top = this.curComponent.style.top * this.curCanvasScale.scaleHeight / 100
|
||||
left = (this.curComponent.x - 1) * this.curCanvasScale.matrixStyleWidth
|
||||
top = (this.curComponent.y - 1) * this.curCanvasScale.matrixStyleHeight
|
||||
|
||||
width = this.curComponent.style.width * this.curCanvasScale.scalePointWidth
|
||||
height = this.curComponent.style.height * this.curCanvasScale.scalePointHeight
|
||||
// console.log('curComponent left:' + left + 'top:' + top + 'width:' + width + 'height:' + height)
|
||||
}
|
||||
// 当前默认为自适应
|
||||
if (this.canvasStyleData.auxiliaryMatrix) {
|
||||
left = Math.round(left / this.curCanvasScale.matrixStyleWidth) * this.curCanvasScale.matrixStyleWidth
|
||||
width = Math.round(width / this.curCanvasScale.matrixStyleWidth) * this.curCanvasScale.matrixStyleWidth
|
||||
top = Math.round(top / this.curCanvasScale.matrixStyleHeight) * this.curCanvasScale.matrixStyleHeight
|
||||
height = Math.round(height / this.curCanvasScale.matrixStyleHeight) * this.curCanvasScale.matrixStyleHeight
|
||||
}
|
||||
// if (this.canvasStyleData.auxiliaryMatrix) {
|
||||
// left = Math.round(left / this.curCanvasScale.matrixStyleWidth) * this.curCanvasScale.matrixStyleWidth
|
||||
// width = Math.round(width / this.curCanvasScale.matrixStyleWidth) * this.curCanvasScale.matrixStyleWidth
|
||||
// top = Math.round(top / this.curCanvasScale.matrixStyleHeight) * this.curCanvasScale.matrixStyleHeight
|
||||
// height = Math.round(height / this.curCanvasScale.matrixStyleHeight) * this.curCanvasScale.matrixStyleHeight
|
||||
// }
|
||||
|
||||
// 防止阴影区超出边界
|
||||
const xGap = left + width - this.canvasWidth
|
||||
@ -82,10 +99,10 @@ export default {
|
||||
this.dragComponentInfo.shadowStyle.y = this.scaleH(y)
|
||||
},
|
||||
scaleH(h) {
|
||||
return h * 100 / this.curCanvasScale.scaleHeight
|
||||
return h / this.curCanvasScale.scalePointHeight
|
||||
},
|
||||
scaleW(w) {
|
||||
return w * 100 / this.curCanvasScale.scaleWidth
|
||||
return w / this.curCanvasScale.scalePointWidth
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,12 @@
|
||||
<span :title="$t('panel.edit')">
|
||||
<i v-if="activeModel==='edit'&&curComponent&&editFilter.includes(curComponent.type)" class="icon iconfont icon-edit" @click.stop="edit" />
|
||||
</span>
|
||||
<span :title="$t('panel.matrix')">
|
||||
<i v-if="activeModel==='edit'&&curComponent.auxiliaryMatrix" class="icon iconfont icon-shujujuzhen" @click.stop="auxiliaryMatrixChange" />
|
||||
</span>
|
||||
<span :title="$t('panel.suspension')">
|
||||
<i v-if="activeModel==='edit'&&!curComponent.auxiliaryMatrix" class="icon iconfont icon-xuanfuanniu" @click.stop="auxiliaryMatrixChange" />
|
||||
</span>
|
||||
<span :title="$t('panel.details')">
|
||||
<i v-if="curComponent.type==='view'" class="icon iconfont icon-fangda" @click.stop="showViewDetails" />
|
||||
</span>
|
||||
@ -87,13 +93,31 @@ export default {
|
||||
'canvasStyleData',
|
||||
'linkageSettingStatus',
|
||||
'targetLinkageInfo',
|
||||
'curLinkageView'
|
||||
'curLinkageView',
|
||||
'curCanvasScale'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
showViewDetails() {
|
||||
this.$emit('showViewDetails')
|
||||
},
|
||||
auxiliaryMatrixChange() {
|
||||
if (this.curComponent.auxiliaryMatrix) {
|
||||
this.curComponent.style.left = (this.curComponent.x - 1) * this.curCanvasScale.matrixStyleOriginWidth
|
||||
this.curComponent.style.top = (this.curComponent.y - 1) * this.curCanvasScale.matrixStyleOriginHeight
|
||||
this.curComponent.style.width = this.curComponent.sizex * this.curCanvasScale.matrixStyleOriginWidth
|
||||
this.curComponent.style.height = this.curComponent.sizey * this.curCanvasScale.matrixStyleOriginHeight
|
||||
this.curComponent.auxiliaryMatrix = false
|
||||
} else {
|
||||
this.curComponent.x = Math.round(this.curComponent.style.left / this.curCanvasScale.matrixStyleOriginWidth) + 1
|
||||
this.curComponent.y = Math.round(this.curComponent.style.top / this.curCanvasScale.matrixStyleOriginHeight) + 1
|
||||
this.curComponent.sizex = Math.round(this.curComponent.style.width / this.curCanvasScale.matrixStyleOriginWidth)
|
||||
this.curComponent.sizey = Math.round(this.curComponent.style.height / this.curCanvasScale.matrixStyleOriginHeight)
|
||||
this.curComponent.auxiliaryMatrix = true
|
||||
}
|
||||
this.$store.state.styleChangeTimes++
|
||||
bus.$emit('auxiliaryMatrixChange')
|
||||
},
|
||||
edit() {
|
||||
// 编辑时临时保存 当前修改的画布
|
||||
this.$store.dispatch('panel/setComponentDataTemp', JSON.stringify(this.componentData))
|
||||
|
47
frontend/src/components/canvas/components/Editor/PGrid.vue
Normal file
47
frontend/src/components/canvas/components/Editor/PGrid.vue
Normal file
@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div class="grid">
|
||||
<!-- positionBox:{{ positionBox.length }}-->
|
||||
<div v-for="(yItem, index) in positionBox" :key="index+'y'" style="float: left; width: 105%">
|
||||
<div v-for="(xItem, index) in yItem" :key="index+'x'" :style="classInfo" style="float: left; border: 0.2px solid #b3d4fc ">
|
||||
{{ xItem.el?1:0 }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
positionBox: {
|
||||
type: Array
|
||||
},
|
||||
matrixStyle: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
classInfo: function() {
|
||||
return {
|
||||
width: this.matrixStyle.width + 'px',
|
||||
height: this.matrixStyle.height + 'px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.grid {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load Diff
@ -173,15 +173,15 @@ export default {
|
||||
'hw': {
|
||||
handler(newVal, oldVla) {
|
||||
// console.log('hw:' + newVal + '---' + oldVla)
|
||||
if (newVal !== oldVla) {
|
||||
this.destroyTimeMachine()
|
||||
this.changeIndex++
|
||||
this.chartResize(this.changeIndex)
|
||||
if (newVal !== oldVla && this.$refs[this.element.propValue.id]) {
|
||||
if (this.chart.type === 'map') {
|
||||
this.destroyTimeMachine()
|
||||
this.changeIndex++
|
||||
this.chartResize(this.changeIndex)
|
||||
} else {
|
||||
this.$refs[this.element.propValue.id].chartResize()
|
||||
}
|
||||
}
|
||||
//
|
||||
// if (this.$refs[this.element.propValue.id]) {
|
||||
// this.$refs[this.element.propValue.id].chartResize()
|
||||
// }
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
|
@ -70,7 +70,11 @@ const list = [
|
||||
verticalAlign: 'middle',
|
||||
backgroundColor: '#ffffff',
|
||||
borderRadius: 0
|
||||
}
|
||||
},
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
sizey: 2
|
||||
},
|
||||
{
|
||||
id: '10002',
|
||||
@ -105,7 +109,11 @@ const list = [
|
||||
width: 300,
|
||||
height: 200,
|
||||
borderRadius: ''
|
||||
}
|
||||
},
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
sizey: 6
|
||||
},
|
||||
{
|
||||
id: '10003-1',
|
||||
@ -128,14 +136,18 @@ const list = [
|
||||
icon: 'juxing',
|
||||
type: 'rect-shape',
|
||||
style: {
|
||||
width: 400,
|
||||
height: 300,
|
||||
width: 300,
|
||||
height: 200,
|
||||
borderStyle: 'solid',
|
||||
borderWidth: 0,
|
||||
borderColor: '#000000',
|
||||
backgroundColor: '#ffffff',
|
||||
borderRadius: 0
|
||||
}
|
||||
},
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
sizey: 6
|
||||
},
|
||||
{
|
||||
id: '10005',
|
||||
@ -145,10 +157,15 @@ const list = [
|
||||
icon: 'juxing',
|
||||
type: 'view',
|
||||
style: {
|
||||
width: 400,
|
||||
height: 300,
|
||||
width: 300,
|
||||
height: 200,
|
||||
borderRadius: ''
|
||||
}
|
||||
},
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
sizey: 6,
|
||||
auxiliaryMatrix: true
|
||||
},
|
||||
{
|
||||
id: '10006',
|
||||
@ -172,7 +189,11 @@ const list = [
|
||||
name: '1',
|
||||
content: null
|
||||
}]
|
||||
}
|
||||
},
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
sizey: 10
|
||||
},
|
||||
{
|
||||
id: '20001',
|
||||
@ -185,7 +206,11 @@ const list = [
|
||||
width: 400,
|
||||
height: 200,
|
||||
borderRadius: ''
|
||||
}
|
||||
},
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
sizey: 5
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1311,7 +1311,9 @@ export default {
|
||||
exit_un_march_linkage_field: 'Exit Un March Linkage Field',
|
||||
details: 'Details',
|
||||
setting: 'Setting',
|
||||
no_drill_field: 'Miss relation field'
|
||||
no_drill_field: 'Miss relation field',
|
||||
matrix: 'matrix',
|
||||
suspension: 'suspension'
|
||||
},
|
||||
plugin: {
|
||||
local_install: 'Local installation',
|
||||
|
@ -1314,7 +1314,9 @@ export default {
|
||||
exit_un_march_linkage_field: '存在未匹配聯動關系的字段',
|
||||
details: '詳情',
|
||||
setting: '設置',
|
||||
no_drill_field: '缺少關聯字段'
|
||||
no_drill_field: '缺少關聯字段',
|
||||
matrix: '矩阵分布',
|
||||
suspension: '悬浮'
|
||||
},
|
||||
plugin: {
|
||||
local_install: '本地安裝',
|
||||
|
@ -1319,7 +1319,9 @@ export default {
|
||||
exit_un_march_linkage_field: '存在未匹配联动关系的字段',
|
||||
details: '详情',
|
||||
setting: '设置',
|
||||
no_drill_field: '缺少关联字段'
|
||||
no_drill_field: '缺少关联字段',
|
||||
matrix: '矩阵分布',
|
||||
suspension: '悬浮'
|
||||
},
|
||||
plugin: {
|
||||
local_install: '本地安装',
|
||||
|
@ -104,11 +104,21 @@ const data = {
|
||||
state.curCanvasScale = curCanvasScale
|
||||
},
|
||||
|
||||
// setShapeStyle({ curComponent, canvasStyleData, curCanvasScale }, { top, left, width, height, rotate }) {
|
||||
// if (top || top === 0) curComponent.style.top = canvasStyleData.selfAdaption ? (top * 100 / curCanvasScale.scaleHeight) : top
|
||||
// if (left || left === 0) curComponent.style.left = canvasStyleData.selfAdaption ? (left * 100 / curCanvasScale.scaleWidth) : left
|
||||
// if (width || width === 0) curComponent.style.width = canvasStyleData.selfAdaption ? (width * 100 / curCanvasScale.scaleWidth) : width
|
||||
// if (height || height === 0) curComponent.style.height = canvasStyleData.selfAdaption ? (height * 100 / curCanvasScale.scaleHeight) : height
|
||||
// if (rotate || rotate === 0) curComponent.style.rotate = rotate
|
||||
// // console.log('setShapeStyle:curComponent' + 'top:' + top + ';left:' + left + '====' + JSON.stringify(curComponent))
|
||||
// },
|
||||
|
||||
setShapeStyle({ curComponent, canvasStyleData, curCanvasScale }, { top, left, width, height, rotate }) {
|
||||
if (top || top === 0) curComponent.style.top = canvasStyleData.selfAdaption ? (top * 100 / curCanvasScale.scaleHeight) : top
|
||||
if (left || left === 0) curComponent.style.left = canvasStyleData.selfAdaption ? (left * 100 / curCanvasScale.scaleWidth) : left
|
||||
if (width || width === 0) curComponent.style.width = canvasStyleData.selfAdaption ? (width * 100 / curCanvasScale.scaleWidth) : width
|
||||
if (height || height === 0) curComponent.style.height = canvasStyleData.selfAdaption ? (height * 100 / curCanvasScale.scaleHeight) : height
|
||||
console.log('setShapeStyle:width=' + width + ';height=' + height)
|
||||
if (top || top === 0) curComponent.style.top = top / curCanvasScale.scalePointHeight
|
||||
if (left || left === 0) curComponent.style.left = left / curCanvasScale.scalePointWidth
|
||||
if (width || width === 0) curComponent.style.width = width / curCanvasScale.scalePointWidth
|
||||
if (height || height === 0) curComponent.style.height = height / curCanvasScale.scalePointHeight
|
||||
if (rotate || rotate === 0) curComponent.style.rotate = rotate
|
||||
// console.log('setShapeStyle:curComponent' + 'top:' + top + ';left:' + left + '====' + JSON.stringify(curComponent))
|
||||
},
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2459092 */
|
||||
src: url('iconfont.woff2?t=1632382166116') format('woff2'),
|
||||
url('iconfont.woff?t=1632382166116') format('woff'),
|
||||
url('iconfont.ttf?t=1632382166116') format('truetype');
|
||||
src: url('iconfont.woff2?t=1633678290478') format('woff2'),
|
||||
url('iconfont.woff?t=1633678290478') format('woff'),
|
||||
url('iconfont.ttf?t=1633678290478') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,30 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-shujujuzhen:before {
|
||||
content: "\e69c";
|
||||
}
|
||||
|
||||
.icon-shitujuzhen_o:before {
|
||||
content: "\eb85";
|
||||
}
|
||||
|
||||
.icon-xuanfu1:before {
|
||||
content: "\e62c";
|
||||
}
|
||||
|
||||
.icon-youxuanfu-copy:before {
|
||||
content: "\e6db";
|
||||
}
|
||||
|
||||
.icon-xuanfu:before {
|
||||
content: "\e6f6";
|
||||
}
|
||||
|
||||
.icon-xuanfuanniu:before {
|
||||
content: "\e8e6";
|
||||
}
|
||||
|
||||
.icon-tabs:before {
|
||||
content: "\e62a";
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -5,6 +5,48 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "1766500",
|
||||
"name": "符号-数据矩阵",
|
||||
"font_class": "shujujuzhen",
|
||||
"unicode": "e69c",
|
||||
"unicode_decimal": 59036
|
||||
},
|
||||
{
|
||||
"icon_id": "5387898",
|
||||
"name": "视图矩阵_o",
|
||||
"font_class": "shitujuzhen_o",
|
||||
"unicode": "eb85",
|
||||
"unicode_decimal": 60293
|
||||
},
|
||||
{
|
||||
"icon_id": "21505923",
|
||||
"name": "悬浮",
|
||||
"font_class": "xuanfu1",
|
||||
"unicode": "e62c",
|
||||
"unicode_decimal": 58924
|
||||
},
|
||||
{
|
||||
"icon_id": "6331823",
|
||||
"name": "右悬浮-选中",
|
||||
"font_class": "youxuanfu-copy",
|
||||
"unicode": "e6db",
|
||||
"unicode_decimal": 59099
|
||||
},
|
||||
{
|
||||
"icon_id": "10788831",
|
||||
"name": "悬浮",
|
||||
"font_class": "xuanfu",
|
||||
"unicode": "e6f6",
|
||||
"unicode_decimal": 59126
|
||||
},
|
||||
{
|
||||
"icon_id": "14541134",
|
||||
"name": "悬浮按钮",
|
||||
"font_class": "xuanfuanniu",
|
||||
"unicode": "e8e6",
|
||||
"unicode_decimal": 59622
|
||||
},
|
||||
{
|
||||
"icon_id": "15196968",
|
||||
"name": "44.tabs",
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -60,6 +60,8 @@ import toast from '@/components/canvas/utils/toast'
|
||||
import { commonStyle, commonAttr } from '@/components/canvas/custom-component/component-list'
|
||||
import generateID from '@/components/canvas/utils/generateID'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AssisComponent',
|
||||
@ -69,6 +71,11 @@ export default {
|
||||
pictureList
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'canvasStyleData'
|
||||
])
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleDragStart(ev) {
|
||||
@ -79,6 +86,7 @@ export default {
|
||||
id: ev.target.dataset.id
|
||||
}
|
||||
ev.dataTransfer.setData('componentInfo', JSON.stringify(dataTrans))
|
||||
eventBus.$emit('startMoveIn')
|
||||
},
|
||||
goFile() {
|
||||
this.$refs.files.click()
|
||||
@ -133,6 +141,7 @@ export default {
|
||||
component = deepCopy(componentTemp)
|
||||
}
|
||||
})
|
||||
component.auxiliaryMatrix = this.canvasStyleData.auxiliaryMatrix
|
||||
return component
|
||||
},
|
||||
handleDragEnd(ev) {
|
||||
|
@ -69,6 +69,9 @@
|
||||
import { tree, findOne } from '@/api/panel/view'
|
||||
import componentList from '@/components/canvas/custom-component/component-list'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'ViewSelect',
|
||||
props: {
|
||||
@ -92,6 +95,11 @@ export default {
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'canvasStyleData'
|
||||
])
|
||||
},
|
||||
watch: {
|
||||
templateFilterText(val) {
|
||||
this.$refs.templateTree.filter(val)
|
||||
@ -130,6 +138,7 @@ export default {
|
||||
id: node.data.id
|
||||
}
|
||||
ev.dataTransfer.setData('componentInfo', JSON.stringify(dataTrans))
|
||||
eventBus.$emit('startMoveIn')
|
||||
},
|
||||
dragEnd() {
|
||||
console.log('dragEnd')
|
||||
@ -178,6 +187,7 @@ export default {
|
||||
component = deepCopy(componentTemp)
|
||||
}
|
||||
})
|
||||
component.auxiliaryMatrix = this.canvasStyleData.auxiliaryMatrix
|
||||
return component
|
||||
}
|
||||
|
||||
|
139
frontend/src/views/panel/drag/base.vue
Normal file
139
frontend/src/views/panel/drag/base.vue
Normal file
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div id="demo">
|
||||
<!-- <button @click="getList">getList</button> -->
|
||||
<div class="head">
|
||||
<router-link to="/" class="arrow">←</router-link>
|
||||
<span>基本应用</span>
|
||||
</div>
|
||||
<power-drag
|
||||
ref="cyGridster"
|
||||
:your-list="myList"
|
||||
:base-margin-left="baseMarginLeft"
|
||||
:base-margin-top="baseMarginTop"
|
||||
:base-width="baseWidth"
|
||||
:base-height="baseHeight"
|
||||
>
|
||||
<!-- <div v-for="(item,index) in myList" :slot="'slot'+index">
|
||||
|
||||
</div> -->
|
||||
<div draggable="true" style="width: 200px;height: 200px;background: #1b6d85">
|
||||
this is test
|
||||
</div>
|
||||
</power-drag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import drag from '@/components/DeDrag/drag.vue'
|
||||
import mock from 'mockjs'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
'power-drag': drag
|
||||
},
|
||||
data() {
|
||||
const list = mock.mock({
|
||||
// "myList|10": [{
|
||||
// "id|+1": 1,
|
||||
// x: '@integer(1,5)',
|
||||
// y: '@integer(1,5)',
|
||||
// sizex: '@integer(1,3)',
|
||||
// sizey: '@integer(1,3)',
|
||||
// }]
|
||||
myList: [{
|
||||
'id': 3,
|
||||
'x': 6,
|
||||
'y': 2,
|
||||
'sizex': 1,
|
||||
'sizey': 1
|
||||
}, {
|
||||
'id': 5,
|
||||
'x': 4,
|
||||
'y': 2,
|
||||
'sizex': 2,
|
||||
'sizey': 1
|
||||
}, {
|
||||
'id': 7,
|
||||
'x': 1,
|
||||
'y': 2,
|
||||
'sizex': 1,
|
||||
'sizey': 1
|
||||
}, {
|
||||
'id': 9,
|
||||
'x': 7,
|
||||
'y': 2,
|
||||
'sizex': 1,
|
||||
'sizey': 1
|
||||
}]
|
||||
})
|
||||
return {
|
||||
myList: list.myList,
|
||||
baseWidth: 0,
|
||||
baseHeight: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 屏幕适配,使得当前布局能在所有分辨率下适用,示例是在1366*638分辨率下完成
|
||||
const screenWidth = window.innerWidth
|
||||
const screenHeight = window.innerHeight
|
||||
this.baseWidth = 90.8333 * (screenWidth / 1366)
|
||||
this.baseHeight = 100 * (screenHeight / 638)
|
||||
this.baseMarginLeft = 0
|
||||
this.baseMarginTop = 0
|
||||
|
||||
this.$nextTick(function() {
|
||||
$('.dragAndResize').css('width', 'calc(100% - ' + (this.baseMarginLeft) + 'px)')
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
const gridster = this.$refs['cyGridster'] // 获取gridster实例
|
||||
gridster.init() // 在适当的时候初始化布局组件
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
const gridster = this.$refs['cyGridster'] // 获取gridster实例
|
||||
console.log(JSON.stringify(gridster.getList()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
& * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
#demo {
|
||||
width: 100%;
|
||||
padding: 1.5em 0 1.5em 0;
|
||||
|
||||
.head {
|
||||
border-bottom: 1px dashed;
|
||||
width: 100%;
|
||||
|
||||
padding-left: 20px;
|
||||
|
||||
height: 50px;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
.arrow {
|
||||
font-size: 20px;
|
||||
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -96,7 +96,7 @@
|
||||
|
||||
<div
|
||||
id="canvasInfo"
|
||||
class="content this_canvas"
|
||||
class="this_canvas"
|
||||
@drop="handleDrop"
|
||||
@mousedown="handleMouseDown"
|
||||
@mouseup="deselectCurComponent"
|
||||
@ -479,9 +479,21 @@ export default {
|
||||
this.currentWidget = ApplicationContext.getService(componentInfo.id)
|
||||
|
||||
this.currentFilterCom = this.currentWidget.getDrawPanel()
|
||||
this.currentFilterCom.style.top = this.getPositionY(e.layerY)
|
||||
this.currentFilterCom.style.left = this.getPositionX(e.layerX)
|
||||
|
||||
if (this.canvasStyleData.auxiliaryMatrix) {
|
||||
this.currentFilterCom.x = this.dropComponentInfo.x
|
||||
this.currentFilterCom.y = this.dropComponentInfo.y
|
||||
this.currentFilterCom.sizex = this.dropComponentInfo.sizex
|
||||
this.currentFilterCom.sizey = this.dropComponentInfo.sizey
|
||||
|
||||
this.currentFilterCom.style.left = (this.dragComponentInfo.x - 1) * this.curCanvasScale.matrixStyleOriginWidth
|
||||
this.currentFilterCom.style.top = (this.dragComponentInfo.y - 1) * this.curCanvasScale.matrixStyleOriginHeight
|
||||
this.currentFilterCom.style.width = this.dragComponentInfo.sizex * this.curCanvasScale.matrixStyleOriginWidth
|
||||
this.currentFilterCom.style.height = this.dragComponentInfo.sizey * this.curCanvasScale.matrixStyleOriginHeight
|
||||
}
|
||||
this.currentFilterCom.id = newComponentId
|
||||
this.currentFilterCom.auxiliaryMatrix = this.canvasStyleData.auxiliaryMatrix
|
||||
|
||||
if (this.currentWidget.filterDialog) {
|
||||
this.show = false
|
||||
this.openFilterDialog()
|
||||
@ -493,12 +505,27 @@ export default {
|
||||
// position = absolution 或导致有偏移 这里中和一下偏移量
|
||||
// component.style.top = this.getPositionY(e.layerY)
|
||||
// component.style.left = this.getPositionX(e.layerX)
|
||||
component.style.top = this.dropComponentInfo.shadowStyle.y
|
||||
component.style.left = this.dropComponentInfo.shadowStyle.x
|
||||
component.style.width = this.dropComponentInfo.shadowStyle.width
|
||||
component.style.height = this.dropComponentInfo.shadowStyle.height
|
||||
|
||||
if (this.canvasStyleData.auxiliaryMatrix) {
|
||||
component.x = this.dropComponentInfo.x
|
||||
component.y = this.dropComponentInfo.y
|
||||
component.sizex = this.dropComponentInfo.sizex
|
||||
component.sizey = this.dropComponentInfo.sizey
|
||||
|
||||
component.style.left = (this.dragComponentInfo.x - 1) * this.curCanvasScale.matrixStyleOriginWidth
|
||||
component.style.top = (this.dragComponentInfo.y - 1) * this.curCanvasScale.matrixStyleOriginHeight
|
||||
component.style.width = this.dragComponentInfo.sizex * this.curCanvasScale.matrixStyleOriginWidth
|
||||
component.style.height = this.dragComponentInfo.sizey * this.curCanvasScale.matrixStyleOriginHeight
|
||||
} else {
|
||||
component.style.top = this.dropComponentInfo.shadowStyle.y
|
||||
component.style.left = this.dropComponentInfo.shadowStyle.x
|
||||
component.style.width = this.dropComponentInfo.shadowStyle.width
|
||||
component.style.height = this.dropComponentInfo.shadowStyle.height
|
||||
}
|
||||
|
||||
component.id = newComponentId
|
||||
// 新拖入的组件矩阵状态 和仪表板当前的矩阵状态 保持一致
|
||||
component.auxiliaryMatrix = this.canvasStyleData.auxiliaryMatrix
|
||||
this.$store.commit('addComponent', { component })
|
||||
this.$store.commit('recordSnapshot', 'handleDrop')
|
||||
this.clearCurrentInfo()
|
||||
@ -611,22 +638,35 @@ export default {
|
||||
const scaleHeight = img.height / 200
|
||||
let scale = scaleWith > scaleHeight ? scaleWith : scaleHeight
|
||||
scale = scale > 1 ? scale : 1
|
||||
this.$store.commit('addComponent', {
|
||||
component: {
|
||||
...commonAttr,
|
||||
id: generateID(),
|
||||
component: 'Picture',
|
||||
label: '图片',
|
||||
icon: '',
|
||||
propValue: fileResult,
|
||||
style: {
|
||||
...commonStyle,
|
||||
top: _this.dropComponentInfo.shadowStyle.y,
|
||||
left: _this.dropComponentInfo.shadowStyle.x,
|
||||
width: _this.dropComponentInfo.shadowStyle.width,
|
||||
height: _this.dropComponentInfo.shadowStyle.height
|
||||
}
|
||||
const component = {
|
||||
...commonAttr,
|
||||
id: generateID(),
|
||||
component: 'Picture',
|
||||
label: '图片',
|
||||
icon: '',
|
||||
propValue: fileResult,
|
||||
style: {
|
||||
...commonStyle
|
||||
}
|
||||
}
|
||||
component.auxiliaryMatrix = _this.canvasStyleData.auxiliaryMatrix
|
||||
if (_this.canvasStyleData.auxiliaryMatrix) {
|
||||
component.x = _this.dropComponentInfo.x
|
||||
component.y = _this.dropComponentInfo.y
|
||||
component.sizex = _this.dropComponentInfo.sizex
|
||||
component.sizey = _this.dropComponentInfo.sizey
|
||||
component.style.left = (_this.dropComponentInfo.x - 1) * _this.curCanvasScale.matrixStyleOriginWidth
|
||||
component.style.top = (_this.dropComponentInfo.y - 1) * _this.curCanvasScale.matrixStyleOriginHeight
|
||||
component.style.width = _this.dropComponentInfo.sizex * _this.curCanvasScale.matrixStyleOriginWidth
|
||||
component.style.height = _this.dropComponentInfo.sizey * _this.curCanvasScale.matrixStyleOriginHeight
|
||||
} else {
|
||||
component.style.top = _this.dropComponentInfo.shadowStyle.y
|
||||
component.style.left = _this.dropComponentInfo.shadowStyle.x
|
||||
component.style.width = _this.dropComponentInfo.shadowStyle.width
|
||||
component.style.height = _this.dropComponentInfo.shadowStyle.height
|
||||
}
|
||||
this.$store.commit('addComponent', {
|
||||
component: component
|
||||
})
|
||||
|
||||
this.$store.commit('recordSnapshot', 'handleFileChange')
|
||||
@ -784,7 +824,8 @@ export default {
|
||||
|
||||
.this_canvas{
|
||||
height: calc(100vh - 91px);
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.el-main{
|
||||
height: calc(100vh - 91px);
|
||||
|
@ -31,6 +31,8 @@
|
||||
<script>
|
||||
import { ApplicationContext } from '@/utils/ApplicationContext'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
import eventBus from '@/components/canvas/utils/eventBus'
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'FilterGroup',
|
||||
data() {
|
||||
@ -66,6 +68,12 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'canvasStyleData',
|
||||
'curCanvasScale'
|
||||
])
|
||||
},
|
||||
created() {
|
||||
for (const key in this.widgetSubjects) {
|
||||
const widgetNames = this.widgetSubjects[key]
|
||||
@ -82,13 +90,22 @@ export default {
|
||||
methods: {
|
||||
handleDragStart(ev) {
|
||||
// 记录拖拽信息
|
||||
this.$store.commit('setDragComponentInfo', deepCopy(ApplicationContext.getService(ev.target.dataset.id).getDrawPanel()))
|
||||
const dragComponentInfo = deepCopy(ApplicationContext.getService(ev.target.dataset.id).getDrawPanel())
|
||||
// 设置矩阵标记点
|
||||
dragComponentInfo.x = 1
|
||||
dragComponentInfo.y = 1
|
||||
dragComponentInfo.sizex = Math.round(dragComponentInfo.style.width / this.curCanvasScale.matrixStyleOriginWidth)
|
||||
dragComponentInfo.sizey = Math.round(dragComponentInfo.style.height / this.curCanvasScale.matrixStyleOriginHeight)
|
||||
dragComponentInfo.auxiliaryMatrix = this.canvasStyleData.auxiliaryMatrix
|
||||
|
||||
this.$store.commit('setDragComponentInfo', dragComponentInfo)
|
||||
ev.dataTransfer.effectAllowed = 'copy'
|
||||
const dataTrans = {
|
||||
type: 'other',
|
||||
id: ev.target.dataset.id
|
||||
}
|
||||
ev.dataTransfer.setData('componentInfo', JSON.stringify(dataTrans))
|
||||
eventBus.$emit('startMoveIn')
|
||||
},
|
||||
handleDragEnd(ev) {
|
||||
this.$store.commit('clearDragComponentInfo')
|
||||
|
Loading…
Reference in New Issue
Block a user