diff --git a/src/views/Editor/Toolbar/ElementAnimationPanel.vue b/src/views/Editor/Toolbar/ElementAnimationPanel.vue
index 7efb3691..1564183d 100644
--- a/src/views/Editor/Toolbar/ElementAnimationPanel.vue
+++ b/src/views/Editor/Toolbar/ElementAnimationPanel.vue
@@ -30,12 +30,24 @@
+
+
+
持续时间(毫秒):
+
updateElementAnimationDuration(value)"
+ style="flex: 3;"
+ />
+
选中画布中的元素添加动画
@@ -57,7 +69,7 @@
【{{element.elType}}】{{element.animationType}}
-
+
@@ -79,6 +91,8 @@ import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import Draggable from 'vuedraggable'
+const defaultDuration = 1000
+
const animationTypes: { [key: string]: string } = {}
for (const type of ANIMATIONS) {
for (const animation of type.children) {
@@ -128,8 +142,13 @@ export default defineComponent({
if (!handleElement.value) return null
const animations = currentSlideAnimations.value || []
const animation = animations.find(item => item.elId === handleElement.value.id)
- if (!animation) return null
- return animationTypes[animation.type]
+ return animation || null
+ })
+
+ // 当前选中元素的入场动画名称
+ const handleElementAnimationName = computed(() => {
+ if (!handleElementAnimation.value) return null
+ return animationTypes[handleElementAnimation.value.type]
})
// 删除元素入场动画
@@ -154,14 +173,16 @@ export default defineComponent({
}
// 执行入场动画预览
- const runAnimation = (elId: string, animationType: string) => {
+ const runAnimation = (elId: string, animationType: string, duration: number) => {
const prefix = 'animate__'
const elRef = document.querySelector(`#editable-element-${elId} [class^=editable-element-]`)
if (elRef) {
const animationName = `${prefix}${animationType}`
+ document.documentElement.style.setProperty('--animate-duration', `${duration}ms`)
elRef.classList.add(`${prefix}animated`, animationName)
const handleAnimationEnd = () => {
+ document.documentElement.style.removeProperty('--animate-duration')
elRef.classList.remove(`${prefix}animated`, animationName)
}
elRef.addEventListener('animationend', handleAnimationEnd, { once: true })
@@ -170,7 +191,9 @@ export default defineComponent({
// 修改元素入场动画,并执行一次预览
const updateElementAnimation = (type: string) => {
- const animations = (currentSlideAnimations.value as PPTAnimation[]).map(item => {
+ if (!currentSlideAnimations.value) return
+
+ const animations = currentSlideAnimations.value.map(item => {
if (item.elId === handleElement.value.id) return { ...item, type }
return item
})
@@ -178,12 +201,28 @@ export default defineComponent({
animationPoolVisible.value = false
addHistorySnapshot()
- runAnimation(handleElement.value.id, type)
+ const animationItem = currentSlideAnimations.value.find(item => item.elId === handleElement.value.id)
+ const duration = animationItem?.duration || defaultDuration
+
+ runAnimation(handleElement.value.id, type, duration)
+ }
+
+ // 修改元素入场动画持续时间
+ const updateElementAnimationDuration = (duration: number) => {
+ if (!currentSlideAnimations.value) return
+ if (duration < 100 || duration > 5000) return
+
+ const animations = currentSlideAnimations.value.map(item => {
+ if (item.elId === handleElement.value.id) return { ...item, duration }
+ return item
+ })
+ store.commit(MutationTypes.UPDATE_SLIDE, { animations })
+ addHistorySnapshot()
}
// 添加元素入场动画,并执行一次预览
const addAnimation = (type: string) => {
- if (handleElementAnimation.value) {
+ if (handleElementAnimationName.value) {
updateElementAnimation(type)
return
}
@@ -191,13 +230,13 @@ export default defineComponent({
animations.push({
elId: handleElement.value.id,
type,
- duration: 1000,
+ duration: defaultDuration,
})
store.commit(MutationTypes.UPDATE_SLIDE, { animations })
animationPoolVisible.value = false
addHistorySnapshot()
- runAnimation(handleElement.value.id, type)
+ runAnimation(handleElement.value.id, type, defaultDuration)
}
return {
@@ -207,10 +246,12 @@ export default defineComponent({
animationSequence,
hoverPreviewAnimation,
handleElementAnimation,
+ handleElementAnimationName,
addAnimation,
deleteAnimation,
handleDragEnd,
runAnimation,
+ updateElementAnimationDuration,
}
},
})
@@ -220,6 +261,12 @@ export default defineComponent({
.element-animation-btn {
width: 100%;
}
+.duration {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ margin: 10px 0;
+}
.tip {
text-align: center;
font-style: italic;
diff --git a/src/views/Screen/index.vue b/src/views/Screen/index.vue
index b36de7cc..6e608ce3 100644
--- a/src/views/Screen/index.vue
+++ b/src/views/Screen/index.vue
@@ -148,9 +148,11 @@ export default defineComponent({
const elRef = document.querySelector(`#screen-element-${animation.elId} [class^=base-element-]`)
if (elRef) {
const animationName = `${prefix}${animation.type}`
+ document.documentElement.style.setProperty('--animate-duration', `${animation.duration}ms`)
elRef.classList.add(`${prefix}animated`, animationName)
const handleAnimationEnd = () => {
+ document.documentElement.style.removeProperty('--animate-duration')
elRef.classList.remove(`${prefix}animated`, animationName)
}
elRef.addEventListener('animationend', handleAnimationEnd, { once: true })