interactivity with animated Canvas in epub3

15 posts / 0 new
Last post

I am working on a canvas animation. It is inserted in an xhtml file, as part of an epub3, and it works.
Based on an example of Canvas cookbook, I try to add a clickable button. It does not work.
If I just change the file extension from xhtml to html, it works. Without changing anything in the file.
But, as far as I know (and tested), idpf epub checker does not accept scripted html as a content file => can anyone help me? Is this a bug? a documented "feature" of epub3? Or does it exist an working alternative?
Thanks in advance!

Hard to know what your problem is from your description, but what works in HTML will work in XHTML, just sometimes with some tinkering. There are differences in scripting of the two, but without seeing your actual markup and code it's impossible to give you much guidance on what that might be. XHTML tag names are case-sensitive and always lowercase, which is a common bug I've found in translating javascript that "works" with HTML. Placing the code in a CDATA block is necessary if it contains any special XML characters (e.g., <).

Have you tried debugging the file with the .xhtml extension in a browser like firefox to see what the JS debugger reports? (Don't debug with a .html extension or the file will be treated as HTML not XHTML.)

But you're right that HTML pages are not valid in EPUB. The format requires the use of XHTML.

Many thanks!
Are variable names also case-sensitive and always lowercase in xhtml?
Are you the author of the veeeeeeery good book Epub3 best practices, or are you just using this name as a pseudo? I could read in this book that Html5 did no more require DTDs. My xhtml file starts with:

<?xml version="1.0" encoding="utf-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
...

Could there be a problem in this part?
Many thanks in advance!

Well, if you're going to flatter me, I have to respond. Yes, I am one and the same, but there were plenty of other good people involved in that project. :)

The lack of the HTML5 DOCTYPE statement shouldn't affect scripting; it doesn't actually do anything in XHTML5.

But, yes, XML element and attribute names are case sensitive, so you need to be aware how you write them in your code. What I have found in the past is javascript code like getElementsByName('INPUT'), which will grab all input elements regardless of case (INPUT, input, Input, InPuT, etc.) because HTML simply isn't case sensitive. You have to fix these to search for the lowercase equivalents.

You also can't do document.write in XHTML. To write new elements and attributes you have to create nodes and append them to the document.

I don't know if any of this is pertinent to your case, as it's really hard to debug script for anyone without seeing it. The WHATWG wiki identifies a number of scripting differences between HTML and XHTML, which is another useful place to check for what might be going wrong.

Then I have a lot of labels to control, many thanks!

Once again, many thanks! I found some variable names to correct, and one
while (obj.tagName != "BODY")
and now it is working :-)

I just stay with a stupid problem: if I use a for loop, i.e.:
for (var i = 0; i <= 30; i++) {
context.beginPath();
context.arc(x1,y1,i*radius_step,0,Math.PI,false);
context.closePath();
context.stroke();

context.beginPath();
context.arc(x2,y2,i*radius_step,0,Math.PI,false);
context.closePath();
context.stroke();
}

I receive the following error message: StartTag: invalid element name.
If I write 30 times the corresponding lines of code, manually incrementing the value of i, it works. Euh... if it is not too much, do you have another brilliant idea for me? Many thanks in advance!

This problem sounds a little more familiar. As I mentioned above, you have to be careful not to use special XML characters in your code without a CDATA block. An XML parser doesn't understand that '<' is not the beginning of a tag but the less-than-sign unless you tell it to treat the section as pure character data (same with '&', which will give you an entity error).

To fix the problem, you likely just need to start and end your code like this:

<script>
<![CDATA[
   // < and & are now plain old characters
]]>
</script>

Sometimes you'll see the CDATA tags commented out to enable cross-(X)HTML scripting. EPUB reading systems are supposed to properly handle content files as application/xhtml+xml, but there's no harm adding // in front of the opening and closing of the CDATA section if you're worried about HTML parsing (or want to use your code in an HTML equivalent).

Thank you so much, now everything is working perfectly! :-)

Now everything is working perfectly... except in iBooks. I made a beautiful replay button, which is working perfectly on my Mac. But in iBooks on iPhone the touch event is captured by iBooks for turning the page when touching on the page sides or switching on/off the menu when touching elsewhere. To prevent this, I inserted:
event.preventDefault();
as the first line in my touch(event) function. It seems it does not function: is this a known feature of iBooks, or is it supposed to work?
Thanks in advance!

Not sure I understand. If you set preventdefault for the canvas on start, move and end, that should prevent page turn operations when someone interacts with it. I haven't heard of it not working before, so maybe check the event listeners for problems.

If you're trying to prevent any action in the chrome around the page, I wouldn't expect that would be possible. If you were to prevent any actions from occurring, how would the user ever turn the page again? It would become a trap that no one could get out of, which is never a nice thing to do!

You are right, it was not clear from my post, I apologize.
I am not setting preventDefault on start of the canvas, but in the drawScreen function that is called each 200 ms, I define a set of events, applying only for one small region of my canvas (which region I put on the center of the page, to avoid any conflict with page turning). This is based on the events class, as defined in a very good example of Canvas cookbook (to be found in http://www.html5canvastutorials.com/cookbook/ in chapter 6, example entitled "Attaching mouse event listeners to regions").
So in my drawScreen function, I have the following structure:
events.setStage(function() {
this.beginRegion();
initialization of the variables
...
context.beginPath();
context.moveTo(x5,y5);
context.lineTo(x6,y6);
context.lineTo(x7,y7);
context.closePath();
context.fill();
this.addRegionEventListener("mousedown",function() {
re-initialisation of the animation parameters to the start values

});
this.addRegionEventListener("mouseup",function() {
idem
});
this.addRegionEventListener("touchstart",function() {
idem
});
this.addRegionEventListener("touchend",function() {
idem
});
this.closeRegion();
});
And in the touch event functions, I tried to start with the preventDefault().
It works on my desktop, no more in iBooks for iPhone.

Many thanks in advance for any suggestion you could make!

A total guess, but if you're not intercepting touchmove isn't there a chance it could fire and cause a page turn? It's not always easy to hit a surface with fingers and not cause movement.

Otherwise, you're moving into the realm of "is it a bug or isn't it?". Canvas support isn't great, so it's possible there is a problem with adding events on regions within the canvas in ibooks, especially if the code is working in another context. Never having tried to do what you're doing, I'm not in the best position to say.

If even you you don't know, I think I would better stop with this.
Thanks anyway for your very useful help!

If you want to send me the book offline, I'd be happy to take a look and see if anything jumps out (just add gmail.com to my name). Can't guarantee an answer, but I'm curious to know what is going on.

It is really kind of you. I just sent it, thank you :-)

Secondary menu