Is there a way to make an iBooks widget Not reload when closing/opening book?


(Anton) #1

So, I have made a simple widget that starts off displaying a five cornered hollow star and when clicked it changes scene to a bronze star, and one more click -> silver, then gold. But to my dismay I have found that when I click it to a gold star and flick a few pages and come back, the widget has gone back to the start.

Is there a way to make a widget that stays on the scene it is on, even when the book is closed and reopened?


(๐•„๐•š๐•”๐•™๐•’๐•–๐• ๐”พ๐•’๐•ฃ๐• ๐•—๐•’๐•๐• ) #2

Iโ€™m not sure if it works in iBooks, but did you try using cookies?


(Anton) #3

I ate cookies yesterday, thatโ€™s about as far as my competence stretches :slight_smile:


(Anton) #4

It seems possible to accomplish my goal with some javascripting - localStorage - but I canโ€™t seem to wrap my head around it. But I only have about 1 hour of experience with javascript, soโ€ฆ :slight_smile:


(๐•„๐•š๐•”๐•™๐•’๐•–๐• ๐”พ๐•’๐•ฃ๐• ๐•—๐•’๐•๐• ) #5

Cookiesโ€ฆ
http://www.w3schools.com/js/js_cookies.asp

Local Storageโ€ฆ
https://discussions.apple.com/thread/3686472

Local Storage seems like a good place to start expanding your expertise. It seems that this is a common issue with iBooks and Local Storage might be the solution.


(Anton) #6

I am a bit pessimistic though - since the widget-โ€œiconโ€ in my ibook serves as my first star and the other stars are inside the widget - but replaces the Icon. I guess that even if I could manage to get local storage working, I would probably have to click on the widget icon to get the โ€œlatestโ€ star I was onโ€ฆ


(๐•„๐•š๐•”๐•™๐•’๐•–๐• ๐”พ๐•’๐•ฃ๐• ๐•—๐•’๐•๐• ) #7

Iโ€™m confused. How are you displaying the widget icon in iBooks? Do you mean the default image? If thatโ€™s what you mean, then you can just set the Widget to play automatically.

It sounds like youโ€™re building a level select. The first scene in Hype can be the level select โ€“ which is automatically updated by the local storage value.

localStorage.stars=stars;

So if โ€œstarsโ€ equals 1, then it goes to frame 1 or scene 1. If it equals 2, then it goes to frame 2 or scene two.

I tested it out in A Book About Hype. Itโ€™s an iBook that uses widgets created with Hype. Now one of my examples should have savable high scores.


(Anton) #8

That is very true, I didnโ€™t think of the play automatically-setting! Then it should definitely be doable.

Would it be doable for someone like me with hardly any javascript-experience and very little html-experience (I can read and understand some of it, but writing - not so much) to get a localstorage-script-thing working through trial and error and tutorials or is it a task that demands having solid javascript experience?


#9

Hereโ€™s an example of storing local storage data within a Widget: https://github.com/widged/iBook-widgets/blob/master/widgets/localStorage.wdgt/main.html

And here is the finished widget: localStorage.wdgt.zip (113.4 KB).

It uses jQuery to make this a bit easier, but here is the core code for storing / retrieving data:

<script language="javascript" type="text/javascript">
		var $input = $("input#studentName");
		if(localStorage.studentName) {
			$('span#lastSaved').html('(last saved: ' + localStorage.studentName + ")")
		}
		$('#btn-save').click(function () {
		 var studentName =  $input.val();
		 localStorage.studentName=studentName;
		 localStorage.completedActivity1=true;
		});
	</script>

It keeps track of whether an activity has been completed and the studentโ€™s name.

You could periodically run hypeDocument.currentSceneName(); to get the current scene, and write that to local storage, but there are many ways to do this. Iโ€™ll put together a demo soon.


(๐•„๐•š๐•”๐•™๐•’๐•–๐• ๐”พ๐•’๐•ฃ๐• ๐•—๐•’๐•๐• ) #10

Like I mentioned before, this is an opportunity to expand your expertise. Itโ€™s actually a pretty good first project in JavaScript. I was surprised at how easy it was to add High Score saving to my project.

It does take patience and determination, as there are issue that appear. I call this โ€œGrindingโ€ in my book. Itโ€™s hard to be a developer because of the constant problem solving. Itโ€™s like lifting weights with your mind. Yet, by powering through it, you can become much better at web development.

I donโ€™t want to give the answer away, as solving problems is how to learn, but itโ€™s certainly much easier than what Daniel just posted. jQuery isnโ€™t necessary. Donโ€™t let that example scare you.


(Anton) #11

