@@ -10,11 +10,22 @@ Usage:
1010})"
1111/>
1212
13- or if you wanna declare a height or a controller:
13+ With autoplay on the timeline:
14+ <MojsInteractive
15+ id="unique_id"
16+ autoplay
17+ code=
18+ "new mojs.Shape({
19+ parent: '#unique_id',
20+ shape: 'circle',
21+ radius: {20: 80},
22+ })"
23+ />
24+
25+ or if you wanna declare a height:
1426
1527<MojsInteractive
1628 id="unique_id"
17- :controller=true
1829 height="200px"
1930 code=
2031"new mojs.Shape({
@@ -24,26 +35,54 @@ or if you wanna declare a height or a controller:
2435})"
2536/>
2637
27- or with no controlls at all (static animation, unless you provide a .play() function):
38+ or with no controlls (will have no animation, unless you provide a .play() function yourself ):
2839
2940<MojsInteractive
3041 id="unique_id"
31- :playbutton =false
42+ :controller =false
3243 code=
3344"new mojs.Shape({
3445 parent: '#unique_id',
3546 shape: 'circle',
3647 radius: {20: 80},
3748}).play()"
3849/>
50+
51+ If you want to show (and use) the decleration of the animation like this:
52+
53+ const bouncyCircle = new mojs.Shape({
54+ ...
55+ });
56+
57+ bouncyCircle.play()
58+
59+ Then you may wanna use the global mode.
60+ The string passed in the global prop should equal the variable you declared.
61+ Note that it will be global, so make sure it's unique, and use it carefully:
62+
63+ <MojsInteractive
64+ id="bouncyCircle"
65+ autoplay
66+ global="circles"
67+ code=
68+ "const circles = new mojs.Shape({
69+ parent: '#bouncyCircle',
70+ shape: 'circle',
71+ fill: {'#F64040': '#FC46AD'},
72+ });
73+
74+ circles.play()"
75+ >
76+ </MojsInteractive >
77+
3978*/
4079
4180<template >
4281 <div class =" mojs-interactive" >
4382 <div
4483 class =" mojs-interactive__code"
4584 >
46- <prism-editor :code="code " language="js" @change="change"></prism-editor>
85+ <prism-editor :code =" rawCode " language =" js" @change =" change" ></prism-editor >
4786 <div class =" buttons" >
4887 <button class =" button button--secondary" v-on:click =" reset" >Reset</button >
4988 <button class =" button" v-on:click =" updateCode" >Update code</button >
@@ -55,8 +94,6 @@ or with no controlls at all (static animation, unless you provide a .play() func
5594 :class =" 'mojs-interactive__result ' + (dark ? 'mojs-interactive__result--dark' : '')"
5695 :style =" style"
5796 >
58- <button class="button button--icon button--control" v-if="!controller && playbutton" v-on:click="playPause" :aria-label="isPlaying ? 'Pause animation' : 'Play animation'">{{isPlaying ? '⑊' : '︎︎︎▶︎'}}</button>
59- <!-- <button class="button button--icon button--control" v-if="!isPlaying && !controller" v-on:click="play" aria-label="Play animation">▶︎</button> -->
6097 <div v-if =" controller" :id =" this.id + '_controller'" class =" mojs-interactive__controller" ></div >
6198 </div >
6299 </div >
@@ -73,13 +110,14 @@ or with no controlls at all (static animation, unless you provide a .play() func
73110
74111 props: {
75112 id: { type: String , default: ' code_example' }, // A unique ID
76- controller: { type: [String, Boolean], default: false }, // this will create a mojs.Player controller
77- playbutton: { type: Boolean, default: true }, // use this if you want a simple contoller with a play button
113+ controller: { type: [String , Boolean ], default: true }, // this will create a mojs.Player controller
114+ playbutton: { type: Boolean , default: false }, // use this if you want a simple contoller with a play button
78115 height: { type: String , default: ' 300px' }, // add a custom height to the container, takes all CSS values
79116 code: { type: String , default: ' ' }, // the code (as a string) to be executed
80117 dark: { type: Boolean , default: false }, // if you want the demo to be dark 🕶
81118 notice: { type: [String , Boolean ], default: false }, // to show a "click somewhere to activate animation" text
82119 autoplay: { type: Boolean , default: false }, // if your REALY want it to autoplay. Use with responsibility!
120+ global: { type: String , default: ' ' }
83121 },
84122
85123 data : function () {
@@ -105,48 +143,46 @@ or with no controlls at all (static animation, unless you provide a .play() func
105143 if (! window ) return ; // For SSR
106144
107145 // Do some cleaning
146+ var domRef = window [' demo_' + this .id ] || (this .global !== ' ' && window [this .global ]);
147+
108148 // Stop, remove and delete previous instance of: demo_', this.id
109- if (window['demo_' + this.id]) { // the mojs animation element
110- window['demo_' + this.id].stop();
111- window['demo_' + this.id].el.remove(); // remove the DOM node
112- delete window['demo_' + this.id];
149+ if (domRef && domRef .stop ) { // the mojs animation element
150+ domRef .stop ();
151+ domRef .el .remove (); // remove the DOM node
113152 }
114153 // Remove and delete previous instance of player: mojsPlayer_', this.id
115154 if (window [' mojsPlayer_' + this .id ]) { // the mojs player element
116155 window [' mojsPlayer_' + this .id ].el .remove (); // remove the DOM node
117156 delete window [' mojsPlayer_' + this .id ];
118157 }
119158
159+ // Normalize variable declaration and moves them to the windows object instead
160+ // Then runs the code using new Function()
161+ if (this .global !== ' ' ) {
162+ let normalizedCode = code .replaceAll (" const " + this .global , " window." + this .global );
163+ normalizedCode = normalizedCode .replaceAll (" var " + this .global , " window." + this .global );
164+ normalizedCode = normalizedCode .replaceAll (" let " + this .global , " window." + this .global );
165+
166+ new Function (normalizedCode)();
167+ } else {
120168 // Creating a global window object from a provided mojs object (code), and play it.
121- const func = new Function('window["demo_' + this.id + '"] = ' + code);
122- try {
123- func();
124- if (!this.controller && this.playbutton) {
125- this.timeline = new mojs.Timeline({
126- onPlaybackComplete: () => {
127- this.isPlaying = false;
128- }
129- })
130- .add(
131- window['demo_' + this.id]
132- );
133- // Autoplay the timeline when we press the "Update code" button
134- if (play) {
135- this.timeline.play();
136- this.isPlaying = true;
137- }
169+
170+ const func = new Function (' window["demo_' + this .id + ' "] = ' + code);
171+ try {
172+ func ();
173+ }
174+ catch (error) {
175+ console .error (' Woops, please check your code for errors.' , error)
138176 }
139177 }
140- catch(error) {
141- console.error('Woops, please check your code for errors.', error)
142- }
143-
178+
144179 // Set the prop :controller=true to include a mojs player
145- if (this.controller && window['demo_' + this.id]) {
180+ domRef = window [' demo_' + this .id ] || (this .global !== ' ' && window [this .global ]);
181+ if (this .controller && domRef) {
146182 const parentDOM = document .getElementById (this .id + ' _controller' );
147183 // Create a global mojs player instance
148184 window [' mojsPlayer_' + this .id ] = new MojsPlayer ({
149- add: window['demo_' + this.id] ,
185+ add: domRef ,
150186 parent: parentDOM,
151187 className: ' controller' ,
152188 isSaveState: false ,
@@ -163,14 +199,14 @@ or with no controlls at all (static animation, unless you provide a .play() func
163199
164200 reset : function () {
165201 this .handleCode (this .code );
202+ this .rawCode = this .code ;
166203 },
167204
168205 playPause : function () {
169206 if (this .isPlaying ) {
170207 this .timeline .pause ();
171208 } else {
172209 this .timeline .play ();
173-
174210 }
175211 this .isPlaying = ! this .isPlaying ;
176212 },
0 commit comments