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_TRIGGER = 'click'
|
||||
export const ANIMATION_CLASS_PREFIX = 'animate__'
|
||||
@ -209,4 +211,24 @@ export const ATTENTION_ANIMATIONS = [
|
||||
{ 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 { useSlidesStore } from '@/store'
|
||||
import type { TurningMode } from '@/types/slides'
|
||||
import { SLIDE_ANIMATIONS } from '@/configs/animation'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
import { Button } from 'ant-design-vue'
|
||||
|
||||
interface Animations {
|
||||
label: string
|
||||
value: TurningMode
|
||||
}
|
||||
import { Button, message } from 'ant-design-vue'
|
||||
|
||||
const slidesStore = useSlidesStore()
|
||||
const { slides, currentSlide } = storeToRefs(slidesStore)
|
||||
|
||||
const currentTurningMode = computed(() => currentSlide.value.turningMode || 'slideY')
|
||||
|
||||
const animations: Animations[] = [
|
||||
{ label: '无', value: 'no' },
|
||||
{ label: '淡入淡出', value: 'fade' },
|
||||
{ label: '左右推移', value: 'slideX' },
|
||||
{ label: '上下推移', value: 'slideY' },
|
||||
]
|
||||
const animations = SLIDE_ANIMATIONS
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
@ -60,6 +51,7 @@ const applyAllSlide = () => {
|
||||
}
|
||||
})
|
||||
slidesStore.setSlides(newSlides)
|
||||
message.success('已应用到全部')
|
||||
addHistorySnapshot()
|
||||
}
|
||||
</script>
|
||||
@ -72,14 +64,14 @@ const applyAllSlide = () => {
|
||||
}
|
||||
.animation-item {
|
||||
width: 50%;
|
||||
height: 115px;
|
||||
height: 100px;
|
||||
border: solid 1px #d6d6d6;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 25px 0 15px 0;
|
||||
padding: 20px 0 15px 0;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
@ -103,13 +95,16 @@ const applyAllSlide = () => {
|
||||
overflow: hidden;
|
||||
|
||||
@mixin elAnimation($animationType) {
|
||||
content: '';
|
||||
content: 'Slide';
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: #d9dadb;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
animation: $animationType $transitionDelaySlow linear;
|
||||
}
|
||||
|
||||
@ -128,6 +123,42 @@ const applyAllSlide = () => {
|
||||
@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 {
|
||||
font-size: 12px;
|
||||
@ -159,4 +190,60 @@ const applyAllSlide = () => {
|
||||
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>
|
@ -3,7 +3,7 @@
|
||||
<div
|
||||
:class="[
|
||||
'slide-item',
|
||||
`turning-mode-${slide.turningMode || 'slideY'}`,
|
||||
`turning-mode-${slide.turningMode}`,
|
||||
{
|
||||
'current': index === slideIndex,
|
||||
'before': index < slideIndex,
|
||||
@ -11,7 +11,7 @@
|
||||
'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"
|
||||
>
|
||||
<div
|
||||
@ -40,6 +40,7 @@ import { storeToRefs } from 'pinia'
|
||||
import { useSlidesStore } from '@/store'
|
||||
import { injectKeySlideScale } from '@/types/injectKey'
|
||||
import { VIEWPORT_SIZE } from '@/configs/canvas'
|
||||
import { SLIDE_ANIMATIONS } from '@/configs/animation'
|
||||
|
||||
import ScreenSlide from './ScreenSlide.vue'
|
||||
|
||||
@ -53,6 +54,21 @@ const props = defineProps<{
|
||||
|
||||
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)
|
||||
provide(injectKeySlideScale, scale)
|
||||
</script>
|
||||
@ -116,6 +132,70 @@ provide(injectKeySlideScale, scale)
|
||||
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 {
|
||||
background-color: #fff;
|
||||
|
Loading…
x
Reference in New Issue
Block a user