sloont
sloont

Reputation: 204

How to render custom Class objects in HTML canvas

Solved Had to render the images globally outside of the draw method. Here's a link to the github if you find this question and are wondering what the solution looks like in the full code. Its a bit too long to post here as an update. github canvas orbs

back to the original question:

I'm trying to render custom Class objects inside an HTML canvas. Doesn't work with class, but the the same data works without class.

Here's the code:

import './styles/index.css';

let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");

var window_height = window.innerHeight;
var window_width = window.innerWidth;

canvas.width = 500;
canvas.height = 400;

canvas.style.background = "#232a2e"

const convertSVG = (svgid) => {
    const svg = document.getElementById(svgid);

    const xml = new XMLSerializer().serializeToString(svg);

    const svg64 = btoa(xml);
    const b64Start = 'data:image/svg+xml;base64, ';

    return b64Start + svg64;
}

class Orb {
    constructor(xpos, ypos, radius, speed, image) {
        this.xpos = xpos;
        this.ypos = ypos;
        this.radius = radius;
        this.speed = speed;
        this.image = convertSVG(image);
    }


    draw(context) {
        const img  = new Image();

        img.onload = function() {
            context.save();
            context.beginPath();
            context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI * 2, false);
            context.clip();
            context.drawImage(img, (this.xpos - this.radius), (this.ypos - this.radius), 64, 64);
            context.restore();
        }
        img.src = this.image;

    }
}

const myOrb = new Orb(150, 150, 30, 1, 'javascript-icon');
myOrb.draw(context);
console.log(myOrb);


const img  = new Image();

img.onload = function() {
    context.save();
    context.beginPath();
    context.arc(300, 300, 30, 0, Math.PI * 2, false);
    context.clip();
    context.drawImage(img, (300-32), (300-32), 64, 64);
    context.restore();
}
img.src = convertSVG('javascript-icon');

Currently it's only displaying the object I draw explicitly at the bottom of the code, and not the object of class Orb.

Here's a screen cap of the canvas:

current canvas render

EDIT: Additionally, I can generate a class object and draw the orb based on that. Like so:

const myOrb = new Orb(300, 300, 30, 1, 'javascript-icon');
const myOrb2 = new Orb(150, 150, 30, 1, 'java-icon');

const img  = new Image();

img.onload = function() {
    context.save();
    context.beginPath();
    context.arc(myOrb.xpos, myOrb.ypos, myOrb.radius, 0, Math.PI * 2, false);
    context.clip();
    context.drawImage(img, (myOrb.xpos-myOrb.radius-2), (myOrb.ypos-myOrb.radius-2), 64, 64);
    context.restore();
}
img.src = myOrb.imageSRC;


console.log(myOrb);
console.log(myOrb2);

myOrb2.draw(context);

myOrb renders, but myOrb2 which is drawn with the method of the class is not rendered.

Upvotes: 0

Views: 814

Answers (1)

Justin
Justin

Reputation: 2958

Here's an approach to take. Load the images globally and call draw when image is loaded.

let canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");

var window_height = window.innerHeight;
var window_width = window.innerWidth;

canvas.width = 500;
canvas.height = 400;

canvas.style.background = "#232a2e"

const img1  = new Image();
img1.src = 'https://cdn.iconscout.com/icon/free/png-256/javascript-2752148-2284965.png';
const img2 = new Image();
img2.src = 'https://iconape.com/wp-content/png_logo_vector/cib-javascript.png'

class Orb {
    constructor(xpos, ypos, radius, speed, image) {
        this.xpos = xpos;
        this.ypos = ypos;
        this.radius = radius;
        this.speed = speed;
        this.image = image;
    }
    draw(context) {
            context.save();
            context.beginPath();
            context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI * 2, false);
            context.clip();
            context.drawImage(this.image, (this.xpos - this.radius), (this.ypos - this.radius), 64, 64);
            context.restore();
    }
}

const myOrb = new Orb(150, 150, 30, 1, img1);
const myOrb2 = new Orb(350, 150, 30, 1, img2);

window.onload = function() {
myOrb.draw(context);
myOrb2.draw(context);
}
<canvas id="canvas"></canvas>

Upvotes: 1

Related Questions