Commit 9e44e40af1a7005c68b3de8e10b06ca597454e5c

Authored by ly525
1 parent 42c972ba

feat: support copy plugin on canvas

front-end/h5/src/components/core/editor/canvas/edit.js
1 1 import { mapState, mapActions } from 'vuex'
2 2 import Shape from '../../support/shape'
3 3  
  4 +const contextmenuOptions = [
  5 + {
  6 + label: '复制',
  7 + value: 'copy'
  8 + },
  9 + {
  10 + label: '删除',
  11 + value: 'delete'
  12 + },
  13 + {
  14 + label: '置顶',
  15 + value: 'bring2Top'
  16 + },
  17 + {
  18 + label: '置底',
  19 + value: 'bring2Bottom'
  20 + },
  21 + {
  22 + label: '上移',
  23 + value: 'addZindex'
  24 + },
  25 + {
  26 + label: '下移',
  27 + value: 'minusZindex'
  28 + }
  29 +]
  30 +
4 31 export default {
5 32 props: ['elements', 'handleClickElementProp', 'handleClickCanvasProp'],
6 33 data: () => ({
... ... @@ -17,7 +44,8 @@ export default {
17 44 ...mapActions('element', [
18 45 'setEditingElement', // -> this.foo()
19 46 'setElementPosition', // -> this.foo()
20   - 'setElementShape' // -> this.foo()
  47 + 'setElementShape', // -> this.foo()
  48 + 'elementManager'
21 49 ]),
22 50 // TODO #!zh: 优化代码
23 51 // generate vertical line
... ... @@ -187,6 +215,9 @@ export default {
187 215 {
188 216 this.contextmenuPos.length
189 217 ? <a-menu
  218 + onSelect={({ item, key, selectedKeys }) => {
  219 + this.elementManager({ type: key })
  220 + }}
190 221 style={{
191 222 left: this.contextmenuPos[0] + 'px',
192 223 top: this.contextmenuPos[1] + 'px',
... ... @@ -195,12 +226,7 @@ export default {
195 226 zIndex: 999
196 227 }}
197 228 >
198   - <a-menu-item data-command='copyEditingElement'>复制</a-menu-item>
199   - <a-menu-item data-command="deleteEditingElement">删除</a-menu-item>
200   - <a-menu-item data-command="bringLayer2Front">置顶</a-menu-item>
201   - <a-menu-item data-command="bringLayer2End">置底</a-menu-item>
202   - <a-menu-item data-command="addLayerZindex">上移</a-menu-item>
203   - <a-menu-item data-command="subtractLayerZindex">下移</a-menu-item>
  229 + { contextmenuOptions.map(option => <a-menu-item key={option.value} data-command={option.value}>{option.label}</a-menu-item>) }
204 230 </a-menu>
205 231 : null
206 232 }
... ...
front-end/h5/src/components/core/editor/index.js
1 1 import Vue from 'vue'
2   -import Element from '../models/element'
  2 +import { mapState, mapActions } from 'vuex'
  3 +// import Element from '../models/element'
  4 +
3 5 import '../styles/index.scss'
4 6  
5 7 import RenderEditCanvas from './canvas/edit'
... ... @@ -30,10 +32,19 @@ export default {
30 32 data: () => ({
31 33 activeMenuKey: 'pluginList',
32 34 pages: [],
33   - elements: [],
  35 + // elements: [],
34 36 isPreviewMode: false
35 37 }),
  38 + computed: {
  39 + ...mapState('element', {
  40 + editingElement: state => state.editingElement,
  41 + elements: state => state.elementsOfCurrentPage
  42 + })
  43 + },
36 44 methods: {
  45 + ...mapActions('element', [
  46 + 'elementManager'
  47 + ]),
37 48 getEditorConfig (pluginName) {
38 49 // const pluginCtor = Vue.options[pluginName]
39 50 // const pluginCtor = this.$options.components[pluginName]
... ... @@ -49,7 +60,11 @@ export default {
49 60 const zindex = this.elements.length + 1
50 61 // const defaultPropsValue = this.getPropsDefaultValue(name)
51 62 const editorConfig = this.getEditorConfig(name)
52   - this.elements.push(new Element({ name, zindex, editorConfig }))
  63 + // this.elements.push(new Element({ name, zindex, editorConfig }))
  64 + this.elementManager({
  65 + type: 'add',
  66 + value: { name, zindex, editorConfig }
  67 + })
53 68 }
54 69 },
55 70 render (h) {
... ...
front-end/h5/src/components/core/models/element.js
... ... @@ -16,28 +16,34 @@ class Element {
16 16 this.name = ele.name
17 17 this.uuid = +new Date()
18 18 this.editorConfig = ele.editorConfig || {}
19   - this.pluginProps = {}
20   - this.commonStyle = {}
21   - this.init()
  19 + /**
  20 + * 之前版本代码:https://github.com/ly525/luban-h5/blob/a7875cbc73c0d18bc2459985ca3ce1d4dc44f141/front-end/h5/src/components/core/models/element.js#L21
  21 + * 1.之前的版本为:this.pluginProps = {}, 改为下面的版本
  22 + * 是因为要支持[复制画布上的元素],所以需要先使用 ele.pluginProps 进行初始化(也就是拷贝之前的元素的值)
  23 + *
  24 + * 2. 移除 this.init() 原因是:如果是 复制元素,则 init 会把 copy 的值重新覆盖为初始值,copy 无效
  25 + */
  26 + this.pluginProps = ele.pluginProps || this.getDefaultPluginProps()
  27 + this.commonStyle = ele.commonStyle || this.getDefaultCommonStyle()
22 28 }
23 29  
24   - init () {
25   - const commonStyle = this.commonStyle
26   - // init common props
27   - Object.keys(defaultProps).forEach(key => {
28   - commonStyle[key] = defaultProps[key]
29   - })
  30 + getDefaultCommonStyle () {
  31 + return { ...defaultProps }
  32 + }
30 33  
  34 + getDefaultPluginProps () {
31 35 // init prop of plugin
32 36 const propConf = this.editorConfig.propsConfig
  37 + const pluginProps = {}
33 38 Object.keys(propConf).forEach(key => {
34 39 // #6
35 40 if (key === 'name') {
36 41 console.warn('Please do not use {name} as plugin prop')
37 42 return
38 43 }
39   - this.pluginProps[key] = propConf[key].defaultPropValue
  44 + pluginProps[key] = propConf[key].defaultPropValue
40 45 })
  46 + return pluginProps
41 47 }
42 48  
43 49 getStyle (position = 'static') {
... ... @@ -64,6 +70,19 @@ class Element {
64 70 getData () {
65 71  
66 72 }
  73 +
  74 + clone () {
  75 + return new Element({
  76 + name: this.name,
  77 + editorConfig: this.editorConfig,
  78 + pluginProps: JSON.parse(JSON.stringify(this.pluginProps)),
  79 + commonStyle: {
  80 + ...this.commonStyle,
  81 + top: this.commonStyle.top + 20,
  82 + left: this.commonStyle.left + 20
  83 + }
  84 + })
  85 + }
67 86 }
68 87  
69 88 export default Element
... ...
front-end/h5/src/store/modules/element.js
1 1 // initial state
  2 +import Element from '../../components/core/models/element'
  3 +
2 4 const state = {
3   - editingElement: null
  5 + editingElement: null,
  6 + elementsOfCurrentPage: []
4 7 }
5 8  
6 9 // getters
... ... @@ -18,6 +21,9 @@ const actions = {
18 21 },
19 22 setElementShape ({ commit }, payload) {
20 23 commit('setElementCommonStyle', payload)
  24 + },
  25 + elementManager ({ commit }, payload) {
  26 + commit('elementManager', payload)
21 27 }
22 28 }
23 29  
... ... @@ -31,6 +37,18 @@ const mutations = {
31 37 ...state.editingElement.commonStyle,
32 38 ...payload
33 39 }
  40 + },
  41 + elementManager (state, { type, value }) {
  42 + switch (type) {
  43 + case 'add':
  44 + const element = new Element(value)
  45 + state.elementsOfCurrentPage.push(element)
  46 + break
  47 + case 'copy':
  48 + state.elementsOfCurrentPage.push(state.editingElement.clone())
  49 + break
  50 + default:
  51 + }
34 52 }
35 53 }
36 54  
... ...