Skip to content

Commit 4e45ae1

Browse files
author
root
committed
6.8. Задание: добавление анимаций в проект Vue-Pizza
Реализованы три типа анимаций: 1. Fade анимация - для всплывающих окон и уведомлений 2. Slide анимация - для переходов между маршрутами 3. Scale анимация - для добавления ингредиентов в пиццу Изменения: - Создан файл transitions.scss с CSS-анимациями - Добавлена анимация переходов между маршрутами в App.vue - Добавлена fade-анимация для уведомления drag-and-drop в HomeView - Добавлена scale-анимация для ингредиентов в PizzaCanvas - Добавлена list-анимация для списка ингредиентов в IngredientsStep - Исправлена проблема дублирования данных в БД - Добавлена защита от параллельных загрузок данных - Удалены избыточные комментарии и отладочные логи
1 parent f492153 commit 4e45ae1

File tree

7 files changed

+143
-40
lines changed

7 files changed

+143
-40
lines changed

frontend/src/App.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
<template>
2-
<RouterView />
2+
<RouterView v-slot="{ Component, route }">
3+
<Transition name="slide" mode="out-in">
4+
<component :is="Component" :key="route.path" />
5+
</Transition>
6+
</RouterView>
37
</template>
48

59
<style lang="scss">
610
@use "@/assets/scss/ds-system/ds-colors";
711
@use "@/assets/scss/ds-system/ds-shadows";
812
@use "@/assets/scss/ds-system/ds-typography";
913
@import "@/assets/scss/app.scss";
14+
@import "@/assets/styles/transitions.scss";
1015
1116
body {
1217
justify-content: center;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
.fade-enter-active,
2+
.fade-leave-active {
3+
transition: opacity 0.3s ease;
4+
}
5+
6+
.fade-enter-from,
7+
.fade-leave-to {
8+
opacity: 0;
9+
}
10+
11+
.slide-enter-active,
12+
.slide-leave-active {
13+
transition: all 0.3s ease;
14+
}
15+
16+
.slide-enter-from {
17+
opacity: 0;
18+
transform: translateX(30px);
19+
}
20+
21+
.slide-leave-to {
22+
opacity: 0;
23+
transform: translateX(-30px);
24+
}
25+
26+
.scale-enter-active {
27+
transition: all 0.3s ease;
28+
}
29+
30+
.scale-enter-from {
31+
opacity: 0;
32+
transform: scale(0.5);
33+
}
34+
35+
.scale-leave-active {
36+
transition: all 0.2s ease;
37+
}
38+
39+
.scale-leave-to {
40+
opacity: 0;
41+
transform: scale(0.8);
42+
}
43+
44+
.list-enter-active,
45+
.list-leave-active {
46+
transition: all 0.3s ease;
47+
}
48+
49+
.list-enter-from {
50+
opacity: 0;
51+
transform: translateY(-10px);
52+
}
53+
54+
.list-leave-to {
55+
opacity: 0;
56+
transform: translateY(10px);
57+
}
58+
59+
.list-move {
60+
transition: transform 0.3s ease;
61+
}
62+

frontend/src/modules/constructor/IngredientsStep.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class="ingredients__drop-zone"
1010
@drop="handleIngredientDrop"
1111
>
12-
<ul class="ingredients__list">
12+
<TransitionGroup name="list" tag="ul" class="ingredients__list">
1313
<li v-for="ingredient in availableIngredients" :key="ingredient.id">
1414
<AppDrag
1515
:data="ingredient"
@@ -25,7 +25,7 @@
2525
/>
2626
</AppDrag>
2727
</li>
28-
</ul>
28+
</TransitionGroup>
2929

3030
<div v-if="isDragActive" class="drop-hint">
3131
Перетащите ингредиенты на пиццу или используйте счетчики

frontend/src/modules/constructor/PizzaCanvas.vue

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,27 @@
2222
<div :class="['pizza', getPizzaFoundationClass()]">
2323
<div class="pizza__wrapper">
2424
<!-- Отображаем ингредиенты на пицце -->
25-
<div
26-
v-for="ingredient in visibleIngredients"
27-
:key="`${ingredient.id}-${ingredient.count}`"
28-
:class="[
29-
'pizza__filling',
30-
`pizza__filling--${ingredient.cssClass}`,
31-
getIngredientModifier(ingredient.count),
32-
]"
33-
/>
25+
<TransitionGroup name="scale">
26+
<div
27+
v-for="ingredient in visibleIngredients"
28+
:key="`${ingredient.id}-${ingredient.count}`"
29+
:class="[
30+
'pizza__filling',
31+
`pizza__filling--${ingredient.cssClass}`,
32+
getIngredientModifier(ingredient.count),
33+
]"
34+
/>
35+
</TransitionGroup>
3436
</div>
3537
</div>
3638

