tinyweb
Graphics, widgets and sound on a web page, kept in time with each other.
A program builds its page by calling the functions below: each
canvas, button, label and slider goes below the ones before it. A
canvas is drawn on with clear, circle, rect, line and text,
in pixels from its top left corner, and a color is a CSS color such
as “#ff0000” or “red”.
A page has a look of its own, the same wherever it is shown: theme
picks one of tinyweb’s, the _style functions change every element
of one kind, and set_style and set_colors change one element.
A program that handed the page a function — on_click, on_frame
and the rest — keeps running after its last line: the page calls the
function each time the event happens. Sound and pictures are kept in
step by one clock, time: a frame is drawn for a time, and play
can start a sound at one.
tinyweb needs a page to show. A program starts with
web_init(port), which serves one and prints its address wherever
the program runs — pyk program.pyk, the REPL, or any compiled
target — and does nothing in a browser, where the page is there
already: on a web page, and beside the program in the notebook and
the playground.
import tinywebbutton
def button(title: String, on_click: () -> () = nothing) -> Int
Adds a button below everything already on the page.
Parameters
title: the text on the button.on_click: the function to call each time it is pressed; by default nothing happens.
Returns
The button’s number.
Example
button_style
def button_style(
background: String = "",
color: String = "",
border: String = "",
radius: Int = -1,
font: String = "",
size: Int = -1,
padding: Int = -1,
) -> ()
Changes every button on the page, those made already and those made later. Only what is named changes; the rest stays as the theme has it.
Parameters
background: a CSS color for the button.color: a CSS color for its text.border: a CSS border, such as"2px solid navy"or"none".radius: how round its corners are, in pixels.font: a font, such as"serif"or"monospace".size: the size of its text, in pixels.padding: the space between its text and its edge, in pixels.
Example
canvas
def canvas(width: Int, height: Int) -> Int
Adds a canvas to draw on, below everything already on the page. It starts white.
Parameters
width: its width in pixels.height: its height in pixels.
Returns
The canvas’s number, which the drawing functions take as c.
Example
canvas_style
def canvas_style(border: String = "", radius: Int = -1) -> ()
Changes the frame of every canvas on the page, those made already and those made later. What is drawn on a canvas is not changed.
Parameters
border: a CSS border, such as"3px solid black"or"none".radius: how round its corners are, in pixels.
Example
circle
def circle(
c: Int,
x: Int,
y: Int,
radius: Int,
color: String = "#000000",
) -> ()
Draws a filled circle on the canvas c.
Parameters
c: the canvas, ascanvasanswered.x,y: the centre, in pixels from the canvas’s top left corner.radius: the radius in pixels.color: a CSS color; black by default.
Example
clear
def clear(c: Int, color: String = "#ffffff") -> ()
Fills the whole canvas c with one color, wiping out what was drawn.
Parameters
c: the canvas, ascanvasanswered.color: a CSS color, such as"#ff0000"or"red"; white by default.
Example
label
def label(text: String) -> Int
Adds a line of text below everything already on the page.
Parameters
text: what the label says.
Returns
The label’s number, which set_label takes to change the text.
Example
label_style
def label_style(
background: String = "",
color: String = "",
border: String = "",
radius: Int = -1,
font: String = "",
size: Int = -1,
padding: Int = -1,
) -> ()
Changes every label on the page, those made already and those made later. Only what is named changes; the rest stays as the theme has it.
Parameters
background: a CSS color behind the text.color: a CSS color for the text.border: a CSS border, such as"1px solid gray".radius: how round its corners are, in pixels.font: a font, such as"serif"or"monospace".size: the size of the text, in pixels.padding: the space between the text and its edge, in pixels.
Example
line
def line(
c: Int,
x1: Int,
y1: Int,
x2: Int,
y2: Int,
color: String = "#000000",
width: Int = 1,
) -> ()
Draws a straight line on the canvas c.
Parameters
c: the canvas, ascanvasanswered.x1,y1: where the line starts, in pixels.x2,y2: where it ends, in pixels.color: a CSS color; black by default.width: how thick it is, in pixels; 1 by default.
Example
load_sample
def load_sample(name: String) -> Int
Starts loading a sound file, so that play can play it without a
delay. The file is looked for beside the page first, then among the
samples tinyweb ships: kick1.wav, snare1.wav, hihat1.wav and
piano_c1.wav.
Parameters
name: the file’s name, such as"kick1.wav".
Returns
The sample’s number, which play takes.
Example
on_frame
def on_frame(draw: (Float) -> ()) -> ()
Calls draw before each frame the page shows, about 60 times a second,
with the time the frame is for. This is how a program animates.
Parameters
draw: the function to call; it is given the frame’s time in seconds, astimereads it.
Example
on_key
def on_key(pressed: (String) -> ()) -> ()
Calls pressed each time a key is pressed while the page has the
focus.
Parameters
pressed: the function to call; it is given the key: a letter or digit as itself, and otherwise the browser’s name for it, such as"ArrowLeft","Enter"or" ".
Example
on_mouse
def on_mouse(c: Int, click: (Int, Int) -> ()) -> ()
Calls click each time the canvas c is clicked, with where the click
was.
Parameters
c: the canvas, ascanvasanswered.click: the function to call; it is givenxandyin pixels from the canvas’s top left corner.
Example
page_style
def page_style(
background: String = "",
color: String = "",
font: String = "",
size: Int = -1,
padding: Int = -1,
gap: Int = -1,
) -> ()
Changes the page itself: its background, and the text and spacing everything on it shares. Only what is named changes; the rest stays as the theme has it.
Parameters
background: a CSS color for the page.color: a CSS color for its text.font: a font, such as"serif","monospace"or"Georgia".size: the size of its text, in pixels.padding: the space around everything on it, in pixels.gap: the space between one element and the next, in pixels.
Example
play
def play(
sample: Int,
at: Float = 0.0,
volume: Float = 1.0,
rate: Float = 1.0,
) -> ()
Plays a sample that load_sample loaded.
Parameters
sample: the sample’s number, asload_sampleanswered.at: when to start, in seconds on the page’s clock (seetime), which counts from when the page started rather than from now: two seconds from now isat = tw.time() + 2.0, whileat = 2.0is already past once the page has been open two seconds. A time already past, such as the default 0.0, means now.volume: how loud, as a multiple of the sample’s own volume; 1.0 by default.rate: how fast, as a multiple of normal speed; 2.0 plays it twice as fast and an octave higher. 1.0 by default.
Example
play_file
def play_file(name: String) -> ()
Plays a sound file now, loading it first if nothing has loaded it yet.
For a sound played often, load_sample once and then play is
quicker.
Parameters
name: the file’s name, such as"snare1.wav"; seeload_samplefor where it is looked for.
Example
rect
def rect(
c: Int,
x: Int,
y: Int,
width: Int,
height: Int,
color: String = "#000000",
) -> ()
Draws a filled rectangle on the canvas c.
Parameters
c: the canvas, ascanvasanswered.x,y: the top left corner, in pixels from the canvas’s top left corner.width,height: the size in pixels.color: a CSS color; black by default.
Example
set_colors
def set_colors(
id: Int,
color: String = "",
background: String = "",
) -> ()
Changes the colors of one button, label or slider. It wins over the
theme and over the _style functions.
Parameters
id: the element, asbutton,labelorslideranswered.color: a CSS color for its text, or for a slider’s track and handle.background: a CSS color behind it.
Example
set_label
def set_label(id: Int, text: String) -> ()
Replaces the text of a label.
Parameters
id: the label’s number, aslabelanswered.text: the new text.
Example
set_style
def set_style(
id: Int,
background: String = "",
color: String = "",
border: String = "",
radius: Int = -1,
font: String = "",
size: Int = -1,
padding: Int = -1,
accent: String = "",
width: Int = -1,
) -> ()
Changes how one element is drawn: a button, a label, a slider or a
canvas. It wins over the theme and over the _style functions. Only
what is named changes.
Parameters
id: the element, as the function that made it answered.background: a CSS color behind it.color: a CSS color for its text.border: a CSS border, such as"2px dashed orange".radius: how round its corners are, in pixels.font: a font, such as"serif"or"monospace".size: the size of its text, in pixels.padding: the space between its text and its edge, in pixels.accent: a CSS color for a slider’s track and handle.width: its width, in pixels.
Example
slider
def slider(
low: Int,
high: Int,
value: Int,
on_change: (Int) -> () = ignore,
) -> Int
Adds a slider below everything already on the page.
Parameters
low,high: the smallest and largest values it can be set to.value: where it starts.on_change: the function to call with each new value it is moved to; by default nothing happens.
Returns
The slider’s number.
Example
slider_style
def slider_style(
accent: String = "",
width: Int = -1,
color: String = "",
font: String = "",
size: Int = -1,
) -> ()
Changes every slider on the page, those made already and those made later. Only what is named changes; the rest stays as the theme has it.
Parameters
accent: a CSS color for the slider’s track and handle.width: how long the slider is, in pixels.color: a CSS color for the value shown beside it.font: a font for that value.size: the size of that value’s text, in pixels.
Example
text
def text(
c: Int,
x: Int,
y: Int,
words: String,
color: String = "#000000",
size: Int = 16,
) -> ()
Writes text on the canvas c.
Parameters
c: the canvas, ascanvasanswered.x,y: the top left corner of the text, in pixels.words: the text to write.color: a CSS color; black by default.size: the height of the letters in pixels; 16 by default.
Example
theme
def theme(name: String) -> ()
Gives the whole page one of tinyweb’s looks: its colors, fonts, and
how buttons, sliders and canvases are drawn. A page starts in
"light", which looks the same wherever it is shown. Call it before
any of the _style functions, since it forgets what they changed.
The themes are "light", "dark", "plain" (the browser’s own
buttons and sliders, on white), "paper" (ink on warm paper, with a
serif font) and "retro" (green on black, in a typewriter font). A
name that is none of these changes nothing, and says so with debug.
Parameters
name: the theme.
Example
time
def time() -> Float
Reads the page’s clock. Once sound has started this is the audio clock,
so a time read here can be given to play to start a sound exactly
then.
Returns
The time in seconds.
Example
web_init
def web_init(port: Int) -> ()
Starts the program’s page. Run as pyk program.pyk or compiled, it
serves the page on port and prints the address to open; in a browser,
the notebook or the playground the page is already there and it does
nothing. Call it before any other tinyweb function.
Parameters
port: the port to serve on; 0 picks any free one.
Example
Without Pyking
Each of tinyweb’s implementations is also a library of its own, usable from a program written in that language with no Pyking at all: Python, JavaScript, OCaml, C, Java. tinyweb without Pyking has the overview.