pictures.js is designed to bring the joy back into programming, for any age and any level, a first program or a thousandth. Write a few lines of JavaScript, with no HTML, and see something move: shapes, animations, games, live charts and lit 3D scenes. Plain drawing functions, the web's 2D canvas and three.js are ready in every file, with nothing to import. It is the JavaScript sibling of Pyctures, which does the same for Python: a scene has the same shape in either language.
Free and open source, MIT licence. Made for projects in Circuitry Studio; runs anywhere a browser does.
A circle crossing the picture. Change the 200 to change its speed, or the 40 to change its size, and press Run.
Open CircuitryChange the code and press Run (or Cmd/Ctrl+Enter). The scene runs in your browser, straight away. Click or tap a scene to give it the keyboard.
The smallest scene is four lines. draw() is called every frame, background paints the picture and circle draws a circle in the middle of it. There is no page to write, no canvas to find and no loop to set up.
function draw() {
background("midnightblue")
circle(width / 2, height / 2, 80, "gold")
}To make it move, keep a number and change it in update(dt), which is called before every draw(). Change the 200 and the circle crosses faster. This scene is the first tab in the box above.
let x = 0
function update(dt) {
x += 200 * dt // 200 points every second
if (x > width) x = 0 // off the right edge: start again on the left
}
function draw() {
background("midnightblue")
circle(x, height / 2, 40, "gold")
}Keys, the mouse, touch, sprites and games come the same way, a few lines at a time: the docs start with these steps. For everything the plain functions do not cover there is ctx, the web's own 2D drawing surface.
pictures run hello.jspictures build hello.js -o site/run shows the scene and runs it again each time you save the file. build makes a folder of plain files, with the pictures the scene loads beside it. The scene's code calls the canvas directly, so it runs at the browser's own speed.
setup(), update(dt) and draw(), keys and mouse, Sprite, await frame() and three.js as THREE are the same in both libraries. Learn one and you can read the other; a scene comes across with little more than its syntax changed.
x = 0
def update(dt):
global x
if "ArrowRight" in keys:
x += 200 * dt
def draw():
ctx.fill_style = "#102030"
ctx.fill_rect(0, 0, width, height)
ctx.fill_style = "tomato"
ctx.fill_rect(x, height / 2, 50, 50)let x = 0
function update(dt) {
if (keys.has("ArrowRight")) x += 200 * dt
}
function draw() {
ctx.fillStyle = "#102030"
ctx.fillRect(0, 0, width, height)
ctx.fillStyle = "tomato"
ctx.fillRect(x, height / 2, 50, 50)
}The full guide: bringing a Pyctures scene across. The Python library: Pyctures.
A scene can keep a value with save and load, write a file and read it back, and keep rows in a SQLite database. All of it is still there the next time the scene runs.
let notes = await loadText("notes.txt").catch(() => "")
async function onKeyDown(key) {
if (key.length === 1) notes += key
if (key === "Enter") await saveText("notes.txt", notes)
}const db = await openDatabase("scores")
await db.run("create table if not exists best (name text, points integer)")
await db.run("insert into best values (?, ?)", "Ann", 12)
const rows = await db.query("select name, points from best order by points desc")On a web page the browser keeps them, for that scene alone, and nothing is sent anywhere. In the Circuitry app on an iPhone, iPad or Android device they are real files beside the scene, which you can see in the file browser. SQLite is loaded only for a scene that opens a database. Files and databases, and every function by area in the function index.
Inside Circuitry, a picture a scene loads has methods that change it: remove its background, resize, crop, rotate, trace it into vector shapes, read what is in it. Each gives a new picture to draw or to save.
const img = loadImage("shoe.jpg")
const cut = await img.removeBackground()
const small = await cut.resize({ width: 800 })
await small.save("shoe cutout.png")
function draw() {
background("white")
picture(small, width / 2, height / 2, height * 0.8)
}The Circuitry app does the work, so these run in scenes inside Circuitry and not in the library on a page of its own. Some run on every device and some need an Apple device. Images from code lists every method and where it runs.
Each scene is a <div> naming a JavaScript file. Its canvas fills the box and follows its size. A page can hold as many as you like, and each keeps its own names.
<div data-pictures-src="balls.js"></div>
<div data-pictures-src="knot.js" style="height: 420px"></div>
<script type="module" src="pictures/pictures.js"></script>In Circuitry's code editor a JavaScript scene shows its picture in a preview beside the code, on phones, iPad, the web and desktop. The preview follows the code as you type, and the footer's video button records it to an .mp4 at a steady 30 or 60 frames a second.
Pick one to run it in the box above, with its code.