Calling a function from Resources with manually added button

I hope the title of this post makes sense and here is what I need to do.

I have a Hype project which includes a function added to the Resources folder. The function does two things: jumps to the next scene and records scene name in local storage.

I know I can just add a button within Hype and add the function on click but I need call this function when clicking a button coded manually inside a rectangle element (don't ask why :slight_smile: ).

I looked here and here and I found this code that should get the work done:

HYPE.documents["documentName"].functions().functionName();

I'm trying to add this code inside the onclick attribute of the manually coded button and the code gets messed up and doesn't work.

Have a look yourself:
test.zip (27.1 KB)

I would be grateful if you can point me in the right direction or suggest an alternative solution.

Thanks!
Greg

There's a few points to consider in observing this code:

HYPE.documents["documentName"].functions().functionName();

The documentName would need to be filled with the name of your document when you export it. There's a more generic way to find the document on the page, as long as it is the first one:

Object.values(HYPE.documents)[0];

This basically says "get all the values of HYPE.documents and return the first on the page". So this is probably easier to use.

Secondarily, the RecordScene() function takes three arguments (hypeDocument, element, event). While you don't use element or event in your code, you do use hypeDocument so it is important to pass that in when you call the code.

So I'd first assign a variable to that first hype document we got, and then use the functions() to get your RecordScene() function and then pass in that variable there. There resulting code you'd put in the onclick part would be:

var mainHypeDocument = Object.values(HYPE.documents)[0]; mainHypeDocument.functions().RecordProgress(mainHypeDocument);

Then it should work.

test-fixed.zip (26.1 KB)

That said, there's one small note. I'm not sure if this is intentional or not, but your RecordScene code is:

hypeDocument.showNextScene(hypeDocument.kSceneTransitionInstant);
localStorage.Scene = hypeDocument.currentSceneName();

Instant transitions literally happen instantly, so do note that the localStorage is going to record "scene2" and not "scene1" since it has already transitioned. If you wanted it to capture what would be "scene1" then you'll need to swap those lines.

2 Likes

If you want to do it that way, here is a simple extension that might help:

1 Like

That's great Jonathan and thanks for all the instructions.

I did not realise that a page can, in theory, have several hypeDocuments which opened a few possibilities for me.

Last thing I don't quite understand is the mainHypeDocument variable used as a parameter for the RecordProgress function. All examples of function parameters I have seen so far when learning JS were numbers, not variables.

Thanks again
Greg

1 Like

I also like this approach. Thanks for sharing Max!

1 Like

They can be any data type including variables. Imagine:

function pythagoras(a, b) {
	return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
}

let width = prompt("What is the width?");
let height = prompt("What is the height?");

let hyp = pythagoras(width, height);

alert("The hypotenuse is " + hyp);
1 Like

Hi Max

Following your implementation example, I'm trying to continue a timeline in reverse on button click and included the following code

onclick="getHypeDocument(this).continueTimelineNamed('timelineName', hypeDocument.kDirectionForward, false)"

However, I think the syntax is wrong and that's where I'm struggling a bit.

Thanks for your help.

Greg

Hi Greg,

Thanks for your message! I see the issue you’re running into. The syntax you’re using is close, but you need to make sure the hypeDocument reference is properly resolved. Right now, you’ve got two separate references to hypeDocument, and they need to come from the same instance.

One way to fix this is to call getHypeDocument twice, like this:

onclick="getHypeDocument(this).continueTimelineNamed('timelineName', getHypeDocument(this).kDirectionReverse, false);"

This works because each getHypeDocument(this) call resolves to the correct hypeDocument for the element. It’s fine to do it this way, but it’s a bit repetitive.

Another option—and what I’d recommend—is storing the result of getHypeDocument(this) in a variable. That way, you only fetch it once and reuse it. Here’s how that looks:

onclick="var hypeDoc = getHypeDocument(this); hypeDoc.continueTimelineNamed('timelineName', hypeDoc.kDirectionReverse, false);"

This approach works the same but is cleaner and easier to read, especially if your code gets more complex later on.

Either way should fix the issue, so pick whichever makes more sense for you! Let me know if you need any more help.

Cheers,

Max

2 Likes

Works like a charm.

Thanks and Merry Xmas Max!