Skip to content

Commit 67b129a

Browse files
committed
feat: support drag&drop element from the left panel to the canvas; !#: 支持从左侧元素列表中拖拽元素至中间画布
1 parent f002c51 commit 67b129a

File tree

4 files changed

+173
-61
lines changed

4 files changed

+173
-61
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* @Author: ly525
3+
* @Date: 2020-05-17 17:21:04
4+
* @LastEditors: ly525
5+
* @LastEditTime: 2020-05-24 18:09:23
6+
* @FilePath: /luban-h5/front-end/h5/src/components/core/editor/drag-mixin.js
7+
* @Github: https://github.com/ly525/luban-h5
8+
* @Copyright 2018 - 2019 luban-h5. All Rights Reserved
9+
* @Description:
10+
* 组件拖拽至画布功能
11+
* 其中部分代码参考自:https://github.com/hakubox/haku-form-design,已经征得作者同意,目的是后续考虑做 tab 之类的嵌套容器
12+
*/
13+
14+
let dragDom = null
15+
16+
let dragConfig = {
17+
isPreDrag: false, // 准备拖拽
18+
isDrag: false, // 正式拖拽
19+
origin: {
20+
clientY: 0, // 鼠标按下时候时候值
21+
clientX: 0,
22+
layerX: 0, // 鼠标.x 相对于元素左上角.left 的偏移
23+
layerY: 0 // 鼠标.y 相对于元素左上角.top 的偏移
24+
}
25+
}
26+
27+
class Drag {
28+
constructor (options) {
29+
this.mousedown = options.mousedown
30+
this.mousemove = options.mousemove
31+
this.mouseup = options.mouseup
32+
33+
this._mousedown = this._mousedown.bind(this)
34+
this._mousemove = this._mousemove.bind(this)
35+
this._mouseup = this._mouseup.bind(this)
36+
}
37+
38+
start (e) {
39+
this._mousedown(e)
40+
}
41+
42+
_mousedown (e) {
43+
this.mousedown(e)
44+
this.toggleListener('add')
45+
}
46+
47+
_mousemove (e) {
48+
console.log('mousemove')
49+
this.mousemove(e)
50+
}
51+
52+
_mouseup (e) {
53+
console.log('mouseup')
54+
this.mouseup(e)
55+
this.toggleListener('remove')
56+
}
57+
58+
toggleListener (action) {
59+
document[`${action}EventListener`]('mousemove', this._mousemove)
60+
document[`${action}EventListener`]('mouseup', this._mouseup)
61+
}
62+
}
63+
64+
export default {
65+
data () {
66+
return {
67+
68+
}
69+
},
70+
methods: {
71+
/**
72+
*
73+
* @param {*} element
74+
* @param {*} e
75+
*/
76+
handleDragStartFromMixin (element, e) {
77+
// https://developer.mozilla.org/zh-CN/docs/Web/API/event.button
78+
// 0 为 左键点击.
79+
if (e.button !== 0) return
80+
if (dragDom) {
81+
document.body.removeChild(dragDom)
82+
dragDom = null
83+
}
84+
this.dragElement = element
85+
dragDom = e.target.cloneNode(true)
86+
document.body.appendChild(dragDom)
87+
88+
new Drag({
89+
mousedown: this.mousedown,
90+
mousemove: this.mousemove,
91+
mouseup: this.mouseup
92+
}).start(e)
93+
},
94+
/**
95+
*
96+
* @param {*} e
97+
*/
98+
mousedown (e) {
99+
// 鼠标.x 相对于元素左上角 的偏移
100+
const { layerX, layerY } = e
101+
dragConfig.origin.layerX = layerX
102+
dragConfig.origin.layerY = layerY
103+
dragConfig.origin.clientX = e.clientX
104+
dragConfig.origin.clientY = e.clientY
105+
106+
dragDom.style.position = 'absolute'
107+
dragDom.style.left = e.clientX - layerX + 'px'
108+
dragDom.style.top = e.clientY - layerY + 'px'
109+
dragDom.classList.add('dragging-dom-ele', 'hidden')
110+
111+
dragConfig.isPreDrag = true
112+
},
113+
/** 组件拖拽中 */
114+
mousemove (e) {
115+
dragDom.classList.remove('hidden')
116+
const { layerX, layerY } = dragConfig.origin
117+
dragDom.style.left = e.clientX - layerX + 'px'
118+
dragDom.style.top = e.clientY - layerY + 'px'
119+
},
120+
mouseup (e) {
121+
const { layerX, layerY } = dragConfig.origin
122+
document.body.removeChild(dragDom)
123+
dragDom = null
124+
125+
const canvasWrapper = document.querySelector('.canvas-wrapper')
126+
const position = canvasWrapper.getBoundingClientRect()
127+
this.dragElement && this.clone({
128+
...this.dragElement,
129+
customStyle: {
130+
left: e.clientX - layerX - position.left,
131+
top: e.clientY - layerY - position.top
132+
}
133+
})
134+
}
135+
},
136+
updated () {
137+
console.log('updated')
138+
}
139+
}

front-end/h5/src/components/core/editor/index.js

