Function

$ (calc)

Evaluate an arithmetic expression, with custom properties as variables. $(1 + 2) is 3; $px(@i * 10) is 10px, 20px, …

Syntax

  • $(<expression>)
  • $<unit>(<expression>)
  • $<name>

The expression is numbers, operators and math functions. Functions such as @i or @r inside it are evaluated first. The operators, functions and rules are listed in the table below.

Expressions

In each cell @i is evaluated first, then the expression is worked out to a number:

@grid: 5 / 60vmin _1px;
background: #000;
color: #fff;
@content: $(@i * 2);

Functions such as mix and clamp work as in GLSL. smoothstep(a, b, x) eases from 0 to 1 as x goes from a to b:

@grid: 9 / 60vmin _1px;
background: #000;
border-radius: 50%;
scale: $(1 - smoothstep(0, 5, @dr));

Units

A unit after $ is appended to the result. Inside the expression a unit reads as 0, so write $px(@i * 10), not $(@i * 10px). Only deg and turn inside a call are read, as angles: $(cos(60deg)) is .5.

@grid: 12x1 / 60vmin;
@place: center;
@size: 40% 3px;
background: #000;
margin: auto;
transform-origin: 0 50%;
rotate: $deg(360 / @I * @i);

Variables

Custom properties drop their -- prefix and any unit, so --step: 10% is step = 10:

@grid: 1x10 / 60vmin;
background: #000;
--step: 10%;
width: $%(step * @i);

The cell variables x, y, i, dr and the others read too, so $(i * 2) is $(@i * 2). Inside a repeat, such as @m or circle*5 in @svg, n, nx, ny and N are its step, as @n reads them. A custom property of the same name comes first.

Without parentheses, $name is the custom property --name. Arithmetic is evaluated, and anything else passes through:

@grid: 5 / 60vmin _1px;
--ink: @p(#000, #e6437d);
--n: @i * @i;
background: $ink;
color: #fff;
@content: $n;

Live values

A live value such as @t has no number when the doodle is generated, so the expression around it becomes CSS math, and each line keeps turning at its own speed:

@grid: 12x1 / 60vmin;
@place: center;
@size: 40% 3px;
background: #000;
margin: auto;
transform-origin: 0 50%;
rotate: $deg(@t / 100 * @i);

Reference

Expressions

PartValue
operators+ - * / % ^, comparisons, && and ||, and parentheses. Expressions has the full list and precedence.
adjacent valuesmultiply: 2x, 2π, (1+2)(3)
functionsthe Math functions, gcd(), match(), pick(k: …) and the GLSL math mod(), fract(), clamp(), mix(), step(), smoothstep(), radians(), degrees() and atan(y, x), the angle of the point (x, y). random() follows the doodle's seed. A function defined with --name() can also be called as name(…), unless a built-in has the name.
variablesthe custom properties declared above the $ on :doodle, :container or the cell, or in an enclosing @svg, without their --. Under them come the cell variables, those of the first cell on :doodle and :container, and a repeat's n, nx, ny and N.
unitsa variable drops its unit, so --w: 10px gives w = 10. A unit written in the expression reads as 0, except deg and turn inside a call.
unknown namesread as 0; there are no errors
resultrounded to 12 significant digits, and anything closer to zero than 1e-9 is 0

Forms

FormValue
$<unit>(…)the result with the unit appended as written, as in $px(1+1), $deg(…) or $%(…). If a function with the unit's name is defined, the call runs that function instead.
$<name>the value of --name, and so is $(name): arithmetic is evaluated, and anything else passes through as written. The name ends where a CSS name does, so with --s: 50, $s% is 50%. With no --x, $x is the cell variable x.
with a live valueCSS math for the browser: $(@t / 10)deg is calc((var(--cssd-utime) / 10) * 1deg). Live values lists what carries over.
@calc()an older form with the same arithmetic, which cannot read custom properties

See also