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
109 changes: 109 additions & 0 deletions examples/canvas.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>c3r - Drawable canvas cube</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;
}

/* The view disables pointer events for the whole scene */
canvas {
pointer-events: auto;
cursor: crosshair;
touch-action: none;
}
</style>
</head>
<body>
<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],
);

const turn = 2 * Math.PI;
const spin = new Tween({
keyframes: [[Transform.rotateX(turn), Transform.rotateY(turn)]],
duration: 2 * turn,
loop: true,
});
box.tween = spin;

const faces = [
[0, 0, "#fdd"],
[0, Math.PI / 2, "#dfd"],
[0, Math.PI, "#ddf"],
[0, -Math.PI / 2, "#ffd"],
[Math.PI / 2, 0, "#fdf"],
[-Math.PI / 2, 0, "#dff"],
];

for (const [x, y, color] of faces) {
const canvas = document.createElement("canvas");
canvas.width = canvas.height = 200;
const context = canvas.getContext("2d");
context.fillStyle = color;
context.fillRect(0, 0, 200, 200);
context.lineWidth = 3;
context.lineCap = "round";

let lastX, lastY;
canvas.addEventListener("pointerdown", (e) => {
if (!e.isPrimary) return;
canvas.setPointerCapture(e.pointerId);
lastX = e.offsetX;
lastY = e.offsetY;
spin.paused = true;
});
canvas.addEventListener("pointermove", (e) => {
if (!canvas.hasPointerCapture(e.pointerId)) return;
context.beginPath();
context.moveTo(lastX, lastY);
context.lineTo(e.offsetX, e.offsetY);
context.stroke();
lastX = e.offsetX;
lastY = e.offsetY;
});
canvas.addEventListener("lostpointercapture", () => {
spin.paused = false;
});

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;
box.addChild(face);
}

container.bake();
</script>
</body>
</html>
91 changes: 50 additions & 41 deletions examples/cube.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,62 +10,71 @@
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">
A spinning box built from CSS 3D transforms, hover to brighten
</div>
<script type="module">
import { Container, Group, Material } from "c3r";
import { mat4, vec3 } from "gl-matrix";
import {
Container,
Filter,
Group,
Material,
Transform,
Tween,
} from "c3r";
import { mat4 } from "gl-matrix";
import { cube } from "primitive-geometry";

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

// The +z face of the cube, counter-clockwise
const face = [
{ position: [-100, 100, 100], uv: [0, 1] },
{ position: [-100, -100, 100], uv: [0, 0] },
{ position: [100, -100, 100], uv: [1, 0] },
{ position: [100, 100, 100], uv: [1, 1] },
];
const box = new Group();
container.root.addChild(box);
box.addMesh(cube({ sx: 200 }));

const turn = Math.PI / 2;
const rotations = [
...[0, 1, 2, 3].map((i) => mat4.fromYRotation(mat4.create(), i * turn)),
mat4.fromXRotation(mat4.create(), turn),
mat4.fromXRotation(mat4.create(), -turn),
];
box.material = new Material();
box.material.background = "textures/crate.jpg";

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

for (const rotation of rotations) {
cube.addPolygon(
face.map(({ position, uv }) => ({
position: vec3.transformMat4(vec3.create(), position, rotation),
uv,
})),
);
}

cube.material = new Material();
cube.material.backgroundImageSrc = "textures/crate.jpg";

// The camera matrix is the inverse world transform
container.camera.matrix = mat4.fromTranslation(
mat4.create(),
[0, 0, -400],
[0, 0, 400],
);

function animate() {
cube.matrix = mat4.fromRotation(
mat4.create(),
Date.now() / 1000,
[1, 1, 1],
);
requestAnimationFrame(animate);
}
const turn = 2 * Math.PI;
const spin = new Tween({
keyframes: [
[
Transform.rotateX(turn),
Transform.rotateY(turn),
Transform.rotateZ(turn),
],
],
duration: turn, // one radian per second
loop: true,
});
const brighten = new Tween({
keyframes: [Filter.brightness(1.5)],
duration: 0.5,
hover: true,
});
box.tween = [spin, brighten];

animate();
container.bake();
</script>
</body>
</html>
Loading
Loading