Hype ChatGPT (Copilot helping with coding)

This thread is an instruction (experiment) to use ChatGPT to write (simple) code functions for Hype. To use this, register an account and visit https://chat.openai.com/chat by Open AI.

Teaching ChatGPT the Tumult Hype API

Open a new chat ChatGPT session and first inform ChatGPT about the Tumult Hype API, as it doesn't seem to know about it.

Copy and paste the following (click the small icon)

Learn the following API and acknowledge by only writing "The Tumult Hype 4 API has been loaded…":

${resourcesFolderName}
A substitution variable for the document's resources folder. Use this to reference documents added via the Resource Library.

For example, if you’ve added jquery-1.8.2.min.js to your document using the Resource Library, this one line will import jQuery 1.8.2 into your Hype document, allowing you to use jQuery when previewing your Hype document:
<script src="${resourcesFolderName}/jquery-1.8.2.min.js"></script>

hypeDocument.documentName()
Returns the name of the document. This value can be used in the global HYPE.documents[documentName].


hypeDocument.documentId()
Returns the id of the container div for the document. This value can be used with document.getElementById() to retrieve the container element itself.


hypeDocument.resourcesFolderURL()
Returns the string value for the the document’s resources folder URL. Use this to reference assets added via the Resource Library.

hypeDocument.functions()
Returns an array of all user-defined JavaScript functions in the Tumult Hype Document.

hypeDocument.customData
An object to put any user-defined data associated with the Tumult Hype Document.

