J.Doe
J.Doe

Reputation: 173

How do I use a custom canvas for ThreeJS?

I am having extreme difficulty to create a simple ThreeJS application that renders 3D text on the scene. All the examples on the website are too heavy to get a beginner like me to get started. So far, I cannot make the scene appear without hacks and I want to use my own canvas element to add css properties to it.

This is the following code I have written to make a cube appear in the scene.

import * as THREE from 'three';
import 'bootstrap';
import css from '../css/custom_css.css';

let scene = new THREE.Scene();

let WIDTH = window.innerWidth;
let HEIGHT = window.innerHeight;

let camera = new THREE.PerspectiveCamera(75, WIDTH / HEIGHT, 0.1, 1000);
let renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(WIDTH, HEIGHT);
renderer.setClearColor(0xE8E2DD, 1);

// Append Renderer to DOM
document.body.appendChild( renderer.domElement );

// Create the shape
let geometry = new THREE.BoxGeometry(1, 1, 1);
// Create a material, colour or image texture
let material = new THREE.MeshBasicMaterial( {
    color: 0xFF0000,
    wireframe: true
});

// Cube
let cube = new THREE.Mesh(geometry, material);
scene.add(cube);

let material_text = new THREE.MeshPhongMaterial({
    color: 0xdddddd
});

var loader = new THREE.FontLoader();

loader.load( 'fonts/helvetiker_regular.typeface.json', function ( font ) {

    var geometry = new THREE.TextGeometry( 'Hello three.js!', {
        font: font,
        size: 80,
        height: 5,
        curveSegments: 12,
        bevelEnabled: true,
        bevelThickness: 10,
        bevelSize: 8,
        bevelOffset: 0,
        bevelSegments: 5
    } );

    let textMesh = new THREE.Mesh(geometry, material_text);
    scene.add(textMesh);

    console.log('added mesh')
} );


camera.position.z = 5;

// Game Logic
let update = function(){
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.005;
};

// Draw Scene
let render = function(){
  renderer.render(scene, camera);
};

// Run game loop, update, render, repeat
let gameLoop = function(){
    requestAnimationFrame(gameLoop);

    update();
    render();
};

gameLoop();

I know it is a canvas issue because everyone is suggesting to simply add

var renderer = new THREE.WebGLRenderer( { canvas: my_canvas } );

, but that does not work for me. I know it doesn't because if I remove that and keep in

// Append Renderer to DOM
document.body.appendChild( renderer.domElement );

then I can see objects in my scene.

Why is it not allowing me to place the scene on my canvas?

My canvas is written as

<!--                            Canvas                         -->
<canvas id="my_canvas" class="container-fluid h-100 w-100 p-0 position-fixed" style="background-color: white; z-index: -1"> </canvas>

Edit: For anyone willing, could you also tell me why my text is not appearing in the scene and only the cube is? Thanks

Edit: canvas: document.getElementById('my_canvas') -- did not work ;(

Upvotes: 6

Views: 6314

Answers (2)

liamdiprose
liamdiprose

Reputation: 433

I've come across this issue in the past, you need to remove position-fixed from your canvas CSS classes. (As @Mugen87 states in his comment).

<canvas id="my_canvas" class="container-fluid h-100 w-100 p-0" style="background-color: white; z-index: -1"> </canvas>

Upvotes: 1

M -
M -

Reputation: 28462

You have to do 3 things in order:

  1. Create your canvas in the document.
  2. Select your canvas via JS
  3. Pass your canvas selector to the ThreeJS renderer.

In HTML:

<canvas id="my_canvas"></canvas>
<script>
    // Make sure your script tags are at the end of the document.
    // Otherwise, your selectors may not work
</script>

In JavaScript:

// Select the canvas from the document
var canvReference = document.getElementById("my_canvas");

// Then pass it to the renderer constructor
var renderer = new THREE.WebGLRenderer({
    antialias:true,
    canvas: canvReference
});

After you have that working, you can assign custom CSS rules via CSS:

#my_canvas {
    width: 100%;
    height: 100%;
}

Upvotes: 7

Related Questions