@revideo/create 0.5.5-alpha.1062 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/default/package.json +7 -7
- package/examples/saas-template/next/package.json +1 -1
- package/examples/saas-template/revideo/package.json +7 -7
- package/examples/three-js-example/README.md +8 -0
- package/examples/three-js-example/package-lock.json +2753 -0
- package/examples/three-js-example/package.json +25 -0
- package/examples/three-js-example/src/components/Three.ts +166 -0
- package/examples/three-js-example/src/global.css +1 -0
- package/examples/three-js-example/src/project.meta +31 -0
- package/examples/three-js-example/src/project.ts +8 -0
- package/examples/three-js-example/src/render.ts +15 -0
- package/examples/three-js-example/src/revideo.d.ts +1 -0
- package/examples/three-js-example/src/scenes/basic3D.meta +5 -0
- package/examples/three-js-example/src/scenes/basic3D.tsx +89 -0
- package/examples/three-js-example/tsconfig.json +9 -0
- package/examples/three-js-example/vite.config.ts +6 -0
- package/package.json +9 -9
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "3d-testing",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "vite",
|
|
7
|
+
"serve": "vite",
|
|
8
|
+
"build": "tsc && vite build",
|
|
9
|
+
"render": "tsc && node dist/render.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@revideo/2d": "0.5.4",
|
|
13
|
+
"@revideo/core": "^0.5.4",
|
|
14
|
+
"@revideo/renderer": "^0.5.4",
|
|
15
|
+
"@revideo/ffmpeg": "^0.5.4",
|
|
16
|
+
"three": "^0.167.1"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@revideo/ui": "^0.5.4",
|
|
20
|
+
"@revideo/vite-plugin": "^0.5.4",
|
|
21
|
+
"@types/three": "^0.167.1",
|
|
22
|
+
"typescript": "^5.2.2",
|
|
23
|
+
"vite": "^4.0.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { Layout, LayoutProps } from "@revideo/2d/lib/components";
|
|
2
|
+
import { computed, initial, signal } from "@revideo/2d/lib/decorators";
|
|
3
|
+
import { Vector2 } from "@revideo/core/lib/types";
|
|
4
|
+
import {
|
|
5
|
+
Camera,
|
|
6
|
+
Color,
|
|
7
|
+
OrthographicCamera,
|
|
8
|
+
PerspectiveCamera,
|
|
9
|
+
Scene,
|
|
10
|
+
WebGLRenderer,
|
|
11
|
+
} from "three";
|
|
12
|
+
import { SimpleSignal } from "@revideo/core/lib/signals";
|
|
13
|
+
|
|
14
|
+
interface RenderCallback {
|
|
15
|
+
(renderer: WebGLRenderer, scene: Scene, camera: Camera): void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ThreeProps extends LayoutProps {
|
|
19
|
+
scene?: Scene;
|
|
20
|
+
camera?: Camera;
|
|
21
|
+
quality?: number;
|
|
22
|
+
background?: string;
|
|
23
|
+
zoom?: number;
|
|
24
|
+
onRender?: RenderCallback;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class Three extends Layout {
|
|
28
|
+
@initial(1)
|
|
29
|
+
@signal()
|
|
30
|
+
public declare readonly quality: SimpleSignal<number, this>;
|
|
31
|
+
|
|
32
|
+
@initial(null)
|
|
33
|
+
@signal()
|
|
34
|
+
public declare readonly camera: SimpleSignal<Camera | null, this>;
|
|
35
|
+
|
|
36
|
+
@initial(null)
|
|
37
|
+
@signal()
|
|
38
|
+
public declare readonly scene: SimpleSignal<Scene | null, this>;
|
|
39
|
+
|
|
40
|
+
@initial(null)
|
|
41
|
+
@signal()
|
|
42
|
+
public declare readonly background: SimpleSignal<string | null, this>;
|
|
43
|
+
|
|
44
|
+
@initial(1)
|
|
45
|
+
@signal()
|
|
46
|
+
public declare readonly zoom: SimpleSignal<number, this>;
|
|
47
|
+
|
|
48
|
+
private readonly renderer: WebGLRenderer;
|
|
49
|
+
private readonly context: WebGLRenderingContext;
|
|
50
|
+
private readonly pixelSample = new Uint8Array(4);
|
|
51
|
+
public onRender: RenderCallback;
|
|
52
|
+
|
|
53
|
+
public constructor({ onRender, ...props }: ThreeProps) {
|
|
54
|
+
super(props);
|
|
55
|
+
this.renderer = borrow();
|
|
56
|
+
this.context = this.renderer.getContext();
|
|
57
|
+
this.onRender =
|
|
58
|
+
onRender ?? ((renderer, scene, camera) => renderer.render(scene, camera));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
protected override async draw(context: CanvasRenderingContext2D) {
|
|
62
|
+
const { width, height } = this.computedSize();
|
|
63
|
+
const quality = this.quality();
|
|
64
|
+
const scene = this.configuredScene();
|
|
65
|
+
const camera = this.configuredCamera();
|
|
66
|
+
const renderer = this.configuredRenderer();
|
|
67
|
+
|
|
68
|
+
if (width > 0 && height > 0) {
|
|
69
|
+
this.onRender(renderer, scene, camera);
|
|
70
|
+
context.imageSmoothingEnabled = false;
|
|
71
|
+
context.drawImage(
|
|
72
|
+
renderer.domElement,
|
|
73
|
+
0,
|
|
74
|
+
0,
|
|
75
|
+
quality * width,
|
|
76
|
+
quality * height,
|
|
77
|
+
width / -2,
|
|
78
|
+
height / -2,
|
|
79
|
+
width,
|
|
80
|
+
height,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
super.draw(context);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@computed()
|
|
88
|
+
private configuredRenderer(): WebGLRenderer {
|
|
89
|
+
const size = this.computedSize();
|
|
90
|
+
const quality = this.quality();
|
|
91
|
+
|
|
92
|
+
this.renderer.setSize(size.width * quality, size.height * quality);
|
|
93
|
+
return this.renderer;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@computed()
|
|
97
|
+
private configuredCamera(): Camera {
|
|
98
|
+
const size = this.computedSize();
|
|
99
|
+
const camera = this.camera();
|
|
100
|
+
const ratio = size.width / size.height;
|
|
101
|
+
const scale = this.zoom() / 2;
|
|
102
|
+
if (camera instanceof OrthographicCamera) {
|
|
103
|
+
camera.left = -ratio * scale;
|
|
104
|
+
camera.right = ratio * scale;
|
|
105
|
+
camera.bottom = -scale;
|
|
106
|
+
camera.top = scale;
|
|
107
|
+
camera.updateProjectionMatrix();
|
|
108
|
+
} else if (camera instanceof PerspectiveCamera) {
|
|
109
|
+
camera.aspect = ratio;
|
|
110
|
+
camera.updateProjectionMatrix();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return camera;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@computed()
|
|
117
|
+
private configuredScene(): Scene | null {
|
|
118
|
+
const scene = this.scene();
|
|
119
|
+
const background = this.background();
|
|
120
|
+
if (scene) {
|
|
121
|
+
scene.background = background ? new Color(background) : null;
|
|
122
|
+
}
|
|
123
|
+
return scene;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public getColorAtPoint(position: Vector2) {
|
|
127
|
+
const relativePosition = position.scale(this.quality());
|
|
128
|
+
this.context.readPixels(
|
|
129
|
+
relativePosition.x,
|
|
130
|
+
relativePosition.y,
|
|
131
|
+
1,
|
|
132
|
+
1,
|
|
133
|
+
this.context.RGBA,
|
|
134
|
+
this.context.UNSIGNED_BYTE,
|
|
135
|
+
this.pixelSample,
|
|
136
|
+
);
|
|
137
|
+
const color = new Color();
|
|
138
|
+
color.setRGB(
|
|
139
|
+
this.pixelSample[0] / 255,
|
|
140
|
+
this.pixelSample[1] / 255,
|
|
141
|
+
this.pixelSample[2] / 255,
|
|
142
|
+
);
|
|
143
|
+
return color;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public dispose() {
|
|
147
|
+
dispose(this.renderer);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const pool: WebGLRenderer[] = [];
|
|
152
|
+
function borrow() {
|
|
153
|
+
if (pool.length) {
|
|
154
|
+
return pool.pop();
|
|
155
|
+
} else {
|
|
156
|
+
return new WebGLRenderer({
|
|
157
|
+
canvas: document.createElement("canvas"),
|
|
158
|
+
// antialias: true,
|
|
159
|
+
alpha: true,
|
|
160
|
+
stencil: true,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function dispose(renderer: WebGLRenderer) {
|
|
165
|
+
pool.push(renderer);
|
|
166
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Lexend:wght@600&family=Noto+Color+Emoji&display=swap");
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 0,
|
|
3
|
+
"shared": {
|
|
4
|
+
"background": "rgb(255,255,255)",
|
|
5
|
+
"range": [
|
|
6
|
+
0,
|
|
7
|
+
null
|
|
8
|
+
],
|
|
9
|
+
"size": {
|
|
10
|
+
"x": 1920,
|
|
11
|
+
"y": 1080
|
|
12
|
+
},
|
|
13
|
+
"audioOffset": 0
|
|
14
|
+
},
|
|
15
|
+
"preview": {
|
|
16
|
+
"fps": 30,
|
|
17
|
+
"resolutionScale": 1
|
|
18
|
+
},
|
|
19
|
+
"rendering": {
|
|
20
|
+
"fps": 60,
|
|
21
|
+
"resolutionScale": 1,
|
|
22
|
+
"colorSpace": "srgb",
|
|
23
|
+
"exporter": {
|
|
24
|
+
"name": "@revideo/core/wasm",
|
|
25
|
+
"options": {
|
|
26
|
+
"fastStart": true,
|
|
27
|
+
"includeAudio": true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {renderVideo} from '@revideo/renderer';
|
|
2
|
+
|
|
3
|
+
async function render() {
|
|
4
|
+
console.log('Rendering video...');
|
|
5
|
+
|
|
6
|
+
// This is the main function that renders the video
|
|
7
|
+
const file = await renderVideo({
|
|
8
|
+
projectFile: './src/project.ts',
|
|
9
|
+
settings: {logProgress: true},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
console.log(`Rendered video to ${file}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
render();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="@revideo/core/project" />
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {Three} from '../components/Three';
|
|
2
|
+
import { makeScene2D, Txt } from '@revideo/2d';
|
|
3
|
+
import { tween, waitFor, delay, createRef, all, chain, linear} from '@revideo/core';
|
|
4
|
+
import * as THREE from 'three';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
function setup3DScene() {
|
|
8
|
+
const threeScene = new THREE.Scene();
|
|
9
|
+
|
|
10
|
+
const geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
|
|
11
|
+
const material = new THREE.MeshNormalMaterial();
|
|
12
|
+
|
|
13
|
+
const mesh = new THREE.Mesh( geometry, material );
|
|
14
|
+
threeScene.add(mesh);
|
|
15
|
+
|
|
16
|
+
const camera = new THREE.PerspectiveCamera(90);
|
|
17
|
+
|
|
18
|
+
mesh.position.set(0, 0, 0);
|
|
19
|
+
mesh.scale.set(1, 1, 1);
|
|
20
|
+
camera.rotation.set(0, 0, 0);
|
|
21
|
+
camera.position.set(0, 0, 0.5);
|
|
22
|
+
|
|
23
|
+
return {threeScene, camera, mesh};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default makeScene2D(function* (view) {
|
|
27
|
+
const {threeScene, camera, mesh} = setup3DScene();
|
|
28
|
+
|
|
29
|
+
const threeRef = createRef<Three>();
|
|
30
|
+
const txtRef = createRef<Txt>();
|
|
31
|
+
|
|
32
|
+
yield view.add(
|
|
33
|
+
<>
|
|
34
|
+
<Three
|
|
35
|
+
width={1920}
|
|
36
|
+
height={1080}
|
|
37
|
+
camera={camera}
|
|
38
|
+
scene={threeScene}
|
|
39
|
+
opacity={0}
|
|
40
|
+
fontWeight={900}
|
|
41
|
+
ref={threeRef}
|
|
42
|
+
/>
|
|
43
|
+
</>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
yield view.add(<Txt fill={"black"} fontFamily={"Lexend"} ref={txtRef} fontSize={80}/>)
|
|
47
|
+
|
|
48
|
+
yield* chain(
|
|
49
|
+
txtRef().text("Revideo x 3D with Three.js", 1),
|
|
50
|
+
all(
|
|
51
|
+
txtRef().position.y(-300, 1),
|
|
52
|
+
delay(0.5, threeRef().opacity(1, 0.5))
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
yield tween(4, value => {
|
|
57
|
+
mesh.rotation.set(
|
|
58
|
+
0,
|
|
59
|
+
linear(value, 0, 2*3.14),
|
|
60
|
+
0
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
yield* waitFor(2);
|
|
65
|
+
|
|
66
|
+
yield addRotatingCube(threeRef().scene(), 0.1, 0.3, -0.2, 0.1);
|
|
67
|
+
yield addRotatingCube(threeRef().scene(), 0.1, -0.3, -0.2, 0.1);
|
|
68
|
+
|
|
69
|
+
yield* waitFor(2);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
function* addRotatingCube(threeScene: THREE.Scene, size: number, x: number, y: number, z: number){
|
|
73
|
+
const geometry = new THREE.BoxGeometry( size, size, size );
|
|
74
|
+
const material = new THREE.MeshNormalMaterial();
|
|
75
|
+
const mesh = new THREE.Mesh( geometry, material );
|
|
76
|
+
|
|
77
|
+
mesh.position.set(x, y, z);
|
|
78
|
+
mesh.scale.set(1, 1, 1);
|
|
79
|
+
|
|
80
|
+
threeScene.add(mesh);
|
|
81
|
+
|
|
82
|
+
yield* tween(4, value => {
|
|
83
|
+
mesh.rotation.set(
|
|
84
|
+
0,
|
|
85
|
+
linear(value, 0, 2*3.14),
|
|
86
|
+
0
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revideo/create",
|
|
3
|
-
"version": "0.5.5
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"description": "Quickly scaffold revideo projects",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "revideo",
|
|
@@ -20,17 +20,17 @@
|
|
|
20
20
|
"url": "https://github.com/havenhq/revideo.git"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@revideo/2d": "
|
|
24
|
-
"@revideo/core": "
|
|
25
|
-
"@revideo/ffmpeg": "
|
|
26
|
-
"@revideo/renderer": "
|
|
27
|
-
"@revideo/ui": "
|
|
28
|
-
"@revideo/vite-plugin": "
|
|
23
|
+
"@revideo/2d": "0.5.5",
|
|
24
|
+
"@revideo/core": "0.5.5",
|
|
25
|
+
"@revideo/ffmpeg": "0.5.5",
|
|
26
|
+
"@revideo/renderer": "0.5.5",
|
|
27
|
+
"@revideo/ui": "0.5.5",
|
|
28
|
+
"@revideo/vite-plugin": "0.5.5"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@revideo/telemetry": "
|
|
31
|
+
"@revideo/telemetry": "0.5.5",
|
|
32
32
|
"minimist": "^1.2.8",
|
|
33
33
|
"prompts": "^2.4.2"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "3dcb623279d10fe09c5dd2eda18c1c4adb4ba1eb"
|
|
36
36
|
}
|