Commit 9e44e40af1a7005c68b3de8e10b06ca597454e5c
1 parent
42c972ba
feat: support copy plugin on canvas
Showing
4 changed files
with
99 additions
and
21 deletions
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 | ... | ... |