This User Guide tells you, how to create Custom Demos for the Curvature App. The code for the Custom Demos must be entered in:
The Curvature App provides some self running Demos. They can be started by clicking one of the designated buttons above the graphic display.
A Custom Demo is a Demo programmed by a User width granted access to the page Curvature App Custom Demo. Through a plug in mechanism the User can programm his own Demo. If such a Demo is programmed, an additional Button appears to start the Custom Demo. The button caption can be programmed as required.
The user may also Replace one or more existing Demos by his own versions.
It is possible to Programming multiple Custom Demos on this page. Via URL parameters one of the Demos may be choosen at a time. Each Custom Demo is enclosed by a pair of named Macros. With the URL parameter one of this names can be choosen to include the corresponding Custom Demo into the App:
url&custom=CustomName
By default the Custom Demo named custom is included, if no such URL parameter is provided.
See also URL Parameters for more parameters
The Curvature App searches for the page Special: Curvature App Custom Demo or for the german version Special: Curvature App Custom Demo. This page may contain pairs of named {{data}}-Macros, which enclose some Javascript code:
{{data|custom}} <jscript> function InitCustomDemo() { // definition of the Custom Demo } </jscript> {{end data|custom}}
The Curvature App includes the code between one of the {{data}}-Macros into its own code and executes the function InitCustomDemo.
There may be multiple Custom Demos in the Curvature App Custom Demo (german Version) page, each within its own pairs of {{data}}-Macros. Each {{data}}-Macro must have a distinctive name. The default Custom Demo must be named custom.
{{data|custom}} <jscript> : </jscript> {{end data|custom}} {{data|demo1}} <jscript> : </jscript> {{end data|demo1}} {{data|demo2}} <jscript> : </jscript> {{end data|demo2}}
Which Demo gets included in the Curvature App is determined by the URL parameter custom. If no such parameter is specified when calling the App page with a link, then custom=custom is applied.
To include the demo1 Custom Demo into the Curvature App, call the page as follows:
http://walter.bislins.ch/...&custom=demo1
A Custom Demo is inserted into the Demo Manager of the App by calling the function InitCustomDemo. In this function you have to make calls to member functions of the Demos object. By this calls you set a caption for the Custom Demo button, make it visible and create the Demo.
The function InitCustomDemo must have the following structure:
{{data|MyDemo}} <jscript> function InitCustomDemo() { Demos.SetButtonText( 'MyDemo' ); Demos.New( 'Custom', 'Text below the Demo buttons' ); Demos.AddState( /* initial state as a json string */ ); Demos.AddAnimation( /* animation definition from initial state to state 1 */ ); Demos.AddState( /* state 1 as a json string */ ); Demos.AddAnimation( /* animation definition from state 1 to state 2 */ ); Demos.AddState( /* state 2 as a json string */ ); : } // end function InitCustomDemo() </jscript> {{end data|MyDemo}}
The Custom Demo object is the container for all demo states and demo animations. You must create an initial state (what is displayed in the graphic display) by calling Demos.AddState. Then pairs of animations and states are created until the demo spcification is finished.
A state is a set of values for the CurveApp object in json-string format. The json-string is passed as the parameter to the call Demos.AddState().
To create a state in json-string format:
Now you have specified the initial state. Next you specifiy some animation/state pairs.
If you want to match a Demo state exactly with an image, you can temporarily include the image in the App as a background and overlay the App graphic onto this image.
The image must be uploaded to the web-werver in the same folder as the blog by the upload function of the Wiki (click the Upload-button while a blog page is displayed) or you have to specify the url of the image. The image can later be deleted from the server by deleting the info page of the image that is created on the upload.
You may blend in and out images in your demos by using the Tool functions TshowImage(), ThideImage() and TjsonImage(), see Usage of Image Credit Functions (Curvature App Demos Code).
To include the image in the App, go to the Save/Restore tab and click Get App State. Scroll to the bottom and assign the image filename to the property BackgroundImage:
CurveApp = { "DemoText": "", "Description": "", "Height": 100, : "showTheodolite": false, "BackgroundImage": "myImage" }
Then press Enter or click Set App State. The image is now displayed as a background image of the App. The image is resized to fit into the window size maintaining the aspect ratio and is centered in the window. To make the App graphic transparent you have to click into the window. The farther left you click, the more transparent the graphic will become.
Now you can play with the sliders until the graphic matches the background image. Click Get App State to get the current graphics setting. Delete the image name of the property BackgroundImage and press Enter to remove the background image. Now you can use this App state for an animation as described at Creating a StateDef.
You can chosse between 2 methods.
a) Create the next state the same way as the initial state. Then define the animation to get from the first to next state by animating all values that have changed between the states in the desired order and speeds.
b) Create an animation by defining changes of some CurveApp properties. Then copy the previous state to the next state and change on the next state all properties that have been changed by the animation accordingly, so that the state reflects the state at the end of the animation.
You can use these methods interchangably.
An AnimationDef as used in a call of Demos.AddAnimation() is an object of the following form:
{ Delay: AnimT1, // optional Mode: 'serial', // or 'parallel' TaskList: [ Task or AnimationDef, : ], }
Mode defines how the tasks are executed, serial one by one or parallel all at the same time (you may delay some of the tasks though).
A Task is an object created with one of the Helper Functions Ttxt, Tval, Tpse and Tpan.
Note that a Task may also be another AnimationDef. In this way you can define a nested list of tasks that contain tasks that are executed parallel. Tasks and AnimationDefs may be nested arbitrarily deep.
You can find all built in Demos and use it as a template for your Animations at
Demos.AddAnimation( { Mode: 'serial', TaskList: [ Tpan( AnimT1 ), Ttxt( 'Looks pretty flat, no Curvature visible. Lets go higher.' ), Tval( 'Height', 500, AnimT3, AnimT3 ), Ttxt( 'Height = 500 m. Still looking flat. Horizon at 80 km.', AnimT1 ), Tpse( AnimT3 ), ], } );
This animation executes 5 property changes in the CurveApp in sequence:
Tip: Don't program big delays for the first task. If you need some delay between the last task of an animation and the first task of the next animation, use Tpse as the last task of the previsous animation to insert a pause between the tasks. In this way when a user resumes a demo from a certain state, there is no big delay until the first task is executed. The delay took place before reaching the current state.
The following Animation uses a nested AnimationDef to execute 2 value changes parallel, at the same time.
Demos.AddAnimation( { Mode: 'serial', TaskList: [ Ttxt( 'Lets climb to ISS Altitude of 400 km:', AnimT1 ), { Delay: AnimT3, Mode: 'parallel', TaskList: [ Tval( 'Height', 400000, AnimT5 ), Tval( 'Tilt', 8.89, AnimT5 ), ], }, Ttxt( 'We should see the Ice Wall at 20015 km on Flat Earth!', AnimT2 ), Tpse(), ], } );
Note: the parallel executed tasks can use different time spans and can be delayed individually to create overlapping changes.
The Helper Functions are used to create animation tasks.
The parameter name can be any public property name of the CurveApp. To see all supported names, select the Save/Restore Panel of the App and click on Get App State. In the displayed App State are all properties listet, that can be changed by the function Tval().
Properties with a wide range of values can be given a time span to change the value. If omitted, the value is changed immediately, which should be the case for all integer or boolean properties.
You can specify a sweep function. Default is cosine, others are linear, ...
delay specifies the time delay to wait until the value is changed.
For time values as time and delay use the AnimT1 to AnimT10 constants to use a corresponding time in seconds.
To replace an existing Demo with own versions, specify the demo to replace in the call to Demos.New by providing the name of the demo.
Say we want to replace the Curve Demo with MyDemo and label the Curve button to MyDemo:
{{data|custom}} <jscript> function InitCustomDemo() { Demos.SetButtonText( 'MyDemo', 'Curve' ); Demos.New( 'Curve', 'Text below the Demo buttons' ); Demos.AddState( /* initial state as a json string */ ); Demos.AddAnimation( /* animation definition from initial state to state 1 */ ); Demos.AddState( /* state 1 as a json string */ ); : } // end function InitCustomDemo() </jscript> {{end data|custom}}
You may replace more than one demo by repeating the steps above in the same InitCustonDemo function:
{{data|custom}} <jscript> function InitCustomDemo() { // replace Curve Demo Demos.SetButtonText( 'MyDemo1', 'Curve' ); Demos.New( 'Curve', 'Text below the Demo buttons' ); Demos.AddState( /* initial state as a json string */ ); Demos.AddAnimation( /* animation definition from initial state to state 1 */ ); Demos.AddState( /* state 1 as a json string */ ); : // replace Bedford Demo Demos.SetButtonText( 'MyDemo2', 'Bedford' ); Demos.New( 'Bedford', 'Text below the Demo buttons' ); Demos.AddState( /* initial state as a json string */ ); Demos.AddAnimation( /* animation definition from initial state to state 1 */ ); Demos.AddState( /* state 1 as a json string */ ); : } // end function InitCustomDemo() </jscript> {{end data|custom}}
Because these Demos are enclosed between the {{data}}-Macros named custom, they automatically replace the corresponding demos on App page load.
You cannot move the camera except up and down by changing Height. To simulate camera movements, you have to move the objects Dist and SidePos accordingly and then use Pan and Tilt to point to the desired location.
Although you can look backwards by entering Pan values greater than 90 degrees, the objects in this direction are not clipped correctly at the horizon. Avoid this situation if possible.
Use a time span of 0 for animation tasks that change a mode or flag like showModel or showData.
Note: you can use negative values for Dist despite the fact that the corresponding slider has no negative range.
Sliders have a certain restricted value range. But you can enter values outside this range into the input fields beside the sliders or by programming them in a state or animation accordingly.
To change refraction you have to set the refractionSync accordingly:
Depending on refractionSync some or all of the values pressure, temperatureC (in Celsius), tempGradient and refractionSync will be ignored in the json-string.
refractionMin and refractionMax limit the refraction range in terms of a multiple of the earths radius.
You can experiment with different sizes of the flat earth and the globe earth by chaning rFEarth and rEarth accordingly within some limit.