Explorar el Código

新增撒花特效

liuziting hace 7 meses
padre
commit
8e23eae7f5
Se han modificado 3 ficheros con 61 adiciones y 10 borrados
  1. 25 0
      package-lock.json
  2. 9 8
      package.json
  3. 27 2
      src/components/RecipeCard.vue

+ 25 - 0
package-lock.json

@@ -10,10 +10,12 @@
             "dependencies": {
                 "@vueuse/core": "^10.7.0",
                 "axios": "^1.6.0",
+                "party-js": "^2.2.0",
                 "vue": "^3.4.0",
                 "vue-router": "^4.2.0"
             },
             "devDependencies": {
+                "@types/node": "^20.0.0",
                 "@vitejs/plugin-vue": "^5.0.0",
                 "autoprefixer": "^10.4.0",
                 "postcss": "^8.4.0",
@@ -865,6 +867,16 @@
             "dev": true,
             "license": "MIT"
         },
+        "node_modules/@types/node": {
+            "version": "20.19.10",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.10.tgz",
+            "integrity": "sha512-iAFpG6DokED3roLSP0K+ybeDdIX6Bc0Vd3mLW5uDqThPWtNos3E+EqOM11mPQHKzfWHqEBuLjIlsBQQ8CsISmQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "undici-types": "~6.21.0"
+            }
+        },
         "node_modules/@types/web-bluetooth": {
             "version": "0.0.20",
             "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
@@ -2251,6 +2263,12 @@
             "dev": true,
             "license": "BlueOak-1.0.0"
         },
+        "node_modules/party-js": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/party-js/-/party-js-2.2.0.tgz",
+            "integrity": "sha512-50hGuALCpvDTrQLPQ1fgUgxKIWAH28ShVkmeK/3zhO0YJyCqkhrZhQEkWPxDYLvbFJ7YAXyROmFEu35gKpZLtQ==",
+            "license": "MIT"
+        },
         "node_modules/path-browserify": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
@@ -2919,6 +2937,13 @@
                 "node": ">=14.17"
             }
         },
+        "node_modules/undici-types": {
+            "version": "6.21.0",
+            "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+            "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/update-browserslist-db": {
             "version": "1.1.3",
             "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",

+ 9 - 8
package.json

@@ -11,19 +11,20 @@
         "type-check": "vue-tsc --noEmit"
     },
     "dependencies": {
-        "vue": "^3.4.0",
-        "vue-router": "^4.2.0",
+        "@vueuse/core": "^10.7.0",
         "axios": "^1.6.0",
-        "@vueuse/core": "^10.7.0"
+        "party-js": "^2.2.0",
+        "vue": "^3.4.0",
+        "vue-router": "^4.2.0"
     },
     "devDependencies": {
+        "@types/node": "^20.0.0",
         "@vitejs/plugin-vue": "^5.0.0",
-        "typescript": "^5.3.0",
-        "vue-tsc": "^1.8.0",
-        "vite": "^5.0.0",
-        "tailwindcss": "^3.4.0",
         "autoprefixer": "^10.4.0",
         "postcss": "^8.4.0",
-        "@types/node": "^20.0.0"
+        "tailwindcss": "^3.4.0",
+        "typescript": "^5.3.0",
+        "vite": "^5.0.0",
+        "vue-tsc": "^1.8.0"
     }
 }

+ 27 - 2
src/components/RecipeCard.vue

@@ -203,8 +203,9 @@
 </template>
 
 <script setup lang="ts">
-import { computed, ref, onUnmounted } from 'vue'
+import { computed, ref, onUnmounted, onMounted } from 'vue'
 import type { Recipe } from '@/types'
+import party from 'party-js'
 import { generateRecipeImage, type GeneratedImage } from '@/services/imageService'
 import { getNutritionAnalysis, getWinePairing } from '@/services/aiService'
 import FavoriteButton from './FavoriteButton.vue'
@@ -268,7 +269,7 @@ const wineLoadingTexts = [
     '完美搭配即将呈现...'
 ]
 
-let imageLoadingInterval: NodeJS.Timeout | null = null
+let imageLoadingInterval: ReturnType<typeof setTimeout> | null = null
 
 const difficultyText = computed(() => {
     const difficultyMap = {
@@ -336,6 +337,30 @@ const generateImage = async () => {
         const { GalleryService } = await import('@/services/galleryService')
         const prompt = `一道精美的${props.recipe.cuisine.replace('大师', '').replace('菜', '')}菜肴:${props.recipe.name}`
         GalleryService.addToGallery(props.recipe, image.url, image.id, prompt)
+
+        // 图片生成成功后触发撒花效果
+        setTimeout(() => {
+            const imgElement = document.querySelector('.recipe-card img') as HTMLElement | null
+            if (imgElement) {
+                try {
+                    console.log('尝试触发撒花效果...')
+                    if (typeof party !== 'undefined') {
+                        party.confetti(imgElement, {
+                            count: party.variation.range(50, 80),
+                            size: party.variation.range(0.8, 1.2),
+                            shapes: ['circle', 'square', 'star'],
+                            spread: 20,
+                            speed: 50
+                        })
+                        console.log('撒花效果已触发')
+                    } else {
+                        console.error('party-js未正确加载')
+                    }
+                } catch (error) {
+                    console.error('撒花效果失败:', error)
+                }
+            }
+        }, 300)
     } catch (error) {
         console.error('生成图片失败:', error)
         imageError.value = '生成图片失败,请稍后重试'