sa2kit 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{UniversalFileService-CEZRJ87g.d.mts → UniversalFileService-BuHN-jrR.d.ts} +47 -259
- package/dist/{UniversalFileService-CEZRJ87g.d.ts → UniversalFileService-CGGzYeeF.d.mts} +47 -259
- package/dist/{chunk-3XG5OHFD.mjs → chunk-CIVO4R6N.mjs} +2 -2
- package/dist/{chunk-3XG5OHFD.mjs.map → chunk-CIVO4R6N.mjs.map} +1 -1
- package/dist/chunk-EV6BCVOQ.mjs +204 -0
- package/dist/chunk-EV6BCVOQ.mjs.map +1 -0
- package/dist/chunk-W35VTQAW.js +211 -0
- package/dist/chunk-W35VTQAW.js.map +1 -0
- package/dist/{chunk-HWJ34NL6.js → chunk-ZRAW3HXA.js} +2 -2
- package/dist/{chunk-HWJ34NL6.js.map → chunk-ZRAW3HXA.js.map} +1 -1
- package/dist/drizzle-schema-BNhqj2AZ.d.mts +1114 -0
- package/dist/drizzle-schema-BNhqj2AZ.d.ts +1114 -0
- package/dist/mmd/admin/index.d.mts +487 -0
- package/dist/mmd/admin/index.d.ts +487 -0
- package/dist/mmd/admin/index.js +871 -0
- package/dist/mmd/admin/index.js.map +1 -0
- package/dist/mmd/admin/index.mjs +822 -0
- package/dist/mmd/admin/index.mjs.map +1 -0
- package/dist/mmd/index.d.mts +4 -193
- package/dist/mmd/index.d.ts +4 -193
- package/dist/mmd/server/index.d.mts +138 -0
- package/dist/mmd/server/index.d.ts +138 -0
- package/dist/mmd/server/index.js +245 -0
- package/dist/mmd/server/index.js.map +1 -0
- package/dist/mmd/server/index.mjs +207 -0
- package/dist/mmd/server/index.mjs.map +1 -0
- package/dist/testYourself/index.d.mts +145 -0
- package/dist/testYourself/index.d.ts +145 -0
- package/dist/testYourself/index.js +1004 -0
- package/dist/testYourself/index.js.map +1 -0
- package/dist/testYourself/index.mjs +993 -0
- package/dist/testYourself/index.mjs.map +1 -0
- package/dist/types-Bc_p-zAR.d.mts +194 -0
- package/dist/types-Bc_p-zAR.d.ts +194 -0
- package/dist/types-CK4We_aI.d.mts +270 -0
- package/dist/types-CK4We_aI.d.ts +270 -0
- package/dist/universalFile/index.d.mts +3 -2
- package/dist/universalFile/index.d.ts +3 -2
- package/dist/universalFile/index.js +48 -10
- package/dist/universalFile/index.js.map +1 -1
- package/dist/universalFile/index.mjs +43 -5
- package/dist/universalFile/index.mjs.map +1 -1
- package/dist/universalFile/server/index.d.mts +3 -2
- package/dist/universalFile/server/index.d.ts +3 -2
- package/dist/universalFile/server/index.js +239 -7
- package/dist/universalFile/server/index.js.map +1 -1
- package/dist/universalFile/server/index.mjs +234 -2
- package/dist/universalFile/server/index.mjs.map +1 -1
- package/package.json +19 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/testYourself/utils/fingerprint.ts","../../src/testYourself/data/defaultResults.ts","../../src/testYourself/components/TestYourself.tsx"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * 设备指纹生成工具\n * Device Fingerprint Generator\n */\n\nimport type { DeviceFingerprint } from '../types';\n\n/**\n * 生成Canvas指纹\n */\nfunction getCanvasFingerprint(): string {\n try {\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) return 'no-canvas';\n\n canvas.width = 200;\n canvas.height = 50;\n\n // 绘制文字\n ctx.textBaseline = 'top';\n ctx.font = '14px Arial';\n ctx.fillStyle = '#f60';\n ctx.fillRect(0, 0, 200, 50);\n ctx.fillStyle = '#069';\n ctx.fillText('Canvas Fingerprint 🎨', 2, 15);\n\n // 转换为数据URL\n return canvas.toDataURL();\n } catch (error) {\n return 'canvas-error';\n }\n}\n\n/**\n * 生成WebGL指纹\n */\nfunction getWebGLFingerprint(): string {\n try {\n const canvas = document.createElement('canvas');\n const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n if (!gl) return 'no-webgl';\n\n const glContext = gl as WebGLRenderingContext;\n const debugInfo = glContext.getExtension('WEBGL_debug_renderer_info');\n \n if (debugInfo) {\n const vendor = glContext.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);\n const renderer = glContext.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);\n return `${vendor}~${renderer}`;\n }\n\n return 'webgl-no-debug';\n } catch (error) {\n return 'webgl-error';\n }\n}\n\n/**\n * 检测可用字体\n */\nfunction getAvailableFonts(): string {\n const testFonts = [\n 'Arial', 'Verdana', 'Courier New', 'Georgia', 'Times New Roman',\n 'Comic Sans MS', 'Trebuchet MS', 'Arial Black', 'Impact',\n 'Courier', 'Helvetica', 'Monaco', 'Consolas', 'Menlo'\n ];\n \n const availableFonts: string[] = [];\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n \n if (!ctx) return 'no-fonts';\n\n const baseFonts = ['monospace', 'sans-serif', 'serif'];\n const testString = 'mmmmmmmmmmlli';\n const baseWidths: { [key: string]: number } = {};\n\n // 获取基础字体宽度\n baseFonts.forEach(font => {\n ctx.font = `72px ${font}`;\n baseWidths[font] = ctx.measureText(testString).width;\n });\n\n // 测试每个字体\n testFonts.forEach(font => {\n let detected = false;\n baseFonts.forEach(baseFont => {\n ctx.font = `72px ${font}, ${baseFont}`;\n const width = ctx.measureText(testString).width;\n if (width !== baseWidths[baseFont]) {\n detected = true;\n }\n });\n if (detected) {\n availableFonts.push(font);\n }\n });\n\n return availableFonts.join(',') || 'no-custom-fonts';\n}\n\n/**\n * 获取设备指纹信息(增强版)\n */\nexport function getDeviceFingerprint(): DeviceFingerprint {\n const fingerprint: DeviceFingerprint = {\n // 基础信息\n userAgent: navigator.userAgent,\n screenResolution: `${window.screen.width}x${window.screen.height}`,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n language: navigator.language,\n platform: navigator.platform,\n\n // 显示信息\n colorDepth: window.screen.colorDepth,\n devicePixelRatio: window.devicePixelRatio,\n\n // 硬件信息\n hardwareConcurrency: navigator.hardwareConcurrency || 0,\n maxTouchPoints: navigator.maxTouchPoints || 0,\n\n // Canvas和WebGL指纹\n canvasFingerprint: getCanvasFingerprint(),\n webglFingerprint: getWebGLFingerprint(),\n\n // 字体检测\n fonts: getAvailableFonts(),\n\n // 浏览器能力\n cookieEnabled: navigator.cookieEnabled,\n localStorageEnabled: (() => {\n try {\n return typeof localStorage !== 'undefined';\n } catch {\n return false;\n }\n })(),\n sessionStorageEnabled: (() => {\n try {\n return typeof sessionStorage !== 'undefined';\n } catch {\n return false;\n }\n })(),\n indexedDBEnabled: (() => {\n try {\n return typeof indexedDB !== 'undefined';\n } catch {\n return false;\n }\n })(),\n };\n\n return fingerprint;\n}\n\n/**\n * 尝试获取IP地址\n * 注意:由于浏览器安全限制,直接获取IP地址需要外部API\n */\nexport async function tryGetIPAddress(): Promise<string | null> {\n try {\n // 尝试使用公共API获取IP\n // 注意:这需要CORS支持,实际使用时可能需要配置\n const response = await fetch('https://api.ipify.org?format=json', {\n method: 'GET',\n mode: 'cors',\n });\n \n if (response.ok) {\n const data = await response.json();\n return data.ip || null;\n }\n } catch (error) {\n console.warn('无法获取IP地址:', error);\n }\n \n return null;\n}\n\n/**\n * 简单的哈希函数 (DJB2算法)\n */\nfunction simpleHash(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) + str.charCodeAt(i);\n }\n return Math.abs(hash);\n}\n\n/**\n * 生成设备唯一标识\n * @param fingerprint 设备指纹\n * @param salt 盐值\n * @returns 唯一标识哈希值\n */\nexport function generateDeviceHash(\n fingerprint: DeviceFingerprint,\n salt: string = 'test-yourself-salt-2024'\n): string {\n // 组合所有指纹信息(包含新增的特征)\n const components = [\n // 基础信息\n fingerprint.userAgent,\n fingerprint.ip || 'no-ip',\n fingerprint.screenResolution,\n fingerprint.timezone,\n fingerprint.language,\n fingerprint.platform,\n \n // 显示信息\n fingerprint.colorDepth?.toString() || '0',\n fingerprint.devicePixelRatio?.toString() || '0',\n \n // 硬件信息\n fingerprint.hardwareConcurrency?.toString() || '0',\n fingerprint.maxTouchPoints?.toString() || '0',\n \n // Canvas和WebGL指纹(这些是最独特的)\n fingerprint.canvasFingerprint || 'no-canvas',\n fingerprint.webglFingerprint || 'no-webgl',\n \n // 字体(不同设备安装的字体不同)\n fingerprint.fonts || 'no-fonts',\n \n // 浏览器能力\n fingerprint.cookieEnabled ? '1' : '0',\n fingerprint.localStorageEnabled ? '1' : '0',\n fingerprint.sessionStorageEnabled ? '1' : '0',\n fingerprint.indexedDBEnabled ? '1' : '0',\n \n // 盐值\n salt,\n ];\n\n // 拼接并生成哈希\n const combined = components.join('|');\n const hash = simpleHash(combined);\n \n return hash.toString(36); // 转换为36进制字符串\n}\n\n/**\n * 根据哈希值选择结果索引\n * @param hash 设备哈希值\n * @param totalResults 总结果数\n * @returns 结果索引 (0 到 totalResults-1)\n */\nexport function selectResultIndex(hash: string, totalResults: number): number {\n const numHash = parseInt(hash, 36);\n return numHash % totalResults;\n}\n\n\n\n","/**\n * 默认测试结果数据\n * Default Test Results Data\n * \n * 包含45个预设结果\n */\n\nimport type { TestResult } from '../types';\n\nexport const DEFAULT_RESULTS: TestResult[] = [\n // 动物系列 (1-15)\n {\n id: 'animal-cat',\n title: '慵懒的猫咪 🐱',\n description: '你就像一只优雅的猫,独立自主,喜欢按照自己的节奏生活。有时高冷,有时粘人,充满神秘魅力。',\n image: '🐱',\n imageType: 'emoji',\n },\n {\n id: 'animal-dog',\n title: '忠诚的狗狗 🐕',\n description: '你像一只热情的狗狗,对朋友忠诚,充满活力。总是能给周围的人带来欢乐和温暖。',\n image: '🐕',\n imageType: 'emoji',\n },\n {\n id: 'animal-panda',\n title: '可爱的熊猫 🐼',\n description: '你就像国宝熊猫一样,呆萌可爱,人见人爱。慢节奏的生活方式让你充满治愈力。',\n image: '🐼',\n imageType: 'emoji',\n },\n {\n id: 'animal-fox',\n title: '机智的狐狸 🦊',\n description: '聪明伶俐,反应敏捷。你总能用智慧解决问题,是团队中的智囊担当。',\n image: '🦊',\n imageType: 'emoji',\n },\n {\n id: 'animal-owl',\n title: '睿智的猫头鹰 🦉',\n description: '你像猫头鹰一样充满智慧,喜欢在夜深人静时思考。理性、沉稳是你的标签。',\n image: '🦉',\n imageType: 'emoji',\n },\n {\n id: 'animal-dolphin',\n title: '快乐的海豚 🐬',\n description: '活泼开朗,社交达人。你的笑容能够感染身边的每一个人。',\n image: '🐬',\n imageType: 'emoji',\n },\n {\n id: 'animal-butterfly',\n title: '自由的蝴蝶 🦋',\n description: '追求自由,热爱美好事物。你的人生充满色彩,从不被束缚。',\n image: '🦋',\n imageType: 'emoji',\n },\n {\n id: 'animal-lion',\n title: '勇敢的狮子 🦁',\n description: '天生的领导者,勇敢果断。你的气场强大,总能激励他人。',\n image: '🦁',\n imageType: 'emoji',\n },\n {\n id: 'animal-rabbit',\n title: '温柔的兔子 🐰',\n description: '心地善良,温柔体贴。你的存在就像春天的微风,让人感到温暖。',\n image: '🐰',\n imageType: 'emoji',\n },\n {\n id: 'animal-penguin',\n title: '呆萌的企鹅 🐧',\n description: '憨态可掬,认真执着。虽然看起来笨拙,但做事一丝不苟。',\n image: '🐧',\n imageType: 'emoji',\n },\n {\n id: 'animal-eagle',\n title: '翱翔的雄鹰 🦅',\n description: '目光远大,志向高远。你总是能看到别人看不到的机会。',\n image: '🦅',\n imageType: 'emoji',\n },\n {\n id: 'animal-koala',\n title: '慵懒的考拉 🐨',\n description: '佛系生活,知足常乐。你懂得享受当下,活在自己的节奏里。',\n image: '🐨',\n imageType: 'emoji',\n },\n {\n id: 'animal-sloth',\n title: '悠闲的树懒 🦥',\n description: '慢慢来,比较快。你相信急不来的事就不要急,保持自己的pace。',\n image: '🦥',\n imageType: 'emoji',\n },\n {\n id: 'animal-unicorn',\n title: '梦幻的独角兽 🦄',\n description: '充满幻想,追求完美。你的世界五彩斑斓,总有独特的想法。',\n image: '🦄',\n imageType: 'emoji',\n },\n {\n id: 'animal-dragon',\n title: '神秘的龙 🐉',\n description: '强大而神秘,充满魅力。你是传说中的存在,令人向往。',\n image: '🐉',\n imageType: 'emoji',\n },\n\n // 星球系列 (16-25)\n {\n id: 'planet-sun',\n title: '温暖的太阳 ☀️',\n description: '你就像太阳一样,是团队的能量来源,温暖着周围的每个人。',\n image: '☀️',\n imageType: 'emoji',\n },\n {\n id: 'planet-moon',\n title: '温柔的月亮 🌙',\n description: '安静而温柔,在黑暗中给人光明。你是夜晚最美的陪伴。',\n image: '🌙',\n imageType: 'emoji',\n },\n {\n id: 'planet-star',\n title: '闪耀的星星 ⭐',\n description: '虽然渺小,但始终闪耀。你用自己的方式发光发热。',\n image: '⭐',\n imageType: 'emoji',\n },\n {\n id: 'planet-earth',\n title: '包容的地球 🌍',\n description: '包容万物,生机勃勃。你有着宽广的胸怀和无限的可能。',\n image: '🌍',\n imageType: 'emoji',\n },\n {\n id: 'planet-saturn',\n title: '独特的土星 🪐',\n description: '与众不同,自成一格。你的个性就像土星环一样令人着迷。',\n image: '🪐',\n imageType: 'emoji',\n },\n {\n id: 'weather-rainbow',\n title: '绚丽的彩虹 🌈',\n description: '风雨过后见彩虹,你总能在困难后看到希望和美好。',\n image: '🌈',\n imageType: 'emoji',\n },\n {\n id: 'weather-cloud',\n title: '飘逸的云朵 ☁️',\n description: '自由自在,随风飘荡。你不被定义,永远充满可能。',\n image: '☁️',\n imageType: 'emoji',\n },\n {\n id: 'weather-lightning',\n title: '闪电 ⚡',\n description: '爆发力强,行动迅速。你的能量就像闪电一样令人震撼。',\n image: '⚡',\n imageType: 'emoji',\n },\n {\n id: 'weather-snowflake',\n title: '独特的雪花 ❄️',\n description: '世界上没有两片相同的雪花,你也是独一无二的存在。',\n image: '❄️',\n imageType: 'emoji',\n },\n {\n id: 'weather-fire',\n title: '热情的火焰 🔥',\n description: '热情似火,充满激情。你的存在能点燃周围的气氛。',\n image: '🔥',\n imageType: 'emoji',\n },\n\n // 植物系列 (26-35)\n {\n id: 'plant-tree',\n title: '坚韧的大树 🌳',\n description: '稳重可靠,根基深厚。你是大家可以依靠的存在。',\n image: '🌳',\n imageType: 'emoji',\n },\n {\n id: 'plant-flower',\n title: '美丽的花朵 🌸',\n description: '绽放自我,美丽动人。你的存在就是一道靓丽的风景。',\n image: '🌸',\n imageType: 'emoji',\n },\n {\n id: 'plant-sunflower',\n title: '向阳的向日葵 🌻',\n description: '永远向着阳光,积极向上。你的乐观感染着每个人。',\n image: '🌻',\n imageType: 'emoji',\n },\n {\n id: 'plant-rose',\n title: '优雅的玫瑰 🌹',\n description: '高贵优雅,充满魅力。虽有刺但更有美丽。',\n image: '🌹',\n imageType: 'emoji',\n },\n {\n id: 'plant-cactus',\n title: '坚强的仙人掌 🌵',\n description: '在艰难环境中依然坚强。你的韧性令人敬佩。',\n image: '🌵',\n imageType: 'emoji',\n },\n {\n id: 'plant-clover',\n title: '幸运的四叶草 🍀',\n description: '幸运的象征,总能给人带来好运和希望。',\n image: '🍀',\n imageType: 'emoji',\n },\n {\n id: 'plant-maple',\n title: '浪漫的枫叶 🍁',\n description: '浪漫而诗意,你的世界充满艺术气息。',\n image: '🍁',\n imageType: 'emoji',\n },\n {\n id: 'plant-mushroom',\n title: '神秘的蘑菇 🍄',\n description: '低调神秘,总有意想不到的惊喜。',\n image: '🍄',\n imageType: 'emoji',\n },\n {\n id: 'plant-cherry',\n title: '浪漫的樱花 🌸',\n description: '短暂而美好,你珍惜每一个瞬间的美丽。',\n image: '🌸',\n imageType: 'emoji',\n },\n {\n id: 'plant-bamboo',\n title: '坚韧的竹子 🎋',\n description: '虚心有节,愈挫愈勇。你的精神值得学习。',\n image: '🎋',\n imageType: 'emoji',\n },\n\n // 食物系列 (36-45)\n {\n id: 'food-coffee',\n title: '提神的咖啡 ☕',\n description: '你就像咖啡,是大家的能量来源,帮助他人保持活力。',\n image: '☕',\n imageType: 'emoji',\n },\n {\n id: 'food-pizza',\n title: '快乐的披萨 🍕',\n description: '人见人爱,总能带来快乐。你是聚会的灵魂。',\n image: '🍕',\n imageType: 'emoji',\n },\n {\n id: 'food-cookie',\n title: '甜蜜的饼干 🍪',\n description: '温暖甜蜜,给人comfort。你是最好的治愈系存在。',\n image: '🍪',\n imageType: 'emoji',\n },\n {\n id: 'food-icecream',\n title: '清凉的冰淇淋 🍦',\n description: '甜美可爱,在炎热时给人清凉。你总能在关键时刻出现。',\n image: '🍦',\n imageType: 'emoji',\n },\n {\n id: 'food-honey',\n title: '甜蜜的蜂蜜 🍯',\n description: '天然甜美,纯粹可爱。你的存在就是幸福的味道。',\n image: '🍯',\n imageType: 'emoji',\n },\n {\n id: 'food-sushi',\n title: '精致的寿司 🍣',\n description: '精致优雅,注重细节。你对生活有着独特的品味。',\n image: '🍣',\n imageType: 'emoji',\n },\n {\n id: 'food-cake',\n title: '甜美的蛋糕 🎂',\n description: '甜蜜美好,是庆祝的象征。你总能给人带来惊喜。',\n image: '🎂',\n imageType: 'emoji',\n },\n {\n id: 'food-donut',\n title: '可爱的甜甜圈 🍩',\n description: '圆圆满满,甜蜜可爱。你的存在让生活更美好。',\n image: '🍩',\n imageType: 'emoji',\n },\n {\n id: 'food-lollipop',\n title: '童真的棒棒糖 🍭',\n description: '保持童心,永远年轻。你的纯真令人羡慕。',\n image: '🍭',\n imageType: 'emoji',\n },\n {\n id: 'food-watermelon',\n title: '清爽的西瓜 🍉',\n description: '清爽解渴,夏日必备。你总能带来清新的感觉。',\n image: '🍉',\n imageType: 'emoji',\n },\n];\n\n// 验证数据集长度\nif (DEFAULT_RESULTS.length !== 45) {\n console.warn(`结果数据集应包含45项,当前: ${DEFAULT_RESULTS.length}`);\n}\n\n\n\n","/**\n * 测测你是什么 - 主组件\n * Test Yourself Game - Main Component\n */\n\n'use client';\n\nimport React, { useState, useEffect, useRef } from 'react';\nimport type { TestYourselfProps, TestResult, TestStatus, DeviceFingerprint } from '../types';\nimport { \n getDeviceFingerprint, \n tryGetIPAddress, \n generateDeviceHash, \n selectResultIndex \n} from '../utils/fingerprint';\nimport { DEFAULT_RESULTS } from '../data/defaultResults';\n\nconst STORAGE_KEY = 'test-yourself-result';\n\nexport const TestYourself: React.FC<TestYourselfProps> = ({\n config,\n onResult,\n className = '',\n}) => {\n const {\n gameTitle,\n gameDescription,\n buttonText = '长按开始测试',\n longPressDuration = 2000,\n results = DEFAULT_RESULTS,\n enableIPFetch = false,\n customSalt,\n resultStyle = 'card',\n } = config;\n\n const [status, setStatus] = useState<TestStatus>('idle');\n const [result, setResult] = useState<TestResult | null>(null);\n const [pressProgress, setPressProgress] = useState(0);\n const [ipWarning, setIpWarning] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n\n const pressTimerRef = useRef<NodeJS.Timeout | null>(null);\n const progressIntervalRef = useRef<NodeJS.Timeout | null>(null);\n const startTimeRef = useRef<number>(0);\n\n // 初始化:检查localStorage和获取IP\n useEffect(() => {\n const initializeTest = async () => {\n // 检查localStorage中是否已有结果\n const savedResult = localStorage.getItem(STORAGE_KEY);\n if (savedResult) {\n try {\n const parsed = JSON.parse(savedResult);\n setResult(parsed);\n setStatus('completed');\n setIsLoading(false);\n return;\n } catch (error) {\n console.error('解析保存的结果失败:', error);\n }\n }\n\n // 如果启用IP获取,尝试获取\n if (enableIPFetch) {\n const ip = await tryGetIPAddress();\n if (!ip) {\n setIpWarning('⚠️ 无法获取IP地址,将仅使用浏览器指纹生成结果');\n }\n }\n\n setIsLoading(false);\n };\n\n initializeTest();\n }, [enableIPFetch]);\n\n // 计算并保存结果\n const calculateResult = async (): Promise<TestResult> => {\n try {\n // 获取设备指纹\n const fingerprint: DeviceFingerprint = getDeviceFingerprint();\n\n // 如果启用IP,尝试获取\n if (enableIPFetch) {\n const ip = await tryGetIPAddress();\n if (ip) {\n fingerprint.ip = ip;\n }\n }\n\n // 使用实际结果数据(如果配置的results为空,使用默认数据)\n const actualResults = results.length > 0 ? results : DEFAULT_RESULTS;\n\n // 生成唯一哈希\n const hash = generateDeviceHash(fingerprint, customSalt);\n\n // 根据哈希选择结果\n const index = selectResultIndex(hash, actualResults.length);\n const selectedResult = actualResults[index];\n\n if (!selectedResult) {\n console.error('无法获取测试结果,index:', index, 'total:', actualResults.length);\n throw new Error('无法获取测试结果');\n }\n\n console.log('计算结果成功:', selectedResult);\n\n // 保存到localStorage\n localStorage.setItem(STORAGE_KEY, JSON.stringify(selectedResult));\n\n return selectedResult;\n } catch (error) {\n console.error('计算结果失败:', error);\n throw error;\n }\n };\n\n // 处理按下\n const handlePressStart = (e: React.MouseEvent | React.TouchEvent) => {\n if (status !== 'idle') return;\n\n // 阻止默认行为(防止移动端长按出现选择菜单)\n e.preventDefault();\n\n setStatus('pressing');\n startTimeRef.current = Date.now();\n\n // 设置进度更新\n progressIntervalRef.current = setInterval(() => {\n const elapsed = Date.now() - startTimeRef.current;\n const progress = Math.min((elapsed / longPressDuration) * 100, 100);\n setPressProgress(progress);\n }, 16); // ~60fps\n\n // 设置完成定时器\n pressTimerRef.current = setTimeout(async () => {\n try {\n setPressProgress(100);\n \n // 清理进度定时器\n if (progressIntervalRef.current) {\n clearInterval(progressIntervalRef.current);\n progressIntervalRef.current = null;\n }\n \n console.log('开始计算结果...');\n \n // 计算结果\n const testResult = await calculateResult();\n \n console.log('结果计算完成,更新状态:', testResult);\n \n // 先更新结果,再更新状态\n setResult(testResult);\n \n // 使用setTimeout确保状态更新\n setTimeout(() => {\n setStatus('completed');\n console.log('状态已更新为 completed');\n }, 0);\n\n // 调用回调\n if (onResult) {\n onResult(testResult);\n }\n } catch (error) {\n console.error('测试失败:', error);\n // 重置状态\n setStatus('idle');\n setPressProgress(0);\n alert('测试失败,请重试');\n }\n }, longPressDuration);\n\n // 添加全局监听器(用于PC端)\n if ('button' in e && e.button === 0) {\n // 鼠标事件\n const handleGlobalMouseUp = () => {\n handlePressEnd();\n document.removeEventListener('mouseup', handleGlobalMouseUp);\n };\n document.addEventListener('mouseup', handleGlobalMouseUp);\n }\n };\n\n // 处理松开\n const handlePressEnd = () => {\n if (status !== 'pressing') return;\n\n // 清理定时器\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n if (progressIntervalRef.current) {\n clearInterval(progressIntervalRef.current);\n progressIntervalRef.current = null;\n }\n\n // 重置状态\n setStatus('idle');\n setPressProgress(0);\n };\n\n // 处理鼠标离开(仅用于提示,不取消长按)\n const handleMouseLeave = (e: React.MouseEvent) => {\n // PC端:不取消长按,让用户可以移出按钮区域\n // 只要保持鼠标按下就继续\n };\n\n // 处理触摸移动(移动端)\n const handleTouchMove = (e: React.TouchEvent) => {\n // 检查手指是否移出按钮区域\n const touch = e.touches[0];\n if (!touch) return;\n \n const target = e.currentTarget as HTMLElement;\n const rect = target.getBoundingClientRect();\n \n const isInside = \n touch.clientX >= rect.left &&\n touch.clientX <= rect.right &&\n touch.clientY >= rect.top &&\n touch.clientY <= rect.bottom;\n \n // 如果移出按钮,取消长按(移动端才取消)\n if (!isInside && status === 'pressing') {\n handlePressEnd();\n }\n };\n\n // 清理\n useEffect(() => {\n return () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n }\n if (progressIntervalRef.current) {\n clearInterval(progressIntervalRef.current);\n }\n };\n }, []);\n\n // 重新测试\n const handleReset = () => {\n localStorage.removeItem(STORAGE_KEY);\n setResult(null);\n setStatus('idle');\n setPressProgress(0);\n };\n\n // 背景容器样式\n const backgroundStyle: React.CSSProperties = {\n position: 'relative',\n minHeight: '100vh',\n overflow: 'hidden',\n background: 'linear-gradient(135deg, #f3e8ff 0%, #fce7f3 50%, #dbeafe 100%)',\n };\n\n // 装饰性光晕\n const DecorativeBackground = () => (\n <>\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '384px',\n height: '384px',\n background: 'radial-gradient(circle, rgba(192, 132, 252, 0.3) 0%, transparent 70%)',\n borderRadius: '50%',\n filter: 'blur(60px)',\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n }} />\n <div style={{\n position: 'absolute',\n top: '50%',\n right: 0,\n width: '384px',\n height: '384px',\n background: 'radial-gradient(circle, rgba(244, 114, 182, 0.3) 0%, transparent 70%)',\n borderRadius: '50%',\n filter: 'blur(60px)',\n transform: 'translateX(50%)',\n pointerEvents: 'none',\n }} />\n <div style={{\n position: 'absolute',\n bottom: 0,\n left: '50%',\n width: '384px',\n height: '384px',\n background: 'radial-gradient(circle, rgba(147, 197, 253, 0.3) 0%, transparent 70%)',\n borderRadius: '50%',\n filter: 'blur(60px)',\n transform: 'translate(-50%, 50%)',\n pointerEvents: 'none',\n }} />\n </>\n );\n\n if (isLoading) {\n return (\n <div className={className} style={backgroundStyle}>\n <DecorativeBackground />\n <div style={{\n position: 'relative',\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '100vh',\n }}>\n <div style={{ textAlign: 'center' }}>\n <div style={{\n position: 'relative',\n width: '64px',\n height: '64px',\n margin: '0 auto 16px',\n }}>\n <div style={{\n position: 'absolute',\n inset: 0,\n border: '4px solid #e9d5ff',\n borderRadius: '50%',\n }} />\n <div style={{\n position: 'absolute',\n inset: 0,\n border: '4px solid transparent',\n borderTopColor: '#a855f7',\n borderRadius: '50%',\n animation: 'spin 1s linear infinite',\n }} />\n </div>\n <p style={{ fontSize: '14px', color: '#6b7280' }}>✨ 加载中</p>\n </div>\n </div>\n </div>\n );\n }\n\n // 结果展示\n if (status === 'completed' && result) {\n return (\n <div className={className} style={backgroundStyle}>\n <DecorativeBackground />\n <div style={{\n position: 'relative',\n zIndex: 10,\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '24px',\n }}>\n <div style={{ maxWidth: '420px', width: '100%' }}>\n {/* 结果卡片 - 可爱风格 */}\n <div style={{\n position: 'relative',\n background: 'linear-gradient(135deg, #fdf2f8 0%, #faf5ff 50%, #eff6ff 100%)',\n borderRadius: '32px',\n boxShadow: '0 25px 50px -12px rgba(168, 85, 247, 0.25), 0 0 0 1px rgba(168, 85, 247, 0.1)',\n overflow: 'hidden',\n padding: '40px 32px',\n textAlign: 'center',\n }}>\n {/* 装饰性星星 */}\n <div style={{ position: 'absolute', top: '20px', left: '20px', fontSize: '24px', opacity: 0.6 }}>✨</div>\n <div style={{ position: 'absolute', top: '40px', right: '30px', fontSize: '20px', opacity: 0.5 }}>⭐</div>\n <div style={{ position: 'absolute', bottom: '30px', left: '40px', fontSize: '18px', opacity: 0.4 }}>💫</div>\n <div style={{ position: 'absolute', bottom: '50px', right: '25px', fontSize: '22px', opacity: 0.5 }}>🌟</div>\n \n {/* Emoji 展示 */}\n <div style={{ marginBottom: '24px' }}>\n <div style={{ \n display: 'inline-block',\n fontSize: '80px',\n animation: 'bounce-slow 2s ease-in-out infinite',\n filter: 'drop-shadow(0 10px 20px rgba(0,0,0,0.1))',\n }}>\n {result.imageType === 'emoji' ? result.image : '🎉'}\n </div>\n </div>\n\n {/* 标题 */}\n <h2 style={{\n fontSize: '32px',\n fontWeight: 800,\n background: 'linear-gradient(135deg, #9333ea 0%, #ec4899 100%)',\n WebkitBackgroundClip: 'text',\n WebkitTextFillColor: 'transparent',\n backgroundClip: 'text',\n marginBottom: '16px',\n lineHeight: 1.3,\n }}>\n {result.title}\n </h2>\n\n {/* 描述卡片 */}\n <div style={{\n background: 'rgba(255, 255, 255, 0.8)',\n borderRadius: '20px',\n padding: '20px 24px',\n marginBottom: '28px',\n boxShadow: '0 4px 15px rgba(168, 85, 247, 0.1)',\n border: '2px dashed rgba(168, 85, 247, 0.2)',\n }}>\n <p style={{\n fontSize: '16px',\n color: '#6b7280',\n lineHeight: 1.7,\n margin: 0,\n }}>\n {result.description}\n </p>\n </div>\n\n {/* 可爱装饰线 */}\n <div style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n marginBottom: '24px',\n }}>\n <span style={{ width: '40px', height: '3px', background: 'linear-gradient(to right, #a855f7, transparent)', borderRadius: '999px' }}></span>\n <span style={{ fontSize: '16px' }}>💕</span>\n <span style={{ width: '40px', height: '3px', background: 'linear-gradient(to left, #ec4899, transparent)', borderRadius: '999px' }}></span>\n </div>\n\n {/* 重新测试按钮 */}\n <button\n onClick={handleReset}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n padding: '14px 32px',\n fontSize: '16px',\n fontWeight: 600,\n color: 'white',\n background: 'linear-gradient(135deg, #a855f7 0%, #ec4899 100%)',\n border: 'none',\n borderRadius: '9999px',\n cursor: 'pointer',\n boxShadow: '0 10px 25px -5px rgba(168, 85, 247, 0.4)',\n transition: 'all 0.3s ease',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.transform = 'scale(1.05) translateY(-2px)';\n e.currentTarget.style.boxShadow = '0 15px 35px -5px rgba(168, 85, 247, 0.5)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.transform = 'scale(1) translateY(0)';\n e.currentTarget.style.boxShadow = '0 10px 25px -5px rgba(168, 85, 247, 0.4)';\n }}\n >\n <span>🔄</span>\n <span>重新测试</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n // 测试界面 - 时尚可爱设计\n return (\n <div className={className} style={backgroundStyle}>\n <DecorativeBackground />\n <div style={{\n position: 'relative',\n zIndex: 10,\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '16px',\n }}>\n <div style={{ maxWidth: '512px', width: '100%', textAlign: 'center', userSelect: 'none' }}>\n {/* 标题区域 */}\n <div style={{ marginBottom: '48px' }}>\n <div style={{ \n display: 'inline-block', \n marginBottom: '16px',\n animation: 'bounce-slow 2s ease-in-out infinite',\n }}>\n <span style={{ fontSize: '56px' }}>🎲</span>\n </div>\n <h1 style={{\n fontSize: '48px',\n fontWeight: 900,\n marginBottom: '12px',\n background: 'linear-gradient(135deg, #9333ea 0%, #ec4899 50%, #3b82f6 100%)',\n WebkitBackgroundClip: 'text',\n WebkitTextFillColor: 'transparent',\n backgroundClip: 'text',\n lineHeight: 1.2,\n }}>\n {gameTitle}\n </h1>\n {gameDescription && (\n <p style={{ \n fontSize: '18px', \n color: '#6b7280', \n fontWeight: 500,\n }}>\n {gameDescription}\n </p>\n )}\n </div>\n\n {/* 长按按钮区域 */}\n <div style={{ marginBottom: '24px' }}>\n {/* 主按钮 */}\n <button\n onMouseDown={handlePressStart}\n onMouseLeave={handleMouseLeave}\n onTouchStart={handlePressStart}\n onTouchEnd={handlePressEnd}\n onTouchMove={handleTouchMove}\n onTouchCancel={handlePressEnd}\n onContextMenu={(e) => e.preventDefault()}\n onDragStart={(e) => e.preventDefault()}\n style={{\n display: 'block',\n margin: '0 auto',\n width: '200px',\n height: '200px',\n borderRadius: '50%',\n border: 'none',\n fontSize: '20px',\n fontWeight: 'bold',\n cursor: 'pointer',\n position: 'relative',\n overflow: 'hidden',\n userSelect: 'none',\n WebkitTouchCallout: 'none',\n WebkitUserSelect: 'none',\n touchAction: 'none',\n transition: 'transform 0.3s ease',\n transform: status === 'pressing' ? 'scale(0.95)' : 'scale(1)',\n background: status === 'pressing' \n ? `linear-gradient(to top, rgb(168, 85, 247) ${pressProgress}%, rgb(236, 72, 153) ${pressProgress}%)`\n : 'linear-gradient(135deg, #4f46e5 0%, #7c3aed 25%, #db2777 50%, #f97316 75%, #059669 100%)',\n boxShadow: status === 'pressing' \n ? 'inset 0 4px 12px rgba(0,0,0,0.3), 0 0 0 4px rgba(168, 85, 247, 0.5)'\n : '0 15px 35px -10px rgba(79, 70, 229, 0.6), 0 0 0 4px rgba(255,255,255,0.8)',\n }}\n >\n {/* 按钮内容 */}\n <div style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n color: 'white',\n pointerEvents: 'none',\n }}>\n {status === 'pressing' ? (\n <>\n <span style={{ fontSize: '36px', fontWeight: 900, marginBottom: '4px' }}>{Math.round(pressProgress)}%</span>\n <span style={{ fontSize: '14px', opacity: 0.8 }}>继续按住</span>\n </>\n ) : (\n <>\n <span style={{ fontSize: '32px', marginBottom: '8px' }}>👆</span>\n <span style={{ fontSize: '16px', fontWeight: 'bold', padding: '0 16px' }}>{buttonText}</span>\n </>\n )}\n </div>\n\n {/* 内部装饰圆环 */}\n {status === 'idle' && (\n <div style={{\n position: 'absolute',\n top: '16px',\n left: '16px',\n right: '16px',\n bottom: '16px',\n border: '2px solid rgba(255,255,255,0.3)',\n borderRadius: '50%',\n }}></div>\n )}\n </button>\n\n {/* 进度条 */}\n {status === 'pressing' && (\n <div style={{\n marginTop: '16px',\n marginLeft: 'auto',\n marginRight: 'auto',\n width: '192px',\n height: '8px',\n backgroundColor: '#e5e7eb',\n borderRadius: '9999px',\n overflow: 'hidden',\n }}>\n <div style={{\n height: '100%',\n width: `${pressProgress}%`,\n background: 'linear-gradient(to right, #a855f7, #ec4899)',\n transition: 'width 0.1s ease',\n }} />\n </div>\n )}\n </div>\n\n {/* 底部提示 - 简洁可爱 */}\n <div style={{ marginTop: '24px' }}>\n {status === 'pressing' ? (\n <p style={{ \n fontSize: '18px', \n fontWeight: 500, \n color: '#9333ea',\n animation: 'pulse 2s ease-in-out infinite',\n }}>\n ✨ 正在分析中...\n </p>\n ) : (\n <div style={{ \n display: 'flex', \n alignItems: 'center', \n justifyContent: 'center', \n gap: '8px',\n }}>\n <span style={{ \n display: 'inline-block', \n width: '6px', \n height: '6px', \n backgroundColor: '#a855f7', \n borderRadius: '50%',\n animation: 'bounce 1s infinite',\n }} />\n <span style={{ \n display: 'inline-block', \n width: '6px', \n height: '6px', \n backgroundColor: '#ec4899', \n borderRadius: '50%',\n animation: 'bounce 1s infinite 0.1s',\n }} />\n <span style={{ \n display: 'inline-block', \n width: '6px', \n height: '6px', \n backgroundColor: '#3b82f6', \n borderRadius: '50%',\n animation: 'bounce 1s infinite 0.2s',\n }} />\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};\n\n// 添加CSS样式来支持触摸优化和动画\nconst touchOptimizationStyles = `\n @keyframes bounce-slow {\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-10px);\n }\n }\n \n @keyframes bounce {\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-4px);\n }\n }\n \n @keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n }\n \n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n`;\n\n// 注入样式\nif (typeof document !== 'undefined' && !document.getElementById('test-yourself-styles')) {\n const style = document.createElement('style');\n style.id = 'test-yourself-styles';\n style.textContent = touchOptimizationStyles;\n document.head.appendChild(style);\n};\n\nexport default TestYourself;\n\n\n"]}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { Vector3 } from 'three';
|
|
2
|
+
|
|
3
|
+
/** MMD 资源配置 */
|
|
4
|
+
interface MMDResources {
|
|
5
|
+
/** 模型文件路径 (.pmx/.pmd) */
|
|
6
|
+
modelPath: string;
|
|
7
|
+
/** 动作文件路径 (.vmd) - 可选 */
|
|
8
|
+
motionPath?: string;
|
|
9
|
+
/** 相机动画路径 (.vmd) - 可选 */
|
|
10
|
+
cameraPath?: string;
|
|
11
|
+
/** 音频文件路径 - 可选 */
|
|
12
|
+
audioPath?: string;
|
|
13
|
+
/** 舞台/场景模型路径 (.pmx/.x) - 可选 */
|
|
14
|
+
stageModelPath?: string;
|
|
15
|
+
/** 附加动作文件 - 可选 */
|
|
16
|
+
additionalMotions?: string[];
|
|
17
|
+
}
|
|
18
|
+
/** 资源列表项 - 用于预设切换 */
|
|
19
|
+
interface MMDResourceItem {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
resources: MMDResources;
|
|
23
|
+
thumbnail?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
}
|
|
26
|
+
/** 资源选项 - 用于自由组合 */
|
|
27
|
+
interface ResourceOption {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
path: string;
|
|
31
|
+
thumbnail?: string;
|
|
32
|
+
}
|
|
33
|
+
interface MMDResourceOptions {
|
|
34
|
+
models: ResourceOption[];
|
|
35
|
+
motions: ResourceOption[];
|
|
36
|
+
cameras?: ResourceOption[];
|
|
37
|
+
audios?: ResourceOption[];
|
|
38
|
+
stages?: ResourceOption[];
|
|
39
|
+
}
|
|
40
|
+
/** 舞台/场景配置 */
|
|
41
|
+
interface MMDStage {
|
|
42
|
+
/** 背景颜色 */
|
|
43
|
+
backgroundColor?: string;
|
|
44
|
+
/** 背景图片 URL */
|
|
45
|
+
backgroundImage?: string;
|
|
46
|
+
/** 是否启用物理模拟 (默认 true) */
|
|
47
|
+
enablePhysics?: boolean;
|
|
48
|
+
/** 物理引擎路径 (ammo.wasm.js 的路径) */
|
|
49
|
+
physicsPath?: string;
|
|
50
|
+
/** 是否启用阴影 (默认 true) */
|
|
51
|
+
enableShadow?: boolean;
|
|
52
|
+
/** 环境光强度 (默认 0.5) */
|
|
53
|
+
ambientLightIntensity?: number;
|
|
54
|
+
/** 方向光强度 (默认 0.8) */
|
|
55
|
+
directionalLightIntensity?: number;
|
|
56
|
+
/** 相机初始位置 */
|
|
57
|
+
cameraPosition?: {
|
|
58
|
+
x: number;
|
|
59
|
+
y: number;
|
|
60
|
+
z: number;
|
|
61
|
+
} | Vector3;
|
|
62
|
+
/** 相机目标点 */
|
|
63
|
+
cameraTarget?: {
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
z: number;
|
|
67
|
+
} | Vector3;
|
|
68
|
+
}
|
|
69
|
+
/** 移动端优化配置 */
|
|
70
|
+
interface MobileOptimization {
|
|
71
|
+
/** 是否启用优化 (默认 true) */
|
|
72
|
+
enabled: boolean;
|
|
73
|
+
/** 像素比 (默认 1.0, 桌面端通常为 window.devicePixelRatio) */
|
|
74
|
+
pixelRatio?: number;
|
|
75
|
+
/** 是否强制关闭物理引擎 (默认 false) */
|
|
76
|
+
disablePhysics?: boolean;
|
|
77
|
+
/** 是否降低阴影质量 (默认 true) */
|
|
78
|
+
reduceShadowQuality?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/** MMDPlayerBase Ref 接口 */
|
|
81
|
+
interface MMDPlayerBaseRef {
|
|
82
|
+
/** 开始播放 */
|
|
83
|
+
play: () => void;
|
|
84
|
+
/** 暂停播放 */
|
|
85
|
+
pause: () => void;
|
|
86
|
+
/** 停止播放 (重置到开头) */
|
|
87
|
+
stop: () => void;
|
|
88
|
+
/** 跳转到指定时间 (秒) */
|
|
89
|
+
seek: (time: number) => void;
|
|
90
|
+
/** 获取当前播放时间 */
|
|
91
|
+
getCurrentTime: () => number;
|
|
92
|
+
/** 获取总时长 */
|
|
93
|
+
getDuration: () => number;
|
|
94
|
+
/** 获取播放状态 */
|
|
95
|
+
isPlaying: () => boolean;
|
|
96
|
+
/** 截图并返回 Base64 字符串 */
|
|
97
|
+
snapshot: () => string;
|
|
98
|
+
}
|
|
99
|
+
/** 基础播放器属性 */
|
|
100
|
+
interface MMDPlayerBaseProps {
|
|
101
|
+
/** 资源配置 */
|
|
102
|
+
resources: MMDResources;
|
|
103
|
+
/** 舞台配置 */
|
|
104
|
+
stage?: MMDStage;
|
|
105
|
+
/** 移动端优化配置 */
|
|
106
|
+
mobileOptimization?: MobileOptimization;
|
|
107
|
+
/** 播放控制 */
|
|
108
|
+
autoPlay?: boolean;
|
|
109
|
+
loop?: boolean;
|
|
110
|
+
volume?: number;
|
|
111
|
+
muted?: boolean;
|
|
112
|
+
/** 调试与辅助 */
|
|
113
|
+
showAxes?: boolean;
|
|
114
|
+
/** 事件回调 */
|
|
115
|
+
onLoad?: () => void;
|
|
116
|
+
onLoadProgress?: (progress: number, item: string) => void;
|
|
117
|
+
onError?: (error: Error) => void;
|
|
118
|
+
onPlay?: () => void;
|
|
119
|
+
onPause?: () => void;
|
|
120
|
+
onEnded?: () => void;
|
|
121
|
+
onTimeUpdate?: (time: number) => void;
|
|
122
|
+
/** 样式 */
|
|
123
|
+
className?: string;
|
|
124
|
+
style?: React.CSSProperties;
|
|
125
|
+
}
|
|
126
|
+
/** 增强播放器属性 */
|
|
127
|
+
interface MMDPlayerEnhancedProps extends Omit<MMDPlayerBaseProps, 'resources'> {
|
|
128
|
+
/** 单一资源模式 */
|
|
129
|
+
resources?: MMDResources;
|
|
130
|
+
/** 列表模式资源 */
|
|
131
|
+
resourcesList?: MMDResourceItem[];
|
|
132
|
+
/** 自由组合模式选项 */
|
|
133
|
+
resourceOptions?: MMDResourceOptions;
|
|
134
|
+
/** 列表模式下的默认 ID */
|
|
135
|
+
defaultResourceId?: string;
|
|
136
|
+
/** 自由组合模式下的默认选择 */
|
|
137
|
+
defaultSelection?: {
|
|
138
|
+
modelId?: string;
|
|
139
|
+
motionId?: string;
|
|
140
|
+
cameraId?: string;
|
|
141
|
+
audioId?: string;
|
|
142
|
+
stageId?: string;
|
|
143
|
+
};
|
|
144
|
+
/** 是否显示调试信息面板 */
|
|
145
|
+
showDebugInfo?: boolean;
|
|
146
|
+
}
|
|
147
|
+
/** 播放列表节点 */
|
|
148
|
+
interface MMDPlaylistNode {
|
|
149
|
+
id: string;
|
|
150
|
+
name: string;
|
|
151
|
+
resources: MMDResources;
|
|
152
|
+
/** 该节点是否循环播放 */
|
|
153
|
+
loop?: boolean;
|
|
154
|
+
/** 预计时长(秒)- 用于进度计算 */
|
|
155
|
+
duration?: number;
|
|
156
|
+
/** 缩略图 */
|
|
157
|
+
thumbnail?: string;
|
|
158
|
+
}
|
|
159
|
+
/** 播放列表配置 */
|
|
160
|
+
interface MMDPlaylistConfig {
|
|
161
|
+
id: string;
|
|
162
|
+
name: string;
|
|
163
|
+
nodes: MMDPlaylistNode[];
|
|
164
|
+
/** 整个播放列表是否循环 */
|
|
165
|
+
loop?: boolean;
|
|
166
|
+
/** 预加载策略
|
|
167
|
+
* - 'none': 不预加载 (默认)
|
|
168
|
+
* - 'next': 预加载下一个节点
|
|
169
|
+
* - 'all': 预加载所有节点
|
|
170
|
+
*/
|
|
171
|
+
preload?: 'none' | 'next' | 'all';
|
|
172
|
+
/** 是否自动播放 */
|
|
173
|
+
autoPlay?: boolean;
|
|
174
|
+
}
|
|
175
|
+
/** 播放列表组件属性 */
|
|
176
|
+
interface MMDPlaylistProps {
|
|
177
|
+
/** 播放列表配置 */
|
|
178
|
+
playlist: MMDPlaylistConfig;
|
|
179
|
+
/** 舞台配置 */
|
|
180
|
+
stage?: MMDStage;
|
|
181
|
+
/** 移动端优化配置 */
|
|
182
|
+
mobileOptimization?: MobileOptimization;
|
|
183
|
+
/** 事件回调 */
|
|
184
|
+
onNodeChange?: (node: MMDPlaylistNode, index: number) => void;
|
|
185
|
+
onPlaylistComplete?: () => void;
|
|
186
|
+
onError?: (error: Error) => void;
|
|
187
|
+
/** 是否显示调试信息面板 */
|
|
188
|
+
showDebugInfo?: boolean;
|
|
189
|
+
/** 样式 */
|
|
190
|
+
className?: string;
|
|
191
|
+
style?: React.CSSProperties;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export type { MMDPlaylistConfig as M, ResourceOption as R, MMDResourceItem as a, MMDPlaylistNode as b, MMDResourceOptions as c, MMDResources as d, MMDPlayerBaseProps as e, MMDPlayerBaseRef as f, MMDPlayerEnhancedProps as g, MMDPlaylistProps as h, MMDStage as i, MobileOptimization as j };
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { Vector3 } from 'three';
|
|
2
|
+
|
|
3
|
+
/** MMD 资源配置 */
|
|
4
|
+
interface MMDResources {
|
|
5
|
+
/** 模型文件路径 (.pmx/.pmd) */
|
|
6
|
+
modelPath: string;
|
|
7
|
+
/** 动作文件路径 (.vmd) - 可选 */
|
|
8
|
+
motionPath?: string;
|
|
9
|
+
/** 相机动画路径 (.vmd) - 可选 */
|
|
10
|
+
cameraPath?: string;
|
|
11
|
+
/** 音频文件路径 - 可选 */
|
|
12
|
+
audioPath?: string;
|
|
13
|
+
/** 舞台/场景模型路径 (.pmx/.x) - 可选 */
|
|
14
|
+
stageModelPath?: string;
|
|
15
|
+
/** 附加动作文件 - 可选 */
|
|
16
|
+
additionalMotions?: string[];
|
|
17
|
+
}
|
|
18
|
+
/** 资源列表项 - 用于预设切换 */
|
|
19
|
+
interface MMDResourceItem {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
resources: MMDResources;
|
|
23
|
+
thumbnail?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
}
|
|
26
|
+
/** 资源选项 - 用于自由组合 */
|
|
27
|
+
interface ResourceOption {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
path: string;
|
|
31
|
+
thumbnail?: string;
|
|
32
|
+
}
|
|
33
|
+
interface MMDResourceOptions {
|
|
34
|
+
models: ResourceOption[];
|
|
35
|
+
motions: ResourceOption[];
|
|
36
|
+
cameras?: ResourceOption[];
|
|
37
|
+
audios?: ResourceOption[];
|
|
38
|
+
stages?: ResourceOption[];
|
|
39
|
+
}
|
|
40
|
+
/** 舞台/场景配置 */
|
|
41
|
+
interface MMDStage {
|
|
42
|
+
/** 背景颜色 */
|
|
43
|
+
backgroundColor?: string;
|
|
44
|
+
/** 背景图片 URL */
|
|
45
|
+
backgroundImage?: string;
|
|
46
|
+
/** 是否启用物理模拟 (默认 true) */
|
|
47
|
+
enablePhysics?: boolean;
|
|
48
|
+
/** 物理引擎路径 (ammo.wasm.js 的路径) */
|
|
49
|
+
physicsPath?: string;
|
|
50
|
+
/** 是否启用阴影 (默认 true) */
|
|
51
|
+
enableShadow?: boolean;
|
|
52
|
+
/** 环境光强度 (默认 0.5) */
|
|
53
|
+
ambientLightIntensity?: number;
|
|
54
|
+
/** 方向光强度 (默认 0.8) */
|
|
55
|
+
directionalLightIntensity?: number;
|
|
56
|
+
/** 相机初始位置 */
|
|
57
|
+
cameraPosition?: {
|
|
58
|
+
x: number;
|
|
59
|
+
y: number;
|
|
60
|
+
z: number;
|
|
61
|
+
} | Vector3;
|
|
62
|
+
/** 相机目标点 */
|
|
63
|
+
cameraTarget?: {
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
z: number;
|
|
67
|
+
} | Vector3;
|
|
68
|
+
}
|
|
69
|
+
/** 移动端优化配置 */
|
|
70
|
+
interface MobileOptimization {
|
|
71
|
+
/** 是否启用优化 (默认 true) */
|
|
72
|
+
enabled: boolean;
|
|
73
|
+
/** 像素比 (默认 1.0, 桌面端通常为 window.devicePixelRatio) */
|
|
74
|
+
pixelRatio?: number;
|
|
75
|
+
/** 是否强制关闭物理引擎 (默认 false) */
|
|
76
|
+
disablePhysics?: boolean;
|
|
77
|
+
/** 是否降低阴影质量 (默认 true) */
|
|
78
|
+
reduceShadowQuality?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/** MMDPlayerBase Ref 接口 */
|
|
81
|
+
interface MMDPlayerBaseRef {
|
|
82
|
+
/** 开始播放 */
|
|
83
|
+
play: () => void;
|
|
84
|
+
/** 暂停播放 */
|
|
85
|
+
pause: () => void;
|
|
86
|
+
/** 停止播放 (重置到开头) */
|
|
87
|
+
stop: () => void;
|
|
88
|
+
/** 跳转到指定时间 (秒) */
|
|
89
|
+
seek: (time: number) => void;
|
|
90
|
+
/** 获取当前播放时间 */
|
|
91
|
+
getCurrentTime: () => number;
|
|
92
|
+
/** 获取总时长 */
|
|
93
|
+
getDuration: () => number;
|
|
94
|
+
/** 获取播放状态 */
|
|
95
|
+
isPlaying: () => boolean;
|
|
96
|
+
/** 截图并返回 Base64 字符串 */
|
|
97
|
+
snapshot: () => string;
|
|
98
|
+
}
|
|
99
|
+
/** 基础播放器属性 */
|
|
100
|
+
interface MMDPlayerBaseProps {
|
|
101
|
+
/** 资源配置 */
|
|
102
|
+
resources: MMDResources;
|
|
103
|
+
/** 舞台配置 */
|
|
104
|
+
stage?: MMDStage;
|
|
105
|
+
/** 移动端优化配置 */
|
|
106
|
+
mobileOptimization?: MobileOptimization;
|
|
107
|
+
/** 播放控制 */
|
|
108
|
+
autoPlay?: boolean;
|
|
109
|
+
loop?: boolean;
|
|
110
|
+
volume?: number;
|
|
111
|
+
muted?: boolean;
|
|
112
|
+
/** 调试与辅助 */
|
|
113
|
+
showAxes?: boolean;
|
|
114
|
+
/** 事件回调 */
|
|
115
|
+
onLoad?: () => void;
|
|
116
|
+
onLoadProgress?: (progress: number, item: string) => void;
|
|
117
|
+
onError?: (error: Error) => void;
|
|
118
|
+
onPlay?: () => void;
|
|
119
|
+
onPause?: () => void;
|
|
120
|
+
onEnded?: () => void;
|
|
121
|
+
onTimeUpdate?: (time: number) => void;
|
|
122
|
+
/** 样式 */
|
|
123
|
+
className?: string;
|
|
124
|
+
style?: React.CSSProperties;
|
|
125
|
+
}
|
|
126
|
+
/** 增强播放器属性 */
|
|
127
|
+
interface MMDPlayerEnhancedProps extends Omit<MMDPlayerBaseProps, 'resources'> {
|
|
128
|
+
/** 单一资源模式 */
|
|
129
|
+
resources?: MMDResources;
|
|
130
|
+
/** 列表模式资源 */
|
|
131
|
+
resourcesList?: MMDResourceItem[];
|
|
132
|
+
/** 自由组合模式选项 */
|
|
133
|
+
resourceOptions?: MMDResourceOptions;
|
|
134
|
+
/** 列表模式下的默认 ID */
|
|
135
|
+
defaultResourceId?: string;
|
|
136
|
+
/** 自由组合模式下的默认选择 */
|
|
137
|
+
defaultSelection?: {
|
|
138
|
+
modelId?: string;
|
|
139
|
+
motionId?: string;
|
|
140
|
+
cameraId?: string;
|
|
141
|
+
audioId?: string;
|
|
142
|
+
stageId?: string;
|
|
143
|
+
};
|
|
144
|
+
/** 是否显示调试信息面板 */
|
|
145
|
+
showDebugInfo?: boolean;
|
|
146
|
+
}
|
|
147
|
+
/** 播放列表节点 */
|
|
148
|
+
interface MMDPlaylistNode {
|
|
149
|
+
id: string;
|
|
150
|
+
name: string;
|
|
151
|
+
resources: MMDResources;
|
|
152
|
+
/** 该节点是否循环播放 */
|
|
153
|
+
loop?: boolean;
|
|
154
|
+
/** 预计时长(秒)- 用于进度计算 */
|
|
155
|
+
duration?: number;
|
|
156
|
+
/** 缩略图 */
|
|
157
|
+
thumbnail?: string;
|
|
158
|
+
}
|
|
159
|
+
/** 播放列表配置 */
|
|
160
|
+
interface MMDPlaylistConfig {
|
|
161
|
+
id: string;
|
|
162
|
+
name: string;
|
|
163
|
+
nodes: MMDPlaylistNode[];
|
|
164
|
+
/** 整个播放列表是否循环 */
|
|
165
|
+
loop?: boolean;
|
|
166
|
+
/** 预加载策略
|
|
167
|
+
* - 'none': 不预加载 (默认)
|
|
168
|
+
* - 'next': 预加载下一个节点
|
|
169
|
+
* - 'all': 预加载所有节点
|
|
170
|
+
*/
|
|
171
|
+
preload?: 'none' | 'next' | 'all';
|
|
172
|
+
/** 是否自动播放 */
|
|
173
|
+
autoPlay?: boolean;
|
|
174
|
+
}
|
|
175
|
+
/** 播放列表组件属性 */
|
|
176
|
+
interface MMDPlaylistProps {
|
|
177
|
+
/** 播放列表配置 */
|
|
178
|
+
playlist: MMDPlaylistConfig;
|
|
179
|
+
/** 舞台配置 */
|
|
180
|
+
stage?: MMDStage;
|
|
181
|
+
/** 移动端优化配置 */
|
|
182
|
+
mobileOptimization?: MobileOptimization;
|
|
183
|
+
/** 事件回调 */
|
|
184
|
+
onNodeChange?: (node: MMDPlaylistNode, index: number) => void;
|
|
185
|
+
onPlaylistComplete?: () => void;
|
|
186
|
+
onError?: (error: Error) => void;
|
|
187
|
+
/** 是否显示调试信息面板 */
|
|
188
|
+
showDebugInfo?: boolean;
|
|
189
|
+
/** 样式 */
|
|
190
|
+
className?: string;
|
|
191
|
+
style?: React.CSSProperties;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export type { MMDPlaylistConfig as M, ResourceOption as R, MMDResourceItem as a, MMDPlaylistNode as b, MMDResourceOptions as c, MMDResources as d, MMDPlayerBaseProps as e, MMDPlayerBaseRef as f, MMDPlayerEnhancedProps as g, MMDPlaylistProps as h, MMDStage as i, MobileOptimization as j };
|