Commit 58d0048461f10dad45e5b9268b83ac191264334d

Authored by ly525
1 parent 911e0e61

feat(animation): run animations in edit mode

front-end/h5/src/components/core/editor/edit-panel/animation.js
@@ -3,29 +3,36 @@ import { animationOptions, animationValue2Name, firstLevelAnimationOptions } fro @@ -3,29 +3,36 @@ import { animationOptions, animationValue2Name, firstLevelAnimationOptions } fro
3 3
4 export default { 4 export default {
5 computed: { 5 computed: {
6 - ...mapState('editor', ['editingElement']) 6 + ...mapState('editor', ['editingElement']),
  7 + animationQueue () {
  8 + return (this.editingElement && this.editingElement.animations) || []
  9 + }
7 }, 10 },
8 data: () => ({ 11 data: () => ({
9 - animationQueue: [], 12 + // animationQueue: [],
10 activeCollapsePanel: 0, 13 activeCollapsePanel: 0,
11 activePreviewAnimation: '', 14 activePreviewAnimation: '',
12 drawerVisible: false 15 drawerVisible: false
13 }), 16 }),
14 methods: { 17 methods: {
15 addAnimation () { 18 addAnimation () {
  19 + // TODO move this to vuex
16 this.animationQueue.push({ 20 this.animationQueue.push({
17 type: '', 21 type: '',
18 - duration: 0, 22 + duration: 2,
19 delay: 0, 23 delay: 0,
20 - countNum: 1, 24 + interationCount: 1,
21 infinite: false 25 infinite: false
22 }) 26 })
23 this.activeCollapsePanel = this.animationQueue.length - 1 27 this.activeCollapsePanel = this.animationQueue.length - 1
24 }, 28 },
25 deleteAnimate (index) { 29 deleteAnimate (index) {
  30 + // TODO move this to vuex
26 this.animationQueue.splice(index, 1) 31 this.animationQueue.splice(index, 1)
27 }, 32 },
28 runAnimate () { 33 runAnimate () {
  34 + // front-end/h5/src/components/core/editor/index.js created()
  35 + window.getEditorApp.$emit('RUN_ANIMATIONS')
29 }, 36 },
30 renderSecondAnimationTabs (animations) { 37 renderSecondAnimationTabs (animations) {
31 return ( 38 return (
@@ -50,11 +57,11 @@ export default { @@ -50,11 +57,11 @@ export default {
50 // https://www.quirksmode.org/js/events_mouse.html#mouseenter 57 // https://www.quirksmode.org/js/events_mouse.html#mouseenter
51 <a-list-item> 58 <a-list-item>
52 <div 59 <div
53 - class={[this.activePreviewAnimation === item.value && item.value + ' animated', 'shortcut-button']}  
54 onClick={(e) => { 60 onClick={(e) => {
55 // TODO move this to vuex mutation 61 // TODO move this to vuex mutation
56 this.editingElement.animations[this.activeCollapsePanel].type = item.value 62 this.editingElement.animations[this.activeCollapsePanel].type = item.value
57 }} 63 }}
  64 + class={[this.activePreviewAnimation === item.value && item.value + ' animated', 'shortcut-button']}
58 onMouseenter={(e) => { 65 onMouseenter={(e) => {
59 this.activePreviewAnimation = item.value 66 this.activePreviewAnimation = item.value
60 }} 67 }}
front-end/h5/src/components/core/editor/index.js
@@ -3,6 +3,7 @@ import undoRedoHistory from &#39;../../../store/plugins/undo-redo/History&#39; @@ -3,6 +3,7 @@ import undoRedoHistory from &#39;../../../store/plugins/undo-redo/History&#39;
3 import { getEditorConfigForEditingElement } from '../../../utils/element' 3 import { getEditorConfigForEditingElement } from '../../../utils/element'
4 4
5 import '../styles/index.scss' 5 import '../styles/index.scss'
  6 +import 'animate.css'
6 7
7 import RenderEditCanvas from './canvas/edit' 8 import RenderEditCanvas from './canvas/edit'
8 import RenderPreviewCanvas from './canvas/preview' 9 import RenderPreviewCanvas from './canvas/preview'
@@ -296,6 +297,8 @@ export default { @@ -296,6 +297,8 @@ export default {
296 ) 297 )
297 }, 298 },
298 created () { 299 created () {
  300 + // event bus for editor
  301 + window.getEditorApp = this
299 let workId = this.$route.params.workId 302 let workId = this.$route.params.workId
300 console.log(workId) 303 console.log(workId)
301 if (workId) { 304 if (workId) {
front-end/h5/src/components/core/models/element.js
@@ -34,6 +34,7 @@ class Element { @@ -34,6 +34,7 @@ class Element {
34 this.pluginProps = (typeof ele.pluginProps === 'object' && clone(ele.pluginProps)) || this.getDefaultPluginProps(ele.editorConfig || {}) 34 this.pluginProps = (typeof ele.pluginProps === 'object' && clone(ele.pluginProps)) || this.getDefaultPluginProps(ele.editorConfig || {})
35 this.commonStyle = (typeof ele.commonStyle === 'object' && clone(ele.commonStyle)) || { ...defaultStyle } 35 this.commonStyle = (typeof ele.commonStyle === 'object' && clone(ele.commonStyle)) || { ...defaultStyle }
36 this.events = [] 36 this.events = []
  37 + this.animations = []
37 } 38 }
38 39
39 getDefaultPluginProps (editorConfig) { 40 getDefaultPluginProps (editorConfig) {
@@ -51,7 +52,7 @@ class Element { @@ -51,7 +52,7 @@ class Element {
51 return pluginProps 52 return pluginProps
52 } 53 }
53 54
54 - getStyle ({ position = 'static', isRem = false }) { 55 + getStyle ({ position = 'static', isRem = false } = {}) {
55 const pluginProps = this.pluginProps 56 const pluginProps = this.pluginProps
56 const commonStyle = this.commonStyle 57 const commonStyle = this.commonStyle
57 let style = { 58 let style = {
front-end/h5/src/components/core/support/shape.js
  1 +import animationMixin from '@/mixins/animation.js'
  2 +
1 /** 3 /**
2 * #!zh: 上下左右 对应的 东南西北 4 * #!zh: 上下左右 对应的 东南西北
3 * #!en: top(north)、bottom(south)、left(west)、right(east) 5 * #!en: top(north)、bottom(south)、left(west)、right(east)
@@ -13,7 +15,8 @@ const directionKey = { @@ -13,7 +15,8 @@ const directionKey = {
13 const points = ['lt', 'rt', 'lb', 'rb', 'l', 'r', 't', 'b'] 15 const points = ['lt', 'rt', 'lb', 'rb', 'l', 'r', 't', 'b']
14 16
15 export default { 17 export default {
16 - props: ['defaultPosition', 'active', 'handleMousedownProp', 'handleElementMoveProp', 'handlePointMoveProp', 'handleElementMouseUpProp', 'handlePointMouseUpProp'], 18 + mixins: [animationMixin],
  19 + props: ['defaultPosition', 'active', 'handleMousedownProp', 'handleElementMoveProp', 'handlePointMoveProp', 'handleElementMouseUpProp', 'handlePointMouseUpProp', 'element'],
17 computed: { 20 computed: {
18 position () { 21 position () {
19 return { ...this.defaultPosition } 22 return { ...this.defaultPosition }
front-end/h5/src/mixins/animation.js 0 → 100644
  1 +// https://stackoverflow.com/questions/26874769/getcomputedstyle-and-csstext-in-ie-and-firefox
  2 +function getComputedCSSText (style) {
  3 + let cssText = ''
  4 + for (let attr in style) {
  5 + // m <?> matched
  6 + // #!en: hump to line
  7 + // #!zh: 驼峰转下划线
  8 + cssText += `${attr.replace(/[A-Z]+/g, m => `-${m.toLowerCase()}`)}:${style[attr]};`
  9 + }
  10 + return cssText
  11 +}
  12 +
  13 +export default {
  14 + methods: {
  15 + async runAnimations () {
  16 + const animationQueue = this.animations || this.element.animations || []
  17 + let len = animationQueue.length
  18 + if (len === 0) return
  19 +
  20 + let that = this
  21 + let parentNode = this.$el
  22 + let animIdx = 0
  23 + const oldStyle = that.element.getStyle({ position: 'absolute' })
  24 + runAnimation()
  25 +
  26 + function runAnimation () {
  27 + if (animIdx < len) {
  28 + const animation = animationQueue[animIdx]
  29 + let animationStyle = {
  30 + animationName: animation.type,
  31 + animationDuration: `${animation.duration}s`,
  32 + animationIterationCount: animation.infinite ? 'infinite' : animation.interationCount,
  33 + animationDelay: `${animation.delay}s`,
  34 + animationFillMode: 'both'
  35 + }
  36 + parentNode.style.cssText = getComputedCSSText(animationStyle) + getComputedCSSText(oldStyle)
  37 + animIdx++
  38 + } else {
  39 + // reset to the initial state after the animation ended
  40 + parentNode.style.cssText = getComputedCSSText(oldStyle)
  41 + }
  42 + }
  43 + parentNode.addEventListener('animationend', runAnimation, false)
  44 + }
  45 + },
  46 + created () {
  47 + const that = this
  48 + window.getEditorApp.$on('RUN_ANIMATIONS', () => {
  49 + if (that.active) {
  50 + that.runAnimations()
  51 + }
  52 + })
  53 + }
  54 +
  55 +}