Going to use Observable for the Global Game Jam at 25-27 January and looking for tips

Thanks for pointing out the issue! I’ve updated my fork so that it detects the method directly rather than attempting to parse the userAgent.

I’m not able to reproduce the performance issue in Safari on my MacBook, unfortunately. I do notice that in Safari I see the gray “cell is working” bar on the left in fullscreen but I don’t in Chrome or Firefox.

1 Like

So there is some issue with resizing p5js sketches at the moment:


p5js has a built in method of resizing its canvas, but what I think happens is that it ends up with an infinite resizing loop with its parent cell so it keeps growing.

Try this?

You shouldn’t need to handle window resizing if you use Observable’s built-in reactive width.

1 Like

Almost works the way we want it! Portrait mode on mobile seems to have some issues:

You got me to figure out a work-around though. Basically, I test for the existence of a fullscreen element using fullscreenElement

Same notebook, updated: https://beta.observablehq.com/d/bb4f3e6763187737/

You shouldn’t need to handle window resizing if you use Observable’s built-in reactive width

Ideally not, no, but apparently there are some browser quirks :stuck_out_tongue:. More importantly though, I didn’t want the sketch to restart when entering full-screen.

(Also, it’s apparently one year since you joined this community. Is Observable really that young?)

Well, this doesn’t work on my notebooks. Investigating it, I assume—because I’m still an apprentice in this area—that it works on your notebook because you’re using a canvas (hence canvasDV is available), while I’m using SVG.

So I added an id on creating the svg with d3:

d3.select(DOM.svg(canvas.port.width, canvas.port.height))
  .attr("id", "WhatEverMakesSense")

Next, I can use that id in fullscreen():

const container = document.querySelector('#WhatEverMakesSense').parentElement;

Bonus: you can now use the full screen button anywhere in your notebook.

A more robust implementation should probably use DOM.uid().

Also, I assume this technique can be used to full screen any cell, provided it has a unique and known id?

Hmmm… new issue. On https://beta.observablehq.com/@martien/flower/2 it immediately flips back out of full screen to normal view. Actually, it’s now broken on Safari, Chrome, and Firefox now.


It works if you trigger fullscreen on the closest HTML parent instead of the SVG:

immediately flips back out of full screen

@mootari has already given the fix, but let me point out that avoiding this behavior is the whole reason the “trick” is needed in @mbostock 's original notebook. I tried to explain this in my fork: “Selecting the canvas element [svg element in your case] directly is no good since the canvas element is destroyed and recreated after each yield.”

[Feel free to correct me if that’s not quite what’s going on.]

Close. The show() function accesses width which is an external variable updated by the Observable runtime. When fullscreen is triggered the width changes, causing a reevaluation of the show cell and all dependent cells. As a result, the content of the mainChart cell is destroyed and recreated.


If you want to avoid restarting the sketch when the window resizes and instead use P5’s windowResized hook, here’s an updated approach:

This function computes the desired canvas size:

function canvasSize() {
  return [
    document.body.clientWidth * screen.height / screen.width

This is the same definition of width that the Observable standard library uses, and the height is computed based on the screen’s aspect ratio. For devices that don’t let you use the entire screen you may want to use screen.availWidth and screen.availHeight instead.

1 Like

Happy Cake Day, Mike! :tada::smiley:

This solution still breaks, also with availWidth/availHeight:


Could it be that document.body.cliendWidth includes padding for the scrollbar somehow?

Ah, well, thanks both of you. It shows that I still have a lot to learn in these areas. I’ll study it more thoroughly (tomorrow) to fully grasp it and come out of that more knowledgeable.

Thanks again @mbostock, @mootari, and @bgchen.

I’ve turned it into function fullscreen(x) that full screens an x and both Flower and X-Matrix now run correctly on Safari, Firefox, and Chrome.

(And I’ve got a cell that, when deleted, creates a new one within a second (see just below Guide).


1 Like

I found the source of the bug (the extra black border when an element is fullscreen), and it should be fixed now!

1 Like

Works flawlessly, thanks! I updated to 0.7.3, to include the latest fixes and added a resize counter. Interestingly, windowResized is triggered two to four times before it the resizing “stabilizes”.

Sadly I haven’t figured out how to get the other p5 libraries to play nice in instance mode yet

So turns out that setting up Howler.js in Observable is trivial, so it is probably easier to use that than trying to get p5.sound to work:

(Also much smaller code size, which is nice)

See my work-in-progress here:

1 Like