Toys
Welcome to the toys page! Here you can find my various web-toys to mess around with.
Phoenix Wright Comic Generator
Launch the Phoenix Wright Comic Generator
The Phoenix Wright Comic Generator is a web toy that allows you to generate your own Phoenix Wright comic!
You can generate a new comic by clicking the “New Seed” button, or by entering a seed into the text box and clicking “Generate”. You can also download the comic panels if you want to by clicking the “Download panel” button.
3D Object Demo using three.js
This is a very simple demo of using three.js to render 3D objects in a web browser. It is rendered in the browser using WebGL, and uses the three.js library to do so.
The code has three main parts: Setting up the scene, adding the objects, and animating the objects.
The setup is quite easy, simply creating a scene, a camera, and a renderer. The scene is created, the camera is configured and positioned at (0, 0, 8) and the renderer is added to the DOM.
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, 2, 1, 1000);
camera.position.z = 8;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.domElement.style.width = "100%";
renderer.domElement.style.height = "200px";
renderer.domElement.style.margin = "auto";
document.getElementById("3dDemoParent").replaceChildren(renderer.domElement);
Now we add the objects to the scene. We create three objects, an octahedron, a sphere, and a torus knot. We add them all to the scene.
const octageometry = new THREE.OctahedronGeometry(1.5, 1);
const ocatamaterial = new THREE.MeshStandardMaterial({ color: 0xff0000, roughness: 0.5, metalness: 0.5, wireframe: true });
const octa = new THREE.Mesh(octageometry, ocatamaterial);
octa.position.set(-5, 0, 0);
scene.add(octa);
const spheregeometry = new THREE.SphereGeometry(1.5, 25, 13);
const spherematerial = new THREE.MeshStandardMaterial({ color: 0x00ff00, roughness: 0.5, metalness: 0.5, wireframe: true });
const sphere = new THREE.Mesh(spheregeometry, spherematerial);
scene.add(sphere);
const torusknotgeometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
const torusknotmaterial = new THREE.MeshStandardMaterial({ color: 0x0000ff, roughness: 0.5, metalness: 0.5, wireframe: true });
const torusknot = new THREE.Mesh(torusknotgeometry, torusknotmaterial);
torusknot.position.set(5, 0, 0);
scene.add(torusknot);
We also need to add the lights so the objects are visible. We add 2 point lights and an ambient light.
const ambientlight = new THREE.AmbientLight(0x404040);
scene.add(ambientlight);
const lightright = new THREE.PointLight(0xffffff, 1);
lightright.position.set(5, 2, 2);
scene.add(lightright);
const lightleft = new THREE.PointLight(0xffffff, 1);
lightleft.position.set(-5, 2, 2);
scene.add(lightleft);
Finally, we animate the objects. We rotate the objects and move the camera around the scene in a circle around the objects, making sure it is always pointing towards them.
const degsToRads = deg => (deg * Math.PI) / 180.0;
var deg = 0;
function animate() {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
requestAnimationFrame(animate);
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
octa.rotation.x += 0.01;
octa.rotation.y += 0.01;
torusknot.rotation.x += 0.01;
torusknot.rotation.y += 0.01;
deg -= 0.1;
if (deg < 1) {
deg = 360;
}
let theta = degsToRads(deg);
let x = Math.cos(theta) * 8;
let y = Math.sin(theta) * 8;
camera.position.x = y;
camera.position.z = x;
camera.lookAt(0, 0, 0);
renderer.render(scene, camera);
};
You may have noticed a function called resizeRendererToDisplaySize()
in the code. This is a function that resizes the renderer to the size of the canvas. This is needed because the canvas is responsive, and so the renderer needs to be resized to match the canvas size. This is what it looks like:
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
Now there is one last thing to do, and that is to call the animate function. This is done at the end of the file.
animate();