mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
翻页动画优化、幻灯片背景设置优化
This commit is contained in:
parent
eac6b2fe8a
commit
66ad8c88b5
@ -5,21 +5,27 @@ export default (background: Ref<SlideBackground | undefined>) => {
|
|||||||
const backgroundStyle = computed(() => {
|
const backgroundStyle = computed(() => {
|
||||||
if(!background.value) return { backgroundColor: '#fff' }
|
if(!background.value) return { backgroundColor: '#fff' }
|
||||||
|
|
||||||
const { type, value, size } = background.value
|
const {
|
||||||
if(type === 'solid') return { backgroundColor: value }
|
type,
|
||||||
|
color,
|
||||||
|
image,
|
||||||
|
imageSize,
|
||||||
|
} = background.value
|
||||||
|
|
||||||
|
if(type === 'solid') return { backgroundColor: color }
|
||||||
else if(type === 'image') {
|
else if(type === 'image') {
|
||||||
if(!value) return { backgroundColor: '#fff' }
|
if(!image) return { backgroundColor: '#fff' }
|
||||||
if(size === 'repeat') {
|
if(imageSize === 'repeat') {
|
||||||
return {
|
return {
|
||||||
backgroundImage: `url(${value}`,
|
backgroundImage: `url(${image}`,
|
||||||
backgroundRepeat: 'repeat',
|
backgroundRepeat: 'repeat',
|
||||||
backgroundSize: 'initial',
|
backgroundSize: 'initial',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
backgroundImage: `url(${value}`,
|
backgroundImage: `url(${image}`,
|
||||||
backgroundRepeat: 'no-repeat',
|
backgroundRepeat: 'no-repeat',
|
||||||
backgroundSize: size,
|
backgroundSize: imageSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ export const slides: Slide[] = [
|
|||||||
id: 'xxx1',
|
id: 'xxx1',
|
||||||
background: {
|
background: {
|
||||||
type: 'solid',
|
type: 'solid',
|
||||||
value: '#fff',
|
color: '#fff',
|
||||||
},
|
},
|
||||||
elements: [
|
elements: [
|
||||||
{
|
{
|
||||||
|
@ -162,8 +162,9 @@ export interface PPTAnimation {
|
|||||||
|
|
||||||
export interface SlideBackground {
|
export interface SlideBackground {
|
||||||
type: 'solid' | 'image';
|
type: 'solid' | 'image';
|
||||||
value: string;
|
color?: string;
|
||||||
size?: 'cover' | 'contain' | 'repeat' | 'initial';
|
image?: string;
|
||||||
|
imageSize?: 'cover' | 'contain' | 'repeat' | 'initial';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Slide {
|
export interface Slide {
|
||||||
|
@ -31,7 +31,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const gridColor = computed(() => {
|
const gridColor = computed(() => {
|
||||||
if(!background.value || background.value.type === 'image') return 'rgba(100, 100, 100, 0.5)'
|
if(!background.value || background.value.type === 'image') return 'rgba(100, 100, 100, 0.5)'
|
||||||
const color = background.value.value
|
const color = background.value.color
|
||||||
const rgba = tinycolor(color).toRgb()
|
const rgba = tinycolor(color).toRgb()
|
||||||
const newRgba = {
|
const newRgba = {
|
||||||
r: rgba.r > 128 ? rgba.r - 128 : rgba.r + 127,
|
r: rgba.r > 128 ? rgba.r - 128 : rgba.r + 127,
|
||||||
|
@ -106,34 +106,30 @@ export default defineComponent({
|
|||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&:hover {
|
@mixin elAnimation($animationType) {
|
||||||
animation: no 2s infinite linear;
|
content: '';
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
background-color: #d9dadb;
|
||||||
|
animation: $animationType .3s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.fade:hover {
|
&.fade:hover {
|
||||||
animation: fade 2s infinite linear;
|
&::after {
|
||||||
|
@include elAnimation(fade);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&.slideX:hover {
|
&.slideX:hover {
|
||||||
&::after {
|
&::after {
|
||||||
width: 192px;
|
@include elAnimation(slideX);
|
||||||
height: 100%;
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
background-image: linear-gradient(to right, #666 0%, #666 64px, #d9dadb 64px, #d9dadb 128px, #666 128px, #666 192px);
|
|
||||||
animation: slideX 3s infinite linear;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.slideY:hover {
|
&.slideY:hover {
|
||||||
&::after {
|
&::after {
|
||||||
width: 100%;
|
@include elAnimation(slideY);
|
||||||
height: 108px;
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
background-image: linear-gradient(to bottom, #666 0%, #666 36px, #d9dadb 36px, #d9dadb 72px, #666 72px, #666 108px);
|
|
||||||
animation: slideY 3s infinite linear;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,78 +139,28 @@ export default defineComponent({
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes no {
|
|
||||||
0% {
|
|
||||||
background-color: #666;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
background-color: #666;
|
|
||||||
}
|
|
||||||
51% {
|
|
||||||
background-color: #d9dadb;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
background-color: #d9dadb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes fade {
|
@keyframes fade {
|
||||||
0% {
|
0% {
|
||||||
background-color: #d9dadb;
|
opacity: 0;
|
||||||
}
|
|
||||||
50% {
|
|
||||||
background-color: #666;
|
|
||||||
}
|
|
||||||
51% {
|
|
||||||
background-color: #d9dadb;
|
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
background-color: #666;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@keyframes slideX {
|
@keyframes slideX {
|
||||||
0% {
|
0% {
|
||||||
left: 0;
|
transform: translateX(100%);
|
||||||
}
|
|
||||||
17% {
|
|
||||||
left: -64px;
|
|
||||||
}
|
|
||||||
33% {
|
|
||||||
left: -64px;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
left: -128px;
|
|
||||||
}
|
|
||||||
67% {
|
|
||||||
left: -128px;
|
|
||||||
}
|
|
||||||
84% {
|
|
||||||
left: -192px;
|
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
left: -192px;
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@keyframes slideY {
|
@keyframes slideY {
|
||||||
0% {
|
0% {
|
||||||
top: 0;
|
transform: translateY(100%);
|
||||||
}
|
|
||||||
17% {
|
|
||||||
top: -36px;
|
|
||||||
}
|
|
||||||
33% {
|
|
||||||
top: -36px;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
top: -72px;
|
|
||||||
}
|
|
||||||
67% {
|
|
||||||
top: -72px;
|
|
||||||
}
|
|
||||||
84% {
|
|
||||||
top: -108px;
|
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
top: -108px;
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -14,16 +14,16 @@
|
|||||||
<Popover trigger="click" v-if="background.type === 'solid'">
|
<Popover trigger="click" v-if="background.type === 'solid'">
|
||||||
<template #content>
|
<template #content>
|
||||||
<ColorPicker
|
<ColorPicker
|
||||||
:modelValue="background.value"
|
:modelValue="background.color"
|
||||||
@update:modelValue="value => updateBackground({ value })"
|
@update:modelValue="color => updateBackground({ color })"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<ColorButton :color="background.value" style="flex: 10;" />
|
<ColorButton :color="background.color || '#fff'" style="flex: 10;" />
|
||||||
</Popover>
|
</Popover>
|
||||||
<Select
|
<Select
|
||||||
style="flex: 10;"
|
style="flex: 10;"
|
||||||
:value="background.size || 'cover'"
|
:value="background.size || 'cover'"
|
||||||
@change="value => updateBackground({ size: value })"
|
@change="value => updateBackground({ imageSize: value })"
|
||||||
v-else
|
v-else
|
||||||
>
|
>
|
||||||
<SelectOption value="initial">原始大小</SelectOption>
|
<SelectOption value="initial">原始大小</SelectOption>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<div class="background-image-wrapper" v-if="background.type === 'image'">
|
<div class="background-image-wrapper" v-if="background.type === 'image'">
|
||||||
<FileInput @change="files => uploadBackgroundImage(files)">
|
<FileInput @change="files => uploadBackgroundImage(files)">
|
||||||
<div class="background-image">
|
<div class="background-image">
|
||||||
<div class="content" :style="{ backgroundImage: `url(${background.value})` }">
|
<div class="content" :style="{ backgroundImage: `url(${background.image})` }">
|
||||||
<IconPlus />
|
<IconPlus />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -79,19 +79,21 @@ export default defineComponent({
|
|||||||
|
|
||||||
const updateBackgroundType = (type: 'solid' | 'image') => {
|
const updateBackgroundType = (type: 'solid' | 'image') => {
|
||||||
if(type === 'solid') {
|
if(type === 'solid') {
|
||||||
const background: SlideBackground = {
|
const newBackground: SlideBackground = {
|
||||||
|
...background.value,
|
||||||
type: 'solid',
|
type: 'solid',
|
||||||
value: '#fff',
|
color: background.value.color || '#fff',
|
||||||
}
|
}
|
||||||
store.commit(MutationTypes.UPDATE_SLIDE, { background })
|
store.commit(MutationTypes.UPDATE_SLIDE, { background: newBackground })
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const background: SlideBackground = {
|
const newBackground: SlideBackground = {
|
||||||
|
...background.value,
|
||||||
type: 'image',
|
type: 'image',
|
||||||
value: '',
|
image: background.value.image || '',
|
||||||
size: 'cover',
|
imageSize: background.value.imageSize || 'cover',
|
||||||
}
|
}
|
||||||
store.commit(MutationTypes.UPDATE_SLIDE, { background })
|
store.commit(MutationTypes.UPDATE_SLIDE, { background: newBackground })
|
||||||
}
|
}
|
||||||
addHistorySnapshot()
|
addHistorySnapshot()
|
||||||
}
|
}
|
||||||
@ -104,7 +106,7 @@ export default defineComponent({
|
|||||||
const uploadBackgroundImage = (files: File[]) => {
|
const uploadBackgroundImage = (files: File[]) => {
|
||||||
const imageFile = files[0]
|
const imageFile = files[0]
|
||||||
if(!imageFile) return
|
if(!imageFile) return
|
||||||
getImageDataURL(imageFile).then(dataURL => updateBackground({ value: dataURL }))
|
getImageDataURL(imageFile).then(dataURL => updateBackground({ image: dataURL }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const applyAllSlide = () => {
|
const applyAllSlide = () => {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
'current': index === slideIndex,
|
'current': index === slideIndex,
|
||||||
'before': index < slideIndex,
|
'before': index < slideIndex,
|
||||||
'after': index > slideIndex,
|
'after': index > slideIndex,
|
||||||
|
'hide': (index === slideIndex - 1 || index === slideIndex + 1) && slide.turningMode !== currentSlide.turningMode,
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
v-for="(slide, index) in slides"
|
v-for="(slide, index) in slides"
|
||||||
@ -224,6 +225,7 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
slides,
|
slides,
|
||||||
slideIndex,
|
slideIndex,
|
||||||
|
currentSlide,
|
||||||
slideWidth,
|
slideWidth,
|
||||||
slideHeight,
|
slideHeight,
|
||||||
scale,
|
scale,
|
||||||
@ -264,6 +266,10 @@ export default defineComponent({
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.hide {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&.turning-mode-no {
|
&.turning-mode-no {
|
||||||
&.before {
|
&.before {
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user