create-anima 0.1.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.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,252 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import readline from 'node:readline';
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const TEMPLATES = {
8
+ 'package.json': (name) => `{
9
+ "name": "${name}",
10
+ "private": true,
11
+ "version": "0.0.0",
12
+ "type": "module",
13
+ "scripts": {
14
+ "dev": "vite",
15
+ "build": "tsc -b && vite build",
16
+ "preview": "vite preview"
17
+ },
18
+ "dependencies": {
19
+ "@it-compiles/anima": "^0.1.1",
20
+ "@radix-ui/react-dialog": "^1.1.15",
21
+ "lucide-react": "^0.562.0",
22
+ "react": "^19.2.0",
23
+ "react-dom": "^19.2.0",
24
+ "tailwindcss": "^4.1.18",
25
+ "@tailwindcss/vite": "^4.1.18"
26
+ },
27
+ "devDependencies": {
28
+ "@types/react": "^19.2.5",
29
+ "@types/react-dom": "^19.2.3",
30
+ "@vitejs/plugin-react": "^5.1.1",
31
+ "typescript": "~5.9.3",
32
+ "vite": "^7.2.4"
33
+ }
34
+ }
35
+ `,
36
+ 'vite.config.ts': () => `import { defineConfig } from 'vite';
37
+ import react from '@vitejs/plugin-react';
38
+ import tailwindcss from '@tailwindcss/vite';
39
+ import { animaPlugin } from '@it-compiles/anima/vite';
40
+
41
+ export default defineConfig({
42
+ plugins: [react(), tailwindcss(), animaPlugin()],
43
+ });
44
+ `,
45
+ 'tsconfig.json': () => `{
46
+ "compilerOptions": {
47
+ "target": "ES2022",
48
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
49
+ "module": "ESNext",
50
+ "skipLibCheck": true,
51
+ "moduleResolution": "bundler",
52
+ "allowImportingTsExtensions": true,
53
+ "isolatedModules": true,
54
+ "moduleDetection": "force",
55
+ "noEmit": true,
56
+ "jsx": "react-jsx",
57
+ "strict": true,
58
+ "noUnusedLocals": true,
59
+ "noUnusedParameters": true,
60
+ "noFallthroughCasesInSwitch": true,
61
+ "noUncheckedSideEffectImports": true
62
+ },
63
+ "include": ["src"]
64
+ }
65
+ `,
66
+ 'index.html': (name) => `<!doctype html>
67
+ <html lang="en">
68
+ <head>
69
+ <meta charset="UTF-8" />
70
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
71
+ <title>${name}</title>
72
+ </head>
73
+ <body>
74
+ <div id="root"></div>
75
+ <script type="module" src="/src/main.tsx"></script>
76
+ </body>
77
+ </html>
78
+ `,
79
+ 'src/main.tsx': () => `import { StrictMode } from 'react';
80
+ import { createRoot } from 'react-dom/client';
81
+ import './index.css';
82
+ import App from './App';
83
+
84
+ createRoot(document.getElementById('root')!).render(
85
+ <StrictMode>
86
+ <App />
87
+ </StrictMode>,
88
+ );
89
+ `,
90
+ 'src/index.css': () => `@import "tailwindcss";
91
+
92
+ html, body, #root {
93
+ @apply h-full flex flex-col overflow-hidden bg-zinc-900 text-zinc-50;
94
+ }
95
+ `,
96
+ 'src/vite-env.d.ts': () => `/// <reference types="vite/client" />
97
+ `,
98
+ 'src/App.tsx': () => `import { useState } from 'react';
99
+ import { AnimaPlayer, RenderDialog } from '@it-compiles/anima/react';
100
+ import animation from './animation';
101
+
102
+ export default function App() {
103
+ const [renderOpen, setRenderOpen] = useState(false);
104
+
105
+ return (
106
+ <div className="h-full flex flex-col">
107
+ <div className="flex items-center justify-between p-4 border-b border-neutral-700">
108
+ <h1 className="text-lg font-medium">My Animation</h1>
109
+ <button
110
+ onClick={() => setRenderOpen(true)}
111
+ className="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white text-sm font-medium rounded transition-colors"
112
+ >
113
+ Render Video
114
+ </button>
115
+ </div>
116
+
117
+ <div className="flex-1 overflow-hidden">
118
+ <AnimaPlayer animation={animation} controls autoPlay />
119
+ </div>
120
+
121
+ <RenderDialog
122
+ open={renderOpen}
123
+ onOpenChange={setRenderOpen}
124
+ animation={animation}
125
+ />
126
+ </div>
127
+ );
128
+ }
129
+ `,
130
+ 'src/animation.ts': () => `import { defineAnimation, easeOut, easeBack, Screen } from '@it-compiles/anima';
131
+
132
+ export default defineAnimation((scene) => {
133
+ // Set background
134
+ scene.bg('#1a1a2e');
135
+
136
+ // Create objects
137
+ const title = scene.text('Hello, Anima!', {
138
+ size: 72,
139
+ color: '#ffffff',
140
+ font: 'system-ui',
141
+ });
142
+
143
+ const subtitle = scene.text('Edit src/animation.ts to get started', {
144
+ size: 24,
145
+ color: '#888888',
146
+ font: 'system-ui',
147
+ });
148
+
149
+ // Build timeline
150
+ return (t) => {
151
+ // Animate title
152
+ t.tween(800, easeBack, (ctx, u) => {
153
+ ctx.pin(title, 'center').to(Screen.at(0.5, 0.4), u);
154
+ ctx.scale(title).from(0).to(1, u);
155
+ ctx.opacity(title).from(0).to(1, u);
156
+ });
157
+
158
+ // Animate subtitle after title
159
+ t.tween(600, easeOut, (ctx, u) => {
160
+ ctx.pin(subtitle, 'center').to(Screen.at(0.5, 0.55), u);
161
+ ctx.opacity(subtitle).from(0).to(1, u);
162
+ });
163
+
164
+ // Hold for a moment
165
+ t.wait(1000);
166
+
167
+ // Fade out
168
+ t.tween(500, easeOut, (ctx, u) => {
169
+ ctx.opacity(title).to(0, u);
170
+ ctx.opacity(subtitle).to(0, u);
171
+ });
172
+ };
173
+ });
174
+ `,
175
+ };
176
+ async function prompt(question) {
177
+ const rl = readline.createInterface({
178
+ input: process.stdin,
179
+ output: process.stdout,
180
+ });
181
+ return new Promise((resolve) => {
182
+ rl.question(question, (answer) => {
183
+ rl.close();
184
+ resolve(answer.trim());
185
+ });
186
+ });
187
+ }
188
+ function isValidPackageName(name) {
189
+ return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(name);
190
+ }
191
+ function toValidPackageName(name) {
192
+ return name
193
+ .toLowerCase()
194
+ .replace(/\s+/g, '-')
195
+ .replace(/[^a-z0-9-~._]/g, '-')
196
+ .replace(/^[._-]+/, '')
197
+ .replace(/[._-]+$/, '');
198
+ }
199
+ async function main() {
200
+ console.log();
201
+ console.log(' \x1b[36m@it-compiles/anima\x1b[0m - Create Animation Project');
202
+ console.log();
203
+ let projectName = process.argv[2];
204
+ if (!projectName) {
205
+ projectName = await prompt(' Project name: ');
206
+ }
207
+ if (!projectName) {
208
+ console.log(' \x1b[31mProject name is required\x1b[0m');
209
+ process.exit(1);
210
+ }
211
+ const targetDir = path.resolve(process.cwd(), projectName);
212
+ const packageName = toValidPackageName(path.basename(targetDir));
213
+ if (!isValidPackageName(packageName)) {
214
+ console.log(` \x1b[31mInvalid package name: ${packageName}\x1b[0m`);
215
+ process.exit(1);
216
+ }
217
+ if (fs.existsSync(targetDir)) {
218
+ const files = fs.readdirSync(targetDir);
219
+ if (files.length > 0) {
220
+ console.log(` \x1b[31mDirectory ${projectName} is not empty\x1b[0m`);
221
+ process.exit(1);
222
+ }
223
+ }
224
+ else {
225
+ fs.mkdirSync(targetDir, { recursive: true });
226
+ }
227
+ console.log();
228
+ console.log(` Creating project in \x1b[32m${targetDir}\x1b[0m`);
229
+ console.log();
230
+ // Create src directory
231
+ fs.mkdirSync(path.join(targetDir, 'src'), { recursive: true });
232
+ // Write all template files
233
+ for (const [filePath, template] of Object.entries(TEMPLATES)) {
234
+ const content = typeof template === 'function'
235
+ ? template(packageName)
236
+ : template;
237
+ const fullPath = path.join(targetDir, filePath);
238
+ fs.writeFileSync(fullPath, content);
239
+ console.log(` \x1b[32m+\x1b[0m ${filePath}`);
240
+ }
241
+ console.log();
242
+ console.log(' \x1b[32mDone!\x1b[0m Now run:');
243
+ console.log();
244
+ console.log(` cd ${projectName}`);
245
+ console.log(' npm install');
246
+ console.log(' npm run dev');
247
+ console.log();
248
+ }
249
+ main().catch((err) => {
250
+ console.error(err);
251
+ process.exit(1);
252
+ });
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "create-anima",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "create-anima": "./dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist",
10
+ "template"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "dev": "tsc --watch"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^24.10.1",
18
+ "typescript": "~5.9.3"
19
+ }
20
+ }