communication with p5 iframes

Short guide explaining how to send data from iframe p5 sketches to a host webpage

The example code for this blog post can also be found on github, including a standalone example project over at github.io.

A student of FH Bielefeld just recently asked me for an advice: She was in need for a technique to have a website react on changes which happen in p5 sketches embedded using <iframe> elements. <iframe> elements are go-to solution for embedding external content, for example if you want to build a website to show off all of your p5 sketches or to create a gallery, which integrates artworks hosted on other sites. In fact, when you click the run button on an fxhash artwork page, it will use an iframe element to integrate and load the original artwork from fxhashs ipfs gateway.

In order to react on changes from a p5 sketch which was embedded using an <iframe> element on your page, a good solution is using the Window.postMessage API. It allows sending messages up to the parent page. As an example, I wil show how to trigger an action on mouse click in the sketch to generate a new background color and let the main page adapt to it:

Click the sketch to change the color

The p5 sketch will need a function that allows to send messages to the parent page. The message contains a descriptive text (what kind of message is send, e.g. "colorchange" in our case here) as well as a value, here it's a p5 color object:

function postMessageToParent(message, value) {
  parent.postMessage({ type: message, value }, "*");
}

let backgroundColor = color(255, 255, 255);

function setup() {
    createCanvas(700, 700);
}

function draw() {
    background(backgroundColor);
}

function mouseClicked() {
    backgroundColor = color(random(0, 255), 
                            random(0, 255),
                            random(0, 255));
    postMessageToParent("colorchange", backgroundColor);
}

On the main page that embeds the sketch with an <iframe> element, we will also need to add a bit of Javascript to listen to messages coming in. In this particular case, I've added a CSS variable which can be used to change the background color of the page dynamically from Javascript:

<style>
:root {
    --color-background: rgb(255, 255, 255);
}

</style>

<iframe width="700" height="700"></iframe>

<script>
function reactOnMessageFromIFrame(event) {
    const { data: { type, value } } = event;
    // Decompose p5 color object
    const [r, g, b, _] = value.levels;
    document.documentElement.style.setProperty(
    "--color-background",
    `rgb(${r}, ${g}, ${b})`
    );
}

window.onmessage = reactOnMessageFromIFrame
</script>

Unfortunatelly this doesn't work when using the iframe export provided by editor.p5js.org. As the editor preview is routed through another web page and ends up in another iframe.

What you can do is to download the sketch source code via File/Downlaod and host it somewhere on your a webspace (e.g. uberspace.de or Github Pages). Then just use the URL of the uploaded sketches index.html for the src attribute on your <iframe> element.

An an example, you can checkout how this technique works out in the field over at generativetools.de, as practical part of Maya Schormanns bachelor thesis in graphic and communication design.