Patrick Rathje commited on
Commit
96fb70e
·
1 Parent(s): 5c94804

Working examples

Browse files
app.py CHANGED
@@ -5,6 +5,7 @@ import shutil
5
  import uuid
6
  import subprocess
7
  from threading import Timer
 
8
 
9
  from gradio_motioncanvasplayer import MotionCanvasPlayer
10
 
@@ -84,32 +85,66 @@ def build_project(code):
84
  # cleanup tmp dir
85
  shutil.rmtree(tmp_dir)
86
 
87
-
88
-
89
- # generate a random uuid for the project
90
- # copy whole MC_PROJECT_DIR to a random tmp dir
91
- # write code to scene.ts
92
- # run npm run build
93
- # return [logs, project_api_path]
94
- # if successful copy MC_PROJECT_DIR/dist/project.js to get_local_path(id)
95
- # always: log the output to logs
96
- # always delete the tmp dir after the build is done
97
-
98
-
99
-
100
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  gr.Markdown("# Motion Canvas MCP Server")
102
  with gr.Row():
103
  with gr.Column():
104
- gr.Markdown("## TS Input for scene.ts")
105
- code = gr.Code(language="typescript")
106
- submit = gr.Button("Build")
 
107
  logs = gr.Textbox(value="", label="Build Logs", interactive=False)
108
  with gr.Column():
109
  gr.Markdown("## Preview")
110
- player = MotionCanvasPlayer(example_project_path, auto=True, quality=0.5, width=1920, height=1080, variables="{}")
111
-
112
 
 
 
 
 
113
  submit.click(build_project, inputs=[code], outputs=[player, logs], api_name="build_project")
114
 
115
  if __name__ == "__main__":
 
5
  import uuid
6
  import subprocess
7
  from threading import Timer
8
+ from functools import partial
9
 
10
  from gradio_motioncanvasplayer import MotionCanvasPlayer
11
 
 
85
  # cleanup tmp dir
86
  shutil.rmtree(tmp_dir)
87
 
88
+ def load_example_code(example_name):
89
+ return open(os.path.join(os.path.dirname(__file__), "examples", example_name + ".tsx")).read()
90
+
91
+ def build_example(example_name):
92
+ iterator = build_project(load_example_code(example_name))
93
+ last = next(iterator)
94
+ for last in iterator:
95
+ continue
96
+
97
+ path = last[0]
98
+ assert path
99
+ return path
100
+
101
+ print("Building examples...")
102
+ EXAMPLES = [
103
+ {
104
+ "name": "Gradio + Motion Canvas",
105
+ "code": load_example_code("gradio-motion-canvas-example"),
106
+ "project_path": build_example("gradio-motion-canvas-example")
107
+ },
108
+ {
109
+ "name": "Blur",
110
+ "code": load_example_code("motion-canvas-blur"),
111
+ "project_path": build_example("motion-canvas-blur")
112
+ },
113
+ {
114
+ "name": "Latex",
115
+ "code": load_example_code("latex"),
116
+ "project_path": build_example("latex")
117
+ },
118
+ {
119
+ "name": "Code",
120
+ "code": load_example_code("code"),
121
+ "project_path": build_example("code")
122
+ },
123
+
124
+ ]
125
+ print("Examples built!")
126
+
127
+ def load_example(example):
128
+ return example['project_path'], example['code'], ""
129
+
130
+
131
+ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
132
  gr.Markdown("# Motion Canvas MCP Server")
133
  with gr.Row():
134
  with gr.Column():
135
+ gr.Markdown("## TS Input for Your Scene")
136
+ gr.Markdown("Leverage the power of Motion Canvas to create your own animations using TypeScript.")
137
+ code = gr.Code(value=EXAMPLES[0]['code'], language="typescript")
138
+ submit = gr.Button("Build", variant="primary")
139
  logs = gr.Textbox(value="", label="Build Logs", interactive=False)
140
  with gr.Column():
141
  gr.Markdown("## Preview")
142
+ player = MotionCanvasPlayer(EXAMPLES[0]['project_path'], auto=True, quality=0.5, width=1920, height=1080, variables="{}")
 
143
 
144
+ for ex in EXAMPLES:
145
+ btn = gr.Button("Load Example: " + ex["name"], variant="secondary")
146
+ btn.click(partial(load_example, ex), outputs=[player, code, logs])
147
+
148
  submit.click(build_project, inputs=[code], outputs=[player, logs], api_name="build_project")
