1
0
This commit is contained in:
2025-06-03 13:27:37 +09:00
parent 5b2379716b
commit f337c20096
35 changed files with 4217 additions and 169 deletions

View File

@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Card } from './Card';
import { Card as CardType } from '../types/card';
import { atprotoOAuthService } from '../services/atproto-oauth';
import '../styles/GachaAnimation.css';
interface GachaAnimationProps {
@ -16,12 +17,14 @@ export const GachaAnimation: React.FC<GachaAnimationProps> = ({
onComplete
}) => {
const [phase, setPhase] = useState<'opening' | 'revealing' | 'complete'>('opening');
const [showCard, setShowCard] = useState(false);
const [isSharing, setIsSharing] = useState(false);
useEffect(() => {
const timer1 = setTimeout(() => setPhase('revealing'), 1500);
const timer2 = setTimeout(() => {
setPhase('complete');
onComplete();
setShowCard(true);
}, 3000);
return () => {
@ -30,6 +33,28 @@ export const GachaAnimation: React.FC<GachaAnimationProps> = ({
};
}, [onComplete]);
const handleCardClick = () => {
if (showCard) {
onComplete();
}
};
const handleSaveToCollection = async (e: React.MouseEvent) => {
e.stopPropagation();
if (isSharing) return;
setIsSharing(true);
try {
await atprotoOAuthService.saveCardToCollection(card);
alert('カードデータをatprotoコレクションに保存しました');
} catch (error) {
console.error('保存エラー:', error);
alert('保存に失敗しました。認証が必要かもしれません。');
} finally {
setIsSharing(false);
}
};
const getEffectClass = () => {
switch (animationType) {
case 'unique':
@ -44,7 +69,7 @@ export const GachaAnimation: React.FC<GachaAnimationProps> = ({
};
return (
<div className={`gacha-container ${getEffectClass()}`}>
<div className={`gacha-container ${getEffectClass()}`} onClick={handleCardClick}>
<AnimatePresence mode="wait">
{phase === 'opening' && (
<motion.div
@ -64,13 +89,34 @@ export const GachaAnimation: React.FC<GachaAnimationProps> = ({
{phase === 'revealing' && (
<motion.div
key="revealing"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ duration: 0.5, type: "spring" }}
initial={{ scale: 0, rotateY: 180 }}
animate={{ scale: 1, rotateY: 0 }}
transition={{ duration: 0.8, type: "spring" }}
>
<Card card={card} isRevealing={true} />
</motion.div>
)}
{phase === 'complete' && showCard && (
<motion.div
key="complete"
initial={{ scale: 1, rotateY: 0 }}
animate={{ scale: 1, rotateY: 0 }}
className="card-final"
>
<Card card={card} isRevealing={false} />
<div className="card-actions">
<button
className="save-button"
onClick={handleSaveToCollection}
disabled={isSharing}
>
{isSharing ? '保存中...' : '💾 atprotoに保存'}
</button>
<div className="click-hint"></div>
</div>
</motion.div>
)}
</AnimatePresence>
{animationType === 'unique' && (