mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
feat: 补充放映切换动画
This commit is contained in:
parent
a8ad6d8fe6
commit
6285188fc6
@ -1,3 +1,5 @@
|
|||||||
|
import type { TurningMode } from '@/types/slides'
|
||||||
|
|
||||||
export const ANIMATION_DEFAULT_DURATION = 1000
|
export const ANIMATION_DEFAULT_DURATION = 1000
|
||||||
export const ANIMATION_DEFAULT_TRIGGER = 'click'
|
export const ANIMATION_DEFAULT_TRIGGER = 'click'
|
||||||
export const ANIMATION_CLASS_PREFIX = 'animate__'
|
export const ANIMATION_CLASS_PREFIX = 'animate__'
|
||||||
@ -209,4 +211,24 @@ export const ATTENTION_ANIMATIONS = [
|
|||||||
{ name: '心跳(快)', value: 'heartBeat' },
|
{ name: '心跳(快)', value: 'heartBeat' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
interface SlideAnimation {
|
||||||
|
label: string
|
||||||
|
value: TurningMode
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SLIDE_ANIMATIONS: SlideAnimation[] = [
|
||||||
|
{ label: '无', value: 'no' },
|
||||||
|
{ label: '随机', value: 'random' },
|
||||||
|
{ label: '左右推移', value: 'slideX' },
|
||||||
|
{ label: '上下推移', value: 'slideY' },
|
||||||
|
{ label: '左右推移(3D)', value: 'slideX3D' },
|
||||||
|
{ label: '上下推移(3D)', value: 'slideY3D' },
|
||||||
|
{ label: '淡入淡出', value: 'fade' },
|
||||||
|
{ label: '旋转', value: 'rotate' },
|
||||||
|
{ label: '上下展开', value: 'scaleY' },
|
||||||
|
{ label: '左右展开', value: 'scaleX' },
|
||||||
|
{ label: '放大', value: 'scale' },
|
||||||
|
{ label: '缩小', value: 'scaleReverse' },
|
||||||
]
|
]
|
@ -658,7 +658,7 @@ export interface SlideBackground {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export type TurningMode = 'no' | 'fade' | 'slideX' | 'slideY'
|
export type TurningMode = 'no' | 'fade' | 'slideX' | 'slideY' | 'random' | 'slideX3D' | 'slideY3D' | 'rotate' | 'scaleY' | 'scaleX' | 'scale' | 'scaleReverse'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 幻灯片页面
|
* 幻灯片页面
|
||||||
|
@ -21,26 +21,17 @@ import { computed } from 'vue'
|
|||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useSlidesStore } from '@/store'
|
import { useSlidesStore } from '@/store'
|
||||||
import type { TurningMode } from '@/types/slides'
|
import type { TurningMode } from '@/types/slides'
|
||||||
|
import { SLIDE_ANIMATIONS } from '@/configs/animation'
|
||||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||||
|
|
||||||
import { Button } from 'ant-design-vue'
|
import { Button, message } from 'ant-design-vue'
|
||||||
|
|
||||||
interface Animations {
|
|
||||||
label: string
|
|
||||||
value: TurningMode
|
|
||||||
}
|
|
||||||
|
|
||||||
const slidesStore = useSlidesStore()
|
const slidesStore = useSlidesStore()
|
||||||
const { slides, currentSlide } = storeToRefs(slidesStore)
|
const { slides, currentSlide } = storeToRefs(slidesStore)
|
||||||
|
|
||||||
const currentTurningMode = computed(() => currentSlide.value.turningMode || 'slideY')
|
const currentTurningMode = computed(() => currentSlide.value.turningMode || 'slideY')
|
||||||
|
|
||||||
const animations: Animations[] = [
|
const animations = SLIDE_ANIMATIONS
|
||||||
{ label: '无', value: 'no' },
|
|
||||||
{ label: '淡入淡出', value: 'fade' },
|
|
||||||
{ label: '左右推移', value: 'slideX' },
|
|
||||||
{ label: '上下推移', value: 'slideY' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const { addHistorySnapshot } = useHistorySnapshot()
|
const { addHistorySnapshot } = useHistorySnapshot()
|
||||||
|
|
||||||
@ -60,6 +51,7 @@ const applyAllSlide = () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
slidesStore.setSlides(newSlides)
|
slidesStore.setSlides(newSlides)
|
||||||
|
message.success('已应用到全部')
|
||||||
addHistorySnapshot()
|
addHistorySnapshot()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -72,14 +64,14 @@ const applyAllSlide = () => {
|
|||||||
}
|
}
|
||||||
.animation-item {
|
.animation-item {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
height: 115px;
|
height: 100px;
|
||||||
border: solid 1px #d6d6d6;
|
border: solid 1px #d6d6d6;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 25px 0 15px 0;
|
padding: 20px 0 15px 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@ -103,13 +95,16 @@ const applyAllSlide = () => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
@mixin elAnimation($animationType) {
|
@mixin elAnimation($animationType) {
|
||||||
content: '';
|
content: 'Slide';
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
background-color: #d9dadb;
|
background-color: #d9dadb;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
animation: $animationType $transitionDelaySlow linear;
|
animation: $animationType $transitionDelaySlow linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +123,42 @@ const applyAllSlide = () => {
|
|||||||
@include elAnimation(slideY);
|
@include elAnimation(slideY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.slideX3D:hover {
|
||||||
|
&::after {
|
||||||
|
@include elAnimation(slideX3D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.slideY3D:hover {
|
||||||
|
&::after {
|
||||||
|
@include elAnimation(slideY3D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.rotate:hover {
|
||||||
|
&::after {
|
||||||
|
transform-origin: 0 0;
|
||||||
|
@include elAnimation(rotate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.scaleY:hover {
|
||||||
|
&::after {
|
||||||
|
@include elAnimation(scaleY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.scaleX:hover {
|
||||||
|
&::after {
|
||||||
|
@include elAnimation(scaleX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.scale:hover {
|
||||||
|
&::after {
|
||||||
|
@include elAnimation(scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.scaleReverse:hover {
|
||||||
|
&::after {
|
||||||
|
@include elAnimation(scaleReverse);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.animation-text {
|
.animation-text {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -159,4 +190,60 @@ const applyAllSlide = () => {
|
|||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@keyframes slideX3D {
|
||||||
|
0% {
|
||||||
|
transform: translateX(100%) scale(.5);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes slideY3D {
|
||||||
|
0% {
|
||||||
|
transform: translateY(100%) scale(.5);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes rotate {
|
||||||
|
0% {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes scaleY {
|
||||||
|
0% {
|
||||||
|
transform: scaleY(.1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleY(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes scaleX {
|
||||||
|
0% {
|
||||||
|
transform: scaleX(.1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleY(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes scale {
|
||||||
|
0% {
|
||||||
|
transform: scale(.25);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes scaleReverse {
|
||||||
|
0% {
|
||||||
|
transform: scale(2);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -3,7 +3,7 @@
|
|||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
'slide-item',
|
'slide-item',
|
||||||
`turning-mode-${slide.turningMode || 'slideY'}`,
|
`turning-mode-${slide.turningMode}`,
|
||||||
{
|
{
|
||||||
'current': index === slideIndex,
|
'current': index === slideIndex,
|
||||||
'before': index < slideIndex,
|
'before': index < slideIndex,
|
||||||
@ -11,7 +11,7 @@
|
|||||||
'hide': (index === slideIndex - 1 || index === slideIndex + 1) && slide.turningMode !== currentSlide.turningMode,
|
'hide': (index === slideIndex - 1 || index === slideIndex + 1) && slide.turningMode !== currentSlide.turningMode,
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
v-for="(slide, index) in slides"
|
v-for="(slide, index) in slidesWithTurningMode"
|
||||||
:key="slide.id"
|
:key="slide.id"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -40,6 +40,7 @@ import { storeToRefs } from 'pinia'
|
|||||||
import { useSlidesStore } from '@/store'
|
import { useSlidesStore } from '@/store'
|
||||||
import { injectKeySlideScale } from '@/types/injectKey'
|
import { injectKeySlideScale } from '@/types/injectKey'
|
||||||
import { VIEWPORT_SIZE } from '@/configs/canvas'
|
import { VIEWPORT_SIZE } from '@/configs/canvas'
|
||||||
|
import { SLIDE_ANIMATIONS } from '@/configs/animation'
|
||||||
|
|
||||||
import ScreenSlide from './ScreenSlide.vue'
|
import ScreenSlide from './ScreenSlide.vue'
|
||||||
|
|
||||||
@ -53,6 +54,21 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const { slides, slideIndex, currentSlide } = storeToRefs(useSlidesStore())
|
const { slides, slideIndex, currentSlide } = storeToRefs(useSlidesStore())
|
||||||
|
|
||||||
|
const slidesWithTurningMode = computed(() => {
|
||||||
|
return slides.value.map(slide => {
|
||||||
|
let turningMode = slide.turningMode
|
||||||
|
if (!turningMode) turningMode = 'slideY'
|
||||||
|
if (turningMode === 'random') {
|
||||||
|
const turningModeKeys = SLIDE_ANIMATIONS.filter(item => !['random', 'no'].includes(item.value)).map(item => item.value)
|
||||||
|
turningMode = turningModeKeys[Math.floor(Math.random() * turningModeKeys.length)]
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...slide,
|
||||||
|
turningMode,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
const scale = computed(() => props.slideWidth / VIEWPORT_SIZE)
|
const scale = computed(() => props.slideWidth / VIEWPORT_SIZE)
|
||||||
provide(injectKeySlideScale, scale)
|
provide(injectKeySlideScale, scale)
|
||||||
</script>
|
</script>
|
||||||
@ -116,6 +132,70 @@ provide(injectKeySlideScale, scale)
|
|||||||
transform: translateY(100%);
|
transform: translateY(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.turning-mode-slideX3D {
|
||||||
|
transition: transform .5s;
|
||||||
|
&.before {
|
||||||
|
transform: translateX(-100%) scale(.5);
|
||||||
|
}
|
||||||
|
&.after {
|
||||||
|
transform: translateX(100%) scale(.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.turning-mode-slideY3D {
|
||||||
|
transition: transform .5s;
|
||||||
|
&.before {
|
||||||
|
transform: translateY(-100%) scale(.5);
|
||||||
|
}
|
||||||
|
&.after {
|
||||||
|
transform: translateY(100%) scale(.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.turning-mode-rotate {
|
||||||
|
transition: transform .5s;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
&.before {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
&.after {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.turning-mode-scaleY {
|
||||||
|
transition: transform .5s;
|
||||||
|
&.before {
|
||||||
|
transform: scaleY(.1);
|
||||||
|
}
|
||||||
|
&.after {
|
||||||
|
transform: scaleY(.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.turning-mode-scaleX {
|
||||||
|
transition: transform .5s;
|
||||||
|
&.before {
|
||||||
|
transform: scaleX(.1);
|
||||||
|
}
|
||||||
|
&.after {
|
||||||
|
transform: scaleX(.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.turning-mode-scale {
|
||||||
|
transition: transform .5s;
|
||||||
|
&.before {
|
||||||
|
transform: scale(.25);
|
||||||
|
}
|
||||||
|
&.after {
|
||||||
|
transform: scale(.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.turning-mode-scaleReverse {
|
||||||
|
transition: transform .5s;
|
||||||
|
&.before {
|
||||||
|
transform: scale(2);
|
||||||
|
}
|
||||||
|
&.after {
|
||||||
|
transform: scale(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.slide-content {
|
.slide-content {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user