149
 
150
  if __name__ == "__main__":
examples/code.tsx ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {makeScene2D, Code} from '@motion-canvas/2d';
2
+ import {all, createRef, DEFAULT, waitFor} from '@motion-canvas/core';
3
+
4
+ // Visit https://motioncanvas.io/docs/code/ for more information.
5
+ export default makeScene2D(function* (view) {
6
+ view.fill('white');
7
+ const code = createRef<Code>();
8
+
9
+ view.add(
10
+ <Code
11
+ ref={code}
12
+ fontSize={28}
13
+ fontFamily={'JetBrains Mono, monospace'}
14
+ fill={"black"}
15
+ offsetX={-1}
16
+ x={-400}
17
+ code={'const number = 7;'}
18
+ />,
19
+ );
20
+
21
+ yield* waitFor(0.6);
22
+ yield* all(
23
+ code().code.replace(code().findFirstRange('number'), 'variable', 0.6),
24
+ code().code.prepend(0.6)`function example() {\n `,
25
+ code().code.append(0.6)`\n}`,
26
+ );
27
+
28
+ yield* waitFor(0.6);
29
+ yield* code().selection(code().findFirstRange('variable'), 0.6);
30
+
31
+ yield* waitFor(0.6);
32
+ yield* all(
33
+ code().code('const number = 7;', 0.6),
34
+ code().selection(DEFAULT, 0.6),
35
+ );
36
+ });
examples/gradio-motion-canvas-example.tsx ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {makeScene2D, Img, Layout, Icon} from '@motion-canvas/2d';
2
+ import {createRef, easeOutCubic, spring, all, waitFor} from '@motion-canvas/core';
3
+
4
+ let gradioLogoSvg = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='576'%20height='576'%20viewBox='0%200%20576%20576'%20fill='none'%3e%3cpath%20d='M287.5%20229L86%20344.5L287.5%20460L489%20344.5L287.5%20229Z'%20stroke='url(%23paint0_linear_102_7)'%20stroke-width='59'%20stroke-linejoin='round'/%3e%3cpath%20d='M287.5%20116L86%20231.5L287.5%20347L489%20231.5L287.5%20116Z'%20stroke='url(%23paint1_linear_102_7)'%20stroke-width='59'%20stroke-linejoin='round'/%3e%3cpath%20d='M86%20344L288%20229'%20stroke='url(%23paint2_linear_102_7)'%20stroke-width='59'%20stroke-linejoin='bevel'/%3e%3cdefs%3e%3clinearGradient%20id='paint0_linear_102_7'%20x1='60'%20y1='341'%20x2='429.5'%20y2='344'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='%23F9D100'/%3e%3cstop%20offset='1'%20stop-color='%23F97700'/%3e%3c/linearGradient%3e%3clinearGradient%20id='paint1_linear_102_7'%20x1='513.5'%20y1='231'%20x2='143.5'%20y2='231'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='%23F9D100'/%3e%3cstop%20offset='1'%20stop-color='%23F97700'/%3e%3c/linearGradient%3e%3clinearGradient%20id='paint2_linear_102_7'%20x1='60'%20y1='344'%20x2='428.987'%20y2='341.811'%20gradientUnits='userSpaceOnUse'%3e%3cstop%20stop-color='%23F9D100'/%3e%3cstop%20offset='1'%20stop-color='%23F97700'/%3e%3c/linearGradient%3e%3c/defs%3e%3c/svg%3e"
5
+
6
+ export default makeScene2D(function* (view) {
7
+ view.fill('white'); // set the background of this scene
8
+
9
+ const gradioLogo = createRef<Img>();
10
+ const addIcon = createRef<Icon>();
11
+ const motionCanvasLogo = createRef<Img>();
12
+ const plusIcon = createRef<Icon>();
13
+ const heartIcon = createRef<Icon>();
14
+
15
+ view.add(
16
+ <Layout layout direction={'row'} size={'100%'} padding={100} gap={0} alignItems={'center'} justifyContent={'center'}>
17
+ <Img ref={gradioLogo} src={gradioLogoSvg} width='25%' offset={[1,2]}/>
18
+ <Icon ref={addIcon} icon="material-symbols-light:add-2-rounded" color="#404040" width='20%' margin={-10} />
19
+ <Img ref={motionCanvasLogo} src="https://motioncanvas.io/img/logo.svg" width='25%' margin={-10} />
20
+ <Icon ref={plusIcon} icon="material-symbols-light:equal" color="#404040" width='20%' margin={-30} />
21
+ <Icon ref={heartIcon} icon="material-symbols-light:favorite" color="#ff6470" width='25%' />
22
+ </Layout>
23
+ );
24
+
25
+ let initalMargin = view.size().y*1.5;
26
+ gradioLogo().margin.bottom(initalMargin);
27
+ addIcon().margin.bottom(initalMargin);
28
+ motionCanvasLogo().margin.bottom(initalMargin);
29
+ plusIcon().margin.bottom(initalMargin);
30
+ heartIcon().margin.bottom(initalMargin);
31
+
32
+ const MySpring = {
33
+ mass: 0.04,
34
+ stiffness: 10.0,
35
+ damping: 0.85,
36
+ initialVelocity: 8.0,
37
+ };
38
+
39
+ let springInAnim = function(obj : any) {
40
+ return spring(MySpring, initalMargin, 0, 5, value => {
41
+ obj().margin.bottom(value);
42
+ });
43
+ };
44
+
45
+ yield* springInAnim(gradioLogo);
46
+ yield* springInAnim(addIcon);
47
+ yield* springInAnim(motionCanvasLogo);
48
+ yield* springInAnim(plusIcon);
49
+ yield* springInAnim(heartIcon);
50
+
51
+ yield * waitFor(1);
52
+
53
+ // let them fade away
54
+ yield* all(
55
+ gradioLogo().opacity(0, 1, easeOutCubic),
56
+ addIcon().opacity(0, 1, easeOutCubic),
57
+ motionCanvasLogo().opacity(0, 1, easeOutCubic),
58
+ plusIcon().opacity(0, 1, easeOutCubic),
59
+ heartIcon().opacity(0, 1, easeOutCubic),
60
+ );
61
+
62
+ yield * waitFor(1);
63
+
64
+ });
examples/latex.tsx ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {Latex, makeScene2D} from '@motion-canvas/2d';
2
+ import {createRef, waitFor} from '@motion-canvas/core';
3
+
4
+ // Visit https://motioncanvas.io/docs/latex/ for more information.
5
+ export default makeScene2D(function* (view) {
6
+ view.fill('white');
7
+ const tex = createRef<Latex>();
8
+ view.add(<Latex ref={tex} tex="{{1}} + {{2}}" fill="black" />);
9
+
10
+ yield* waitFor(0.5);
11
+ yield* tex().tex(['2', '+', '3', '+', '4'], 1);
12
+ });
examples/motion-canvas-blur.tsx ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {Img, makeScene2D} from '@motion-canvas/2d';
2
+ import {createRef} from '@motion-canvas/core';
3
+
4
+ // Visit https://motioncanvas.io/docs for more information.
5
+ export default makeScene2D(function* (view) {
6
+ view.fill('#141414');
7
+
8
+ const iconRef = createRef<Img>();
9
+ yield view.add(<Img src={'https://motioncanvas.io/img/logo_dark.svg'} size={500} ref={iconRef} />);
10
+ // Modification happens by accessing the `filters` property.
11
+ // Individual filters don't need to be initialized. If a filter you set doesn't
12
+ // exists, it will be automatically created and added to the list of filters.
13
+ // If you have multiple filters of the same type, this will only
14
+ // modify the first instance (you can use the array method for more control).
15
+ yield* iconRef().filters.blur(10, 1);
16
+ yield* iconRef().filters.blur(0, 1);
17
+ });
examples/simple-sphere.tsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {makeScene2D, Circle} from '@motion-canvas/2d';
2
+ import {all, createRef} from '@motion-canvas/core';
3
+
4
+ // Visit https://motioncanvas.io/docs for more information.
5
+ export default makeScene2D(function* (view) {
6
+ const myCircle = createRef<Circle>();
7
+
8
+ view.add(
9
+ <Circle
10
+ ref={myCircle}
11
+ // try changing these properties:
12
+ x={-300}
13
+ width={140}
14
+ height={140}
15
+ fill="#e13238"
16
+ />,
17
+ );
18
+
19
+ yield* all(
20
+ myCircle().position.x(300, 1).to(-300, 1),
21
+ myCircle().fill('#e6a700', 1).to('#e13238', 1),
22
+ );
23
+ });