Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CSS-FEATURES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# CSS feature TODOs

Changes to make once a feature is stable in Chrome, Firefox and Safari. Status from 2026-10-31.

| Feature | Waiting on | Change |
| ---------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inherit()` | Chrome release, Firefox | Replace the alternating slots and `@container style()` rules in `Accumulator` with `--name: combine(inherit(--name), var(--name-input))`. Chrome 158 and 159 compute it without a flag only when the declaration contains `var()`, and `CSS.supports()` still reports false. |
| `random()` | Firefox, in Nightly 161 | Give the `particle()` callback of `ParticleSystem` per-element CSS values instead of the `Math.random()` numbers its `random` helper returns. This changes its API. Check the final keyword name first, `element-scoped` is being renamed to `per-element`. |
| `@function` | Firefox | Express the filters and transforms from the `particle()` callback as custom functions of its random values and a shared progress, so `ParticleSystem` no longer needs `Tween`s per particle. |
| `image(<color>)` | WebKit `multiply` bug | Replace the `linear-gradient(color, color)` tint layer in `Filter`. WebKit 27.2 paints `image(<color>)` without applying `background-blend-mode: multiply`, which the tint relies on. |
| `user-select` | Safari, preview only | Remove `-webkit-user-select` from `styles.css`. |
90 changes: 90 additions & 0 deletions examples/billboard.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>c3r - Billboards</title>
<style>
body {
margin: 0;
background-color: #000;
overflow: hidden;
}

#info {
position: absolute;
z-index: 1;
top: 0;
width: 100%;
padding: 5px;
box-sizing: border-box;
color: #fff;
font: 13px monospace;
text-align: center;
}
</style>
</head>
<body>
<div id="info">
Sprites that always face the camera, on a tumbling ring around a box
</div>
<script type="module">
import {
Billboard,
Container,
Group,
Material,
Transform,
Tween,
} from "c3r";
import { cube, quad } from "primitive-geometry";

const container = new Container();
document.body.appendChild(container.domElement);

const turn = 2 * Math.PI;

const ring = new Group();
container.root.addChild(ring);
ring.tween = new Tween({
keyframes: [[Transform.rotateX(turn), Transform.rotateY(turn)]],
duration: 12,
loop: true,
});

const box = new Group();
ring.addChild(box);
box.addMesh(cube({ sx: 120 }));
box.material = new Material();
box.material.background = "textures/crate.jpg";

const sprite = new Material();
sprite.background = "textures/sprite.png";
sprite.doubleSided = true;

for (let i = 0; i < 8; i++) {
const billboard = new Billboard();
ring.addChild(billboard);
billboard.transform = [
Transform.rotateY((i / 8) * turn),
Transform.translate([250, 0, 0]),
];
billboard.material = sprite;
billboard.addMesh(quad({ scale: 100 }));
}

container.camera.tween = new Tween({
from: [
Transform.rotateY(0),
Transform.rotateX(-0.4),
Transform.translate([0, 0, 800]),
],
keyframes: [Transform.rotateY(turn)],
duration: 20,
loop: true,
});

container.bake();
</script>
</body>
</html>
15 changes: 6 additions & 9 deletions examples/canvas.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,14 @@
<div id="info">Each face is a canvas element, draw on them</div>
<script type="module">
import { Container, ElementObject, Group, Transform, Tween } from "c3r";
import { mat4 } from "gl-matrix";

const container = new Container();
document.body.appendChild(container.domElement);

const box = new Group();
container.root.addChild(box);

container.camera.matrix = mat4.fromTranslation(
mat4.create(),
[0, 0, 400],
);
container.camera.transform = Transform.translate([0, 0, 400]);

const turn = 2 * Math.PI;
const spin = new Tween({
Expand Down Expand Up @@ -96,10 +92,11 @@
});

const face = new ElementObject(canvas);
const matrix = mat4.fromXRotation(mat4.create(), x);
mat4.rotateY(matrix, matrix, y);
mat4.translate(matrix, matrix, [0, 0, 100]);
face.matrix = matrix;
face.transform = [
Transform.rotateX(x),
Transform.rotateY(y),
Transform.translate([0, 0, 100]),
];
box.addChild(face);
}

Expand Down
6 changes: 1 addition & 5 deletions examples/cube.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
Transform,
Tween,
} from "c3r";
import { mat4 } from "gl-matrix";
import { cube } from "primitive-geometry";

const container = new Container();
Expand All @@ -50,10 +49,7 @@
box.material = new Material();
box.material.background = "textures/crate.jpg";

container.camera.matrix = mat4.fromTranslation(
mat4.create(),
[0, 0, 400],
);
container.camera.transform = Transform.translate([0, 0, 400]);

const turn = 2 * Math.PI;
const spin = new Tween({
Expand Down
25 changes: 10 additions & 15 deletions examples/filters.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
Transform,
Tween,
} from "c3r";
import { mat4 } from "gl-matrix";
import {
cone,
cube,
Expand All @@ -65,10 +64,7 @@

const container = new Container();
document.body.appendChild(container.domElement);
container.camera.matrix = mat4.fromTranslation(
mat4.create(),
[0, 0, 320],
);
container.camera.transform = Transform.translate([0, 0, 320]);

// A disc facing up or down at height y
const cap = (radius, segments, y, texture) => ({
Expand All @@ -78,11 +74,10 @@
innerSegments: 1,
mapping: mappings.rectangular,
}),
matrix: mat4.rotateX(
mat4.create(),
mat4.fromTranslation(mat4.create(), [0, y, 0]),
-Math.sign(y) * (Math.PI / 2),
),
transform: [
Transform.translate([0, y, 0]),
Transform.rotateX(-Math.sign(y) * (Math.PI / 2)),
],
texture,
});

Expand Down Expand Up @@ -193,14 +188,14 @@
container.root.addChild(model);
const { mesh, texture, caps = [] } = shapes[i % shapes.length];
model.addMesh(mesh);
model.matrix = mat4.fromTranslation(mat4.create(), [x, y, 0]);
model.transform = Transform.translate([x, y, 0]);
model.material = textured(texture, filter);
// Caps inherit the model's filters and tweens
for (const { mesh, matrix, texture } of caps) {
for (const { mesh, transform, texture } of caps) {
const lid = new Group();
model.addChild(lid);
lid.addMesh(mesh);
lid.matrix = matrix;
lid.transform = transform;
lid.material = textured(texture);
}
const spin = new Tween({
Expand All @@ -217,7 +212,7 @@
const text = new ElementObject(caption);
text.setSize(160, 16);
container.root.addChild(text);
text.matrix = mat4.fromTranslation(mat4.create(), [x, y - 62, 0]);
text.transform = Transform.translate([x, y - 62, 0]);
});

["Hover to\nplay", "Static"].forEach((title, row) => {
Expand All @@ -227,7 +222,7 @@
const text = new ElementObject(heading);
text.setSize(60, 32);
container.root.addChild(text);
text.matrix = mat4.fromTranslation(mat4.create(), at(-1, row));
text.transform = Transform.translate(at(-1, row));
});

container.bake();
Expand Down
Loading
Loading