3739
<!-- Подсказка при перетаскивании -->
38-
<div v-if="isDragOver" class="drop-hint">
39-
<span v-if="isValidDrop">Отпустите, чтобы добавить ингредиент</span>
40-
<span v-else>Этот ингредиент нельзя добавить на пиццу</span>
41-
</div>
40+
<Transition name="fade">
41+
<div v-if="isDragOver" class="drop-hint">
42+
<span v-if="isValidDrop">Отпустите, чтобы добавить ингредиент</span>
43+
<span v-else>Этот ингредиент нельзя добавить на пиццу</span>
44+
</div>
45+
</Transition>
4246
</AppDrop>
4347
</div>
4448

frontend/src/stores/cart.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ export const useCartStore = defineStore('cart', {
121121
this.misc = response.data
122122
} catch (error) {
123123
console.error('Ошибка загрузки дополнительных товаров:', error)
124-
this.misc = []
124+
const miscData = await import('@/mocks/misc.json')
125+
this.misc = miscData.default
125126
}
126127
},
127128

frontend/src/stores/pizza.js

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ export const usePizzaStore = defineStore('pizza', {
2525
],
2626

2727
loading: false,
28-
error: null
28+
error: null,
29+
30+
dataLoaded: false,
31+
32+
loadingPromise: null
2933
}),
3034

3135
getters: {
@@ -158,28 +162,53 @@ export const usePizzaStore = defineStore('pizza', {
158162

159163
actions: {
160164
async loadConstructorData() {
165+
if (this.loadingPromise) {
166+
return this.loadingPromise
167+
}
168+
169+
if (this.dataLoaded) {
170+
return
171+
}
172+
161173
this.loading = true
162174
this.error = null
163175

164-
try {
165-
const [sizesRes, doughsRes, saucesRes, ingredientsRes] = await Promise.all([
166-
sizesService.getAll(),
167-
doughService.getAll(),
168-
saucesService.getAll(),
169-
ingredientsService.getAll()
170-
])
171-
172-
this.sizes = sizesRes.data
173-
this.doughs = doughsRes.data
174-
this.sauces = saucesRes.data
175-
this.ingredients = ingredientsRes.data
176-
177-
} catch (error) {
178-
this.error = error.response?.data?.message || error.message
179-
console.error('Ошибка загрузки данных конструктора:', error)
180-
} finally {
181-
this.loading = false
182-
}
176+
this.loadingPromise = (async () => {
177+
try {
178+
const [sizesRes, doughsRes, saucesRes, ingredientsRes] = await Promise.all([
179+
sizesService.getAll(),
180+
doughService.getAll(),
181+
saucesService.getAll(),
182+
ingredientsService.getAll()
183+
])
184+
185+
this.sizes = sizesRes.data
186+
this.doughs = doughsRes.data
187+
this.sauces = saucesRes.data
188+
this.ingredients = ingredientsRes.data
189+
this.dataLoaded = true
190+
191+
} catch (error) {
192+
this.error = error.response?.data?.message || error.message
193+
console.error('Ошибка загрузки данных конструктора:', error)
194+
195+
const doughData = await import('@/mocks/dough.json')
196+
const sizesData = await import('@/mocks/sizes.json')
197+
const saucesData = await import('@/mocks/sauces.json')
198+
const ingredientsData = await import('@/mocks/ingredients.json')
199+
200+
this.doughs = doughData.default
201+
this.sizes = sizesData.default
202+
this.sauces = saucesData.default
203+
this.ingredients = ingredientsData.default
204+
this.dataLoaded = true
205+
} finally {
206+
this.loading = false
207+
this.loadingPromise = null
208+
}
209+
})()
210+
211+
return this.loadingPromise
183212
},
184213

185214
setPizzaName(name) {

frontend/src/views/HomeView.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@
6060
</form>
6161

6262
<!-- Уведомление о drag-and-drop -->
63-
<div v-if="isDraggingIngredient" class="drag-notification">
64-
<p>💫 Перетащите ингредиент на пиццу для добавления</p>
65-
</div>
63+
<Transition name="fade">
64+
<div v-if="isDraggingIngredient" class="drag-notification">
65+
<p>💫 Перетащите ингредиент на пиццу для добавления</p>
66+
</div>
67+
</Transition>
6668

6769
<!-- Debug панель (только в development) -->
6870
<div v-if="showDebugInfo" class="debug-panel">

0 commit comments

Comments
 (0)