| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- import React, { useRef } from 'react';
- import { snapdom } from '@zumer/snapdom';
- interface MagicalGirlCardACGProps {
- magicalGirl: {
- codename: string;
- appearance: {
- outfit: string;
- accessories: string;
- colorScheme: string;
- overallLook: string;
- };
- magicWeapon: {
- name: string;
- form: string;
- basicAbilities: string[];
- description: string;
- };
- specialMove: {
- name: string;
- chant: string;
- description: string;
- };
- awakening: {
- name: string;
- evolvedAbilities: string[];
- evolvedForm: string;
- evolvedOutfit: string;
- };
- analysis: {
- personalityAnalysis: string;
- abilityReasoning: string;
- coreTraits: string[];
- predictionBasis: string;
- };
- };
- gradientStyle: string;
- onSaveImage?: (imageUrl: string) => void;
- }
- const MagicalGirlCardACG: React.FC<MagicalGirlCardACGProps> = ({
- magicalGirl,
- gradientStyle,
- onSaveImage
- }) => {
- const resultRef = useRef<HTMLDivElement>(null);
- const handleSaveImage = async () => {
- if (!resultRef.current) return;
- try {
- const saveButton = resultRef.current.querySelector('.save-button') as HTMLElement;
- const logoPlaceholder = resultRef.current.querySelector('.logo-placeholder') as HTMLElement;
- if (saveButton) saveButton.style.display = 'none';
- if (logoPlaceholder) logoPlaceholder.style.display = 'flex';
- const result = await snapdom(resultRef.current, {
- scale: 1,
- });
- if (saveButton) saveButton.style.display = 'block';
- if (logoPlaceholder) logoPlaceholder.style.display = 'none';
- const imgElement = await result.toPng();
- const imageUrl = imgElement.src;
- if (onSaveImage) {
- onSaveImage(imageUrl);
- }
- } catch {
- alert('生成图片失败,请重试');
- const saveButton = resultRef.current?.querySelector('.save-button') as HTMLElement;
- const logoPlaceholder = resultRef.current?.querySelector('.logo-placeholder') as HTMLElement;
- if (saveButton) saveButton.style.display = 'block';
- if (logoPlaceholder) logoPlaceholder.style.display = 'none';
- }
- };
- return (
- <div
- ref={resultRef}
- className="result-card"
- style={{ background: gradientStyle }}
- >
- <div className="result-content">
- <div className="flex justify-center items-center" style={{ marginBottom: '1rem', background: 'transparent' }}>
- <img src="/questionnaire-title.svg" width={300} height={70} alt="Logo" style={{ display: 'block', background: 'transparent' }} />
- </div>
- {/* 基本信息 */}
- <div className="result-item">
- <div className="result-label">💖 魔法少女代号</div>
- <div className="result-value">{magicalGirl.codename}</div>
- </div>
- {/* 外观描述 */}
- <div className="result-item">
- <div className="result-label">🎀 魔法少女外观</div>
- <div className="result-value">
- <div><strong>战斗服:</strong>{magicalGirl.appearance.outfit}</div>
- <div><strong>饰品:</strong>{magicalGirl.appearance.accessories}</div>
- <div><strong>主色调:</strong>{magicalGirl.appearance.colorScheme}</div>
- <div><strong>整体气质:</strong>{magicalGirl.appearance.overallLook}</div>
- </div>
- </div>
- {/* 魔法武器 */}
- <div className="result-item">
- <div className="result-label">🌟 魔法武器</div>
- <div className="result-value">
- <div><strong>名称:</strong>{magicalGirl.magicWeapon.name}</div>
- <div><strong>形态:</strong>{magicalGirl.magicWeapon.form}</div>
- <div><strong>核心能力:</strong></div>
- <ul style={{ marginLeft: '1rem', marginTop: '0.5rem' }}>
- {magicalGirl.magicWeapon.basicAbilities.map((ability: string, index: number) => (
- <li key={index}>✨ {ability}</li>
- ))}
- </ul>
- <div style={{ marginTop: '0.5rem' }}><strong>背景:</strong>{magicalGirl.magicWeapon.description}</div>
- </div>
- </div>
- {/* 必杀技 */}
- <div className="result-item">
- <div className="result-label">🌠 必杀技</div>
- <div className="result-value">
- <div><strong>名称:</strong>{magicalGirl.specialMove.name}</div>
- <div style={{ marginTop: '0.5rem' }}><strong>咏唱:</strong><span style={{ fontStyle: 'italic' }}>「{magicalGirl.specialMove.chant}」</span></div>
- <div style={{ marginTop: '0.5rem' }}><strong>效果:</strong>{magicalGirl.specialMove.description}</div>
- </div>
- </div>
- {/* 觉醒形态 */}
- <div className="result-item">
- <div className="result-label">🌌 觉醒形态</div>
- <div className="result-value">
- <div><strong>形态名称:</strong>{magicalGirl.awakening.name}</div>
- <div><strong>进化能力:</strong></div>
- <ul style={{ marginLeft: '1rem', marginTop: '0.5rem' }}>
- {magicalGirl.awakening.evolvedAbilities.map((ability: string, index: number) => (
- <li key={index}>🌠 {ability}</li>
- ))}
- </ul>
- <div><strong>武器进化:</strong>{magicalGirl.awakening.evolvedForm}</div>
- <div><strong>服装进化:</strong>{magicalGirl.awakening.evolvedOutfit}</div>
- </div>
- </div>
- {/* 综合分析 */}
- <div className="result-item">
- <div className="result-label">🧠 综合分析</div>
- <div className="result-value">
- <div><strong>性格分析:</strong>{magicalGirl.analysis.personalityAnalysis}</div>
- <div><strong>能力设定思路:</strong>{magicalGirl.analysis.abilityReasoning}</div>
- <div><strong>核心萌属性:</strong>{magicalGirl.analysis.coreTraits.join('、')}</div>
- <div><strong>创作依据:</strong>{magicalGirl.analysis.predictionBasis}</div>
- </div>
- </div>
- <button onClick={handleSaveImage} className="save-button">
- 📱 保存为图片
- </button>
- <div className="logo-placeholder" style={{ display: 'none', justifyContent: 'center', marginTop: '1rem' }}>
- <img
- src="/logo-white-qrcode.svg"
- width={320}
- height={80}
- alt="Logo"
- style={{
- display: 'block',
- maxWidth: '100%',
- height: 'auto'
- }}
- />
- </div>
- </div>
- </div>
- );
- };
- export default MagicalGirlCardACG;
|