Allright! Well, Iโ€™ve have spent alot of time grinding before and the problem solver in me loves it. And hates it :slight_smile: But yeah, Iโ€™m up for it. But would Daniels example be a good start or do you have somewhere you can point me that doesnโ€™t include jquery? I feel like googling localstorage might be a bit ungraspable :slight_smile:


(๐•„๐•š๐•”๐•™๐•’๐•–๐• ๐”พ๐•’๐•ฃ๐• ๐•—๐•’๐•๐• ) #12

No offense to @Daniel :smiley: but I think jQuery should be avoided when possible.

Hereโ€™s a list of what will be helpful in figuring it outโ€ฆ

Conditionalsโ€ฆ
http://www.w3schools.com/js/js_comparisons.asp

If something is true, then run code. In your example, youโ€™re switching the scene or frame position based on the number of stars.

Weโ€™ve already established the main part of the codeโ€ฆ

localStorage.stars

That stores your value. Learning about variables is important.

Then, by combining those two, you can move around the Hype Timeline or switch scenes. That involves the Hype JavaScript APIโ€ฆ

hypeDocument.goToTimeInTimelineNamed(0, 'timelineName')

A major hint โ€“ line up the keyframes with the number of starsโ€ฆ If localStorage.stars is greater than zero, then go to frame localStorage.stars.

I think thatโ€™s a good starting point. By figuring out some of the basics in JavaScript and how to use that to leverage the Hype API, you should be able to do a lot more than whatโ€™s available with the no-coding part of Hype.


(Anton) #13

Great, thanks!!
Iโ€™m gonna start the grind in a few hours, gotta go to the piano and write some music for next weekends gigs first before I start writing code :slight_smile:


(Anton) #14

So, should I write the code into the _hype_generated_script.js-file in the widget or in the html-file? Or is there some way to code inside Hype?


(๐•„๐•š๐•”๐•™๐•’๐•–๐• ๐”พ๐•’๐•ฃ๐• ๐•—๐•’๐•๐• ) #15


(๐•„๐•š๐•”๐•™๐•’๐•–๐• ๐”พ๐•’๐•ฃ๐• ๐•—๐•’๐•๐• ) #16

Hey @anton

Did you figure it out?


(Anton) #17

Hey! Thanks for the check up!

Honestly, the last two weeks Iโ€™ve been working in an office full time and on my free time Iโ€™ve been preparing and playing on a lot of church music-gigs. So if I grind on my almost non-existing free free time Iโ€™m gonna hit the wall :slight_smile: But next week my schedule should start clearing up a bit, and then Iโ€™ll start. I have this page always open in a tab so I donโ€™t forget it. And when I start Iโ€™ll definitely fill this page with new questions :smile:


(Anton) #18

Ok. So, my four weeks of 170% work load is over and Iโ€™m ready to do this. :slight_smile:

Just to be clear about how my simple widget works. Itโ€™s about 120x120px. I have four scenes, the first is just blank/ a white rectangle on a white background, the next scene has a bronze star in it. Next scene has a silver star, and the last scene a gold star. You go to the next scene by clicking the rectangle or star.

Now to the coding. (I feel like I have no idea what Iโ€™m doing)

I understand that by writing localStorage.stars i create a variable that will be able to store info about the last visited star in my widget. Iโ€™m guessing I just named the variable โ€˜starsโ€™, right?

Ok, so logically, I guess I somehow need to tell localStorage.stars to store the name of the scene Iโ€™m at every time a new scene is visited. Should there be js-code in each scene then, telling localStorage that this scene has just been visited?

Secondly I need to have some kind of code in the first scene saying that IF there is any data pointing to a scene in localStorage.stars then I will go there. And if localStorage.stars is empty or filled with โ€œ1โ€ then Iโ€™ll just stay on scene 1. I guess I could assign value 1 to the variable right away.

But if Iโ€™m using scenes, can I move to another scene using this code:
hypeDocument.goToTimeInTimelineNamed(0, โ€˜timelineNameโ€™)

Isnโ€™t this only for moving within a scene?

I feel like I kind of know what I need to do, but I have no idea where to start.


#19

You can navigate the scenes using the Scenes functions in the API :wink:

You could then name your scenes 1, 2, 3, etcโ€ฆ and go to the scene with the value of localStorage.stars perhaps


(Anton) #20

Ah, of course :slight_smile:

So then, instead of:
hypeDocument.showSceneNamed(โ€˜1โ€™)
could i instead write something like:
hypeDocument.showSceneNamed(โ€˜starsโ€™) or something to make it go to the scene contained in the stars-variable?

And, how do i declare the localStorage.stars? As a variable? var localStorage.stars?