+7-61
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,7 @@ import LangSelect from '@/components/common/header/LangSelect.vue'
2222
import Feedback from '@/components/common/feedback/index'
2323
import AdjustLineV from '@/components/core/support/adjust-line/vertical'
2424

25-
// const sidebarMenus = [
26-
// {
27-
// i18nLabel: 'editor.sidebar.components',
28-
// label: '组件列表',
29-
// value: 'pluginList',
30-
// antIcon: 'bars'
31-
// },
32-
// {
33-
// i18nLabel: 'editor.sidebar.pages',
34-
// label: '页面管理',
35-
// value: 'pageManagement',
36-
// antIcon: 'snippets'
37-
// },
38-
// {
39-
// i18nLabel: 'editor.sidebar.templates',
40-
// label: '免费模板',
41-
// value: 'freeTemplate',
42-
// antIcon: 'appstore'
43-
// }
44-
// ]
25+
import DragMixin from './drag-mixin'
4526

4627
const fixedTools = [
4728
{
@@ -103,6 +84,7 @@ const fixedTools = [
10384
]
10485

10586
export default {
87+
mixins: [DragMixin],
10688
name: 'Editor',
10789
components: {
10890
LogoOfHeader,
@@ -184,7 +166,11 @@ export default {
184166
<strong>{ this.$t('editor.tip.click') }</strong>{ this.$t('editor.tip.click') }
185167
</i18n>
186168
</div>
187-
<RenderShortcutsPanel pluginsList={this.pluginsList} handleClickShortcut={this.clone} />
169+
<RenderShortcutsPanel
170+
pluginsList={this.pluginsList}
171+
handleClickShortcut={this.clone}
172+
handleDragStart={this.handleDragStartFromMixin}
173+
/>
188174
</a-tab-pane>
189175
<a-tab-pane key='page-manager' tab={this.$t('editor.sidebar.pages')}>
190176
<RenderPageManager
@@ -202,46 +188,6 @@ export default {
202188
</a-tab-pane>
203189
</a-tabs>
204190
)
205-
// switch (this.activeMenuKey) {
206-
// case sidebarMenus[0].value:
207-
// return (
208-
// <a-tabs
209-
// style="height: 100%;"
210-
// tabBarGutter={10}
211-
// >
212-
// <a-tab-pane key="plugin-list" tab={this.$t('editor.sidebar.components')}>
213-
// <RenderShortcutsPanel pluginsList={this.pluginsList} handleClickShortcut={this.clone} />
214-
// </a-tab-pane>
215-
// <a-tab-pane key='page-manager' tab={this.$t('editor.sidebar.pages')}>
216-
// <RenderPageManager
217-
// pages={this.pages}
218-
// editingPage={this.editingPage}
219-
// onSelectMenuItem={(menuKey) => {
220-
// this.pageManager({ type: menuKey })
221-
// }}
222-
// onEditTitle={({ pageIndexForEditingTitle, newTitle }) => {
223-
// this.pageManager({ type: 'editTitle', value: { pageIndexForEditingTitle, newTitle } })
224-
// this.saveWork({ isSaveCover: false })
225-
// }}
226-
// onSelectPage={(pageIndex) => { this.setEditingPage(pageIndex) }}
227-
// />
228-
// </a-tab-pane>
229-
// </a-tabs>
230-
// )
231-
// case sidebarMenus[1].value:
232-
// return (
233-
// <RenderPageManager
234-
// pages={this.pages}
235-
// editingPage={this.editingPage}
236-
// onSelectMenuItem={(menuKey) => {
237-
// this.pageManager({ type: menuKey })
238-
// }}
239-
// onSelectPage={(pageIndex) => { this.setEditingPage(pageIndex) }}
240-
// />
241-
// )
242-
// default:
243-
// return null
244-
// }
245191
}
246192
},
247193
mounted () {

front-end/h5/src/components/core/editor/shortcuts-panel/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export default {
1111
},
1212
handleClickShortcut: {
1313
type: Function
14+
},
15+
handleDragStart: {
16+
type: Function,
17+
default: (e) => {}
1418
}
1519
},
1620
data: () => ({
@@ -97,6 +101,7 @@ export default {
97101
<a-col span={12} style={{ marginTop: '10px' }}>
98102
<ShortcutButton
99103
clickFn={this.onClickShortcut.bind(this, plugin)}
104+
mousedownFn={this.handleDragStart.bind(this, plugin)}
100105
// title={plugin.title}
101106
title={plugin.i18nTitle[this.currentLang] || plugin.title}
102107
faIcon={plugin.icon}

front-end/h5/src/components/core/styles/index.scss

+22
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,28 @@
5252
}
5353
}
5454

55+
.hidden {
56+
display: none !important;
57+
}
58+
59+
// 拖拽出来的控件
60+
.dragging-dom-ele {
61+
position: fixed !important;
62+
z-index: 100;
63+
64+
display: inline-block;
65+
box-sizing: border-box;
66+
67+
height: 30px;
68+
width: 130px;
69+
border-radius: 4px;
70+
border: 1px solid #CCC;
71+
72+
cursor: grabbing;
73+
user-select: none;
74+
opacity: 0.6;
75+
}
76+
5577
.ant-tabs-nav .ant-tabs-tab {
5678
padding: 12px 0 !important;
5779
}

0 commit comments

Comments
 (0)