diff --git a/src/App.css b/src/App.css index d5f35e9..9187feb 100644 --- a/src/App.css +++ b/src/App.css @@ -75,15 +75,29 @@ padding: 8px 16px; background: #4caf50; color: white; - border: none; border-radius: 4px; cursor: pointer; + border: 1px solid #d9d9d9; + box-shadow: 0 2px #00000004; + transition: .8s; + opacity: 4; } .action-btn:hover { background: #3d8b40; } +.action-btn:active { + box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.2); + opacity: 0; +} + +.action-btn:active::after { + box-shadow: none; + opacity: 0.4; + transition: 0s; +} + .stop-btn { margin-right: 10px; padding: 8px 16px; diff --git a/src/pages/ElectronicWoodenFish.css b/src/pages/ElectronicWoodenFish.css new file mode 100644 index 0000000..4c15948 --- /dev/null +++ b/src/pages/ElectronicWoodenFish.css @@ -0,0 +1,64 @@ +.dzmy-bg { + background-color: black; + width: 100%; + height: 500px; + display: flex; + flex-direction: column; + justify-content: space-evenly; + position: relative; +} + +.dzmy-count { + position: absolute; + top: 10px; + left: 10px; + color: #ffffff; +} + +.dzmy-img { + width: 160px; + height: 120px; + cursor: pointer; + transition: transform 0.12s ease; + transform: scale(1); +} + +.dzmy-img.active { + transform: scale(0.92); +} + +.dzmy-box { + text-align: center; + position: relative; +} + +.tips { + position: absolute; + top: -50px; + width: 100%; + text-align: center; + pointer-events: none; +} + +.tip-item { + position: absolute; + width: 100%; + animation: floatUp 0.5s ease-out forwards; + color: #fadb14; + font-weight: bold; +} + +@keyframes floatUp { + 0% { + transform: translateY(0); + opacity: 1; + } + 100% { + transform: translateY(-50px); + opacity: 0; + } +} + +.dzmy-controls { + margin-bottom: 10px; +} \ No newline at end of file diff --git a/src/pages/ElectronicWoodenFishPage.js b/src/pages/ElectronicWoodenFishPage.js index 7826446..dc8493c 100644 --- a/src/pages/ElectronicWoodenFishPage.js +++ b/src/pages/ElectronicWoodenFishPage.js @@ -1,32 +1,99 @@ +import React, {useState, useCallback, useEffect} from 'react'; import dzmyImg from '../assets/images/dzmy.png'; -import {useState} from "react"; +import './ElectronicWoodenFish.css'; +import storageAdapter from "../utils/storageAdapter"; const ElectronicWoodenFishPage = () => { const [active, setActive] = useState(false); + const [count, setCount] = useState(0); + const [tipList, setTipList] = useState([]); + const [countName, setCountName] = useState('金钱'); - const clickAnimation = () => { + useEffect(() => { + const init = async () => { + const savedCount = await storageAdapter.get('count'); + const savedCountName = await storageAdapter.get('countName'); + if (savedCount) { + setCount(savedCount); + } else { + await storageAdapter.set('count', 0); + } + if (savedCountName) { + setCountName(savedCountName); + } else { + await storageAdapter.set('countName', '金钱'); + } + } + init(); + }, []); + + const clickAnimation = useCallback(async () => { + // 1. 木鱼缩放动画触发 setActive(true); + setTimeout(() => setActive(false), 100); + + // 2. 更新计数 + setCount((prev) => prev + 1); + + // 3. 生成唯一的 Tip 对象 + const newTip = { + id: Date.now() + Math.random(), // 唯一 ID + value: count + 1 + }; + + // 4. 添加到列表 + setTipList((prev) => [...prev, newTip]); + + // 5. 自动移除:500ms 后删除该特定 Tip setTimeout(() => { - setActive(false); - }, 120); - }; + setTipList((prev) => prev.filter((t) => t.id !== newTip.id)); + }, 500); + + await storageAdapter.set('count', count + 1); + await storageAdapter.set('countName', countName); + }, [count]); - return (