hypeDocument.getElementById(id)
Searches the current document for the specified id (entered through the Identity inspector's "Unique Element ID") and returns the DOM HTML Element. This is similar to the typical 'document.getElementById', however the API version should be used instead as Tumult Hype may reassign ids in cases of collision.

hypeDocument.getElementProperty(element, propertyName)
Gets a property of an element based on the Hype runtime's knowledge. 

The element argument must be a DOM element, generally obtained by the hypeDocument.getElementById() function. 

Valid property names (quotes required):
'top'
'left'
'width'
'height'
'rotateZ'
'scaleX'
'scaleY'
'opacity'
'z-index'
'background-image'
Physics property names (pro only):
'physics-engine' - a Matter.js Engine object
'physics-body' - a Matter.js Body object
'physics-bounce'
'physics-friction'
'physics-air-drag'
'physics-density'
'physics-body-type' - Can be hypeDocument.kPhysicsBodyTypeDead, hypeDocument.kPhysicsBodyTypeStatic, or hypeDocument.kPhysicsBodyTypeDynamic

hypeDocument.setElementProperty(element, propertyName, value, optionalDuration, optionalTimingFunctionNameOrMathEquationFunction)
Sets a property of an element in a manner compatible with the Hype runtime. If the optionalDuration is provided, it will perform a transition animation from the current value to the specified value. 

The element argument must be a DOM element, generally obtained by the hypeDocument.getElementById() function. 

Valid property names (quotes required):
'top'
'left'
'width'
'height'
'rotateZ'
'scaleX'
'scaleY'
'opacity'
'z-index'
'background-image'
Physics property names (pro only):
'physics-bounce'
'physics-friction'
'physics-air-drag'
'physics-density'
'physics-body-type' - Can be hypeDocument.kPhysicsBodyTypeDead, hypeDocument.kPhysicsBodyTypeStatic, or hypeDocument.kPhysicsBodyTypeDynamic
optionalDuration is given in seconds; the default value is 0.

optionalTimingFunctionNameOrMathEquationFunction will default to 'easeinout' if not provided. Valid timing function names (quotes required):
'easeinout'
'easein'
'easeout'
'linear'
A function with this structure can also be used:
function (t, start, dur) { 
	// return percent complete
}

hypeDocument.relayoutIfNecessary()
Explicitly tells the document to relayout all elements and groups for the current scene when using a flexible layout. Use if you have externally changed the bounding size of the main container.


hypeDocument.triggerCustomBehaviorNamed(customBehaviorName)
Informs any elements which have a custom behavior with customBehaviorName to run its actions.


hypeDocument.sceneNames()
Returns a list of all scenes in the document. Note: scene names are not enforced to be unique as they are specified by in the scene selector interface. If you are going to use the showSceneNamed() function, be sure that no two scenes have the same name!

hypeDocument.currentSceneName()
Returns the string value for the currently shown scene.

hypeDocument.currentSceneId()
Returns the id of the container div for the current scene. This value can be used with document.getElementId() to retrieve the container element itself.

hypeDocument.showSceneNamed(sceneName, optionalTransition, optionalDuration)
Changes to the specified scene. If the optionalTransition is not specified it will default to the instant transition. 

Valid transition constants:
hypeDocument.kSceneTransitionInstant
hypeDocument.kSceneTransitionCrossfade
hypeDocument.kSceneTransitionSwap
hypeDocument.kSceneTransitionPushLeftToRight
hypeDocument.kSceneTransitionPushRightToLeft
hypeDocument.kSceneTransitionPushBottomToTop
hypeDocument.kSceneTransitionPushTopToBottom
optionalDuration is given in seconds; the default value is 1.1.



hypeDocument.showNextScene(optionalTransition, optionalDuration)
Shows the next scene, based on the order in the scene selector interface. If the optionalTransition is not specified it will default to the instant transition. 

Valid transition constants:
hypeDocument.kSceneTransitionInstant
hypeDocument.kSceneTransitionCrossfade
hypeDocument.kSceneTransitionSwap
hypeDocument.kSceneTransitionPushLeftToRight
hypeDocument.kSceneTransitionPushRightToLeft
hypeDocument.kSceneTransitionPushBottomToTop
hypeDocument.kSceneTransitionPushTopToBottom
optionalDuration is given in seconds; the default value is 1.1.



hypeDocument.showPreviousScene(optionalTransition, optionalDuration)
Shows the previous scene, based on the order in the scene selector interface. If the optionalTransition is not specified it will default to the instant transition. 

Valid transition constants:
hypeDocument.kSceneTransitionInstant
hypeDocument.kSceneTransitionCrossfade
hypeDocument.kSceneTransitionSwap
hypeDocument.kSceneTransitionPushLeftToRight
hypeDocument.kSceneTransitionPushRightToLeft
hypeDocument.kSceneTransitionPushBottomToTop
hypeDocument.kSceneTransitionPushTopToBottom
optionalDuration is given in seconds; the default value is 1.1.

hypeDocument.layoutsForSceneNamed(sceneName)
Returns a list of layout info for the given scene. Layout info is given as an object with the following keys:
'name'
'breakpoint'
'width'
'height'


hypeDocument.currentLayoutName()
Returns the string value for the name of the currently shown layout.


hypeDocument.showLayoutNamed(layoutName)
Changes instantly to the specified layout in the current scene. The layout may change back on a resize event, scene change, or relayoutIfNecessary() call.

In order to force specific layouts, use the HYPE_eventListeners infrastructure to listen to "HypeLayoutRequest" events and return a different layout name from the callback.


hypeDocument.startTimelineNamed(timelineName, direction)
Starts the specified timeline at the beginning for the current scene. Note: timelines are user-defined, so they are not enforced to be unique. If you are going to use this function, be sure that no two timelines in any scene have the same name!

Direction to play timeline:
hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse


hypeDocument.pauseTimelineNamed(timelineName)
Pauses the specified timeline for the current scene. Note: timelines are user-defined, so they are not enforced to be unique. If you are going to use this function, be sure that no two timelines in any scene have the same name!


hypeDocument.continueTimelineNamed(timelineName, direction, canRestartTimeline)
Continues the specified timeline where it left off for the current scene. Note: timelines are user-defined, so they are not enforced to be unique. If you are going to use this function, be sure that no two timelines in any scene have the same name!

By default continue will not start the timeline over if it is at the end, to change this behavior pass true for canRestartTimeline.

Direction to play timeline:
hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse



hypeDocument.goToTimeInTimelineNamed(timeInSeconds, timelineName)
Jumps to a specific time in the specified timeline for the current scene. Note: timelines are user-defined, so they are not enforced to be unique. If you are going to use this function, be sure that no two timelines in any scene have the same name!


hypeDocument.currentTimeInTimelineNamed(timelineName)
Returns the current time of the specified timeline in seconds.

hypeDocument.durationForTimelineNamed(timelineName)
Returns the duration of the specified timeline in seconds.

hypeDocument.currentDirectionForTimelineNamed(timelineName)
Returns the playback direction of the specified timeline. 

Possible return values:
hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse

hypeDocument.isPlayingTimelineNamed(timelineName)
Returns true if the timeline is playing and false if it is not.


hypeDocument.getSymbolInstanceById(id)
Returns the symbolInstance for the symbol with the specified id.

The symbol instance can be used to control timelines in the symbol. See the Symbol Instances section for more information.

hypeDocument.getSymbolInstancesByName(symbolName)
Returns all symbolInstances with the specified name. A symbol's name can be found in the Symbol Library.

The symbol instance can be used to control timelines in the symbol. See the Symbol Instances section for more information.



symbolInstance.getSymbolInstancesByName(symbolName)
Returns all symbolInstances with the specified name that are children of symbolInstance.element(). A symbol's name can be found in the Symbol Library.


symbolInstance.symbolName()
Returns the name of the symbol.



symbolInstance.element()
Returns the element representing the symbol.


symbolInstance.startTimelineNamed(timelineName, direction)
Starts the specified timeline at the beginning for the symbol. Note: timelines are user-defined, so they are not enforced to be unique. If you are going to use this function, be sure that no two timelines in the symbol have the same name!

Direction to play timeline:
hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse

symbolInstance.pauseTimelineNamed(timelineName)
Pauses the specified timeline for the symbol. Note: timelines are user-defined, so they are not enforced to be unique. If you are going to use this function, be sure that no two timelines in the symbol have the same name!

symbolInstance.continueTimelineNamed(timelineName, direction, canRestartTimeline)
Continues the specified timeline where it left off for the symbol. Note: timelines are user-defined, so they are not enforced to be unique. If you are going to use this function, be sure that no two timelines in the symbol have the same name!

By default continue will not start the timeline over if it is at the end, to change this behavior pass true for canRestartTimeline.

Direction to play timeline:
hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse

symbolInstance.goToTimeInTimelineNamed(timeInSeconds, timelineName)
Jumps to a specific time in the specified timeline for the symbol. Note: timelines are user-defined, so they are not enforced to be unique. If you are going to use this function, be sure that no two timelines in the symbol have the same name!


symbolInstance.currentTimeInTimelineNamed(timelineName)
Returns the current time of the specified timeline in seconds.

symbolInstance.durationForTimelineNamed(timelineName)
Returns the duration of the specified timeline in seconds.


symbolInstance.currentDirectionForTimelineNamed(timelineName)
Returns the playback direction of the specified timeline. 

Possible return values:
hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse

symbolInstance.isPlayingTimelineNamed(timelineName)
Returns true if the timeline is playing and false if it is not.


event['hypeGesturePhase']
When receiving a callback for the "On Drag" event with the "Run JavaScript…" action the event object also offers information about whether the current drag gesture has just started or ended, was canceled, or the coordinates were updated. To get that state, access the hypeGesturePhase property in the event object:
hypeDocument.kHypeGesturePhaseStart
hypeDocument.kHypeGesturePhaseMove
hypeDocument.kHypeGesturePhaseEnd
hypeDocument.kHypeGesturePhaseCancel


event['hypeGestureXPosition']
Returns the current x position of a drag when using the "On Drag" event with the "Run JavaScript…" action.


event['hypeGestureYPosition']
Returns the current y position of a drag when using the "On Drag" event with the "Run JavaScript…" action.

Coding guidelines and instructions

We need to inform ChatGPT about best coding practice and that Hype functions are called and used in an interface…

Copy and paste the following

Acknowledge the following coding guidelines and information, by only saying "Coding guidelines acknowledged":

# Coding guidelines and best practice

## Format for responses

Always use the following Hype Function template to write (replace the comment):

function yourFunctionNameGoesHere(hypeDocument, element, event) {
	
	// your code goes here

}

Try to use querySelector and querySelectorAll if possible
Make sure to limit queries to the Hype Scene by first fetching the Hype Scene element using:

var hypeSceneElm = document.getElementById(hypeDocument.currentSceneId())

If you fetch elements add "Elm" at the end of variables to identify them as such.

Important: If you create variables outside of the scope of the Hype Function store them in hypeDocument.customData

Important: Use modern JavaScript and assign variable using let and const

Important: Helper functions must be either declared inside the Hype Function scope before usage or added to the API (hypeDocument must be extended with them). It is not an option to add them to the global scope (window).


## Context of the code
Calling functions is done through the visual interface of Tumult Hype 4:
* by using Timeline Actions [keyframes on a timeline] to trigger them
* by setting them up in the Interaction Panel [On Mouse Click (Tap), On Mouse Down (Touch Start), On Mouse Up (Touch End), On Mouse Over, On Mouse Out, On Drag, On Enter Viewport, On Exit Viewport].
* by setting them up in the Document Panel [On Prepare For Display, On Scene Load, On Scene Unload, On Key Press, On Key Down, On Key Up,On Swipe Left,On Swipe Right, On Swipe Up, On Swipe Down]
* by creating a Custom Behavior Listener (simple text string behavior) to trigger them (works scene wide)

Important: When instructing a user describe (if necessary) where to place the function in the interface!  Write code always in code blocks! And try to be smart about suggesting about the context. 

If functions are linked to each other by a custom behavior and it is appropriate, instruct the user to register the subsequent function in the Scene Panel by creating the custom behavior name using "Add New Behavior". 


## Addressing the user and comment style
When you are explaining talk directly to the user asking you questions (you). Remember to add your train of thought and in code blocks make sure to add comments to explain yourself as most Hype users are not very well versed in coding.

## Limit yourself to the official Hype API

Very import ONLY use hypeDocument functions, constants and objects from the following list!
Only use other functions in hypeDocument if explicitly told they exist (in cases the API has been extended).

### Place to store custom data and values (object)
hypeDocument.customData

### constants stored in the API
hypeDocument.kSceneTransitionInstant
hypeDocument.kSceneTransitionCrossfade
hypeDocument.kSceneTransitionSwap
hypeDocument.kSceneTransitionPushLeftToRight
hypeDocument.kSceneTransitionPushRightToLeft
hypeDocument.kSceneTransitionPushBottomToTop
hypeDocument.kSceneTransitionPushTopToBottom
hypeDocument.kHypeGesturePhaseStart
hypeDocument.kHypeGesturePhaseMove
hypeDocument.kHypeGesturePhaseEnd
hypeDocument.kHypeGesturePhaseCancel
hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse

###  Hype API functions
hypeDocument.documentName
hypeDocument.documentId
hypeDocument.sceneNames
hypeDocument.currentSceneName
hypeDocument.currentSceneId
hypeDocument.layoutsForSceneNamed
hypeDocument.currentLayoutName
hypeDocument.showLayoutNamed
hypeDocument.showSceneNamed
hypeDocument.showNextScene
hypeDocument.showPreviousScene
hypeDocument.playTimelineNamed
hypeDocument.startTimelineNamed
hypeDocument.goToTimeInTimelineNamed
hypeDocument.pauseTimelineNamed
hypeDocument.continueTimelineNamed
hypeDocument.getElementById
hypeDocument.setElementProperty
hypeDocument.getElementProperty
hypeDocument.functions
hypeDocument.resourcesFolderURL
hypeDocument.relayoutIfNecessary
hypeDocument.currentTimeInTimelineNamed
hypeDocument.durationForTimelineNamed
hypeDocument.currentDirectionForTimelineNamed
hypeDocument.isPlayingTimelineNamed
hypeDocument.triggerCustomBehaviorNamed
hypeDocument.getSymbolInstanceById
hypeDocument.getSymbolInstancesByName

Prompting:

After that, you can prompt ChatGPT with your problems and ask for a solution. You can continue asking and don't need to reload the API or guidelines as long as you don't refresh the page.


Release notes for v1.0.0 (11. December 2022):

I wrote the API code for a playground test and limited it to the 4000 tokens allowed at the time. In ChatGPT we are dealing with a much more generous rolling 8000 token window. I will probably refine the API description to details (suggestions welcome). Furthermore, the guidelines are also older (GPT3) and the interface part was improvised for ChatGPT. Both could use some refinement as well…

Release notes for v1.0.1 (11. December 2022):

I am tweaking the best practice guidlines. Currently, they are stricly focused on Hype functions and not ment to produce code in Head HTML


Please share your results if possible and feedback and improvements are welcome!

14 Likes

↑ look at prompts you need to get the results below

Now you can prompt ChatGPT for Hype 4 function help… for example:

Prompt

Write a function that stops the main timeline on the third call. It then should start a timeline called "outro".

Response from Hype ChatGPT

including all the instructions (might be different every time):

Here is an example function that stops the main timeline on the third call, and then starts a timeline called "outro":
function stopTimelineOnThirdCall(hypeDocument, element, event) {
	// First, check if the function has been called three times
	if (hypeDocument.customData.callCount === 3) {
		// If it has been called three times, stop the main timeline
		hypeDocument.pauseTimelineNamed('timelineName');

		// Then start the "outro" timeline
		hypeDocument.startTimelineNamed('outro');
	} else {
		// If the function has not been called three times, increment the call count
		hypeDocument.customData.callCount++;
	}
}

To use this function, you would set it up in the Interaction Panel. For example, you could set it to run "On Mouse Click (Tap)" on a particular element. You would also need to initialize the callCount property in the hypeDocument.customData object, either in the "On Prepare for Display" document action, or in some other function that runs before the stopTimelineOnThirdCall function is called.

function initializeCustomData(hypeDocument, element, event) {
	// Initialize the callCount property
	hypeDocument.customData.callCount = 0;
}

You would then set up the "outro" timeline in the Timeline Editor, and add any necessary keyframes and actions to it.

2 Likes

↑ look at prompts you need to get the results below

Prompt:

Create a function that fetches a element by id "red" and animates to 200,400 and roation 30°

Response from Hype ChatGPT:

Here is an example function that fetches an element with the id "red" and animates it to position 200, 400 and rotation 30°:
function animateRedElement(hypeDocument, element, event) {
	// First, fetch the element with the id "red"
	var redElm = hypeDocument.getElementById('red');

	// Then animate its position and rotation using the setElementProperty function
	hypeDocument.setElementProperty(redElm, 'top', 200, 0.5, 'easeinout');
	hypeDocument.setElementProperty(redElm, 'left', 400, 0.5, 'easeinout');
	hypeDocument.setElementProperty(redElm, 'rotateZ', 30, 0.5, 'easeinout');
}

To use this function, you would set it up in the Interaction Panel. For example, you could set it to run "On Mouse Click (Tap)" on a particular element. You would also need to make sure that the element with the id "red" exists in the document and has the appropriate properties (position and rotation) set in the Identity Inspector.

2 Likes

↑ look at prompts you need to get the results below

I updated the Coding Guidelines to use modern JS and custom behavior if needed (version 1.1) … check out what is now possible!

Prompt:

Write a function that fetches data from an endpoint, stores it and triggers an custom behavior. Write a second function that when triggered searches for elements with data-key. It then uses the value to resolve the loaded data and if that yields a value assigns it to inner HTML.

Response form Hype ChatGPT:

To fetch data from an endpoint, store it and trigger a custom behavior, we can use the following function:
function fetchData(hypeDocument, element, event) {
  // Store the endpoint URL in a variable
  const endpointURL = 'https://www.example.com/data';

  // Fetch the data from the endpoint
  fetch(endpointURL)
	.then(response => response.json()) // Parse the response as JSON
	.then(data => {
	  // Store the data in the `customData` object
	  hypeDocument.customData.data = data;

	  // Trigger the custom behavior
	  hypeDocument.triggerCustomBehaviorNamed('dataLoaded');
	})
	.catch(error => {
	  // Log the error to the console
	  console.error(error);
	});
}

To search for elements with a data-key attribute, resolve the corresponding data value and assign it to the inner HTML, we can use the following function:

function updateElements(hypeDocument, element, event) {
  // Get the Hype scene element
  const hypeSceneElm = document.getElementById(hypeDocument.currentSceneId());

  // Use querySelectorAll to find all elements with a `data-key` attribute
  const elements = hypeSceneElm.querySelectorAll('[data-key]');

  // Loop through the elements
  elements.forEach(element => {
	// Get the data key from the `data-key` attribute
	const dataKey = element.getAttribute('data-key');

	// Resolve the data value using the key
	const dataValue = hypeDocument.customData.data[dataKey];

	// If the data value is not undefined, set the element's inner HTML to the value
	if (dataValue !== undefined) {
	  element.innerHTML = dataValue;
	}
  });
}

To use these functions, you can call the fetchData function to start the process of fetching the data from the endpoint. When the data is loaded, the dataLoaded custom behavior will be triggered. You can then register the updateElements function for the dataLoaded behavior in the Scene Panel to have it run when the data is loaded. This will search for elements with a data-key attribute and update their inner HTML with the corresponding data value.

Follow-up prompt

Is there a way to resolve more complex keys? For example data-key could be "product.1"  or "weather.berlin.temperature".

Response form Hype ChatGPT:

Yes, it is possible to resolve more complex keys using the bracket notation for accessing object properties, as shown below:

function updateElements(hypeDocument, element, event) {
  // Get the Hype scene element
  const hypeSceneElm = document.getElementById(hypeDocument.currentSceneId());

  // Use querySelectorAll to find all elements with a `data-key` attribute
  const elements = hypeSceneElm.querySelectorAll('[data-key]');

  // Loop through the elements
  elements.forEach(element => {
	// Get the data key from the `data-key` attribute
	const dataKey = element.getAttribute('data-key');

	// Split the data key by the dot character to get the individual keys
	const keys = dataKey.split('.');

	// Start with the data object
	let dataValue = hypeDocument.customData.data;

	// Loop through the keys
	keys.forEach(key => {
	  // Use the bracket notation to access the property of the data object
	  dataValue = dataValue[key];
	});

	// If the data value is not undefined, set the element's inner HTML to the value
	if (dataValue !== undefined) {
	  element.innerHTML = dataValue;
	}
  });
}

In this updated function, we split the data-key attribute by the dot character to get an array of individual keys. We then loop through these keys, using the bracket notation to access the corresponding property of the data object. This allows us to resolve more complex keys, such as "product.1" or "weather.berlin.temperature".

You can then use this updated function in the same way as the previous one, by calling the fetchData function and registering the updateElements function for the dataLoaded custom behavior.


I updated this example to illustrate that followups are also possible, and ChatGPT is astounding at refining solutions as well :exploding_head:!

10 Likes

Wow - this is amazing!

They told people… learn to code …but this looks like the developers will be amongst first to be automated. :smile:

Although, it probably can't do this task… “Update Hype to version 5.0, with some fancy features.” …but it seems like it might do an OK job with documentation, so do people need books about Hype 5.0 anymore? :blush:

1 Like

That really depends on when Hype 5 is coming out :stuck_out_tongue_winking_eye:
In 2023… totally… give it a year more or two… and things might look quite differently.

1 Like

The longer we wait, the more AI can make Hype v5 :crazy_face:

3 Likes

From the brief things I have seen regarding this, is that the code coming out is only as good as the code going in. Meaning its learning source can be corrupted with bad examples which work but will have problems outside of the immediate answer.

it will offer answers with a confident explanation as being correct even if the answer is flawed.

Also as I think about this there is the correct way of doing things and then there is the inventive way of doing things which can lead to new correct ways of doing things.

Basically the A.I I think will only show you a an assumed correct way, will not innovate (yet?)
So I thing real coders are safe. (Most anyway)

2 Likes

It's a the beginning of something great/new.... And by the way; amazing you came up with this! That's also pretty cool! Thanks.

2 Likes

This is actually bad. Everyone is taking this Dalle2 and ChatGPT or even Diffusion as something harmless. I speak for all the developers, including myself when I say "We're doomed."