Spaces:
Sleeping
Sleeping
upload
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitignore +7 -0
- Dockerfile +54 -0
- README.md +63 -10
- package.json +38 -0
- remotion/Root.tsx +96 -0
- remotion/index.tsx +8 -0
- src/player/animated/index.ts +3 -0
- src/player/animated/presets.ts +629 -0
- src/player/animated/text-animated-full.tsx +164 -0
- src/player/animated/text-animated-types/animations-in/background-in.tsx +71 -0
- src/player/animated/text-animated-types/animations-in/beatiful-question-in.tsx +49 -0
- src/player/animated/text-animated-types/animations-in/count-down-in.tsx +78 -0
- src/player/animated/text-animated-types/animations-in/descompress-in.tsx +36 -0
- src/player/animated/text-animated-types/animations-in/domino-dreams-in.tsx +43 -0
- src/player/animated/text-animated-types/animations-in/drop-in.tsx +36 -0
- src/player/animated/text-animated-types/animations-in/great-thinkers-in.tsx +43 -0
- src/player/animated/text-animated-types/animations-in/made-with-love-in.tsx +54 -0
- src/player/animated/text-animated-types/animations-in/reality-is-broken-in.tsx +71 -0
- src/player/animated/text-animated-types/animations-in/rising-strong-in.tsx +51 -0
- src/player/animated/text-animated-types/animations-in/sound-wave-in.tsx +150 -0
- src/player/animated/text-animated-types/animations-in/sunny-mornings-in.tsx +51 -0
- src/player/animated/text-animated-types/animations-in/text-animated-in.tsx +62 -0
- src/player/animated/text-animated-types/animations-in/type-writer-in.tsx +64 -0
- src/player/animated/text-animated-types/animations-loop/billboard.tsx +24 -0
- src/player/animated/text-animated-types/animations-loop/dragonfly.tsx +30 -0
- src/player/animated/text-animated-types/animations-loop/font-change.tsx +41 -0
- src/player/animated/text-animated-types/animations-loop/glitch.tsx +40 -0
- src/player/animated/text-animated-types/animations-loop/heartbeat.tsx +30 -0
- src/player/animated/text-animated-types/animations-loop/pulse.tsx +61 -0
- src/player/animated/text-animated-types/animations-loop/rotate-3d.tsx +49 -0
- src/player/animated/text-animated-types/animations-loop/shake-text.tsx +23 -0
- src/player/animated/text-animated-types/animations-loop/shaky-letters-text.tsx +33 -0
- src/player/animated/text-animated-types/animations-loop/spin.tsx +24 -0
- src/player/animated/text-animated-types/animations-loop/vintage.tsx +62 -0
- src/player/animated/text-animated-types/animations-loop/vogue.tsx +30 -0
- src/player/animated/text-animated-types/animations-loop/wave.tsx +26 -0
- src/player/animated/text-animated-types/animations-out/background-out.tsx +86 -0
- src/player/animated/text-animated-types/animations-out/beatiful-question-out.tsx +52 -0
- src/player/animated/text-animated-types/animations-out/descompress-out.tsx +41 -0
- src/player/animated/text-animated-types/animations-out/domino-dreams-out.tsx +47 -0
- src/player/animated/text-animated-types/animations-out/drop-out.tsx +42 -0
- src/player/animated/text-animated-types/animations-out/great-thinkers-out.tsx +46 -0
- src/player/animated/text-animated-types/animations-out/made-with-love-out.tsx +57 -0
- src/player/animated/text-animated-types/animations-out/reality-is-broken-out.tsx +69 -0
- src/player/animated/text-animated-types/animations-out/sunny-mornings-out.tsx +52 -0
- src/player/animated/text-animated-types/animations-out/text-animated-out.tsx +60 -0
- src/player/animated/text-animated-types/animations-out/type-writer-out.tsx +71 -0
- src/player/animated/text-animated.tsx +226 -0
- src/player/animated/types.ts +58 -0
- src/player/base-sequence.tsx +101 -0
.gitignore
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules/
|
| 2 |
+
dist/
|
| 3 |
+
videos/
|
| 4 |
+
jobs/
|
| 5 |
+
*.log
|
| 6 |
+
.env
|
| 7 |
+
.env.local
|
Dockerfile
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM node:20-slim
|
| 2 |
+
|
| 3 |
+
# Install FFmpeg and Chromium dependencies
|
| 4 |
+
RUN apt-get update && apt-get install -y \
|
| 5 |
+
ffmpeg \
|
| 6 |
+
chromium \
|
| 7 |
+
fonts-liberation \
|
| 8 |
+
libasound2 \
|
| 9 |
+
libatk-bridge2.0-0 \
|
| 10 |
+
libatk1.0-0 \
|
| 11 |
+
libatspi2.0-0 \
|
| 12 |
+
libcups2 \
|
| 13 |
+
libdbus-1-3 \
|
| 14 |
+
libdrm2 \
|
| 15 |
+
libgbm1 \
|
| 16 |
+
libgtk-3-0 \
|
| 17 |
+
libnspr4 \
|
| 18 |
+
libnss3 \
|
| 19 |
+
libxcomposite1 \
|
| 20 |
+
libxdamage1 \
|
| 21 |
+
libxfixes3 \
|
| 22 |
+
libxrandr2 \
|
| 23 |
+
xdg-utils \
|
| 24 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 25 |
+
|
| 26 |
+
# Set Chromium path for Puppeteer
|
| 27 |
+
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
|
| 28 |
+
|
| 29 |
+
WORKDIR /app
|
| 30 |
+
|
| 31 |
+
# Copy package files
|
| 32 |
+
COPY package*.json ./
|
| 33 |
+
|
| 34 |
+
# Install dependencies
|
| 35 |
+
RUN npm install --production
|
| 36 |
+
|
| 37 |
+
# Copy source files
|
| 38 |
+
COPY . .
|
| 39 |
+
|
| 40 |
+
# Build TypeScript
|
| 41 |
+
RUN npm run build
|
| 42 |
+
|
| 43 |
+
# Create directories for videos and jobs
|
| 44 |
+
RUN mkdir -p videos jobs
|
| 45 |
+
|
| 46 |
+
# Expose port 7860 (Hugging Face default)
|
| 47 |
+
EXPOSE 7860
|
| 48 |
+
|
| 49 |
+
# Set environment variables
|
| 50 |
+
ENV PORT=7860
|
| 51 |
+
ENV NODE_ENV=production
|
| 52 |
+
|
| 53 |
+
# Start the server
|
| 54 |
+
CMD ["npm", "start"]
|
README.md
CHANGED
|
@@ -1,10 +1,63 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# VEditor Render Server
|
| 2 |
+
|
| 3 |
+
Standalone render server for video generation using Remotion.
|
| 4 |
+
|
| 5 |
+
## Deploy to Hugging Face Spaces
|
| 6 |
+
|
| 7 |
+
1. Create a new Space with "Docker" SDK
|
| 8 |
+
2. Push this folder to the Space
|
| 9 |
+
3. Wait for build to complete
|
| 10 |
+
|
| 11 |
+
## API Endpoints
|
| 12 |
+
|
| 13 |
+
### POST /render
|
| 14 |
+
Start a new render job.
|
| 15 |
+
|
| 16 |
+
**Request:**
|
| 17 |
+
```json
|
| 18 |
+
{
|
| 19 |
+
"design": { ... },
|
| 20 |
+
"options": {
|
| 21 |
+
"fps": 30,
|
| 22 |
+
"width": 1920,
|
| 23 |
+
"height": 1080,
|
| 24 |
+
"format": "mp4"
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
```
|
| 28 |
+
|
| 29 |
+
**Response:**
|
| 30 |
+
```json
|
| 31 |
+
{
|
| 32 |
+
"jobId": "abc123",
|
| 33 |
+
"status": "pending"
|
| 34 |
+
}
|
| 35 |
+
```
|
| 36 |
+
|
| 37 |
+
### GET /render/:jobId
|
| 38 |
+
Check render status.
|
| 39 |
+
|
| 40 |
+
**Response:**
|
| 41 |
+
```json
|
| 42 |
+
{
|
| 43 |
+
"jobId": "abc123",
|
| 44 |
+
"status": "completed",
|
| 45 |
+
"progress": 100,
|
| 46 |
+
"outputUrl": "/videos/abc123.mp4"
|
| 47 |
+
}
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
### GET /videos/:filename
|
| 51 |
+
Download rendered video.
|
| 52 |
+
|
| 53 |
+
## Local Development
|
| 54 |
+
|
| 55 |
+
```bash
|
| 56 |
+
npm install
|
| 57 |
+
npm run dev
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
## Environment Variables
|
| 61 |
+
|
| 62 |
+
- `PORT`: Server port (default: 7860)
|
| 63 |
+
- `CONCURRENCY`: Render threads (default: 4)
|
package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "veditor-render-server",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"description": "Standalone render server for VEditor using Remotion",
|
| 5 |
+
"main": "dist/server.js",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"dev": "tsx watch src/server.ts",
|
| 8 |
+
"build": "tsc",
|
| 9 |
+
"start": "node dist/server.js",
|
| 10 |
+
"render": "tsx src/render.ts"
|
| 11 |
+
},
|
| 12 |
+
"dependencies": {
|
| 13 |
+
"@designcombo/events": "^0.0.1",
|
| 14 |
+
"@designcombo/state": "^0.0.1",
|
| 15 |
+
"@designcombo/transitions": "^0.0.1",
|
| 16 |
+
"@designcombo/types": "^0.0.1",
|
| 17 |
+
"@remotion/bundler": "4.0.407",
|
| 18 |
+
"@remotion/renderer": "4.0.407",
|
| 19 |
+
"cors": "^2.8.5",
|
| 20 |
+
"express": "^4.18.2",
|
| 21 |
+
"lodash": "^4.17.21",
|
| 22 |
+
"react": "^18.2.0",
|
| 23 |
+
"react-dom": "^18.2.0",
|
| 24 |
+
"remotion": "4.0.407",
|
| 25 |
+
"uuid": "^9.0.0",
|
| 26 |
+
"zustand": "^4.4.7"
|
| 27 |
+
},
|
| 28 |
+
"devDependencies": {
|
| 29 |
+
"@types/cors": "^2.8.17",
|
| 30 |
+
"@types/express": "^4.17.21",
|
| 31 |
+
"@types/lodash": "^4.14.202",
|
| 32 |
+
"@types/node": "^20.10.0",
|
| 33 |
+
"@types/react": "^18.2.43",
|
| 34 |
+
"@types/uuid": "^9.0.7",
|
| 35 |
+
"tsx": "^4.7.0",
|
| 36 |
+
"typescript": "^5.3.2"
|
| 37 |
+
}
|
| 38 |
+
}
|
remotion/Root.tsx
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Remotion Root - Entry point for Render Server
|
| 3 |
+
*
|
| 4 |
+
* Uses SSRComposition from the copied player folder.
|
| 5 |
+
*/
|
| 6 |
+
|
| 7 |
+
import React from "react";
|
| 8 |
+
import { Composition } from "remotion";
|
| 9 |
+
import { SSRComposition } from "../../../src/player/ssr-composition";
|
| 10 |
+
|
| 11 |
+
// Default design types
|
| 12 |
+
interface IDesign {
|
| 13 |
+
id?: string;
|
| 14 |
+
size?: { width: number; height: number };
|
| 15 |
+
fps?: number;
|
| 16 |
+
trackItemIds?: string[];
|
| 17 |
+
trackItemsMap?: Record<string, unknown>;
|
| 18 |
+
tracks?: unknown[];
|
| 19 |
+
transitionIds?: string[];
|
| 20 |
+
transitionsMap?: Record<string, unknown>;
|
| 21 |
+
duration?: number;
|
| 22 |
+
background?: string | { value: string };
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
interface ITrackItem {
|
| 26 |
+
display?: { from: number; to: number };
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
// Default empty design
|
| 30 |
+
const defaultDesign: IDesign = {
|
| 31 |
+
id: "default",
|
| 32 |
+
size: { width: 1920, height: 1080 },
|
| 33 |
+
fps: 30,
|
| 34 |
+
trackItemIds: [],
|
| 35 |
+
trackItemsMap: {},
|
| 36 |
+
tracks: [],
|
| 37 |
+
transitionIds: [],
|
| 38 |
+
transitionsMap: {},
|
| 39 |
+
duration: 5000,
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
// Calculate actual duration from track items
|
| 43 |
+
const calculateDesignDuration = (design: IDesign): number => {
|
| 44 |
+
const trackItems = Object.values(design.trackItemsMap || {}) as ITrackItem[];
|
| 45 |
+
|
| 46 |
+
if (trackItems.length === 0) {
|
| 47 |
+
return design.duration || 5000;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
const maxEndTime = Math.max(
|
| 51 |
+
...trackItems.map(item => item.display?.to || 0)
|
| 52 |
+
);
|
| 53 |
+
|
| 54 |
+
return maxEndTime || design.duration || 5000;
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
export const RemotionRoot: React.FC = () => {
|
| 58 |
+
return (
|
| 59 |
+
<>
|
| 60 |
+
<Composition
|
| 61 |
+
id="VEditor"
|
| 62 |
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
| 63 |
+
component={SSRComposition as React.ComponentType<any>}
|
| 64 |
+
durationInFrames={150}
|
| 65 |
+
fps={30}
|
| 66 |
+
width={1920}
|
| 67 |
+
height={1080}
|
| 68 |
+
defaultProps={{
|
| 69 |
+
design: defaultDesign,
|
| 70 |
+
}}
|
| 71 |
+
calculateMetadata={async ({ props }) => {
|
| 72 |
+
const design = (props as { design: IDesign }).design;
|
| 73 |
+
const fps = design.fps || 30;
|
| 74 |
+
|
| 75 |
+
const durationMs = calculateDesignDuration(design);
|
| 76 |
+
const durationInFrames = Math.max(1, Math.ceil((durationMs / 1000) * fps));
|
| 77 |
+
|
| 78 |
+
console.log('[Remotion] Metadata:', {
|
| 79 |
+
durationMs,
|
| 80 |
+
durationInFrames,
|
| 81 |
+
fps,
|
| 82 |
+
width: design.size?.width || 1920,
|
| 83 |
+
height: design.size?.height || 1080,
|
| 84 |
+
});
|
| 85 |
+
|
| 86 |
+
return {
|
| 87 |
+
durationInFrames,
|
| 88 |
+
fps,
|
| 89 |
+
width: design.size?.width || 1920,
|
| 90 |
+
height: design.size?.height || 1080,
|
| 91 |
+
};
|
| 92 |
+
}}
|
| 93 |
+
/>
|
| 94 |
+
</>
|
| 95 |
+
);
|
| 96 |
+
};
|
remotion/index.tsx
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Remotion Entry Point for Render Server
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
import { registerRoot } from 'remotion';
|
| 6 |
+
import { RemotionRoot } from './Root';
|
| 7 |
+
|
| 8 |
+
registerRoot(RemotionRoot);
|
src/player/animated/index.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export * from "./types";
|
| 2 |
+
|
| 3 |
+
export { presets } from "./presets";
|
src/player/animated/presets.ts
ADDED
|
@@ -0,0 +1,629 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Easing } from "remotion";
|
| 2 |
+
import { Animation } from "./types";
|
| 3 |
+
|
| 4 |
+
// Define preset names
|
| 5 |
+
export type PresetName =
|
| 6 |
+
| "fadeIn"
|
| 7 |
+
| "fadeOut"
|
| 8 |
+
| "scaleIn"
|
| 9 |
+
| "scaleOut"
|
| 10 |
+
| "slideInRight"
|
| 11 |
+
| "slideInLeft"
|
| 12 |
+
| "slideInTop"
|
| 13 |
+
| "slideInBottom"
|
| 14 |
+
| "slideOutRight"
|
| 15 |
+
| "slideOutLeft"
|
| 16 |
+
| "slideOutTop"
|
| 17 |
+
| "slideOutBottom"
|
| 18 |
+
| "rotateIn"
|
| 19 |
+
| "flipIn"
|
| 20 |
+
| "shakeHorizontalIn"
|
| 21 |
+
| "shakeVerticalIn"
|
| 22 |
+
| "shakeHorizontalOut"
|
| 23 |
+
| "shakeVerticalOut"
|
| 24 |
+
| "typeWriterIn"
|
| 25 |
+
| "typeWriterOut"
|
| 26 |
+
| "animatedTextIn"
|
| 27 |
+
| "sunnyMorningsAnimationIn"
|
| 28 |
+
| "dominoDreamsIn"
|
| 29 |
+
// | "thursdayIn"
|
| 30 |
+
| "greatThinkersAnimationIn"
|
| 31 |
+
| "beautifulQuestionsAnimationIn"
|
| 32 |
+
| "madeWithLoveAnimationIn"
|
| 33 |
+
// | "risingStrongAnimationIn"
|
| 34 |
+
| "realityIsBrokenAnimationIn"
|
| 35 |
+
| "animatedTextOut"
|
| 36 |
+
| "sunnyMorningsAnimationOut"
|
| 37 |
+
| "dominoDreamsAnimationOut"
|
| 38 |
+
| "beautifulQuestionsAnimationOut"
|
| 39 |
+
| "madeWithLoveAnimationOut"
|
| 40 |
+
| "realityIsBrokenAnimationOut"
|
| 41 |
+
| "greatThinkersAnimationOut"
|
| 42 |
+
| "vogueAnimationLoop"
|
| 43 |
+
| "dragonFlyAnimationLoop"
|
| 44 |
+
| "billboardAnimationLoop"
|
| 45 |
+
| "descompressAnimationIn"
|
| 46 |
+
| "dropAnimationIn"
|
| 47 |
+
| "dropAnimationOut"
|
| 48 |
+
| "descompressAnimationOut"
|
| 49 |
+
| "heartbeatAnimationLoop"
|
| 50 |
+
| "spinAnimationLoop"
|
| 51 |
+
| "waveAnimationLoop"
|
| 52 |
+
| "rotate3dAnimationLoop"
|
| 53 |
+
| "shakeTextAnimationLoop"
|
| 54 |
+
| "shakyLettersTextAnimationLoop"
|
| 55 |
+
| "vintageAnimationLoop"
|
| 56 |
+
| "textFontChangeAnimationLoop"
|
| 57 |
+
| "pulseAnimationLoop"
|
| 58 |
+
| "glitchAnimationLoop"
|
| 59 |
+
| "countDownAnimationIn"
|
| 60 |
+
| "soundWaveIn"
|
| 61 |
+
| "backgroundAnimationOut"
|
| 62 |
+
| "backgroundAnimationIn";
|
| 63 |
+
|
| 64 |
+
// Type-safe preset object
|
| 65 |
+
export const presets: Record<PresetName, Animation> = {
|
| 66 |
+
pulseAnimationLoop: {
|
| 67 |
+
property: "pulseTextAnimationLoop",
|
| 68 |
+
from: 0,
|
| 69 |
+
to: 1,
|
| 70 |
+
durationInFrames: 30,
|
| 71 |
+
ease: Easing.linear,
|
| 72 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 73 |
+
name: "Pulse Animation Loop"
|
| 74 |
+
},
|
| 75 |
+
glitchAnimationLoop: {
|
| 76 |
+
property: "glitchTextAnimationLoop",
|
| 77 |
+
from: 0,
|
| 78 |
+
to: 1,
|
| 79 |
+
durationInFrames: 30,
|
| 80 |
+
ease: Easing.linear,
|
| 81 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 82 |
+
name: "Glitch Animation Loop"
|
| 83 |
+
},
|
| 84 |
+
countDownAnimationIn: {
|
| 85 |
+
property: "countDownTextAnimationIn",
|
| 86 |
+
from: 0,
|
| 87 |
+
to: 1,
|
| 88 |
+
durationInFrames: 30,
|
| 89 |
+
ease: Easing.linear,
|
| 90 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 91 |
+
name: "Count Down Animation In"
|
| 92 |
+
},
|
| 93 |
+
soundWaveIn: {
|
| 94 |
+
property: "soundWaveTextAnimationIn",
|
| 95 |
+
from: 0,
|
| 96 |
+
to: 1,
|
| 97 |
+
durationInFrames: 30,
|
| 98 |
+
ease: Easing.linear,
|
| 99 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 100 |
+
name: "Sound Wave Animation In"
|
| 101 |
+
},
|
| 102 |
+
backgroundAnimationOut: {
|
| 103 |
+
property: "backgroundTextAnimationOut",
|
| 104 |
+
from: 0,
|
| 105 |
+
to: 1,
|
| 106 |
+
durationInFrames: 30,
|
| 107 |
+
ease: Easing.linear,
|
| 108 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 109 |
+
name: "Background Animation Out"
|
| 110 |
+
},
|
| 111 |
+
backgroundAnimationIn: {
|
| 112 |
+
property: "backgroundTextAnimationIn",
|
| 113 |
+
from: 0,
|
| 114 |
+
to: 1,
|
| 115 |
+
durationInFrames: 30,
|
| 116 |
+
ease: Easing.linear,
|
| 117 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 118 |
+
name: "Background Animation In"
|
| 119 |
+
},
|
| 120 |
+
textFontChangeAnimationLoop: {
|
| 121 |
+
property: "textFontChangeAnimationLoop",
|
| 122 |
+
from: 0,
|
| 123 |
+
to: 1,
|
| 124 |
+
durationInFrames: 30,
|
| 125 |
+
ease: Easing.linear,
|
| 126 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 127 |
+
name: "Font Change Animation Loop",
|
| 128 |
+
details: {
|
| 129 |
+
fonts: [
|
| 130 |
+
{
|
| 131 |
+
fontFamily: "Bangers-Regular",
|
| 132 |
+
url: "https://fonts.gstatic.com/s/bangers/v13/FeVQS0BTqb0h60ACL5la2bxii28.ttf"
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
fontFamily: "AnonymousPro-BoldItalic",
|
| 136 |
+
url: "https://fonts.gstatic.com/s/anonymouspro/v14/rP2ap2a15UIB7Un-bOeISG3pHl4OTCzc6IG30KqB9Q.ttf"
|
| 137 |
+
},
|
| 138 |
+
{
|
| 139 |
+
fontFamily: "Frijole",
|
| 140 |
+
url: "https://fonts.gstatic.com/s/frijole/v9/uU9PCBUR8oakM2BQ7xPb3vyHmlI.ttf"
|
| 141 |
+
},
|
| 142 |
+
{
|
| 143 |
+
fontFamily: "Bangers-Regular",
|
| 144 |
+
url: "https://fonts.gstatic.com/s/bangers/v13/FeVQS0BTqb0h60ACL5la2bxii28.ttf"
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
fontFamily: "Allura-Regular",
|
| 148 |
+
url: "https://fonts.gstatic.com/s/allura/v15/9oRPNYsQpS4zjuAPjAIXPtrrGA.ttf"
|
| 149 |
+
}
|
| 150 |
+
]
|
| 151 |
+
}
|
| 152 |
+
},
|
| 153 |
+
vintageAnimationLoop: {
|
| 154 |
+
property: "vintageTextAnimationLoop",
|
| 155 |
+
from: 0,
|
| 156 |
+
to: 1,
|
| 157 |
+
durationInFrames: 30,
|
| 158 |
+
ease: Easing.linear,
|
| 159 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 160 |
+
name: "Vintage Animation Loop"
|
| 161 |
+
},
|
| 162 |
+
shakyLettersTextAnimationLoop: {
|
| 163 |
+
property: "shakyLettersTextAnimationLoop",
|
| 164 |
+
from: 0,
|
| 165 |
+
to: 1,
|
| 166 |
+
durationInFrames: 30,
|
| 167 |
+
ease: Easing.linear,
|
| 168 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 169 |
+
name: "Shaky Letters Animation Loop"
|
| 170 |
+
},
|
| 171 |
+
shakeTextAnimationLoop: {
|
| 172 |
+
property: "shakeTextAnimationLoop",
|
| 173 |
+
from: 0,
|
| 174 |
+
to: 1,
|
| 175 |
+
durationInFrames: 30,
|
| 176 |
+
ease: Easing.linear,
|
| 177 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 178 |
+
name: "Shake Text Animation Loop"
|
| 179 |
+
},
|
| 180 |
+
rotate3dAnimationLoop: {
|
| 181 |
+
property: "rotate3dTextAnimationLoop",
|
| 182 |
+
from: 0,
|
| 183 |
+
to: 360,
|
| 184 |
+
durationInFrames: 30,
|
| 185 |
+
ease: Easing.linear,
|
| 186 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 187 |
+
name: "Rotate 3D Animation Loop"
|
| 188 |
+
},
|
| 189 |
+
heartbeatAnimationLoop: {
|
| 190 |
+
property: "heartbeatTextAnimationLoop",
|
| 191 |
+
from: 0,
|
| 192 |
+
to: 1,
|
| 193 |
+
durationInFrames: 30,
|
| 194 |
+
ease: Easing.linear,
|
| 195 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 196 |
+
name: "Heartbeat Animation Loop"
|
| 197 |
+
},
|
| 198 |
+
spinAnimationLoop: {
|
| 199 |
+
property: "spinTextAnimationLoop",
|
| 200 |
+
from: 0,
|
| 201 |
+
to: 1,
|
| 202 |
+
durationInFrames: 30,
|
| 203 |
+
ease: Easing.linear,
|
| 204 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 205 |
+
name: "Spin Animation Loop"
|
| 206 |
+
},
|
| 207 |
+
waveAnimationLoop: {
|
| 208 |
+
property: "waveTextAnimationLoop",
|
| 209 |
+
from: 0,
|
| 210 |
+
to: 1,
|
| 211 |
+
durationInFrames: 30,
|
| 212 |
+
ease: Easing.linear,
|
| 213 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 214 |
+
name: "Wave Animation Loop"
|
| 215 |
+
},
|
| 216 |
+
descompressAnimationIn: {
|
| 217 |
+
property: "descompressTextAnimationIn",
|
| 218 |
+
from: 0,
|
| 219 |
+
to: 1,
|
| 220 |
+
durationInFrames: 30,
|
| 221 |
+
ease: Easing.linear,
|
| 222 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 223 |
+
name: "Descompress Animation In"
|
| 224 |
+
},
|
| 225 |
+
dropAnimationIn: {
|
| 226 |
+
property: "dropTextAnimationIn",
|
| 227 |
+
from: 0,
|
| 228 |
+
to: 1,
|
| 229 |
+
durationInFrames: 30,
|
| 230 |
+
ease: Easing.linear,
|
| 231 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 232 |
+
name: "Drop Animation In"
|
| 233 |
+
},
|
| 234 |
+
dropAnimationOut: {
|
| 235 |
+
property: "dropTextAnimationOut",
|
| 236 |
+
from: 0,
|
| 237 |
+
to: 1,
|
| 238 |
+
durationInFrames: 30,
|
| 239 |
+
ease: Easing.linear,
|
| 240 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 241 |
+
name: "Drop Animation Out"
|
| 242 |
+
},
|
| 243 |
+
descompressAnimationOut: {
|
| 244 |
+
property: "descompressTextAnimationOut",
|
| 245 |
+
from: 0,
|
| 246 |
+
to: 1,
|
| 247 |
+
durationInFrames: 30,
|
| 248 |
+
ease: Easing.linear,
|
| 249 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 250 |
+
name: "Descompress Animation Out"
|
| 251 |
+
},
|
| 252 |
+
vogueAnimationLoop: {
|
| 253 |
+
property: "vogueTextAnimationLoop",
|
| 254 |
+
from: 0,
|
| 255 |
+
to: 1,
|
| 256 |
+
durationInFrames: 30,
|
| 257 |
+
ease: Easing.linear,
|
| 258 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 259 |
+
name: "Vogue Animation Loop"
|
| 260 |
+
},
|
| 261 |
+
dragonFlyAnimationLoop: {
|
| 262 |
+
property: "dragonFlyTextAnimationLoop",
|
| 263 |
+
from: 0,
|
| 264 |
+
to: 1,
|
| 265 |
+
durationInFrames: 30,
|
| 266 |
+
ease: Easing.linear,
|
| 267 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 268 |
+
name: "Dragon Fly Animation Loop"
|
| 269 |
+
},
|
| 270 |
+
billboardAnimationLoop: {
|
| 271 |
+
property: "billboardTextAnimationLoop",
|
| 272 |
+
from: 0,
|
| 273 |
+
to: 1,
|
| 274 |
+
durationInFrames: 30,
|
| 275 |
+
ease: Easing.linear,
|
| 276 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 277 |
+
name: "Billboard Animation Loop"
|
| 278 |
+
},
|
| 279 |
+
typeWriterOut: {
|
| 280 |
+
property: "typeWriterTextAnimationOut",
|
| 281 |
+
from: 0,
|
| 282 |
+
to: 1,
|
| 283 |
+
durationInFrames: 30,
|
| 284 |
+
ease: Easing.linear,
|
| 285 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 286 |
+
name: "Type Writer"
|
| 287 |
+
},
|
| 288 |
+
greatThinkersAnimationOut: {
|
| 289 |
+
property: "greatThinkersTextAnimationOut",
|
| 290 |
+
from: 0,
|
| 291 |
+
to: 1,
|
| 292 |
+
durationInFrames: 30,
|
| 293 |
+
ease: Easing.linear,
|
| 294 |
+
previewUrl: "https://cdn.designcombo.dev/animations/great-thinker-out.webp",
|
| 295 |
+
name: "Great Thinkers"
|
| 296 |
+
},
|
| 297 |
+
realityIsBrokenAnimationOut: {
|
| 298 |
+
property: "realityIsBrokenTextAnimationOut",
|
| 299 |
+
from: 0,
|
| 300 |
+
to: 1,
|
| 301 |
+
durationInFrames: 30,
|
| 302 |
+
ease: Easing.linear,
|
| 303 |
+
previewUrl:
|
| 304 |
+
"https://cdn.designcombo.dev/animations/realisty-is-broken-out.webp",
|
| 305 |
+
name: "Reality is Broken"
|
| 306 |
+
},
|
| 307 |
+
madeWithLoveAnimationOut: {
|
| 308 |
+
property: "madeWithLoveTextAnimationOut",
|
| 309 |
+
from: 0,
|
| 310 |
+
to: 1,
|
| 311 |
+
durationInFrames: 30,
|
| 312 |
+
ease: Easing.linear,
|
| 313 |
+
previewUrl:
|
| 314 |
+
"https://cdn.designcombo.dev/animations/made-with-love-out.webp",
|
| 315 |
+
name: "Made With Love"
|
| 316 |
+
},
|
| 317 |
+
realityIsBrokenAnimationIn: {
|
| 318 |
+
property: "realityIsBrokenTextAnimationIn",
|
| 319 |
+
from: 0,
|
| 320 |
+
to: 1,
|
| 321 |
+
durationInFrames: 30,
|
| 322 |
+
ease: Easing.linear,
|
| 323 |
+
previewUrl:
|
| 324 |
+
"https://cdn.designcombo.dev/animations/reality-is-broken-in.webp",
|
| 325 |
+
name: "Reality is Broken"
|
| 326 |
+
},
|
| 327 |
+
beautifulQuestionsAnimationOut: {
|
| 328 |
+
property: "beautifulQuestionsTextAnimationOut",
|
| 329 |
+
from: 0,
|
| 330 |
+
to: 1,
|
| 331 |
+
durationInFrames: 30,
|
| 332 |
+
ease: Easing.linear,
|
| 333 |
+
previewUrl:
|
| 334 |
+
"https://cdn.designcombo.dev/animations/beatiful-question-out.webp",
|
| 335 |
+
name: "Beautiful Questions"
|
| 336 |
+
},
|
| 337 |
+
animatedTextOut: {
|
| 338 |
+
property: "animatedTextOut",
|
| 339 |
+
from: 0,
|
| 340 |
+
to: 1,
|
| 341 |
+
durationInFrames: 30,
|
| 342 |
+
ease: Easing.linear,
|
| 343 |
+
previewUrl: "https://cdn.designcombo.dev/animations/animated-text-out.webp",
|
| 344 |
+
name: "Animated Text"
|
| 345 |
+
},
|
| 346 |
+
sunnyMorningsAnimationOut: {
|
| 347 |
+
property: "sunnyMorningsTextAnimationOut",
|
| 348 |
+
from: 0,
|
| 349 |
+
to: 1,
|
| 350 |
+
durationInFrames: 30,
|
| 351 |
+
ease: Easing.linear,
|
| 352 |
+
previewUrl:
|
| 353 |
+
"https://cdn.designcombo.dev/animations/sunny-mornings-out.webp",
|
| 354 |
+
name: "Sunny Mornings"
|
| 355 |
+
},
|
| 356 |
+
dominoDreamsAnimationOut: {
|
| 357 |
+
property: "dominoDreamsTextAnimationOut",
|
| 358 |
+
from: 0,
|
| 359 |
+
to: 1,
|
| 360 |
+
durationInFrames: 30,
|
| 361 |
+
ease: Easing.linear,
|
| 362 |
+
previewUrl: "https://cdn.designcombo.dev/animations/domino-dreams-out.webp",
|
| 363 |
+
name: "Domino Dreams"
|
| 364 |
+
},
|
| 365 |
+
madeWithLoveAnimationIn: {
|
| 366 |
+
property: "madeWithLoveTextAnimationIn",
|
| 367 |
+
from: 0,
|
| 368 |
+
to: 1,
|
| 369 |
+
durationInFrames: 30,
|
| 370 |
+
ease: Easing.linear,
|
| 371 |
+
previewUrl: "https://cdn.designcombo.dev/animations/made-with-love-in.webp",
|
| 372 |
+
name: "Made With Love"
|
| 373 |
+
},
|
| 374 |
+
beautifulQuestionsAnimationIn: {
|
| 375 |
+
property: "beautifulQuestionsTextAnimationIn",
|
| 376 |
+
from: 0,
|
| 377 |
+
to: 1,
|
| 378 |
+
durationInFrames: 30,
|
| 379 |
+
ease: Easing.linear,
|
| 380 |
+
previewUrl:
|
| 381 |
+
"https://cdn.designcombo.dev/animations/beautiful-questions-in.webp",
|
| 382 |
+
name: "Beatiful Questions"
|
| 383 |
+
},
|
| 384 |
+
greatThinkersAnimationIn: {
|
| 385 |
+
property: "greatThinkersTextAnimationIn",
|
| 386 |
+
from: 0,
|
| 387 |
+
to: 1,
|
| 388 |
+
durationInFrames: 30,
|
| 389 |
+
ease: Easing.linear,
|
| 390 |
+
previewUrl: "https://cdn.designcombo.dev/animations/great-thinker-in.webp",
|
| 391 |
+
name: "Great Thinkers"
|
| 392 |
+
},
|
| 393 |
+
// thursdayIn: {
|
| 394 |
+
// property: "textThursday",
|
| 395 |
+
// from: 0,
|
| 396 |
+
// to: 1,
|
| 397 |
+
// durationInFrames: 30,
|
| 398 |
+
// ease: Easing.linear,
|
| 399 |
+
// previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 400 |
+
// name: "TextThursday"
|
| 401 |
+
// },
|
| 402 |
+
dominoDreamsIn: {
|
| 403 |
+
property: "dominoDreamsTextAnimationIn",
|
| 404 |
+
from: 0,
|
| 405 |
+
to: 1,
|
| 406 |
+
durationInFrames: 30,
|
| 407 |
+
ease: Easing.linear,
|
| 408 |
+
previewUrl: "https://cdn.designcombo.dev/animations/domino-dreams-in.webp",
|
| 409 |
+
name: "Domino Dreams"
|
| 410 |
+
},
|
| 411 |
+
typeWriterIn: {
|
| 412 |
+
property: "typeWriterTextAnimationIn",
|
| 413 |
+
from: 0,
|
| 414 |
+
to: 1,
|
| 415 |
+
durationInFrames: 30,
|
| 416 |
+
ease: Easing.linear,
|
| 417 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 418 |
+
name: "Type Writer"
|
| 419 |
+
},
|
| 420 |
+
animatedTextIn: {
|
| 421 |
+
property: "animatedTextIn",
|
| 422 |
+
from: 0,
|
| 423 |
+
to: 1,
|
| 424 |
+
durationInFrames: 30,
|
| 425 |
+
ease: Easing.linear,
|
| 426 |
+
previewUrl: "https://cdn.designcombo.dev/animations/animated-text-in.webp",
|
| 427 |
+
name: "Animated Text"
|
| 428 |
+
},
|
| 429 |
+
sunnyMorningsAnimationIn: {
|
| 430 |
+
property: "sunnyMorningsTextAnimationIn",
|
| 431 |
+
from: 0,
|
| 432 |
+
to: 1,
|
| 433 |
+
durationInFrames: 30,
|
| 434 |
+
ease: Easing.linear,
|
| 435 |
+
previewUrl: "https://cdn.designcombo.dev/animations/sunny-mornings-in.webp",
|
| 436 |
+
name: "Sunny Mornings"
|
| 437 |
+
},
|
| 438 |
+
shakeHorizontalOut: {
|
| 439 |
+
property: "shakeHorizontalOut",
|
| 440 |
+
from: 0,
|
| 441 |
+
to: -0,
|
| 442 |
+
durationInFrames: 30,
|
| 443 |
+
ease: Easing.elastic(1),
|
| 444 |
+
previewUrl:
|
| 445 |
+
"https://cdn.designcombo.dev/animations/ShakeHorizontalOut.webp",
|
| 446 |
+
name: "Shake Horizontal"
|
| 447 |
+
},
|
| 448 |
+
|
| 449 |
+
shakeVerticalOut: {
|
| 450 |
+
property: "shakeVerticalOut",
|
| 451 |
+
from: 0,
|
| 452 |
+
to: -0,
|
| 453 |
+
durationInFrames: 30,
|
| 454 |
+
ease: Easing.elastic(1),
|
| 455 |
+
previewUrl: "https://cdn.designcombo.dev/animations/ShakeVerticalOut.webp",
|
| 456 |
+
name: "Shake Vertical"
|
| 457 |
+
},
|
| 458 |
+
|
| 459 |
+
shakeHorizontalIn: {
|
| 460 |
+
property: "shakeHorizontalIn",
|
| 461 |
+
from: 0,
|
| 462 |
+
to: -0,
|
| 463 |
+
durationInFrames: 30,
|
| 464 |
+
ease: Easing.elastic(1),
|
| 465 |
+
previewUrl: "https://cdn.designcombo.dev/animations/ShakeHorizontalIn.webp",
|
| 466 |
+
name: "Shake Horizontal"
|
| 467 |
+
},
|
| 468 |
+
|
| 469 |
+
shakeVerticalIn: {
|
| 470 |
+
property: "shakeVerticalIn",
|
| 471 |
+
from: 0,
|
| 472 |
+
to: -0,
|
| 473 |
+
durationInFrames: 30,
|
| 474 |
+
ease: Easing.elastic(1),
|
| 475 |
+
previewUrl: "https://cdn.designcombo.dev/animations/ShakeVerticalIn.webp",
|
| 476 |
+
name: "Shake Vertical"
|
| 477 |
+
},
|
| 478 |
+
|
| 479 |
+
rotateIn: {
|
| 480 |
+
property: "rotate",
|
| 481 |
+
from: 0,
|
| 482 |
+
to: 360,
|
| 483 |
+
durationInFrames: 30,
|
| 484 |
+
ease: Easing.linear,
|
| 485 |
+
previewUrl: "https://cdn.designcombo.dev/animations/scaleAndRotate.webp",
|
| 486 |
+
name: "Rotate"
|
| 487 |
+
},
|
| 488 |
+
|
| 489 |
+
flipIn: {
|
| 490 |
+
property: "rotateY",
|
| 491 |
+
from: -90,
|
| 492 |
+
to: 0,
|
| 493 |
+
durationInFrames: 30,
|
| 494 |
+
ease: Easing.linear,
|
| 495 |
+
previewUrl: "https://cdn.designcombo.dev/animations/flipIn.webp",
|
| 496 |
+
name: "Flip"
|
| 497 |
+
},
|
| 498 |
+
|
| 499 |
+
fadeIn: {
|
| 500 |
+
property: "opacity",
|
| 501 |
+
from: 0,
|
| 502 |
+
to: 1,
|
| 503 |
+
durationInFrames: 15,
|
| 504 |
+
ease: Easing.linear,
|
| 505 |
+
previewUrl: "https://cdn.designcombo.dev/animations/FadeIn.webp",
|
| 506 |
+
name: "Fade"
|
| 507 |
+
},
|
| 508 |
+
|
| 509 |
+
fadeOut: {
|
| 510 |
+
property: "opacity",
|
| 511 |
+
from: 1,
|
| 512 |
+
to: 0,
|
| 513 |
+
durationInFrames: 15,
|
| 514 |
+
ease: Easing.linear,
|
| 515 |
+
previewUrl: "https://cdn.designcombo.dev/animations/FadeOut.webp",
|
| 516 |
+
name: "Fade"
|
| 517 |
+
},
|
| 518 |
+
|
| 519 |
+
scaleIn: {
|
| 520 |
+
property: "scale",
|
| 521 |
+
from: 0,
|
| 522 |
+
to: 1,
|
| 523 |
+
durationInFrames: 15,
|
| 524 |
+
ease: Easing.ease,
|
| 525 |
+
previewUrl: "https://cdn.designcombo.dev/animations/ScaleIn.webp",
|
| 526 |
+
name: "Scale"
|
| 527 |
+
},
|
| 528 |
+
|
| 529 |
+
scaleOut: {
|
| 530 |
+
property: "scale",
|
| 531 |
+
from: 1,
|
| 532 |
+
to: 0,
|
| 533 |
+
durationInFrames: 15,
|
| 534 |
+
ease: Easing.ease,
|
| 535 |
+
previewUrl: "https://cdn.designcombo.dev/animations/ScaleOut.webp",
|
| 536 |
+
name: "Scale"
|
| 537 |
+
},
|
| 538 |
+
|
| 539 |
+
slideInRight: {
|
| 540 |
+
property: "translateX",
|
| 541 |
+
from: -900,
|
| 542 |
+
to: 0,
|
| 543 |
+
durationInFrames: 15,
|
| 544 |
+
delay: 0,
|
| 545 |
+
ease: Easing.ease,
|
| 546 |
+
previewUrl: "https://cdn.designcombo.dev/animations/SlideInRight.webp",
|
| 547 |
+
name: "Slide Right"
|
| 548 |
+
},
|
| 549 |
+
|
| 550 |
+
slideInLeft: {
|
| 551 |
+
property: "translateX",
|
| 552 |
+
from: 900,
|
| 553 |
+
to: 0,
|
| 554 |
+
durationInFrames: 15,
|
| 555 |
+
delay: 0,
|
| 556 |
+
ease: Easing.ease,
|
| 557 |
+
previewUrl: "https://cdn.designcombo.dev/animations/SlideInLeft.webp",
|
| 558 |
+
name: "Slide Left"
|
| 559 |
+
},
|
| 560 |
+
|
| 561 |
+
slideInTop: {
|
| 562 |
+
property: "translateY",
|
| 563 |
+
from: 900,
|
| 564 |
+
to: 0,
|
| 565 |
+
durationInFrames: 15,
|
| 566 |
+
delay: 0,
|
| 567 |
+
ease: Easing.ease,
|
| 568 |
+
previewUrl: "https://cdn.designcombo.dev/animations/SlideInTop.webp",
|
| 569 |
+
name: "Slide Top"
|
| 570 |
+
},
|
| 571 |
+
|
| 572 |
+
slideInBottom: {
|
| 573 |
+
property: "translateY",
|
| 574 |
+
from: -900,
|
| 575 |
+
to: 0,
|
| 576 |
+
durationInFrames: 15,
|
| 577 |
+
delay: 0,
|
| 578 |
+
ease: Easing.ease,
|
| 579 |
+
previewUrl: "https://cdn.designcombo.dev/animations/SlideInBottom.webp",
|
| 580 |
+
name: "Slide Bottom"
|
| 581 |
+
},
|
| 582 |
+
|
| 583 |
+
slideOutRight: {
|
| 584 |
+
property: "translateX",
|
| 585 |
+
from: 0,
|
| 586 |
+
to: -50,
|
| 587 |
+
durationInFrames: 15,
|
| 588 |
+
delay: 0,
|
| 589 |
+
ease: Easing.ease,
|
| 590 |
+
previewUrl: "https://cdn.designcombo.dev/animations/SlideOutRight.webp",
|
| 591 |
+
name: "Slide Right"
|
| 592 |
+
},
|
| 593 |
+
|
| 594 |
+
slideOutLeft: {
|
| 595 |
+
property: "translateX",
|
| 596 |
+
from: 0,
|
| 597 |
+
to: 50,
|
| 598 |
+
durationInFrames: 15,
|
| 599 |
+
delay: 0,
|
| 600 |
+
ease: Easing.ease,
|
| 601 |
+
previewUrl: "https://cdn.designcombo.dev/animations/SlideOutLeft.webp",
|
| 602 |
+
name: "Slide Left"
|
| 603 |
+
},
|
| 604 |
+
|
| 605 |
+
slideOutTop: {
|
| 606 |
+
property: "translateY",
|
| 607 |
+
from: 0,
|
| 608 |
+
to: 50,
|
| 609 |
+
durationInFrames: 15,
|
| 610 |
+
delay: 0,
|
| 611 |
+
ease: Easing.ease,
|
| 612 |
+
previewUrl: "https://cdn.designcombo.dev/animations/SlideOutUp.webp",
|
| 613 |
+
name: "Slide Top"
|
| 614 |
+
},
|
| 615 |
+
|
| 616 |
+
slideOutBottom: {
|
| 617 |
+
property: "translateY",
|
| 618 |
+
from: 0,
|
| 619 |
+
to: -50,
|
| 620 |
+
durationInFrames: 15,
|
| 621 |
+
delay: 0,
|
| 622 |
+
ease: Easing.ease,
|
| 623 |
+
previewUrl: "https://cdn.designcombo.dev/animations/slideOutDown.webp",
|
| 624 |
+
name: "Slide Bottom"
|
| 625 |
+
}
|
| 626 |
+
} as const;
|
| 627 |
+
|
| 628 |
+
// Export type for external usage
|
| 629 |
+
export type AnimationPresets = typeof presets;
|
src/player/animated/text-animated-full.tsx
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import TypeWriterIn from "./text-animated-types/animations-in/type-writer-in";
|
| 3 |
+
import TypeWriterOut from "./text-animated-types/animations-out/type-writer-out";
|
| 4 |
+
import BackgroundIn from "./text-animated-types/animations-in/background-in";
|
| 5 |
+
import BackgroundOut from "./text-animated-types/animations-out/background-out";
|
| 6 |
+
import SoundWaveIn from "./text-animated-types/animations-in/sound-wave-in";
|
| 7 |
+
import CountDownIn from "./text-animated-types/animations-in/count-down-in";
|
| 8 |
+
import Spin from "./text-animated-types/animations-loop/spin";
|
| 9 |
+
import Rotate3d from "./text-animated-types/animations-loop/rotate-3d";
|
| 10 |
+
import FontChange from "./text-animated-types/animations-loop/font-change";
|
| 11 |
+
import ShakeText from "./text-animated-types/animations-loop/shake-text";
|
| 12 |
+
import Vintage from "./text-animated-types/animations-loop/vintage";
|
| 13 |
+
import GlitchText from "./text-animated-types/animations-loop/glitch";
|
| 14 |
+
import { JSX } from "react";
|
| 15 |
+
|
| 16 |
+
type FullTextAnimationProps = {
|
| 17 |
+
frame: number;
|
| 18 |
+
text: string;
|
| 19 |
+
details: ITextDetails;
|
| 20 |
+
fps: number;
|
| 21 |
+
durationInFrames: number;
|
| 22 |
+
animationTextInFrames: number;
|
| 23 |
+
animationTextOutFrames: number;
|
| 24 |
+
animationTextLoopFrames: number;
|
| 25 |
+
animationFonts: { fontFamily: string; url: string }[];
|
| 26 |
+
validAnimIn: boolean;
|
| 27 |
+
validAnimOut: boolean;
|
| 28 |
+
textAnimationNameIn: string;
|
| 29 |
+
textAnimationNameOut: string;
|
| 30 |
+
textAnimationNameLoop: string;
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
export const renderFullTextAnimation = ({
|
| 34 |
+
frame,
|
| 35 |
+
text,
|
| 36 |
+
details,
|
| 37 |
+
fps,
|
| 38 |
+
durationInFrames,
|
| 39 |
+
animationTextInFrames,
|
| 40 |
+
animationTextOutFrames,
|
| 41 |
+
animationFonts,
|
| 42 |
+
validAnimIn,
|
| 43 |
+
validAnimOut,
|
| 44 |
+
textAnimationNameIn,
|
| 45 |
+
textAnimationNameOut,
|
| 46 |
+
textAnimationNameLoop
|
| 47 |
+
}: FullTextAnimationProps): JSX.Element | null => {
|
| 48 |
+
// Animaciones de entrada
|
| 49 |
+
if (validAnimIn) {
|
| 50 |
+
if (textAnimationNameIn === "typeWriterIn") {
|
| 51 |
+
return (
|
| 52 |
+
<TypeWriterIn
|
| 53 |
+
frame={frame}
|
| 54 |
+
durationInFrames={animationTextInFrames}
|
| 55 |
+
text={text}
|
| 56 |
+
style={details}
|
| 57 |
+
/>
|
| 58 |
+
);
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
if (textAnimationNameIn === "backgroundAnimationIn") {
|
| 62 |
+
return (
|
| 63 |
+
<BackgroundIn
|
| 64 |
+
text={text}
|
| 65 |
+
frame={frame}
|
| 66 |
+
details={details}
|
| 67 |
+
animationTextInFrames={animationTextInFrames}
|
| 68 |
+
/>
|
| 69 |
+
);
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
if (textAnimationNameIn === "soundWaveIn") {
|
| 73 |
+
return (
|
| 74 |
+
<SoundWaveIn
|
| 75 |
+
text={text}
|
| 76 |
+
frame={frame}
|
| 77 |
+
animationTextInFrames={animationTextInFrames}
|
| 78 |
+
details={details}
|
| 79 |
+
/>
|
| 80 |
+
);
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
if (textAnimationNameIn === "countDownAnimationIn") {
|
| 84 |
+
return (
|
| 85 |
+
<CountDownIn
|
| 86 |
+
text={text}
|
| 87 |
+
frame={frame}
|
| 88 |
+
animationTextInFrames={animationTextInFrames}
|
| 89 |
+
details={details}
|
| 90 |
+
/>
|
| 91 |
+
);
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
// Animaciones de salida
|
| 96 |
+
if (validAnimOut) {
|
| 97 |
+
if (textAnimationNameOut === "typeWriterOut") {
|
| 98 |
+
return (
|
| 99 |
+
<TypeWriterOut
|
| 100 |
+
frame={frame}
|
| 101 |
+
durationInFrames={durationInFrames}
|
| 102 |
+
text={text}
|
| 103 |
+
details={details}
|
| 104 |
+
animationDuration={animationTextOutFrames}
|
| 105 |
+
/>
|
| 106 |
+
);
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
if (textAnimationNameOut === "backgroundAnimationOut") {
|
| 110 |
+
return (
|
| 111 |
+
<BackgroundOut
|
| 112 |
+
text={text}
|
| 113 |
+
frame={frame}
|
| 114 |
+
animationTextOutFrames={animationTextOutFrames}
|
| 115 |
+
details={details}
|
| 116 |
+
durationInFrames={durationInFrames}
|
| 117 |
+
fps={fps}
|
| 118 |
+
/>
|
| 119 |
+
);
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
// Animaciones en bucle
|
| 124 |
+
if (!validAnimIn && !validAnimOut) {
|
| 125 |
+
if (textAnimationNameLoop === "spinAnimationLoop") {
|
| 126 |
+
return <Spin text={text} frame={frame} fps={fps} />;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
if (textAnimationNameLoop === "rotate3dAnimationLoop") {
|
| 130 |
+
return (
|
| 131 |
+
<Rotate3d
|
| 132 |
+
text={text}
|
| 133 |
+
frame={frame}
|
| 134 |
+
durationInFrames={durationInFrames}
|
| 135 |
+
/>
|
| 136 |
+
);
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
if (textAnimationNameLoop === "textFontChangeAnimationLoop") {
|
| 140 |
+
return (
|
| 141 |
+
<FontChange
|
| 142 |
+
text={text}
|
| 143 |
+
frame={frame}
|
| 144 |
+
details={details}
|
| 145 |
+
animationFonts={animationFonts}
|
| 146 |
+
/>
|
| 147 |
+
);
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
if (textAnimationNameLoop === "shakeTextAnimationLoop") {
|
| 151 |
+
return <ShakeText text={text} frame={frame} />;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
if (textAnimationNameLoop === "vintageAnimationLoop") {
|
| 155 |
+
return <Vintage text={text} frame={frame} details={details} fps={fps} />;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
if (textAnimationNameLoop === "glitchAnimationLoop") {
|
| 159 |
+
return <GlitchText text={text} frame={frame} />;
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
return null;
|
| 164 |
+
};
|
src/player/animated/text-animated-types/animations-in/background-in.tsx
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import { interpolate } from "remotion";
|
| 3 |
+
|
| 4 |
+
const BackgroundIn = ({
|
| 5 |
+
text,
|
| 6 |
+
frame,
|
| 7 |
+
details,
|
| 8 |
+
animationTextInFrames
|
| 9 |
+
}: {
|
| 10 |
+
text: string;
|
| 11 |
+
frame: number;
|
| 12 |
+
details: ITextDetails;
|
| 13 |
+
animationTextInFrames: number;
|
| 14 |
+
}) => {
|
| 15 |
+
const progress = interpolate(frame, [0, animationTextInFrames], [0, 1], {
|
| 16 |
+
extrapolateRight: "clamp"
|
| 17 |
+
});
|
| 18 |
+
const fullWidth = details.width;
|
| 19 |
+
const fullHeight = details.height;
|
| 20 |
+
|
| 21 |
+
const revealWidth = interpolate(progress, [0, 1], [0, fullWidth]);
|
| 22 |
+
const textTranslateX = interpolate(progress, [0, 1], [fullWidth / 2, 0]);
|
| 23 |
+
|
| 24 |
+
return (
|
| 25 |
+
<div
|
| 26 |
+
style={{
|
| 27 |
+
flex: 1,
|
| 28 |
+
position: "relative",
|
| 29 |
+
justifyContent: "flex-start",
|
| 30 |
+
alignItems: "center",
|
| 31 |
+
display: "flex",
|
| 32 |
+
width: details.width,
|
| 33 |
+
height: details.height
|
| 34 |
+
}}
|
| 35 |
+
>
|
| 36 |
+
<div
|
| 37 |
+
style={{
|
| 38 |
+
width: revealWidth,
|
| 39 |
+
height: fullHeight,
|
| 40 |
+
overflow: "hidden",
|
| 41 |
+
display: "flex",
|
| 42 |
+
position: "relative",
|
| 43 |
+
alignItems: "center",
|
| 44 |
+
justifyContent: "center",
|
| 45 |
+
backgroundColor: "white"
|
| 46 |
+
}}
|
| 47 |
+
>
|
| 48 |
+
<div
|
| 49 |
+
style={{
|
| 50 |
+
fontSize: parseFloat(details.fontSize.toString()),
|
| 51 |
+
display: "flex",
|
| 52 |
+
position: "absolute",
|
| 53 |
+
justifyContent: "center",
|
| 54 |
+
alignItems: "center",
|
| 55 |
+
width: details.width,
|
| 56 |
+
height: details.height,
|
| 57 |
+
color:
|
| 58 |
+
details.color === "white" || details.color.includes("fff")
|
| 59 |
+
? "black"
|
| 60 |
+
: details.color,
|
| 61 |
+
transform: `translateX(${textTranslateX * 2}px)`
|
| 62 |
+
}}
|
| 63 |
+
>
|
| 64 |
+
{text}
|
| 65 |
+
</div>
|
| 66 |
+
</div>
|
| 67 |
+
</div>
|
| 68 |
+
);
|
| 69 |
+
};
|
| 70 |
+
|
| 71 |
+
export default BackgroundIn;
|
src/player/animated/text-animated-types/animations-in/beatiful-question-in.tsx
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate, spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const BeatifulQuestionAnimationIn = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextInFrames
|
| 10 |
+
}: {
|
| 11 |
+
char: string;
|
| 12 |
+
index: number;
|
| 13 |
+
frame: number;
|
| 14 |
+
fps: number;
|
| 15 |
+
textLength: number;
|
| 16 |
+
animationTextInFrames: number;
|
| 17 |
+
}) => {
|
| 18 |
+
const totalDuration = animationTextInFrames;
|
| 19 |
+
const delayFactor = totalDuration / textLength;
|
| 20 |
+
const delay = index * delayFactor;
|
| 21 |
+
|
| 22 |
+
const translateY = spring({
|
| 23 |
+
frame: frame - delay,
|
| 24 |
+
fps,
|
| 25 |
+
from: 1.1,
|
| 26 |
+
to: 0,
|
| 27 |
+
config: { damping: 10 }
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
const opacity = interpolate(frame - delay, [0, totalDuration / 2], [0, 1], {
|
| 31 |
+
extrapolateRight: "clamp",
|
| 32 |
+
extrapolateLeft: "clamp"
|
| 33 |
+
});
|
| 34 |
+
|
| 35 |
+
return (
|
| 36 |
+
<span
|
| 37 |
+
key={index}
|
| 38 |
+
style={{
|
| 39 |
+
display: "inline-block",
|
| 40 |
+
transform: `translateY(${translateY}em)`,
|
| 41 |
+
opacity
|
| 42 |
+
}}
|
| 43 |
+
>
|
| 44 |
+
{char === " " ? " " : char}
|
| 45 |
+
</span>
|
| 46 |
+
);
|
| 47 |
+
};
|
| 48 |
+
|
| 49 |
+
export default BeatifulQuestionAnimationIn;
|
src/player/animated/text-animated-types/animations-in/count-down-in.tsx
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import { interpolate } from "remotion";
|
| 3 |
+
|
| 4 |
+
const numbers = ["3", "2", "1"];
|
| 5 |
+
|
| 6 |
+
const CountDownIn = ({
|
| 7 |
+
text,
|
| 8 |
+
frame,
|
| 9 |
+
animationTextInFrames,
|
| 10 |
+
details
|
| 11 |
+
}: {
|
| 12 |
+
text: string;
|
| 13 |
+
frame: number;
|
| 14 |
+
animationTextInFrames: number;
|
| 15 |
+
details: ITextDetails;
|
| 16 |
+
}) => {
|
| 17 |
+
const countdownFrames = (animationTextInFrames * 3) / 4;
|
| 18 |
+
const framesPerNumber = Math.floor(countdownFrames / numbers.length);
|
| 19 |
+
|
| 20 |
+
let displayText = "";
|
| 21 |
+
let localFrame = 0;
|
| 22 |
+
let duration = framesPerNumber;
|
| 23 |
+
let initialScale = 2;
|
| 24 |
+
let finalScale = 0.5;
|
| 25 |
+
let fontSize = parseFloat(details.fontSize.toString());
|
| 26 |
+
|
| 27 |
+
if (frame < countdownFrames) {
|
| 28 |
+
// Mostrar el número correspondiente
|
| 29 |
+
const idx = Math.floor(frame / framesPerNumber);
|
| 30 |
+
displayText = numbers[idx];
|
| 31 |
+
localFrame = frame - idx * framesPerNumber;
|
| 32 |
+
duration = framesPerNumber;
|
| 33 |
+
initialScale = 2;
|
| 34 |
+
finalScale = 0.5;
|
| 35 |
+
fontSize = parseFloat(details.fontSize.toString());
|
| 36 |
+
} else if (frame < animationTextInFrames) {
|
| 37 |
+
// Mostrar el texto final con animación
|
| 38 |
+
displayText = text;
|
| 39 |
+
localFrame = frame - countdownFrames;
|
| 40 |
+
duration = animationTextInFrames - countdownFrames;
|
| 41 |
+
initialScale = 2;
|
| 42 |
+
finalScale = 1;
|
| 43 |
+
fontSize = parseFloat(details.fontSize.toString());
|
| 44 |
+
} else {
|
| 45 |
+
// Después de la animación, mostrar el texto final estático
|
| 46 |
+
displayText = text;
|
| 47 |
+
localFrame = duration;
|
| 48 |
+
initialScale = 1;
|
| 49 |
+
finalScale = 1;
|
| 50 |
+
fontSize = parseFloat(details.fontSize.toString());
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
const progress = Math.min(localFrame / duration, 1);
|
| 54 |
+
const scale = interpolate(progress, [0, 1], [initialScale, finalScale]);
|
| 55 |
+
const opacity = interpolate(progress, [0, 1], [0.3, 1]);
|
| 56 |
+
const blur = interpolate(progress, [0, 1], [8, 0]);
|
| 57 |
+
|
| 58 |
+
return (
|
| 59 |
+
<span
|
| 60 |
+
style={{
|
| 61 |
+
opacity,
|
| 62 |
+
display: "flex",
|
| 63 |
+
width: details.width,
|
| 64 |
+
height: details.height,
|
| 65 |
+
textAlign: "center",
|
| 66 |
+
justifyContent: "center",
|
| 67 |
+
alignItems: "center",
|
| 68 |
+
transform: `scale(${scale})`,
|
| 69 |
+
filter: `blur(${blur}px)`,
|
| 70 |
+
fontSize: `${fontSize}px`
|
| 71 |
+
}}
|
| 72 |
+
>
|
| 73 |
+
{displayText}
|
| 74 |
+
</span>
|
| 75 |
+
);
|
| 76 |
+
};
|
| 77 |
+
|
| 78 |
+
export default CountDownIn;
|
src/player/animated/text-animated-types/animations-in/descompress-in.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const DescompressAnimationIn = ({
|
| 2 |
+
char,
|
| 3 |
+
index,
|
| 4 |
+
frame,
|
| 5 |
+
fps,
|
| 6 |
+
animationTextInFrames
|
| 7 |
+
}: {
|
| 8 |
+
char: string;
|
| 9 |
+
index: number;
|
| 10 |
+
frame: number;
|
| 11 |
+
fps: number;
|
| 12 |
+
animationTextInFrames: number;
|
| 13 |
+
}) => {
|
| 14 |
+
const endTime = animationTextInFrames / fps;
|
| 15 |
+
const time = frame / fps;
|
| 16 |
+
|
| 17 |
+
const progress = Math.min(Math.max(time / endTime, 0), 1);
|
| 18 |
+
|
| 19 |
+
const scaleX = 3 - progress * 2;
|
| 20 |
+
const opacity = progress;
|
| 21 |
+
|
| 22 |
+
return (
|
| 23 |
+
<span
|
| 24 |
+
key={index}
|
| 25 |
+
style={{
|
| 26 |
+
display: "inline-block",
|
| 27 |
+
transform: `scaleX(${scaleX})`,
|
| 28 |
+
opacity: opacity
|
| 29 |
+
}}
|
| 30 |
+
>
|
| 31 |
+
{char === " " ? " " : char}
|
| 32 |
+
</span>
|
| 33 |
+
);
|
| 34 |
+
};
|
| 35 |
+
|
| 36 |
+
export default DescompressAnimationIn;
|
src/player/animated/text-animated-types/animations-in/domino-dreams-in.tsx
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const DominoDreamsIn = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextInFrames
|
| 10 |
+
}: {
|
| 11 |
+
char: string;
|
| 12 |
+
index: number;
|
| 13 |
+
frame: number;
|
| 14 |
+
fps: number;
|
| 15 |
+
textLength: number;
|
| 16 |
+
animationTextInFrames: number;
|
| 17 |
+
}) => {
|
| 18 |
+
const totalDuration = animationTextInFrames;
|
| 19 |
+
const delayFactor = totalDuration / textLength;
|
| 20 |
+
const delay = index * delayFactor;
|
| 21 |
+
|
| 22 |
+
const rotateY = spring({
|
| 23 |
+
frame: frame - delay,
|
| 24 |
+
fps,
|
| 25 |
+
from: -90,
|
| 26 |
+
to: 0,
|
| 27 |
+
config: { mass: 1, damping: 12 }
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
return (
|
| 31 |
+
<span
|
| 32 |
+
key={index}
|
| 33 |
+
style={{
|
| 34 |
+
display: "inline-block",
|
| 35 |
+
transform: `rotateY(${rotateY}deg)`
|
| 36 |
+
}}
|
| 37 |
+
>
|
| 38 |
+
{char === " " ? " " : char}
|
| 39 |
+
</span>
|
| 40 |
+
);
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
export default DominoDreamsIn;
|
src/player/animated/text-animated-types/animations-in/drop-in.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const DropAnimationIn = ({
|
| 2 |
+
char,
|
| 3 |
+
index,
|
| 4 |
+
frame,
|
| 5 |
+
fps,
|
| 6 |
+
animationTextInFrames
|
| 7 |
+
}: {
|
| 8 |
+
char: string;
|
| 9 |
+
index: number;
|
| 10 |
+
frame: number;
|
| 11 |
+
fps: number;
|
| 12 |
+
animationTextInFrames: number;
|
| 13 |
+
}) => {
|
| 14 |
+
const endTime = animationTextInFrames / fps;
|
| 15 |
+
const time = frame / fps;
|
| 16 |
+
|
| 17 |
+
const progress = Math.min(Math.max(time / endTime, 0), 1);
|
| 18 |
+
|
| 19 |
+
const scale = 3 - progress * 2;
|
| 20 |
+
const opacity = progress;
|
| 21 |
+
|
| 22 |
+
return (
|
| 23 |
+
<span
|
| 24 |
+
key={index}
|
| 25 |
+
style={{
|
| 26 |
+
display: "inline-block",
|
| 27 |
+
transform: `scale(${scale})`,
|
| 28 |
+
opacity: opacity
|
| 29 |
+
}}
|
| 30 |
+
>
|
| 31 |
+
{char === " " ? " " : char}
|
| 32 |
+
</span>
|
| 33 |
+
);
|
| 34 |
+
};
|
| 35 |
+
|
| 36 |
+
export default DropAnimationIn;
|
src/player/animated/text-animated-types/animations-in/great-thinkers-in.tsx
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const GetThinkersAnimationIn = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextInFrames
|
| 10 |
+
}: {
|
| 11 |
+
char: string;
|
| 12 |
+
index: number;
|
| 13 |
+
frame: number;
|
| 14 |
+
fps: number;
|
| 15 |
+
textLength: number;
|
| 16 |
+
animationTextInFrames: number;
|
| 17 |
+
}) => {
|
| 18 |
+
const totalDuration = animationTextInFrames;
|
| 19 |
+
const delayFactor = totalDuration / textLength;
|
| 20 |
+
const delay = index * delayFactor;
|
| 21 |
+
|
| 22 |
+
const opacity = spring({
|
| 23 |
+
frame: frame - delay,
|
| 24 |
+
fps,
|
| 25 |
+
from: 0,
|
| 26 |
+
to: 1,
|
| 27 |
+
config: { stiffness: 60, damping: 10 }
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
return (
|
| 31 |
+
<span
|
| 32 |
+
key={index}
|
| 33 |
+
style={{
|
| 34 |
+
display: "inline-block",
|
| 35 |
+
opacity
|
| 36 |
+
}}
|
| 37 |
+
>
|
| 38 |
+
{char === " " ? " " : char}
|
| 39 |
+
</span>
|
| 40 |
+
);
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
export default GetThinkersAnimationIn;
|
src/player/animated/text-animated-types/animations-in/made-with-love-in.tsx
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate, spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const MadeWithLoveAnimationIn = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextInFrames
|
| 10 |
+
}: {
|
| 11 |
+
char: string;
|
| 12 |
+
index: number;
|
| 13 |
+
frame: number;
|
| 14 |
+
fps: number;
|
| 15 |
+
textLength: number;
|
| 16 |
+
animationTextInFrames: number;
|
| 17 |
+
}) => {
|
| 18 |
+
const totalDuration = animationTextInFrames;
|
| 19 |
+
const delayFactor = totalDuration / textLength;
|
| 20 |
+
const delay = index * delayFactor; // Calculate delay for each letter
|
| 21 |
+
|
| 22 |
+
const translateY = spring({
|
| 23 |
+
frame: frame - delay,
|
| 24 |
+
fps,
|
| 25 |
+
from: -100,
|
| 26 |
+
to: 0,
|
| 27 |
+
config: { damping: 20, stiffness: 120 }
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
const opacity = interpolate(
|
| 31 |
+
frame - delay,
|
| 32 |
+
[0, totalDuration / 2], // Complete opacity ramp-up within half the duration
|
| 33 |
+
[0, 1],
|
| 34 |
+
{
|
| 35 |
+
extrapolateRight: "clamp",
|
| 36 |
+
extrapolateLeft: "clamp"
|
| 37 |
+
}
|
| 38 |
+
);
|
| 39 |
+
|
| 40 |
+
return (
|
| 41 |
+
<span
|
| 42 |
+
key={index}
|
| 43 |
+
style={{
|
| 44 |
+
display: "inline-block",
|
| 45 |
+
transform: `translateY(${translateY}px)`,
|
| 46 |
+
opacity
|
| 47 |
+
}}
|
| 48 |
+
>
|
| 49 |
+
{char === " " ? " " : char}
|
| 50 |
+
</span>
|
| 51 |
+
);
|
| 52 |
+
};
|
| 53 |
+
|
| 54 |
+
export default MadeWithLoveAnimationIn;
|
src/player/animated/text-animated-types/animations-in/reality-is-broken-in.tsx
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate, spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const RealityIsBrokenAnimationIn = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextInFrames
|
| 10 |
+
}: {
|
| 11 |
+
char: string;
|
| 12 |
+
index: number;
|
| 13 |
+
frame: number;
|
| 14 |
+
fps: number;
|
| 15 |
+
textLength: number;
|
| 16 |
+
animationTextInFrames: number;
|
| 17 |
+
}) => {
|
| 18 |
+
const totalDuration = animationTextInFrames;
|
| 19 |
+
const delayFactor = totalDuration / textLength;
|
| 20 |
+
const delay = index * delayFactor;
|
| 21 |
+
|
| 22 |
+
const translateY = spring({
|
| 23 |
+
frame: frame - delay,
|
| 24 |
+
fps,
|
| 25 |
+
from: 1.1,
|
| 26 |
+
to: 0,
|
| 27 |
+
config: { damping: 10 }
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
const translateX = spring({
|
| 31 |
+
frame: frame - delay,
|
| 32 |
+
fps,
|
| 33 |
+
from: 0.55,
|
| 34 |
+
to: 0,
|
| 35 |
+
config: { damping: 10 }
|
| 36 |
+
});
|
| 37 |
+
|
| 38 |
+
const rotateZ = spring({
|
| 39 |
+
frame: frame - delay,
|
| 40 |
+
fps,
|
| 41 |
+
from: 180,
|
| 42 |
+
to: 0,
|
| 43 |
+
config: { damping: 10 }
|
| 44 |
+
});
|
| 45 |
+
|
| 46 |
+
const opacity = interpolate(
|
| 47 |
+
frame,
|
| 48 |
+
[delay, delay + 15], // Adjust for opacity ramp-up
|
| 49 |
+
[0, 1],
|
| 50 |
+
{
|
| 51 |
+
extrapolateRight: "clamp",
|
| 52 |
+
extrapolateLeft: "clamp"
|
| 53 |
+
}
|
| 54 |
+
);
|
| 55 |
+
|
| 56 |
+
return (
|
| 57 |
+
<span
|
| 58 |
+
key={index}
|
| 59 |
+
style={{
|
| 60 |
+
display: "inline-block",
|
| 61 |
+
transformOrigin: "0 100%",
|
| 62 |
+
transform: `translateY(${translateY}em) translateX(${translateX}em) rotateZ(${rotateZ}deg)`,
|
| 63 |
+
opacity
|
| 64 |
+
}}
|
| 65 |
+
>
|
| 66 |
+
{char === " " ? " " : char}
|
| 67 |
+
</span>
|
| 68 |
+
);
|
| 69 |
+
};
|
| 70 |
+
|
| 71 |
+
export default RealityIsBrokenAnimationIn;
|
src/player/animated/text-animated-types/animations-in/rising-strong-in.tsx
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate } from "remotion";
|
| 2 |
+
|
| 3 |
+
const RisingStrongAnimationIn = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
textLength,
|
| 8 |
+
animationTextInFrames
|
| 9 |
+
}: {
|
| 10 |
+
char: string;
|
| 11 |
+
index: number;
|
| 12 |
+
frame: number;
|
| 13 |
+
textLength: number;
|
| 14 |
+
animationTextInFrames: number;
|
| 15 |
+
}) => {
|
| 16 |
+
const totalDuration = animationTextInFrames / 2;
|
| 17 |
+
const delayFactor = totalDuration / textLength;
|
| 18 |
+
const appearDelay = index * delayFactor;
|
| 19 |
+
|
| 20 |
+
// Adjust the disappearance to happen after the complete animation if needed
|
| 21 |
+
const disappearStart = totalDuration + appearDelay;
|
| 22 |
+
|
| 23 |
+
const opacity = interpolate(
|
| 24 |
+
frame - appearDelay,
|
| 25 |
+
[0, totalDuration / 2, disappearStart, disappearStart + totalDuration / 2],
|
| 26 |
+
[0, 1, 1, 0],
|
| 27 |
+
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
|
| 28 |
+
);
|
| 29 |
+
|
| 30 |
+
const translateY = interpolate(
|
| 31 |
+
frame - appearDelay,
|
| 32 |
+
[0, totalDuration],
|
| 33 |
+
[100, 0],
|
| 34 |
+
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
|
| 35 |
+
);
|
| 36 |
+
|
| 37 |
+
return (
|
| 38 |
+
<span
|
| 39 |
+
key={index}
|
| 40 |
+
style={{
|
| 41 |
+
display: "inline-block",
|
| 42 |
+
transform: `translateY(${translateY}px)`,
|
| 43 |
+
opacity
|
| 44 |
+
}}
|
| 45 |
+
>
|
| 46 |
+
{char === " " ? " " : char}
|
| 47 |
+
</span>
|
| 48 |
+
);
|
| 49 |
+
};
|
| 50 |
+
|
| 51 |
+
export default RisingStrongAnimationIn;
|
src/player/animated/text-animated-types/animations-in/sound-wave-in.tsx
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import { interpolate } from "remotion";
|
| 3 |
+
|
| 4 |
+
const SoundWaveIn = ({
|
| 5 |
+
text,
|
| 6 |
+
frame,
|
| 7 |
+
animationTextInFrames,
|
| 8 |
+
details
|
| 9 |
+
}: {
|
| 10 |
+
text: string;
|
| 11 |
+
frame: number;
|
| 12 |
+
animationTextInFrames: number;
|
| 13 |
+
details: ITextDetails;
|
| 14 |
+
}) => {
|
| 15 |
+
const waveDisappearStart = animationTextInFrames * 0.5;
|
| 16 |
+
const waveDisappearEnd = animationTextInFrames;
|
| 17 |
+
const trailCount = 8;
|
| 18 |
+
const baseScale = interpolate(frame, [0, waveDisappearStart], [0.5, 1], {
|
| 19 |
+
extrapolateRight: "clamp"
|
| 20 |
+
});
|
| 21 |
+
const mainScale = baseScale;
|
| 22 |
+
const mainBlur = 0;
|
| 23 |
+
const mainOpacity = 1;
|
| 24 |
+
const waveScaleX = interpolate(frame, [0, waveDisappearStart], [2, 1], {
|
| 25 |
+
extrapolateRight: "clamp"
|
| 26 |
+
});
|
| 27 |
+
const waveBlur =
|
| 28 |
+
frame < waveDisappearStart
|
| 29 |
+
? interpolate(frame, [0, waveDisappearStart], [20, 0], {
|
| 30 |
+
extrapolateRight: "clamp"
|
| 31 |
+
})
|
| 32 |
+
: interpolate(frame, [waveDisappearStart, waveDisappearEnd], [0, 40], {
|
| 33 |
+
extrapolateLeft: "clamp",
|
| 34 |
+
extrapolateRight: "clamp"
|
| 35 |
+
});
|
| 36 |
+
// Opacidad: de 0.7 a 1, luego a 0
|
| 37 |
+
const waveOpacity =
|
| 38 |
+
frame < waveDisappearStart
|
| 39 |
+
? interpolate(frame, [0, waveDisappearStart], [0.7, 1], {
|
| 40 |
+
extrapolateRight: "clamp"
|
| 41 |
+
})
|
| 42 |
+
: interpolate(frame, [waveDisappearStart, waveDisappearEnd], [1, 0], {
|
| 43 |
+
extrapolateLeft: "clamp",
|
| 44 |
+
extrapolateRight: "clamp"
|
| 45 |
+
});
|
| 46 |
+
|
| 47 |
+
const trails = [];
|
| 48 |
+
for (let i = trailCount; i > 0; i--) {
|
| 49 |
+
// Cada trail está más atrás en el tiempo
|
| 50 |
+
const trailFrame = Math.max(frame - i * 2, 0);
|
| 51 |
+
|
| 52 |
+
// Escalado y estiramiento X para el efecto de eco
|
| 53 |
+
const trailScale = interpolate(
|
| 54 |
+
trailFrame,
|
| 55 |
+
[0, waveDisappearStart],
|
| 56 |
+
[0.5, 1],
|
| 57 |
+
{ extrapolateRight: "clamp" }
|
| 58 |
+
);
|
| 59 |
+
// const trailScaleX = interpolate(
|
| 60 |
+
// trailFrame,
|
| 61 |
+
// [0, waveDisappearStart],
|
| 62 |
+
// [2.5, 1],
|
| 63 |
+
// { extrapolateRight: "clamp" },
|
| 64 |
+
// );
|
| 65 |
+
|
| 66 |
+
// Opacidad más baja para los trails lejanos
|
| 67 |
+
const trailOpacity = interpolate(
|
| 68 |
+
trailFrame,
|
| 69 |
+
[0, waveDisappearStart],
|
| 70 |
+
[0.15, 0],
|
| 71 |
+
{ extrapolateRight: "clamp" }
|
| 72 |
+
);
|
| 73 |
+
|
| 74 |
+
trails.push(
|
| 75 |
+
<span
|
| 76 |
+
key={i}
|
| 77 |
+
style={{
|
| 78 |
+
position: "absolute",
|
| 79 |
+
top: 0,
|
| 80 |
+
left: 0,
|
| 81 |
+
opacity: trailOpacity,
|
| 82 |
+
transform: `scale(${trailScale * 2})`,
|
| 83 |
+
pointerEvents: "none"
|
| 84 |
+
}}
|
| 85 |
+
>
|
| 86 |
+
{text}
|
| 87 |
+
</span>
|
| 88 |
+
);
|
| 89 |
+
}
|
| 90 |
+
return (
|
| 91 |
+
<div
|
| 92 |
+
style={{
|
| 93 |
+
display: "flex",
|
| 94 |
+
width: details.width,
|
| 95 |
+
height: details.height,
|
| 96 |
+
transform: `scale(${baseScale})`,
|
| 97 |
+
position: "relative"
|
| 98 |
+
}}
|
| 99 |
+
>
|
| 100 |
+
{/* Texto wave */}
|
| 101 |
+
|
| 102 |
+
<span
|
| 103 |
+
style={{
|
| 104 |
+
width: details.width,
|
| 105 |
+
height: details.height,
|
| 106 |
+
background: "transparent",
|
| 107 |
+
transform: `scale(${mainScale})`
|
| 108 |
+
}}
|
| 109 |
+
>
|
| 110 |
+
{text}
|
| 111 |
+
</span>
|
| 112 |
+
<span
|
| 113 |
+
style={{
|
| 114 |
+
position: "absolute",
|
| 115 |
+
opacity: waveOpacity,
|
| 116 |
+
width: details.width,
|
| 117 |
+
height: details.height,
|
| 118 |
+
transform: `scaleX(${waveScaleX})`,
|
| 119 |
+
filter: `blur(${waveBlur * 3}px)`
|
| 120 |
+
}}
|
| 121 |
+
>
|
| 122 |
+
{text}
|
| 123 |
+
</span>
|
| 124 |
+
{/* </span> */}
|
| 125 |
+
<span
|
| 126 |
+
style={{
|
| 127 |
+
opacity: mainOpacity,
|
| 128 |
+
filter: `blur(${mainBlur}px)`,
|
| 129 |
+
transform: `scale(${mainScale})`,
|
| 130 |
+
fontSize: parseFloat(details.fontSize.toString()),
|
| 131 |
+
position: "absolute",
|
| 132 |
+
width: details.width,
|
| 133 |
+
height: details.height
|
| 134 |
+
}}
|
| 135 |
+
>
|
| 136 |
+
<div
|
| 137 |
+
style={{
|
| 138 |
+
width: details.width,
|
| 139 |
+
height: details.height,
|
| 140 |
+
position: "relative"
|
| 141 |
+
}}
|
| 142 |
+
>
|
| 143 |
+
{trails}
|
| 144 |
+
</div>
|
| 145 |
+
</span>
|
| 146 |
+
</div>
|
| 147 |
+
);
|
| 148 |
+
};
|
| 149 |
+
|
| 150 |
+
export default SoundWaveIn;
|
src/player/animated/text-animated-types/animations-in/sunny-mornings-in.tsx
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate, spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const SunnyMorningsAnimationIn = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextInFrames
|
| 10 |
+
}: {
|
| 11 |
+
char: string;
|
| 12 |
+
index: number;
|
| 13 |
+
frame: number;
|
| 14 |
+
fps: number;
|
| 15 |
+
textLength: number;
|
| 16 |
+
animationTextInFrames: number;
|
| 17 |
+
}) => {
|
| 18 |
+
const totalDuration = animationTextInFrames;
|
| 19 |
+
const delayFactor = totalDuration / (textLength + 1);
|
| 20 |
+
const delay = index * delayFactor;
|
| 21 |
+
|
| 22 |
+
const scale = spring({
|
| 23 |
+
frame: frame - delay,
|
| 24 |
+
fps,
|
| 25 |
+
from: 4,
|
| 26 |
+
to: 1,
|
| 27 |
+
config: { mass: 1, damping: 10 }
|
| 28 |
+
});
|
| 29 |
+
|
| 30 |
+
const opacity = interpolate(
|
| 31 |
+
frame - delay,
|
| 32 |
+
[0, totalDuration / 2], // Ensure opacity fades in within half the duration
|
| 33 |
+
[0, 1],
|
| 34 |
+
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
|
| 35 |
+
);
|
| 36 |
+
|
| 37 |
+
return (
|
| 38 |
+
<span
|
| 39 |
+
key={index}
|
| 40 |
+
style={{
|
| 41 |
+
display: "inline-block",
|
| 42 |
+
transform: `scale(${scale})`,
|
| 43 |
+
opacity: opacity
|
| 44 |
+
}}
|
| 45 |
+
>
|
| 46 |
+
{char === " " ? " " : char}
|
| 47 |
+
</span>
|
| 48 |
+
);
|
| 49 |
+
};
|
| 50 |
+
|
| 51 |
+
export default SunnyMorningsAnimationIn;
|
src/player/animated/text-animated-types/animations-in/text-animated-in.tsx
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const AnimatedTextIn = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextInFrames
|
| 10 |
+
}: {
|
| 11 |
+
char: string;
|
| 12 |
+
index: number;
|
| 13 |
+
frame: number;
|
| 14 |
+
fps: number;
|
| 15 |
+
textLength: number;
|
| 16 |
+
animationTextInFrames: number;
|
| 17 |
+
}) => {
|
| 18 |
+
// Adjust delay based on total frames available for the entire animation
|
| 19 |
+
const totalDelay = animationTextInFrames;
|
| 20 |
+
const delayFactor = totalDelay / textLength;
|
| 21 |
+
const delay = index * delayFactor;
|
| 22 |
+
|
| 23 |
+
const opacity = spring({
|
| 24 |
+
frame: frame - delay,
|
| 25 |
+
fps,
|
| 26 |
+
from: 0,
|
| 27 |
+
to: 1,
|
| 28 |
+
config: { mass: 0.5, damping: 10 }
|
| 29 |
+
});
|
| 30 |
+
|
| 31 |
+
const y = spring({
|
| 32 |
+
frame: frame - delay,
|
| 33 |
+
fps,
|
| 34 |
+
from: -50,
|
| 35 |
+
to: 0,
|
| 36 |
+
config: { mass: 0.5, damping: 10 }
|
| 37 |
+
});
|
| 38 |
+
|
| 39 |
+
const rotate = spring({
|
| 40 |
+
frame: frame - delay,
|
| 41 |
+
fps,
|
| 42 |
+
from: -180,
|
| 43 |
+
to: 0,
|
| 44 |
+
config: { mass: 0.5, damping: 12 }
|
| 45 |
+
});
|
| 46 |
+
|
| 47 |
+
return (
|
| 48 |
+
<span
|
| 49 |
+
key={index}
|
| 50 |
+
style={{
|
| 51 |
+
display: "inline-block",
|
| 52 |
+
opacity,
|
| 53 |
+
transform: `translateY(${y}px) rotate(${rotate}deg)`,
|
| 54 |
+
transition: "all 0.05s ease-out"
|
| 55 |
+
}}
|
| 56 |
+
>
|
| 57 |
+
{char === " " ? " " : char}
|
| 58 |
+
</span>
|
| 59 |
+
);
|
| 60 |
+
};
|
| 61 |
+
|
| 62 |
+
export default AnimatedTextIn;
|
src/player/animated/text-animated-types/animations-in/type-writer-in.tsx
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import { useMemo } from "react";
|
| 3 |
+
import { interpolate } from "remotion";
|
| 4 |
+
|
| 5 |
+
export default function TypeWriterIn({
|
| 6 |
+
frame,
|
| 7 |
+
durationInFrames,
|
| 8 |
+
text,
|
| 9 |
+
style
|
| 10 |
+
}: {
|
| 11 |
+
frame: number;
|
| 12 |
+
durationInFrames: number;
|
| 13 |
+
text: string;
|
| 14 |
+
style: ITextDetails;
|
| 15 |
+
}) {
|
| 16 |
+
const visibleCharacters = Math.floor(
|
| 17 |
+
interpolate(frame, [0, durationInFrames], [0, text.length], {
|
| 18 |
+
extrapolateRight: "clamp"
|
| 19 |
+
})
|
| 20 |
+
);
|
| 21 |
+
|
| 22 |
+
const visibleText = useMemo(() => {
|
| 23 |
+
let count = 0;
|
| 24 |
+
return text
|
| 25 |
+
.split(" ")
|
| 26 |
+
.map((word) => {
|
| 27 |
+
if (count + word.length <= visibleCharacters) {
|
| 28 |
+
count += word.length + 1;
|
| 29 |
+
return word;
|
| 30 |
+
}
|
| 31 |
+
if (count < visibleCharacters) {
|
| 32 |
+
const partialWord = word.slice(0, visibleCharacters - count);
|
| 33 |
+
count = visibleCharacters;
|
| 34 |
+
return partialWord;
|
| 35 |
+
}
|
| 36 |
+
return "";
|
| 37 |
+
})
|
| 38 |
+
.join(" ");
|
| 39 |
+
}, [visibleCharacters]);
|
| 40 |
+
|
| 41 |
+
return (
|
| 42 |
+
<div
|
| 43 |
+
style={{
|
| 44 |
+
textAlign: "center"
|
| 45 |
+
}}
|
| 46 |
+
>
|
| 47 |
+
<span
|
| 48 |
+
style={{
|
| 49 |
+
fontSize: style.fontSize
|
| 50 |
+
}}
|
| 51 |
+
>
|
| 52 |
+
{visibleText}
|
| 53 |
+
</span>
|
| 54 |
+
<span
|
| 55 |
+
style={{
|
| 56 |
+
color: "#60a5fa",
|
| 57 |
+
opacity: frame % 15 < 7 ? 1 : 0
|
| 58 |
+
}}
|
| 59 |
+
>
|
| 60 |
+
|
|
| 61 |
+
</span>
|
| 62 |
+
</div>
|
| 63 |
+
);
|
| 64 |
+
}
|
src/player/animated/text-animated-types/animations-loop/billboard.tsx
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const BillboardText = ({
|
| 2 |
+
frame,
|
| 3 |
+
fps,
|
| 4 |
+
char
|
| 5 |
+
}: {
|
| 6 |
+
char: string;
|
| 7 |
+
frame: number;
|
| 8 |
+
fps: number;
|
| 9 |
+
}) => {
|
| 10 |
+
const scale = 1 + 0.2 * Math.sin((2 * Math.PI * frame) / (fps * 1)); // 1 ciclo por segundo
|
| 11 |
+
|
| 12 |
+
return (
|
| 13 |
+
<span
|
| 14 |
+
style={{
|
| 15 |
+
display: "inline-block",
|
| 16 |
+
transform: `scale(${scale})`
|
| 17 |
+
}}
|
| 18 |
+
>
|
| 19 |
+
{char}
|
| 20 |
+
</span>
|
| 21 |
+
);
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
+
export default BillboardText;
|
src/player/animated/text-animated-types/animations-loop/dragonfly.tsx
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const DragonflyText = ({
|
| 2 |
+
char,
|
| 3 |
+
frame,
|
| 4 |
+
fps
|
| 5 |
+
}: {
|
| 6 |
+
char: string;
|
| 7 |
+
frame: number;
|
| 8 |
+
fps: number;
|
| 9 |
+
}) => {
|
| 10 |
+
const t = frame / fps;
|
| 11 |
+
|
| 12 |
+
const x = 80 * Math.sin(t * 2 * Math.PI); // movimiento lateral
|
| 13 |
+
const y = 80 * Math.sin(t * 2.5 * Math.PI); // movimiento vertical
|
| 14 |
+
const rotate = 5 * Math.sin(t * 3 * Math.PI); // rotación en grados
|
| 15 |
+
const scale = 1 + 0.05 * Math.sin(t * 4 * Math.PI); // pequeño pulso
|
| 16 |
+
|
| 17 |
+
return (
|
| 18 |
+
<span
|
| 19 |
+
style={{
|
| 20 |
+
display: "inline-block",
|
| 21 |
+
transform: `translate(${x}px, ${y}px) rotate(${rotate}deg) scale(${scale})`,
|
| 22 |
+
transition: "transform 0.1s linear"
|
| 23 |
+
}}
|
| 24 |
+
>
|
| 25 |
+
{char}
|
| 26 |
+
</span>
|
| 27 |
+
);
|
| 28 |
+
};
|
| 29 |
+
|
| 30 |
+
export default DragonflyText;
|
src/player/animated/text-animated-types/animations-loop/font-change.tsx
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
|
| 3 |
+
const FontChange = ({
|
| 4 |
+
frame,
|
| 5 |
+
text,
|
| 6 |
+
details,
|
| 7 |
+
animationFonts
|
| 8 |
+
}: {
|
| 9 |
+
text: string;
|
| 10 |
+
frame: number;
|
| 11 |
+
details: ITextDetails;
|
| 12 |
+
animationFonts: { fontFamily: string; url: string }[];
|
| 13 |
+
}) => {
|
| 14 |
+
const totalFonts = [{ fontFamily: details.fontFamily }, ...animationFonts];
|
| 15 |
+
const cycleDuration = 30; // Duración de un ciclo completo en frames
|
| 16 |
+
const framesPerFont = cycleDuration / totalFonts.length; // Frames por cada fuente
|
| 17 |
+
|
| 18 |
+
const fontIndex = Math.floor((frame % cycleDuration) / framesPerFont);
|
| 19 |
+
|
| 20 |
+
return (
|
| 21 |
+
<div
|
| 22 |
+
style={{
|
| 23 |
+
width: "100%",
|
| 24 |
+
height: "100%",
|
| 25 |
+
position: "relative",
|
| 26 |
+
background: "transparent",
|
| 27 |
+
perspective: 1000 // necesaria para el efecto 3D
|
| 28 |
+
}}
|
| 29 |
+
>
|
| 30 |
+
<div
|
| 31 |
+
style={{
|
| 32 |
+
fontFamily: totalFonts[fontIndex].fontFamily
|
| 33 |
+
}}
|
| 34 |
+
>
|
| 35 |
+
{text}
|
| 36 |
+
</div>
|
| 37 |
+
</div>
|
| 38 |
+
);
|
| 39 |
+
};
|
| 40 |
+
|
| 41 |
+
export default FontChange;
|
src/player/animated/text-animated-types/animations-loop/glitch.tsx
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const GlitchText = ({ text, frame }: { text: string; frame: number }) => {
|
| 2 |
+
const glitchIntensity = Math.sin(frame / 10) * 10;
|
| 3 |
+
const rgbOffset = Math.sin(frame / 5) * 10;
|
| 4 |
+
|
| 5 |
+
return (
|
| 6 |
+
<span
|
| 7 |
+
style={{
|
| 8 |
+
display: "inline-block",
|
| 9 |
+
position: "relative",
|
| 10 |
+
opacity: 0.8
|
| 11 |
+
}}
|
| 12 |
+
>
|
| 13 |
+
<div
|
| 14 |
+
style={{
|
| 15 |
+
position: "absolute",
|
| 16 |
+
color: "cyan",
|
| 17 |
+
transform: `translate(${rgbOffset}px, ${glitchIntensity}px)`,
|
| 18 |
+
mixBlendMode: "screen"
|
| 19 |
+
}}
|
| 20 |
+
>
|
| 21 |
+
{text}
|
| 22 |
+
</div>
|
| 23 |
+
<div
|
| 24 |
+
style={{
|
| 25 |
+
position: "absolute",
|
| 26 |
+
color: "magenta",
|
| 27 |
+
transform: `translate(${-rgbOffset}px, ${-glitchIntensity}px)`,
|
| 28 |
+
mixBlendMode: "screen"
|
| 29 |
+
}}
|
| 30 |
+
>
|
| 31 |
+
{text}
|
| 32 |
+
</div>
|
| 33 |
+
<div style={{ color: "white" }}>
|
| 34 |
+
<span style={{ paddingInline: "10px" }}>{text}</span>
|
| 35 |
+
</div>
|
| 36 |
+
</span>
|
| 37 |
+
);
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
export default GlitchText;
|
src/player/animated/text-animated-types/animations-loop/heartbeat.tsx
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const Heartbeat = ({
|
| 2 |
+
char,
|
| 3 |
+
frame,
|
| 4 |
+
fps
|
| 5 |
+
}: {
|
| 6 |
+
char: string;
|
| 7 |
+
frame: number;
|
| 8 |
+
fps: number;
|
| 9 |
+
}) => {
|
| 10 |
+
const time = frame / fps;
|
| 11 |
+
const cycleDuration = 1;
|
| 12 |
+
const cycleTime = time % cycleDuration;
|
| 13 |
+
|
| 14 |
+
let scale = 1;
|
| 15 |
+
if (cycleTime < 0.2 || (cycleTime >= 0.3 && cycleTime < 0.5)) {
|
| 16 |
+
scale = 1 + Math.sin((cycleTime % 0.2) * Math.PI * 5) * 0.8;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
return (
|
| 20 |
+
<span
|
| 21 |
+
style={{
|
| 22 |
+
display: "inline-block",
|
| 23 |
+
transform: `scale(${scale})`
|
| 24 |
+
}}
|
| 25 |
+
>
|
| 26 |
+
{char}
|
| 27 |
+
</span>
|
| 28 |
+
);
|
| 29 |
+
};
|
| 30 |
+
export default Heartbeat;
|
src/player/animated/text-animated-types/animations-loop/pulse.tsx
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import { interpolate } from "remotion";
|
| 3 |
+
|
| 4 |
+
const PulseText = ({
|
| 5 |
+
char,
|
| 6 |
+
index,
|
| 7 |
+
frame,
|
| 8 |
+
details
|
| 9 |
+
}: {
|
| 10 |
+
char: string;
|
| 11 |
+
index: number;
|
| 12 |
+
frame: number;
|
| 13 |
+
details: ITextDetails;
|
| 14 |
+
}) => {
|
| 15 |
+
const delay = index * 6;
|
| 16 |
+
const pulse = interpolate(
|
| 17 |
+
((frame + 30 - delay) % 30) / 30,
|
| 18 |
+
[0, 0.5, 1],
|
| 19 |
+
[1, 1.2, 1],
|
| 20 |
+
{
|
| 21 |
+
extrapolateRight: "clamp"
|
| 22 |
+
}
|
| 23 |
+
);
|
| 24 |
+
const opacity = interpolate(
|
| 25 |
+
((frame + 30 - delay) % 30) / 30,
|
| 26 |
+
[0, 0.5, 1],
|
| 27 |
+
[0.5, 1, 0.5],
|
| 28 |
+
{
|
| 29 |
+
extrapolateRight: "clamp"
|
| 30 |
+
}
|
| 31 |
+
);
|
| 32 |
+
|
| 33 |
+
return (
|
| 34 |
+
<span
|
| 35 |
+
style={{
|
| 36 |
+
opacity: opacity,
|
| 37 |
+
position: "relative",
|
| 38 |
+
fontSize: parseFloat(details.fontSize.toString()) * pulse,
|
| 39 |
+
scale: pulse
|
| 40 |
+
}}
|
| 41 |
+
>
|
| 42 |
+
{char}
|
| 43 |
+
<div
|
| 44 |
+
style={{
|
| 45 |
+
position: "absolute",
|
| 46 |
+
top: "50%",
|
| 47 |
+
left: "50%",
|
| 48 |
+
transform: "translate(-50%, -50%)",
|
| 49 |
+
width: parseFloat(details.fontSize.toString()) * 1.5,
|
| 50 |
+
height: parseFloat(details.fontSize.toString()) * 1.5,
|
| 51 |
+
background: "rgba(255, 255, 255, 0.1)",
|
| 52 |
+
borderRadius: "50%",
|
| 53 |
+
filter: "blur(20px)",
|
| 54 |
+
opacity: opacity
|
| 55 |
+
}}
|
| 56 |
+
/>
|
| 57 |
+
</span>
|
| 58 |
+
);
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
export default PulseText;
|
src/player/animated/text-animated-types/animations-loop/rotate-3d.tsx
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate } from "remotion";
|
| 2 |
+
|
| 3 |
+
const Rotate3d = ({
|
| 4 |
+
frame,
|
| 5 |
+
durationInFrames,
|
| 6 |
+
text
|
| 7 |
+
}: {
|
| 8 |
+
text: string;
|
| 9 |
+
frame: number;
|
| 10 |
+
durationInFrames: number;
|
| 11 |
+
}) => {
|
| 12 |
+
const rotation = interpolate(frame, [0, durationInFrames / 2], [0, 360]);
|
| 13 |
+
const rotation2 = rotation - 90;
|
| 14 |
+
|
| 15 |
+
return (
|
| 16 |
+
<div
|
| 17 |
+
style={{
|
| 18 |
+
width: "100%",
|
| 19 |
+
height: "100%",
|
| 20 |
+
position: "relative",
|
| 21 |
+
background: "transparent",
|
| 22 |
+
perspective: 1000 // necesaria para el efecto 3D
|
| 23 |
+
}}
|
| 24 |
+
>
|
| 25 |
+
<div
|
| 26 |
+
style={{
|
| 27 |
+
transform: `rotateY(${rotation}deg)`,
|
| 28 |
+
transformStyle: "preserve-3d",
|
| 29 |
+
background: "transparent"
|
| 30 |
+
}}
|
| 31 |
+
>
|
| 32 |
+
{text}
|
| 33 |
+
</div>
|
| 34 |
+
<div
|
| 35 |
+
style={{
|
| 36 |
+
transform: `rotateY(${rotation2}deg)`,
|
| 37 |
+
transformStyle: "preserve-3d",
|
| 38 |
+
position: "absolute",
|
| 39 |
+
top: 0,
|
| 40 |
+
background: "transparent"
|
| 41 |
+
}}
|
| 42 |
+
>
|
| 43 |
+
{text}
|
| 44 |
+
</div>
|
| 45 |
+
</div>
|
| 46 |
+
);
|
| 47 |
+
};
|
| 48 |
+
|
| 49 |
+
export default Rotate3d;
|
src/player/animated/text-animated-types/animations-loop/shake-text.tsx
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
function random(seed: number) {
|
| 2 |
+
const x = Math.sin(seed) * 10000;
|
| 3 |
+
return x - Math.floor(x);
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
const ShakeText = ({ text, frame }: { text: string; frame: number }) => {
|
| 7 |
+
const offsetX = (random(frame) - 0.5) * 8; // entre -4 y 4 px
|
| 8 |
+
const offsetY = (random(frame + 999) - 0.5) * 8;
|
| 9 |
+
const rotate = (random(frame + 500) - 0.5) * 6; // entre -3 y 3 grados
|
| 10 |
+
|
| 11 |
+
return (
|
| 12 |
+
<span
|
| 13 |
+
style={{
|
| 14 |
+
display: "inline-block",
|
| 15 |
+
transform: `translate(${offsetX}px, ${offsetY}px) rotate(${rotate}deg)`
|
| 16 |
+
}}
|
| 17 |
+
>
|
| 18 |
+
{text}
|
| 19 |
+
</span>
|
| 20 |
+
);
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
export default ShakeText;
|
src/player/animated/text-animated-types/animations-loop/shaky-letters-text.tsx
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
function random(seed: number) {
|
| 2 |
+
const x = Math.sin(seed) * 10000;
|
| 3 |
+
return x - Math.floor(x);
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
const ShakyLettersText = ({
|
| 7 |
+
char,
|
| 8 |
+
index,
|
| 9 |
+
frame
|
| 10 |
+
}: {
|
| 11 |
+
char: string;
|
| 12 |
+
index: number;
|
| 13 |
+
frame: number;
|
| 14 |
+
}) => {
|
| 15 |
+
const seed = frame * 100 + index * 999;
|
| 16 |
+
const offsetX = (random(seed) - 0.5) * 8;
|
| 17 |
+
const offsetY = (random(seed + 1) - 0.5) * 8;
|
| 18 |
+
const rotate = (random(seed + 2) - 0.5) * 6;
|
| 19 |
+
|
| 20 |
+
return (
|
| 21 |
+
<span
|
| 22 |
+
key={index}
|
| 23 |
+
style={{
|
| 24 |
+
display: "inline-block",
|
| 25 |
+
transform: `translate(${offsetX}px, ${offsetY}px) rotate(${rotate}deg)`
|
| 26 |
+
}}
|
| 27 |
+
>
|
| 28 |
+
{char}
|
| 29 |
+
</span>
|
| 30 |
+
);
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
export default ShakyLettersText;
|
src/player/animated/text-animated-types/animations-loop/spin.tsx
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const Spin = ({
|
| 2 |
+
text,
|
| 3 |
+
frame,
|
| 4 |
+
fps
|
| 5 |
+
}: {
|
| 6 |
+
text: string;
|
| 7 |
+
frame: number;
|
| 8 |
+
fps: number;
|
| 9 |
+
}) => {
|
| 10 |
+
const t = frame / fps;
|
| 11 |
+
const rotateZ = t * 360;
|
| 12 |
+
|
| 13 |
+
return (
|
| 14 |
+
<span
|
| 15 |
+
style={{
|
| 16 |
+
display: "inline-block",
|
| 17 |
+
transform: `rotateZ(${rotateZ}deg)`
|
| 18 |
+
}}
|
| 19 |
+
>
|
| 20 |
+
{text}
|
| 21 |
+
</span>
|
| 22 |
+
);
|
| 23 |
+
};
|
| 24 |
+
export default Spin;
|
src/player/animated/text-animated-types/animations-loop/vintage.tsx
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate } from "remotion";
|
| 2 |
+
|
| 3 |
+
const TOTAL_LAYERS = 9;
|
| 4 |
+
|
| 5 |
+
const Vintage = ({
|
| 6 |
+
text,
|
| 7 |
+
frame,
|
| 8 |
+
details,
|
| 9 |
+
fps
|
| 10 |
+
}: {
|
| 11 |
+
text: string;
|
| 12 |
+
frame: number;
|
| 13 |
+
details: {
|
| 14 |
+
fontSize: number;
|
| 15 |
+
color: string;
|
| 16 |
+
};
|
| 17 |
+
fps: number;
|
| 18 |
+
}) => {
|
| 19 |
+
const duration = fps;
|
| 20 |
+
const half = duration / 2;
|
| 21 |
+
const layerCount = Math.round(
|
| 22 |
+
frame % fps <= half
|
| 23 |
+
? interpolate(frame % fps, [0, half], [1, TOTAL_LAYERS])
|
| 24 |
+
: interpolate(frame % fps, [half, duration], [TOTAL_LAYERS, 1])
|
| 25 |
+
);
|
| 26 |
+
|
| 27 |
+
return (
|
| 28 |
+
<div
|
| 29 |
+
style={{
|
| 30 |
+
width: "100%",
|
| 31 |
+
height: "100%",
|
| 32 |
+
position: "relative"
|
| 33 |
+
}}
|
| 34 |
+
>
|
| 35 |
+
{Array.from({ length: layerCount }).map((_, i) => {
|
| 36 |
+
const dx = i * 4;
|
| 37 |
+
const dy = -i * 2;
|
| 38 |
+
const opacity = 1 / (layerCount - i);
|
| 39 |
+
|
| 40 |
+
return (
|
| 41 |
+
<div
|
| 42 |
+
key={i}
|
| 43 |
+
style={{
|
| 44 |
+
position: "absolute",
|
| 45 |
+
transform: `translate(${dx * 4}px, ${dy * 4}px)`,
|
| 46 |
+
fontWeight: "bold",
|
| 47 |
+
fontSize: details.fontSize,
|
| 48 |
+
zIndex: i,
|
| 49 |
+
color: layerCount !== i + 1 ? "red" : details.color,
|
| 50 |
+
background: "transparent",
|
| 51 |
+
opacity
|
| 52 |
+
}}
|
| 53 |
+
>
|
| 54 |
+
{text}
|
| 55 |
+
</div>
|
| 56 |
+
);
|
| 57 |
+
})}
|
| 58 |
+
</div>
|
| 59 |
+
);
|
| 60 |
+
};
|
| 61 |
+
|
| 62 |
+
export default Vintage;
|
src/player/animated/text-animated-types/animations-loop/vogue.tsx
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const VogueLetterByLetter = ({
|
| 2 |
+
char,
|
| 3 |
+
frame,
|
| 4 |
+
fps,
|
| 5 |
+
index
|
| 6 |
+
}: {
|
| 7 |
+
char: string;
|
| 8 |
+
frame: number;
|
| 9 |
+
fps: number;
|
| 10 |
+
index: number;
|
| 11 |
+
}) => {
|
| 12 |
+
const delay = index * 4; // desfase por letra
|
| 13 |
+
const t = (frame - delay) / fps;
|
| 14 |
+
|
| 15 |
+
// Loop suave con rotación más notoria
|
| 16 |
+
const scale = 1 + 0.25 * Math.sin(t * 2 * Math.PI);
|
| 17 |
+
const rotateY = 40 * Math.sin(t * 2 * Math.PI);
|
| 18 |
+
|
| 19 |
+
return (
|
| 20 |
+
<span
|
| 21 |
+
style={{
|
| 22 |
+
display: "inline-block",
|
| 23 |
+
transform: `scale(${scale}) rotateY(${rotateY}deg)`
|
| 24 |
+
}}
|
| 25 |
+
>
|
| 26 |
+
{char}
|
| 27 |
+
</span>
|
| 28 |
+
);
|
| 29 |
+
};
|
| 30 |
+
export default VogueLetterByLetter;
|
src/player/animated/text-animated-types/animations-loop/wave.tsx
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const Wave = ({
|
| 2 |
+
char,
|
| 3 |
+
frame,
|
| 4 |
+
fps,
|
| 5 |
+
index
|
| 6 |
+
}: {
|
| 7 |
+
char: string;
|
| 8 |
+
frame: number;
|
| 9 |
+
fps: number;
|
| 10 |
+
index: number;
|
| 11 |
+
}) => {
|
| 12 |
+
const offset = index * 20;
|
| 13 |
+
const translateY = Math.sin((frame * 8 - offset) / fps) * 20;
|
| 14 |
+
|
| 15 |
+
return (
|
| 16 |
+
<span
|
| 17 |
+
style={{
|
| 18 |
+
display: "inline-block",
|
| 19 |
+
transform: `translateY(${translateY}px)`
|
| 20 |
+
}}
|
| 21 |
+
>
|
| 22 |
+
{char}
|
| 23 |
+
</span>
|
| 24 |
+
);
|
| 25 |
+
};
|
| 26 |
+
export default Wave;
|
src/player/animated/text-animated-types/animations-out/background-out.tsx
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import { interpolate } from "remotion";
|
| 3 |
+
|
| 4 |
+
const BackgroundOut = ({
|
| 5 |
+
text,
|
| 6 |
+
frame,
|
| 7 |
+
animationTextOutFrames,
|
| 8 |
+
details,
|
| 9 |
+
durationInFrames,
|
| 10 |
+
fps
|
| 11 |
+
}: {
|
| 12 |
+
text: string;
|
| 13 |
+
frame: number;
|
| 14 |
+
animationTextOutFrames: number;
|
| 15 |
+
details: ITextDetails;
|
| 16 |
+
durationInFrames: number;
|
| 17 |
+
fps: number;
|
| 18 |
+
}) => {
|
| 19 |
+
const start = durationInFrames - animationTextOutFrames;
|
| 20 |
+
const duration = animationTextOutFrames;
|
| 21 |
+
|
| 22 |
+
// Progreso de la animación de salida
|
| 23 |
+
const progress = interpolate(frame, [start, start + duration], [0, 1], {
|
| 24 |
+
extrapolateRight: "clamp"
|
| 25 |
+
});
|
| 26 |
+
const fullWidth = details.width;
|
| 27 |
+
const fullHeight = details.height;
|
| 28 |
+
|
| 29 |
+
// El rectángulo se reduce de ancho completo a 0
|
| 30 |
+
const revealWidth = interpolate(
|
| 31 |
+
Math.round(progress * 100),
|
| 32 |
+
[0, 100 - fps / 10],
|
| 33 |
+
[fullWidth, 0]
|
| 34 |
+
);
|
| 35 |
+
// El texto se mueve del centro hacia la derecha
|
| 36 |
+
const textTranslateX = interpolate(progress, [0, 1], [0, fullWidth * 2]);
|
| 37 |
+
|
| 38 |
+
return (
|
| 39 |
+
<div
|
| 40 |
+
style={{
|
| 41 |
+
flex: 1,
|
| 42 |
+
position: "relative",
|
| 43 |
+
justifyContent: "flex-start",
|
| 44 |
+
alignItems: "center",
|
| 45 |
+
display: "flex",
|
| 46 |
+
width: details.width,
|
| 47 |
+
height: details.height
|
| 48 |
+
}}
|
| 49 |
+
>
|
| 50 |
+
{/* Máscara que oculta el texto fuera del rectángulo */}
|
| 51 |
+
<div
|
| 52 |
+
style={{
|
| 53 |
+
width: revealWidth,
|
| 54 |
+
height: fullHeight,
|
| 55 |
+
overflow: "hidden",
|
| 56 |
+
display: "flex",
|
| 57 |
+
position: "relative",
|
| 58 |
+
alignItems: "center",
|
| 59 |
+
justifyContent: "center",
|
| 60 |
+
backgroundColor: "white"
|
| 61 |
+
}}
|
| 62 |
+
>
|
| 63 |
+
<div
|
| 64 |
+
style={{
|
| 65 |
+
fontSize: parseFloat(details.fontSize.toString()),
|
| 66 |
+
display: "flex",
|
| 67 |
+
position: "absolute",
|
| 68 |
+
justifyContent: "center",
|
| 69 |
+
alignItems: "center",
|
| 70 |
+
width: details.width,
|
| 71 |
+
height: details.height,
|
| 72 |
+
color:
|
| 73 |
+
details.color === "white" || details.color.includes("fff")
|
| 74 |
+
? "black"
|
| 75 |
+
: details.color,
|
| 76 |
+
transform: `translateX(${textTranslateX}px)`
|
| 77 |
+
}}
|
| 78 |
+
>
|
| 79 |
+
{text}
|
| 80 |
+
</div>
|
| 81 |
+
</div>
|
| 82 |
+
</div>
|
| 83 |
+
);
|
| 84 |
+
};
|
| 85 |
+
|
| 86 |
+
export default BackgroundOut;
|
src/player/animated/text-animated-types/animations-out/beatiful-question-out.tsx
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate, spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const BeatifulQuestionAnimationOut = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextOutFrames,
|
| 10 |
+
durationInFrames
|
| 11 |
+
}: {
|
| 12 |
+
char: string;
|
| 13 |
+
index: number;
|
| 14 |
+
frame: number;
|
| 15 |
+
fps: number;
|
| 16 |
+
textLength: number;
|
| 17 |
+
animationTextOutFrames: number;
|
| 18 |
+
durationInFrames: number;
|
| 19 |
+
}) => {
|
| 20 |
+
const exitDuration = animationTextOutFrames;
|
| 21 |
+
const delayPerChar = exitDuration / textLength;
|
| 22 |
+
const exitStart = durationInFrames - animationTextOutFrames;
|
| 23 |
+
const charExitStart = exitStart + index * delayPerChar;
|
| 24 |
+
const progress = frame - charExitStart;
|
| 25 |
+
|
| 26 |
+
const translateY = spring({
|
| 27 |
+
frame: progress,
|
| 28 |
+
fps,
|
| 29 |
+
from: 0,
|
| 30 |
+
to: 1.1,
|
| 31 |
+
config: { damping: 10 }
|
| 32 |
+
});
|
| 33 |
+
|
| 34 |
+
const opacity = interpolate(progress, [0, delayPerChar], [1, 0], {
|
| 35 |
+
extrapolateRight: "clamp",
|
| 36 |
+
extrapolateLeft: "clamp"
|
| 37 |
+
});
|
| 38 |
+
return (
|
| 39 |
+
<span
|
| 40 |
+
key={index}
|
| 41 |
+
style={{
|
| 42 |
+
display: "inline-block",
|
| 43 |
+
transform: `translateY(${translateY}em)`,
|
| 44 |
+
opacity
|
| 45 |
+
}}
|
| 46 |
+
>
|
| 47 |
+
{char === " " ? " " : char}
|
| 48 |
+
</span>
|
| 49 |
+
);
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
export default BeatifulQuestionAnimationOut;
|
src/player/animated/text-animated-types/animations-out/descompress-out.tsx
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const DescompressAnimationOut = ({
|
| 2 |
+
char,
|
| 3 |
+
index,
|
| 4 |
+
frame,
|
| 5 |
+
fps,
|
| 6 |
+
animationTextOutFrames,
|
| 7 |
+
durationInFrames
|
| 8 |
+
}: {
|
| 9 |
+
char: string;
|
| 10 |
+
index: number;
|
| 11 |
+
frame: number;
|
| 12 |
+
fps: number;
|
| 13 |
+
animationTextOutFrames: number;
|
| 14 |
+
durationInFrames: number;
|
| 15 |
+
}) => {
|
| 16 |
+
const startTime = (durationInFrames - animationTextOutFrames) / fps;
|
| 17 |
+
const endTime = durationInFrames / fps;
|
| 18 |
+
const time = frame / fps;
|
| 19 |
+
|
| 20 |
+
const progress = Math.min(
|
| 21 |
+
Math.max((time - startTime) / (endTime - startTime), 0),
|
| 22 |
+
1
|
| 23 |
+
);
|
| 24 |
+
const scaleX = 1 + progress;
|
| 25 |
+
const opacity = 1 - progress;
|
| 26 |
+
|
| 27 |
+
return (
|
| 28 |
+
<span
|
| 29 |
+
key={index}
|
| 30 |
+
style={{
|
| 31 |
+
display: "inline-block",
|
| 32 |
+
transform: `scaleX(${scaleX})`,
|
| 33 |
+
opacity: opacity
|
| 34 |
+
}}
|
| 35 |
+
>
|
| 36 |
+
{char === " " ? " " : char}
|
| 37 |
+
</span>
|
| 38 |
+
);
|
| 39 |
+
};
|
| 40 |
+
|
| 41 |
+
export default DescompressAnimationOut;
|
src/player/animated/text-animated-types/animations-out/domino-dreams-out.tsx
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const DominoDreamsAnimationOut = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextOutFrames,
|
| 10 |
+
durationInFrames
|
| 11 |
+
}: {
|
| 12 |
+
char: string;
|
| 13 |
+
index: number;
|
| 14 |
+
frame: number;
|
| 15 |
+
fps: number;
|
| 16 |
+
textLength: number;
|
| 17 |
+
animationTextOutFrames: number;
|
| 18 |
+
durationInFrames: number;
|
| 19 |
+
}) => {
|
| 20 |
+
const exitDuration = animationTextOutFrames;
|
| 21 |
+
const delayPerChar = exitDuration / textLength;
|
| 22 |
+
const exitStart = durationInFrames - animationTextOutFrames;
|
| 23 |
+
const charExitStart = exitStart + index * delayPerChar;
|
| 24 |
+
const progress = frame - charExitStart;
|
| 25 |
+
|
| 26 |
+
const rotateY = spring({
|
| 27 |
+
frame: progress,
|
| 28 |
+
fps,
|
| 29 |
+
from: 0,
|
| 30 |
+
to: 90,
|
| 31 |
+
config: { mass: 1, damping: 12 }
|
| 32 |
+
});
|
| 33 |
+
|
| 34 |
+
return (
|
| 35 |
+
<span
|
| 36 |
+
key={index}
|
| 37 |
+
style={{
|
| 38 |
+
display: "inline-block",
|
| 39 |
+
transform: `rotateY(${rotateY}deg)`
|
| 40 |
+
}}
|
| 41 |
+
>
|
| 42 |
+
{char === " " ? " " : char}
|
| 43 |
+
</span>
|
| 44 |
+
);
|
| 45 |
+
};
|
| 46 |
+
|
| 47 |
+
export default DominoDreamsAnimationOut;
|
src/player/animated/text-animated-types/animations-out/drop-out.tsx
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const DropAnimationOut = ({
|
| 2 |
+
char,
|
| 3 |
+
index,
|
| 4 |
+
frame,
|
| 5 |
+
fps,
|
| 6 |
+
animationTextOutFrames,
|
| 7 |
+
durationInFrames
|
| 8 |
+
}: {
|
| 9 |
+
char: string;
|
| 10 |
+
index: number;
|
| 11 |
+
frame: number;
|
| 12 |
+
fps: number;
|
| 13 |
+
animationTextOutFrames: number;
|
| 14 |
+
durationInFrames: number;
|
| 15 |
+
}) => {
|
| 16 |
+
const startTime = (durationInFrames - animationTextOutFrames) / fps;
|
| 17 |
+
const endTime = durationInFrames / fps;
|
| 18 |
+
const time = frame / fps;
|
| 19 |
+
|
| 20 |
+
const progress = Math.min(
|
| 21 |
+
Math.max((time - startTime) / (endTime - startTime), 0),
|
| 22 |
+
1
|
| 23 |
+
);
|
| 24 |
+
|
| 25 |
+
const scale = 1 + progress;
|
| 26 |
+
const opacity = 1 - progress;
|
| 27 |
+
|
| 28 |
+
return (
|
| 29 |
+
<span
|
| 30 |
+
key={index}
|
| 31 |
+
style={{
|
| 32 |
+
display: "inline-block",
|
| 33 |
+
transform: `scale(${scale})`,
|
| 34 |
+
opacity: opacity
|
| 35 |
+
}}
|
| 36 |
+
>
|
| 37 |
+
{char === " " ? " " : char}
|
| 38 |
+
</span>
|
| 39 |
+
);
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
export default DropAnimationOut;
|
src/player/animated/text-animated-types/animations-out/great-thinkers-out.tsx
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const GreatThinkersAnimationOut = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextOutFrames,
|
| 10 |
+
durationInFrames
|
| 11 |
+
}: {
|
| 12 |
+
char: string;
|
| 13 |
+
index: number;
|
| 14 |
+
frame: number;
|
| 15 |
+
fps: number;
|
| 16 |
+
textLength: number;
|
| 17 |
+
animationTextOutFrames: number;
|
| 18 |
+
durationInFrames: number;
|
| 19 |
+
}) => {
|
| 20 |
+
const exitStart = durationInFrames - animationTextOutFrames;
|
| 21 |
+
const delayPerChar = animationTextOutFrames / textLength;
|
| 22 |
+
const charExitStart = exitStart + index * delayPerChar;
|
| 23 |
+
const progress = frame - charExitStart;
|
| 24 |
+
|
| 25 |
+
const opacity = spring({
|
| 26 |
+
frame: progress,
|
| 27 |
+
fps,
|
| 28 |
+
from: 1,
|
| 29 |
+
to: 0,
|
| 30 |
+
config: { stiffness: 60, damping: 10 }
|
| 31 |
+
});
|
| 32 |
+
|
| 33 |
+
return (
|
| 34 |
+
<span
|
| 35 |
+
key={index}
|
| 36 |
+
style={{
|
| 37 |
+
display: "inline-block",
|
| 38 |
+
opacity
|
| 39 |
+
}}
|
| 40 |
+
>
|
| 41 |
+
{char === " " ? " " : char}
|
| 42 |
+
</span>
|
| 43 |
+
);
|
| 44 |
+
};
|
| 45 |
+
|
| 46 |
+
export default GreatThinkersAnimationOut;
|
src/player/animated/text-animated-types/animations-out/made-with-love-out.tsx
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate, spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const MadeWithLoveAnimationOut = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextOutFrames,
|
| 10 |
+
durationInFrames
|
| 11 |
+
}: {
|
| 12 |
+
char: string;
|
| 13 |
+
index: number;
|
| 14 |
+
frame: number;
|
| 15 |
+
fps: number;
|
| 16 |
+
textLength: number;
|
| 17 |
+
animationTextOutFrames: number;
|
| 18 |
+
durationInFrames: number;
|
| 19 |
+
}) => {
|
| 20 |
+
const exitStart = durationInFrames - animationTextOutFrames;
|
| 21 |
+
const delayPerChar = animationTextOutFrames / textLength;
|
| 22 |
+
const charExitStart = exitStart + index * delayPerChar;
|
| 23 |
+
const progress = frame - charExitStart;
|
| 24 |
+
|
| 25 |
+
const translateY = spring({
|
| 26 |
+
frame: progress,
|
| 27 |
+
fps,
|
| 28 |
+
from: 0,
|
| 29 |
+
to: 100, // Move text out of view
|
| 30 |
+
config: { damping: 20, stiffness: 120 }
|
| 31 |
+
});
|
| 32 |
+
|
| 33 |
+
const opacity = interpolate(
|
| 34 |
+
progress,
|
| 35 |
+
[0, delayPerChar], // Frames for opacity fade-out
|
| 36 |
+
[1, 0],
|
| 37 |
+
{
|
| 38 |
+
extrapolateRight: "clamp",
|
| 39 |
+
extrapolateLeft: "clamp"
|
| 40 |
+
}
|
| 41 |
+
);
|
| 42 |
+
|
| 43 |
+
return (
|
| 44 |
+
<span
|
| 45 |
+
key={index}
|
| 46 |
+
style={{
|
| 47 |
+
display: "inline-block",
|
| 48 |
+
transform: `translateY(${translateY}px)`,
|
| 49 |
+
opacity
|
| 50 |
+
}}
|
| 51 |
+
>
|
| 52 |
+
{char === " " ? "\u00A0" : char}
|
| 53 |
+
</span>
|
| 54 |
+
);
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
export default MadeWithLoveAnimationOut;
|
src/player/animated/text-animated-types/animations-out/reality-is-broken-out.tsx
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate, spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const RealityIsBrokenAnimationOut = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextOutFrames,
|
| 10 |
+
durationInFrames
|
| 11 |
+
}: {
|
| 12 |
+
char: string;
|
| 13 |
+
index: number;
|
| 14 |
+
frame: number;
|
| 15 |
+
fps: number;
|
| 16 |
+
textLength: number;
|
| 17 |
+
animationTextOutFrames: number;
|
| 18 |
+
durationInFrames: number;
|
| 19 |
+
}) => {
|
| 20 |
+
const exitStart = durationInFrames - animationTextOutFrames;
|
| 21 |
+
const delayPerChar = animationTextOutFrames / textLength;
|
| 22 |
+
const charExitStart = exitStart + index * delayPerChar;
|
| 23 |
+
const progress = frame - charExitStart;
|
| 24 |
+
|
| 25 |
+
const translateY = spring({
|
| 26 |
+
frame: progress,
|
| 27 |
+
fps,
|
| 28 |
+
from: 0,
|
| 29 |
+
to: 1,
|
| 30 |
+
config: { mass: 1, damping: 10 }
|
| 31 |
+
});
|
| 32 |
+
|
| 33 |
+
const translateX = spring({
|
| 34 |
+
frame: progress,
|
| 35 |
+
fps,
|
| 36 |
+
from: 0,
|
| 37 |
+
to: 0.55,
|
| 38 |
+
config: { mass: 1, damping: 10 }
|
| 39 |
+
});
|
| 40 |
+
|
| 41 |
+
const rotateZ = spring({
|
| 42 |
+
frame: progress,
|
| 43 |
+
fps,
|
| 44 |
+
from: 0,
|
| 45 |
+
to: 180,
|
| 46 |
+
config: { mass: 1, damping: 10 }
|
| 47 |
+
});
|
| 48 |
+
|
| 49 |
+
const opacity = interpolate(progress, [0, delayPerChar], [1, 0], {
|
| 50 |
+
extrapolateLeft: "clamp",
|
| 51 |
+
extrapolateRight: "clamp"
|
| 52 |
+
});
|
| 53 |
+
|
| 54 |
+
return (
|
| 55 |
+
<span
|
| 56 |
+
key={index}
|
| 57 |
+
style={{
|
| 58 |
+
display: "inline-block",
|
| 59 |
+
transformOrigin: "0 100%",
|
| 60 |
+
transform: `translateY(${translateY}em) translateX(${translateX}em) rotateZ(${rotateZ}deg)`,
|
| 61 |
+
opacity
|
| 62 |
+
}}
|
| 63 |
+
>
|
| 64 |
+
{char === " " ? "\u00A0" : char}
|
| 65 |
+
</span>
|
| 66 |
+
);
|
| 67 |
+
};
|
| 68 |
+
|
| 69 |
+
export default RealityIsBrokenAnimationOut;
|
src/player/animated/text-animated-types/animations-out/sunny-mornings-out.tsx
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { interpolate, spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const SunnyMorningsAnimationOut = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextOutFrames,
|
| 10 |
+
durationInFrames
|
| 11 |
+
}: {
|
| 12 |
+
char: string;
|
| 13 |
+
index: number;
|
| 14 |
+
frame: number;
|
| 15 |
+
fps: number;
|
| 16 |
+
textLength: number;
|
| 17 |
+
animationTextOutFrames: number;
|
| 18 |
+
durationInFrames: number;
|
| 19 |
+
}) => {
|
| 20 |
+
const exitStart = durationInFrames - animationTextOutFrames;
|
| 21 |
+
const delayPerChar = animationTextOutFrames / textLength;
|
| 22 |
+
|
| 23 |
+
const charExitStart = exitStart + index * delayPerChar;
|
| 24 |
+
const progress = frame - charExitStart;
|
| 25 |
+
|
| 26 |
+
const scale = spring({
|
| 27 |
+
frame: progress,
|
| 28 |
+
fps,
|
| 29 |
+
from: 1,
|
| 30 |
+
to: 0,
|
| 31 |
+
config: { mass: 1, damping: 10 }
|
| 32 |
+
});
|
| 33 |
+
|
| 34 |
+
const opacity = interpolate(progress, [0, delayPerChar], [1, 0], {
|
| 35 |
+
extrapolateLeft: "clamp",
|
| 36 |
+
extrapolateRight: "clamp"
|
| 37 |
+
});
|
| 38 |
+
|
| 39 |
+
return (
|
| 40 |
+
<span
|
| 41 |
+
key={index}
|
| 42 |
+
style={{
|
| 43 |
+
display: "inline-block",
|
| 44 |
+
transform: `scale(${scale})`,
|
| 45 |
+
opacity
|
| 46 |
+
}}
|
| 47 |
+
>
|
| 48 |
+
{char === " " ? " " : char}
|
| 49 |
+
</span>
|
| 50 |
+
);
|
| 51 |
+
};
|
| 52 |
+
export default SunnyMorningsAnimationOut;
|
src/player/animated/text-animated-types/animations-out/text-animated-out.tsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { spring } from "remotion";
|
| 2 |
+
|
| 3 |
+
const AnimatedTextOut = ({
|
| 4 |
+
char,
|
| 5 |
+
index,
|
| 6 |
+
frame,
|
| 7 |
+
fps,
|
| 8 |
+
textLength,
|
| 9 |
+
animationTextOutFrames,
|
| 10 |
+
durationInFrames
|
| 11 |
+
}: {
|
| 12 |
+
char: string;
|
| 13 |
+
index: number;
|
| 14 |
+
frame: number;
|
| 15 |
+
fps: number;
|
| 16 |
+
textLength: number;
|
| 17 |
+
animationTextOutFrames: number;
|
| 18 |
+
durationInFrames: number;
|
| 19 |
+
}) => {
|
| 20 |
+
const startExitFrame = durationInFrames - animationTextOutFrames;
|
| 21 |
+
const delay = (index / textLength) * (durationInFrames - startExitFrame);
|
| 22 |
+
|
| 23 |
+
const opacity = spring({
|
| 24 |
+
frame: frame - startExitFrame - delay,
|
| 25 |
+
fps,
|
| 26 |
+
from: 1,
|
| 27 |
+
to: 0,
|
| 28 |
+
config: { mass: 0.5, damping: 10 }
|
| 29 |
+
});
|
| 30 |
+
|
| 31 |
+
const y = spring({
|
| 32 |
+
frame: frame - startExitFrame - delay,
|
| 33 |
+
fps,
|
| 34 |
+
from: 0,
|
| 35 |
+
to: 50,
|
| 36 |
+
config: { mass: 0.5, damping: 10 }
|
| 37 |
+
});
|
| 38 |
+
|
| 39 |
+
const rotate = spring({
|
| 40 |
+
frame: frame - startExitFrame - delay,
|
| 41 |
+
fps,
|
| 42 |
+
from: 0,
|
| 43 |
+
to: 180,
|
| 44 |
+
config: { mass: 0.5, damping: 12 }
|
| 45 |
+
});
|
| 46 |
+
return (
|
| 47 |
+
<span
|
| 48 |
+
key={index}
|
| 49 |
+
style={{
|
| 50 |
+
display: "inline-block",
|
| 51 |
+
opacity,
|
| 52 |
+
transform: `translateY(${y}px) rotate(${rotate}deg)`
|
| 53 |
+
}}
|
| 54 |
+
>
|
| 55 |
+
{char === " " ? " " : char}
|
| 56 |
+
</span>
|
| 57 |
+
);
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
export default AnimatedTextOut;
|
src/player/animated/text-animated-types/animations-out/type-writer-out.tsx
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import { useMemo } from "react";
|
| 3 |
+
import { interpolate } from "remotion";
|
| 4 |
+
|
| 5 |
+
const TypeWriterOut = ({
|
| 6 |
+
animationDuration,
|
| 7 |
+
text,
|
| 8 |
+
details,
|
| 9 |
+
frame,
|
| 10 |
+
durationInFrames
|
| 11 |
+
}: {
|
| 12 |
+
animationDuration: number;
|
| 13 |
+
text: string;
|
| 14 |
+
details: ITextDetails;
|
| 15 |
+
frame: number;
|
| 16 |
+
durationInFrames: number;
|
| 17 |
+
}) => {
|
| 18 |
+
const visibleCharacters = Math.floor(
|
| 19 |
+
interpolate(
|
| 20 |
+
frame,
|
| 21 |
+
[durationInFrames - animationDuration, durationInFrames],
|
| 22 |
+
[text.length, 0],
|
| 23 |
+
{ extrapolateRight: "clamp" }
|
| 24 |
+
)
|
| 25 |
+
);
|
| 26 |
+
|
| 27 |
+
const visibleText = useMemo(() => {
|
| 28 |
+
let count = 0;
|
| 29 |
+
return text
|
| 30 |
+
.split(" ")
|
| 31 |
+
.map((word) => {
|
| 32 |
+
if (count + word.length <= visibleCharacters) {
|
| 33 |
+
count += word.length + 1; // Contamos el espacio
|
| 34 |
+
return word;
|
| 35 |
+
}
|
| 36 |
+
if (count < visibleCharacters) {
|
| 37 |
+
const partialWord = word.slice(0, visibleCharacters - count);
|
| 38 |
+
count = visibleCharacters;
|
| 39 |
+
return partialWord;
|
| 40 |
+
}
|
| 41 |
+
return "";
|
| 42 |
+
})
|
| 43 |
+
.join(" ");
|
| 44 |
+
}, [visibleCharacters]);
|
| 45 |
+
|
| 46 |
+
return (
|
| 47 |
+
<div
|
| 48 |
+
style={{
|
| 49 |
+
textAlign: "center"
|
| 50 |
+
}}
|
| 51 |
+
>
|
| 52 |
+
<span
|
| 53 |
+
style={{
|
| 54 |
+
fontSize: details.fontSize
|
| 55 |
+
}}
|
| 56 |
+
>
|
| 57 |
+
{visibleText}
|
| 58 |
+
</span>
|
| 59 |
+
<span
|
| 60 |
+
style={{
|
| 61 |
+
color: "#60a5fa",
|
| 62 |
+
opacity: frame % 15 < 7 ? 1 : 0
|
| 63 |
+
}}
|
| 64 |
+
>
|
| 65 |
+
|
|
| 66 |
+
</span>
|
| 67 |
+
</div>
|
| 68 |
+
);
|
| 69 |
+
};
|
| 70 |
+
|
| 71 |
+
export default TypeWriterOut;
|
src/player/animated/text-animated.tsx
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ITextDetails } from "@designcombo/types";
|
| 2 |
+
import React, { useMemo } from "react";
|
| 3 |
+
import { useCurrentFrame } from "remotion";
|
| 4 |
+
import AnimatedTextIn from "./text-animated-types/animations-in/text-animated-in";
|
| 5 |
+
import SunnyMorningsAnimationIn from "./text-animated-types/animations-in/sunny-mornings-in";
|
| 6 |
+
import DominoDreamsIn from "./text-animated-types/animations-in/domino-dreams-in";
|
| 7 |
+
import GetThinkersAnimationIn from "./text-animated-types/animations-in/great-thinkers-in";
|
| 8 |
+
import BeatifulQuestionAnimationIn from "./text-animated-types/animations-in/beatiful-question-in";
|
| 9 |
+
import MadeWithLoveAnimationIn from "./text-animated-types/animations-in/made-with-love-in";
|
| 10 |
+
import AnimatedTextOut from "./text-animated-types/animations-out/text-animated-out";
|
| 11 |
+
import SunnyMorningsAnimationOut from "./text-animated-types/animations-out/sunny-mornings-out";
|
| 12 |
+
import DominoDreamsAnimationOut from "./text-animated-types/animations-out/domino-dreams-out";
|
| 13 |
+
import BeatifulQuestionAnimationOut from "./text-animated-types/animations-out/beatiful-question-out";
|
| 14 |
+
import RealityIsBrokenAnimationIn from "./text-animated-types/animations-in/reality-is-broken-in";
|
| 15 |
+
import MadeWithLoveAnimationOut from "./text-animated-types/animations-out/made-with-love-out";
|
| 16 |
+
import RealityIsBrokenAnimationOut from "./text-animated-types/animations-out/reality-is-broken-out";
|
| 17 |
+
import GreatThinkersAnimationOut from "./text-animated-types/animations-out/great-thinkers-out";
|
| 18 |
+
import VogueLetterByLetter from "./text-animated-types/animations-loop/vogue";
|
| 19 |
+
import DragonflyText from "./text-animated-types/animations-loop/dragonfly";
|
| 20 |
+
import BillboardText from "./text-animated-types/animations-loop/billboard";
|
| 21 |
+
import DropAnimationIn from "./text-animated-types/animations-in/drop-in";
|
| 22 |
+
import DescompressAnimationIn from "./text-animated-types/animations-in/descompress-in";
|
| 23 |
+
import DescompressAnimationOut from "./text-animated-types/animations-out/descompress-out";
|
| 24 |
+
import DropAnimationOut from "./text-animated-types/animations-out/drop-out";
|
| 25 |
+
import Heartbeat from "./text-animated-types/animations-loop/heartbeat";
|
| 26 |
+
import Wave from "./text-animated-types/animations-loop/wave";
|
| 27 |
+
import ShakyLettersText from "./text-animated-types/animations-loop/shaky-letters-text";
|
| 28 |
+
import PulseText from "./text-animated-types/animations-loop/pulse";
|
| 29 |
+
import { renderFullTextAnimation } from "./text-animated-full";
|
| 30 |
+
|
| 31 |
+
const animationsIn: { [key: string]: React.FC<any> } = {
|
| 32 |
+
animatedTextIn: AnimatedTextIn,
|
| 33 |
+
sunnyMorningsAnimationIn: SunnyMorningsAnimationIn,
|
| 34 |
+
dominoDreamsIn: DominoDreamsIn,
|
| 35 |
+
greatThinkersAnimationIn: GetThinkersAnimationIn,
|
| 36 |
+
beautifulQuestionsAnimationIn: BeatifulQuestionAnimationIn,
|
| 37 |
+
madeWithLoveAnimationIn: MadeWithLoveAnimationIn,
|
| 38 |
+
realityIsBrokenAnimationIn: RealityIsBrokenAnimationIn,
|
| 39 |
+
dropAnimationIn: DropAnimationIn,
|
| 40 |
+
descompressAnimationIn: DescompressAnimationIn
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
const animationsOut: { [key: string]: React.FC<any> } = {
|
| 44 |
+
animatedTextOut: AnimatedTextOut,
|
| 45 |
+
sunnyMorningsAnimationOut: SunnyMorningsAnimationOut,
|
| 46 |
+
dominoDreamsAnimationOut: DominoDreamsAnimationOut,
|
| 47 |
+
beautifulQuestionsAnimationOut: BeatifulQuestionAnimationOut,
|
| 48 |
+
madeWithLoveAnimationOut: MadeWithLoveAnimationOut,
|
| 49 |
+
realityIsBrokenAnimationOut: RealityIsBrokenAnimationOut,
|
| 50 |
+
greatThinkersAnimationOut: GreatThinkersAnimationOut,
|
| 51 |
+
descompressAnimationOut: DescompressAnimationOut,
|
| 52 |
+
dropAnimationOut: DropAnimationOut
|
| 53 |
+
};
|
| 54 |
+
|
| 55 |
+
const animationsLoop: { [key: string]: React.FC<any> } = {
|
| 56 |
+
vogueAnimationLoop: VogueLetterByLetter,
|
| 57 |
+
dragonFlyAnimationLoop: DragonflyText,
|
| 58 |
+
billboardAnimationLoop: BillboardText,
|
| 59 |
+
heartbeatAnimationLoop: Heartbeat,
|
| 60 |
+
waveAnimationLoop: Wave,
|
| 61 |
+
shakyLettersTextAnimationLoop: ShakyLettersText,
|
| 62 |
+
pulseAnimationLoop: PulseText
|
| 63 |
+
};
|
| 64 |
+
|
| 65 |
+
const getTextLines = (
|
| 66 |
+
text: string,
|
| 67 |
+
width: number,
|
| 68 |
+
fontSize: number
|
| 69 |
+
): string[] => {
|
| 70 |
+
const canvas = document.createElement("canvas");
|
| 71 |
+
const context = canvas.getContext("2d");
|
| 72 |
+
|
| 73 |
+
if (!context) return [];
|
| 74 |
+
|
| 75 |
+
context.font = `${fontSize}px Arial`;
|
| 76 |
+
const words = text.split(" ");
|
| 77 |
+
let lines: string[] = [];
|
| 78 |
+
let currentLine = "";
|
| 79 |
+
|
| 80 |
+
words.forEach((word) => {
|
| 81 |
+
const testLine = currentLine ? `${currentLine} ${word}` : word;
|
| 82 |
+
const textWidth = context.measureText(testLine).width;
|
| 83 |
+
|
| 84 |
+
if (textWidth > width) {
|
| 85 |
+
lines.push(currentLine);
|
| 86 |
+
currentLine = word;
|
| 87 |
+
} else {
|
| 88 |
+
currentLine = testLine;
|
| 89 |
+
}
|
| 90 |
+
});
|
| 91 |
+
|
| 92 |
+
if (currentLine) lines.push(currentLine);
|
| 93 |
+
|
| 94 |
+
return lines;
|
| 95 |
+
};
|
| 96 |
+
|
| 97 |
+
export const TextAnimated: React.FC<{
|
| 98 |
+
text: string;
|
| 99 |
+
fps: number;
|
| 100 |
+
textAnimationNameIn: string;
|
| 101 |
+
textAnimationNameOut: string;
|
| 102 |
+
textAnimationNameLoop: string;
|
| 103 |
+
details: ITextDetails;
|
| 104 |
+
animationTextInFrames: number;
|
| 105 |
+
animationTextOutFrames: number;
|
| 106 |
+
animationTextLoopFrames: number;
|
| 107 |
+
durationInFrames: number;
|
| 108 |
+
animationFonts: { fontFamily: string; url: string }[];
|
| 109 |
+
}> = ({
|
| 110 |
+
text,
|
| 111 |
+
fps,
|
| 112 |
+
textAnimationNameIn,
|
| 113 |
+
textAnimationNameOut,
|
| 114 |
+
textAnimationNameLoop,
|
| 115 |
+
details,
|
| 116 |
+
animationTextInFrames,
|
| 117 |
+
animationTextOutFrames,
|
| 118 |
+
animationTextLoopFrames,
|
| 119 |
+
durationInFrames,
|
| 120 |
+
animationFonts
|
| 121 |
+
}) => {
|
| 122 |
+
const frame = useCurrentFrame();
|
| 123 |
+
const animInFrom = animationTextInFrames;
|
| 124 |
+
const animOut = durationInFrames - animationTextOutFrames;
|
| 125 |
+
const validAnimIn = textAnimationNameIn ? animInFrom >= frame : false;
|
| 126 |
+
const validAnimOut = textAnimationNameOut ? animOut < frame : false;
|
| 127 |
+
if (!validAnimOut && !validAnimIn) {
|
| 128 |
+
return (
|
| 129 |
+
<div
|
| 130 |
+
style={{
|
| 131 |
+
whiteSpace: "pre-line",
|
| 132 |
+
maxWidth: "100%"
|
| 133 |
+
}}
|
| 134 |
+
>
|
| 135 |
+
{text}
|
| 136 |
+
</div>
|
| 137 |
+
);
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
const lines = getTextLines(text, details.width, details.fontSize);
|
| 141 |
+
|
| 142 |
+
const fullTextAnimation = renderFullTextAnimation({
|
| 143 |
+
frame,
|
| 144 |
+
text,
|
| 145 |
+
details,
|
| 146 |
+
fps,
|
| 147 |
+
durationInFrames,
|
| 148 |
+
animationTextInFrames,
|
| 149 |
+
animationTextOutFrames,
|
| 150 |
+
animationTextLoopFrames,
|
| 151 |
+
animationFonts,
|
| 152 |
+
validAnimIn,
|
| 153 |
+
validAnimOut,
|
| 154 |
+
textAnimationNameIn,
|
| 155 |
+
textAnimationNameOut,
|
| 156 |
+
textAnimationNameLoop
|
| 157 |
+
});
|
| 158 |
+
|
| 159 |
+
if (fullTextAnimation) {
|
| 160 |
+
return fullTextAnimation;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
const maxTextLengthInLine = lines.reduce(
|
| 164 |
+
(max, line) => Math.max(max, line.length),
|
| 165 |
+
0
|
| 166 |
+
);
|
| 167 |
+
|
| 168 |
+
const AnimationComponentIn = animationsIn[textAnimationNameIn];
|
| 169 |
+
const AnimationComponentOut = animationsOut[textAnimationNameOut];
|
| 170 |
+
const AnimationComponentLoop = animationsLoop[textAnimationNameLoop];
|
| 171 |
+
|
| 172 |
+
return (
|
| 173 |
+
<>
|
| 174 |
+
{lines.map((line, rowIndex) => (
|
| 175 |
+
<div key={rowIndex}>
|
| 176 |
+
{line.split("").map((char, index) => {
|
| 177 |
+
if (validAnimIn && AnimationComponentIn) {
|
| 178 |
+
return (
|
| 179 |
+
<AnimationComponentIn
|
| 180 |
+
key={index}
|
| 181 |
+
char={char}
|
| 182 |
+
index={index}
|
| 183 |
+
frame={frame}
|
| 184 |
+
textLength={maxTextLengthInLine}
|
| 185 |
+
fps={fps}
|
| 186 |
+
animationTextInFrames={animationTextInFrames}
|
| 187 |
+
details={details}
|
| 188 |
+
/>
|
| 189 |
+
);
|
| 190 |
+
}
|
| 191 |
+
if (validAnimOut && AnimationComponentOut) {
|
| 192 |
+
return (
|
| 193 |
+
<AnimationComponentOut
|
| 194 |
+
key={index}
|
| 195 |
+
char={char}
|
| 196 |
+
index={index}
|
| 197 |
+
frame={frame}
|
| 198 |
+
textLength={maxTextLengthInLine}
|
| 199 |
+
fps={fps}
|
| 200 |
+
animationTextOutFrames={animationTextOutFrames}
|
| 201 |
+
durationInFrames={durationInFrames}
|
| 202 |
+
details={details}
|
| 203 |
+
/>
|
| 204 |
+
);
|
| 205 |
+
}
|
| 206 |
+
if (textAnimationNameLoop && !validAnimIn && !validAnimOut) {
|
| 207 |
+
return (
|
| 208 |
+
<AnimationComponentLoop
|
| 209 |
+
key={index}
|
| 210 |
+
char={char}
|
| 211 |
+
index={index}
|
| 212 |
+
frame={frame}
|
| 213 |
+
textLength={maxTextLengthInLine}
|
| 214 |
+
fps={fps}
|
| 215 |
+
animationTextLoopFrames={animationTextLoopFrames}
|
| 216 |
+
details={details}
|
| 217 |
+
/>
|
| 218 |
+
);
|
| 219 |
+
}
|
| 220 |
+
return <span key={index}>{char}</span>;
|
| 221 |
+
})}
|
| 222 |
+
</div>
|
| 223 |
+
))}
|
| 224 |
+
</>
|
| 225 |
+
);
|
| 226 |
+
};
|
src/player/animated/types.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// types.ts
|
| 2 |
+
|
| 3 |
+
export interface Animation {
|
| 4 |
+
property: string;
|
| 5 |
+
from: number;
|
| 6 |
+
to: number;
|
| 7 |
+
durationInFrames: number;
|
| 8 |
+
ease: (t: number) => number;
|
| 9 |
+
delay?: number;
|
| 10 |
+
previewUrl?: string;
|
| 11 |
+
name?: string;
|
| 12 |
+
details?: {
|
| 13 |
+
fonts?: {
|
| 14 |
+
fontFamily: string;
|
| 15 |
+
url: string;
|
| 16 |
+
}[];
|
| 17 |
+
};
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
export interface StaggerConfig {
|
| 21 |
+
amount: number;
|
| 22 |
+
overlap?: number; // 0-1, where 1 means full overlap
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
export interface AnimationConfig {
|
| 26 |
+
in?: Animation | Animation[];
|
| 27 |
+
out?: Animation | Animation[];
|
| 28 |
+
stagger?: StaggerConfig;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
export interface AnimatedElementProps {
|
| 32 |
+
animationIn?: Animation | Animation[];
|
| 33 |
+
animationOut?: Animation | Animation[];
|
| 34 |
+
durationInFrames: number;
|
| 35 |
+
children: React.ReactNode;
|
| 36 |
+
className?: string;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
export interface AnimatedTextProps {
|
| 40 |
+
children: string;
|
| 41 |
+
durationInFrames: number;
|
| 42 |
+
wordAnimation?: AnimationConfig;
|
| 43 |
+
letterAnimation?: AnimationConfig;
|
| 44 |
+
className?: string;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
// You might want to export these utility types as well
|
| 48 |
+
export type CombineAnimations = (
|
| 49 |
+
...animations: (Animation | Animation[] | undefined)[]
|
| 50 |
+
) => Animation[];
|
| 51 |
+
|
| 52 |
+
export type CreateStaggeredAnimations = (
|
| 53 |
+
animations: Animation | Animation[] | undefined,
|
| 54 |
+
count: number,
|
| 55 |
+
stagger: StaggerConfig,
|
| 56 |
+
durationInFrames: number,
|
| 57 |
+
isOut: boolean
|
| 58 |
+
) => Animation[];
|
src/player/base-sequence.tsx
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ISize, ITrackItem } from "@designcombo/types";
|
| 2 |
+
import { AbsoluteFill, Sequence } from "remotion";
|
| 3 |
+
import { calculateFrames } from "../utils/frames";
|
| 4 |
+
import { calculateContainerStyles } from "./styles";
|
| 5 |
+
import { TransitionSeries } from "@designcombo/transitions";
|
| 6 |
+
|
| 7 |
+
export interface SequenceItemOptions {
|
| 8 |
+
handleTextChange?: (id: string, text: string) => void;
|
| 9 |
+
fps: number;
|
| 10 |
+
editableTextId?: string | null;
|
| 11 |
+
currentTime?: number;
|
| 12 |
+
zIndex?: number;
|
| 13 |
+
onTextBlur?: (id: string, text: string) => void;
|
| 14 |
+
size?: ISize;
|
| 15 |
+
frame?: number;
|
| 16 |
+
isTransition?: boolean;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
export const BaseSequence = ({
|
| 20 |
+
item,
|
| 21 |
+
options,
|
| 22 |
+
children
|
| 23 |
+
}: {
|
| 24 |
+
item: ITrackItem;
|
| 25 |
+
options: SequenceItemOptions;
|
| 26 |
+
children: React.ReactNode;
|
| 27 |
+
}) => {
|
| 28 |
+
const { details } = item as ITrackItem;
|
| 29 |
+
const { fps, isTransition } = options;
|
| 30 |
+
const { from, durationInFrames } = calculateFrames(
|
| 31 |
+
{
|
| 32 |
+
from: item.display.from,
|
| 33 |
+
to: item.display.to
|
| 34 |
+
},
|
| 35 |
+
fps
|
| 36 |
+
);
|
| 37 |
+
const crop = details.crop || {
|
| 38 |
+
x: 0,
|
| 39 |
+
y: 0,
|
| 40 |
+
width: item.details.width,
|
| 41 |
+
height: item.details.height
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
const background =
|
| 45 |
+
details?.background?.type === "color"
|
| 46 |
+
? details?.background?.value
|
| 47 |
+
: typeof details?.background === "string"
|
| 48 |
+
? details?.background
|
| 49 |
+
: "transparent";
|
| 50 |
+
|
| 51 |
+
if (isTransition) {
|
| 52 |
+
return (
|
| 53 |
+
<TransitionSeries.Sequence
|
| 54 |
+
key={item.id}
|
| 55 |
+
durationInFrames={durationInFrames}
|
| 56 |
+
style={{ pointerEvents: "none" }}
|
| 57 |
+
>
|
| 58 |
+
<AbsoluteFill
|
| 59 |
+
id={item.id}
|
| 60 |
+
data-track-item="transition-element"
|
| 61 |
+
className={`designcombo-scene-item id-${item.id} designcombo-scene-item-type-${item.type}`}
|
| 62 |
+
style={calculateContainerStyles(details, crop, { background })}
|
| 63 |
+
>
|
| 64 |
+
{children}
|
| 65 |
+
</AbsoluteFill>
|
| 66 |
+
</TransitionSeries.Sequence>
|
| 67 |
+
);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
return (
|
| 71 |
+
<Sequence
|
| 72 |
+
key={item.id}
|
| 73 |
+
from={from}
|
| 74 |
+
durationInFrames={durationInFrames || 1 / fps}
|
| 75 |
+
style={{
|
| 76 |
+
pointerEvents: "none"
|
| 77 |
+
}}
|
| 78 |
+
>
|
| 79 |
+
<AbsoluteFill
|
| 80 |
+
id={item.id}
|
| 81 |
+
data-track-item="transition-element"
|
| 82 |
+
className={`designcombo-scene-item id-${item.id} designcombo-scene-item-type-${item.type}`}
|
| 83 |
+
style={calculateContainerStyles(
|
| 84 |
+
details,
|
| 85 |
+
crop,
|
| 86 |
+
{
|
| 87 |
+
background,
|
| 88 |
+
pointerEvents: item.type === "audio" ? "none" : "auto",
|
| 89 |
+
overflow:
|
| 90 |
+
item.type !== "caption" && item.type !== "text"
|
| 91 |
+
? "hidden"
|
| 92 |
+
: "visible"
|
| 93 |
+
},
|
| 94 |
+
item.type
|
| 95 |
+
)}
|
| 96 |
+
>
|
| 97 |
+
{children}
|
| 98 |
+
</AbsoluteFill>
|
| 99 |
+
</Sequence>
|
| 100 |
+
);
|
| 101 |
+
};
|