Some checks failed
CI/CD Pipeline / Test & Lint (16.x) (push) Has been cancelled
CI/CD Pipeline / Test & Lint (18.x) (push) Has been cancelled
CI/CD Pipeline / Test & Lint (20.x) (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Release (push) Has been cancelled
Demo Deployment / Build Demo (push) Has been cancelled
Demo Deployment / Test Demo (push) Has been cancelled
Demo Deployment / Performance Audit (push) Has been cancelled
Demo Deployment / Deploy to Staging (push) Has been cancelled
Demo Deployment / Deploy to Production (push) Has been cancelled
Animation Processing Pipeline / Validate Animation Names (push) Has been cancelled
Animation Processing Pipeline / Process Blender Animation Assets (push) Has been cancelled
Multi-Scheme Testing / Validate Naming Schemes (artist) (push) Has been cancelled
Multi-Scheme Testing / Validate Naming Schemes (hierarchical) (push) Has been cancelled
Multi-Scheme Testing / Validate Naming Schemes (legacy) (push) Has been cancelled
Multi-Scheme Testing / Validate Naming Schemes (semantic) (push) Has been cancelled
Multi-Scheme Testing / Test Scheme Conversions (push) Has been cancelled
Multi-Scheme Testing / Validate Demo Functionality (push) Has been cancelled
Multi-Scheme Testing / Performance Benchmarks (push) Has been cancelled
Performance Testing / Animation Conversion Performance (100, artist) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (100, hierarchical) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (100, legacy) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (100, semantic) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (1000, artist) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (1000, hierarchical) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (1000, legacy) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (1000, semantic) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (5000, artist) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (5000, hierarchical) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (5000, legacy) (push) Has been cancelled
Performance Testing / Animation Conversion Performance (5000, semantic) (push) Has been cancelled
Performance Testing / Memory Usage Analysis (push) Has been cancelled
Performance Testing / Demo Performance Audit (push) Has been cancelled
Animation Processing Pipeline / Update Animation Documentation (push) Has been cancelled
Animation Processing Pipeline / Deploy Animation Demo (push) Has been cancelled
Performance Testing / Generate Performance Report (push) Has been cancelled
- Added AnimationNameMapper class to handle conversion between different animation naming schemes (legacy, artist, hierarchical, semantic). - Included methods for initialization, pattern matching, conversion, and validation of animation names. - Developed comprehensive unit tests for the animation name converter and demo pages using Playwright. - Created a Vite configuration for the demo application, including asset handling and optimization settings. - Enhanced the demo with features for batch conversion, performance metrics, and responsive design.
401 lines
12 KiB
HTML
401 lines
12 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Examples - Owen Animation System</title>
|
|
<link rel="stylesheet" href="./styles/main.css" />
|
|
<link rel="stylesheet" href="./styles/examples.css" />
|
|
</head>
|
|
<body>
|
|
<header class="demo-header">
|
|
<div class="container">
|
|
<h1 class="logo">
|
|
<span class="logo-text">Owen</span>
|
|
<span class="logo-subtitle">Examples</span>
|
|
</h1>
|
|
<nav class="demo-nav">
|
|
<a href="index.html" class="nav-link">Demo</a>
|
|
<a href="examples.html" class="nav-link active">Examples</a>
|
|
<a href="comparison.html" class="nav-link">Comparison</a>
|
|
<a href="interactive.html" class="nav-link">Interactive</a>
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="examples-main">
|
|
<div class="container">
|
|
<section class="examples-hero">
|
|
<h2>Code Examples & Integration Patterns</h2>
|
|
<p>
|
|
Explore practical examples of using the Owen Animation System in
|
|
different frameworks and scenarios.
|
|
</p>
|
|
</section>
|
|
|
|
<section class="examples-grid">
|
|
<div class="example-category">
|
|
<h3>Framework Integration</h3>
|
|
<div class="example-cards">
|
|
<div class="example-card">
|
|
<h4>React Integration</h4>
|
|
<p>Complete React component with animation state management</p>
|
|
<a href="#react-example" class="example-link">View Example</a>
|
|
</div>
|
|
<div class="example-card">
|
|
<h4>Vue Integration</h4>
|
|
<p>Vue 3 composition API with reactive animation controls</p>
|
|
<a href="#vue-example" class="example-link">View Example</a>
|
|
</div>
|
|
<div class="example-card">
|
|
<h4>Node.js Server</h4>
|
|
<p>Server-side animation processing and validation</p>
|
|
<a href="#nodejs-example" class="example-link">View Example</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="example-category">
|
|
<h3>Multi-Scheme Usage</h3>
|
|
<div class="example-cards">
|
|
<div class="example-card">
|
|
<h4>Scheme Conversion</h4>
|
|
<p>Converting animations between different naming schemes</p>
|
|
<a href="#conversion-example" class="example-link"
|
|
>View Example</a
|
|
>
|
|
</div>
|
|
<div class="example-card">
|
|
<h4>Batch Processing</h4>
|
|
<p>Processing multiple animations with automated conversion</p>
|
|
<a href="#batch-example" class="example-link">View Example</a>
|
|
</div>
|
|
<div class="example-card">
|
|
<h4>Validation Pipeline</h4>
|
|
<p>Complete validation workflow with error handling</p>
|
|
<a href="#validation-example" class="example-link"
|
|
>View Example</a
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="example-category">
|
|
<h3>Advanced Features</h3>
|
|
<div class="example-cards">
|
|
<div class="example-card">
|
|
<h4>Custom Schemes</h4>
|
|
<p>Creating and registering custom naming schemes</p>
|
|
<a href="#custom-example" class="example-link">View Example</a>
|
|
</div>
|
|
<div class="example-card">
|
|
<h4>Performance Optimization</h4>
|
|
<p>Optimizing animation loading and caching strategies</p>
|
|
<a href="#performance-example" class="example-link"
|
|
>View Example</a
|
|
>
|
|
</div>
|
|
<div class="example-card">
|
|
<h4>Testing Integration</h4>
|
|
<p>Unit and integration testing for animation systems</p>
|
|
<a href="#testing-example" class="example-link">View Example</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Detailed Examples -->
|
|
<section class="detailed-examples">
|
|
<div id="react-example" class="example-detail">
|
|
<h3>React Integration Example</h3>
|
|
<pre><code class="javascript">import React, { useEffect, useRef, useState } from 'react'
|
|
import { OwenAnimationContext } from '@kjanat/owen'
|
|
|
|
export function AnimatedCharacter({ characterModel, namingScheme = 'semantic' }) {
|
|
const containerRef = useRef()
|
|
const [animationContext, setAnimationContext] = useState(null)
|
|
const [currentAnimation, setCurrentAnimation] = useState('idle')
|
|
const [isPlaying, setIsPlaying] = useState(false)
|
|
|
|
useEffect(() => {
|
|
// Initialize Owen Animation Context
|
|
const context = new OwenAnimationContext({
|
|
namingScheme,
|
|
autoConvert: true,
|
|
container: containerRef.current
|
|
})
|
|
|
|
context.loadModel(characterModel).then(() => {
|
|
setAnimationContext(context)
|
|
})
|
|
|
|
return () => context?.dispose()
|
|
}, [characterModel, namingScheme])
|
|
|
|
const playAnimation = async (animationName) => {
|
|
if (!animationContext) return
|
|
|
|
try {
|
|
await animationContext.playAnimation(animationName)
|
|
setCurrentAnimation(animationName)
|
|
setIsPlaying(true)
|
|
} catch (error) {
|
|
console.error('Failed to play animation:', error)
|
|
}
|
|
}
|
|
|
|
const stopAnimation = () => {
|
|
animationContext?.stopAnimation()
|
|
setIsPlaying(false)
|
|
}
|
|
|
|
return (
|
|
<div className="animated-character">
|
|
<div ref={containerRef} className="character-viewport" />
|
|
|
|
<div className="animation-controls">
|
|
<button onClick={() => playAnimation('walk_forward')}>
|
|
Walk
|
|
</button>
|
|
<button onClick={() => playAnimation('character_run')}>
|
|
Run
|
|
</button>
|
|
<button onClick={() => playAnimation('jump_high')}>
|
|
Jump
|
|
</button>
|
|
<button onClick={stopAnimation}>
|
|
Stop
|
|
</button>
|
|
</div>
|
|
|
|
<div className="animation-info">
|
|
<p>Current: {currentAnimation}</p>
|
|
<p>Status: {isPlaying ? 'Playing' : 'Stopped'}</p>
|
|
<p>Scheme: {namingScheme}</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}</code></pre>
|
|
</div>
|
|
|
|
<div id="conversion-example" class="example-detail">
|
|
<h3>Animation Name Conversion</h3>
|
|
<pre><code class="javascript">import { AnimationNameMapper } from '@kjanat/owen'
|
|
|
|
// Initialize the mapper
|
|
const mapper = new AnimationNameMapper()
|
|
|
|
// Single animation conversion
|
|
function convertAnimation(animationName, fromScheme, toScheme) {
|
|
try {
|
|
const converted = mapper.convert(animationName, toScheme, fromScheme)
|
|
console.log(`${fromScheme}: ${animationName} → ${toScheme}: ${converted}`)
|
|
return converted
|
|
} catch (error) {
|
|
console.error('Conversion failed:', error.message)
|
|
return null
|
|
}
|
|
}
|
|
|
|
// Batch conversion with validation
|
|
function convertAnimationBatch(animations, fromScheme, toScheme) {
|
|
const results = {
|
|
successful: [],
|
|
failed: [],
|
|
conflicts: []
|
|
}
|
|
|
|
animations.forEach(anim => {
|
|
try {
|
|
const converted = mapper.convert(anim, toScheme, fromScheme)
|
|
|
|
// Check for conflicts
|
|
if (results.successful.includes(converted)) {
|
|
results.conflicts.push({
|
|
original: anim,
|
|
converted,
|
|
conflict: 'Duplicate target name'
|
|
})
|
|
} else {
|
|
results.successful.push({
|
|
original: anim,
|
|
converted,
|
|
schemes: { from: fromScheme, to: toScheme }
|
|
})
|
|
}
|
|
} catch (error) {
|
|
results.failed.push({
|
|
original: anim,
|
|
error: error.message,
|
|
suggestions: mapper.suggestCorrections(anim, fromScheme)
|
|
})
|
|
}
|
|
})
|
|
|
|
return results
|
|
}
|
|
|
|
// Example usage
|
|
const legacyAnimations = [
|
|
'walk_forward', 'run_fast', 'jump_high',
|
|
'attack_sword', 'defend_shield', 'idle_breathing'
|
|
]
|
|
|
|
const conversionResults = convertAnimationBatch(
|
|
legacyAnimations,
|
|
'legacy',
|
|
'semantic'
|
|
)
|
|
|
|
console.log('Conversion Results:', conversionResults)</code></pre>
|
|
</div>
|
|
|
|
<div id="batch-example" class="example-detail">
|
|
<h3>Batch Processing Pipeline</h3>
|
|
<pre><code class="javascript">import { AnimationProcessor } from '@kjanat/owen'
|
|
import fs from 'fs/promises'
|
|
import path from 'path'
|
|
|
|
class AnimationBatchProcessor {
|
|
constructor(options = {}) {
|
|
this.processor = new AnimationProcessor(options)
|
|
this.inputDir = options.inputDir || './assets/raw'
|
|
this.outputDir = options.outputDir || './assets/processed'
|
|
this.targetScheme = options.targetScheme || 'semantic'
|
|
}
|
|
|
|
async processDirectory() {
|
|
console.log('Starting batch animation processing...')
|
|
|
|
try {
|
|
// Scan input directory
|
|
const files = await this.scanAnimationFiles()
|
|
console.log(`Found ${files.length} animation files`)
|
|
|
|
// Process each file
|
|
const results = await Promise.allSettled(
|
|
files.map(file => this.processFile(file))
|
|
)
|
|
|
|
// Generate summary report
|
|
const summary = this.generateSummary(results)
|
|
await this.saveReport(summary)
|
|
|
|
return summary
|
|
} catch (error) {
|
|
console.error('Batch processing failed:', error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async scanAnimationFiles() {
|
|
const files = []
|
|
const entries = await fs.readdir(this.inputDir, { withFileTypes: true })
|
|
|
|
for (const entry of entries) {
|
|
if (entry.isFile() && /\.(gltf|glb|fbx)$/i.test(entry.name)) {
|
|
files.push(path.join(this.inputDir, entry.name))
|
|
}
|
|
}
|
|
|
|
return files
|
|
}
|
|
|
|
async processFile(inputFile) {
|
|
const filename = path.basename(inputFile)
|
|
console.log(`Processing: ${filename}`)
|
|
|
|
try {
|
|
// Load and analyze animation
|
|
const animation = await this.processor.loadAnimation(inputFile)
|
|
|
|
// Convert naming scheme
|
|
const convertedName = this.processor.convertName(
|
|
animation.name,
|
|
this.targetScheme
|
|
)
|
|
|
|
// Apply optimizations
|
|
const optimized = await this.processor.optimize(animation)
|
|
|
|
// Save processed animation
|
|
const outputFile = path.join(this.outputDir, `${convertedName}.gltf`)
|
|
await this.processor.saveAnimation(optimized, outputFile)
|
|
|
|
return {
|
|
status: 'success',
|
|
inputFile,
|
|
outputFile,
|
|
originalName: animation.name,
|
|
convertedName,
|
|
size: optimized.size,
|
|
duration: optimized.duration
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
status: 'error',
|
|
inputFile,
|
|
error: error.message
|
|
}
|
|
}
|
|
}
|
|
|
|
generateSummary(results) {
|
|
const successful = results.filter(r => r.value?.status === 'success')
|
|
const failed = results.filter(r => r.status === 'rejected' || r.value?.status === 'error')
|
|
|
|
return {
|
|
timestamp: new Date().toISOString(),
|
|
total: results.length,
|
|
successful: successful.length,
|
|
failed: failed.length,
|
|
successRate: (successful.length / results.length * 100).toFixed(2),
|
|
details: {
|
|
successful: successful.map(r => r.value),
|
|
failed: failed.map(r => ({
|
|
file: r.value?.inputFile || 'unknown',
|
|
error: r.value?.error || r.reason
|
|
}))
|
|
}
|
|
}
|
|
}
|
|
|
|
async saveReport(summary) {
|
|
const reportPath = path.join(this.outputDir, 'processing-report.json')
|
|
await fs.mkdir(path.dirname(reportPath), { recursive: true })
|
|
await fs.writeFile(reportPath, JSON.stringify(summary, null, 2))
|
|
console.log(`Report saved: ${reportPath}`)
|
|
}
|
|
}
|
|
|
|
// Usage
|
|
const processor = new AnimationBatchProcessor({
|
|
inputDir: './assets/blender-exports',
|
|
outputDir: './assets/animations',
|
|
targetScheme: 'semantic'
|
|
})
|
|
|
|
processor.processDirectory().then(summary => {
|
|
console.log('Processing complete:', summary)
|
|
}).catch(error => {
|
|
console.error('Processing failed:', error)
|
|
process.exit(1)
|
|
})</code></pre>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
|
|
<footer class="demo-footer">
|
|
<div class="container">
|
|
<p>
|
|
© 2024 Owen Animation System. All examples are MIT licensed for
|
|
educational use.
|
|
</p>
|
|
</div>
|
|
</footer>
|
|
|
|
<script type="module" src="./js/examples.js"></script>
|
|
</body>
|
|
</html>
|