zarocknz/javascript-winwheel

How to make it responsive?

Closed this issue · 4 comments

I need some help to know how can I make it responsive.
Thanks

Hi @farhantahir,

Altering the canvas width and height with some javaScript when the window resizes is the way to go. CSS properties do not work as they "zoom" the canvas meaning things drawn on it look fuzzy, plus Winwheel.js features like getting the segment the user clicked on probably don't work.

After a bit research and playing around I managed to create a function (below) which re-sizes the canvas width when the screen size is changed. To use the function I simply changed the body tag of the page to call the function on resize...

<body onresize="resizeCanvas()">

You would probably what to call the function when the window first loads as well to ensure the canvas is the correct size when the user first visits the page.

Please ensure that you test your wheel thoroughly before making it live as I have not tested all the features of the Winwheel.js inside a responsive canvas before.

function resizeCanvas()
{
	// Get the canvas
	var canvas = document.getElementById('canvas');

	// Get width of window.
	var w = window.innerWidth;

	// Set height to the current height of the canvas since we don't adjust it.
	var h = canvas.height;

	// Assuming only the width will change to be responsive.
	canvas.width = w;

	// To ensure the wheel stays inside the canvas, work out what is the smaller
	// value between width and height, and set the outerRadius to half of that.
	if (w < h) {
		theWheel.outerRadius = (w / 2);
	} else {
		theWheel.outerRadius = (h / 2);
	}

	// In order to keep the wheel in the center of the canvas the centerX and
	// centerY need to be set to the middle point of the canvas.
	theWheel.centerX = (canvas.width / 2);
	theWheel.centerY = (canvas.height / 2);

	// Other possible TODO
	// - Alter the font size.
	// - Adjust inner radius if the wheel has one.

	// Re-draw the wheel.
	theWheel.draw();
}

Cheers,
DouG

Hey @zarocknz
Really amazing work on the lib. this works super well for making the canvas responsive.

I am however using an image for my wheel, and I'm trying to wrap my head around how to make that response as well, do you have any ideas?

Because right now it just crops the sides of my wheel.

// Jonathan

I managed to solve this myself, I will leave my question if any one else wonders.

Winwheel.prototype.drawWheelImage = function()
{
    // Double check the wheelImage property of this class is not null. This does not actually detect that an image
    // source was set and actually loaded so might get error if this is not the case. This is why the initial call
    // to draw() should be done from a wheelImage.onload callback as detailed in example documentation.
    if (this.wheelImage != null)
    {
        // Work out the correct X and Y to draw the image at. We need to get the center point of the image
        // aligned over the center point of the wheel, we can't just place it at 0, 0.
        ---> var imageLeft = (this.centerX - (this.canvas.height / 2))
        ---> var imageTop  = (this.centerY - (this.canvas.width / 2));

        // Rotate and then draw the wheel.
        // We must rotate by the rotationAngle before drawing to ensure that image wheels will spin.
        this.ctx.save();
        this.ctx.translate(this.centerX, this.centerY);
        this.ctx.rotate(this.degToRad(this.rotationAngle));
        this.ctx.translate(-this.centerX, -this.centerY);

        ---> this.ctx.drawImage(this.wheelImage, imageLeft, imageTop, this.canvas.width, this.canvas.height); 

        this.ctx.restore();
    }
}

I changed by the arrows to use the size of the canvas instead of the image, and also I added the size of the canvas to the drawImage method.

Thanks. Great that you figured this out. Responsive is becoming more important these days so I should probably make a tutorial on this. Cheers.

Hi @farhantahir,

Altering the canvas width and height with some javaScript when the window resizes is the way to go. CSS properties do not work as they "zoom" the canvas meaning things drawn on it look fuzzy, plus Winwheel.js features like getting the segment the user clicked on probably don't work.

After a bit research and playing around I managed to create a function (below) which re-sizes the canvas width when the screen size is changed. To use the function I simply changed the body tag of the page to call the function on resize...

<body onresize="resizeCanvas()">

You would probably what to call the function when the window first loads as well to ensure the canvas is the correct size when the user first visits the page.

Please ensure that you test your wheel thoroughly before making it live as I have not tested all the features of the Winwheel.js inside a responsive canvas before.

function resizeCanvas()
{
	// Get the canvas
	var canvas = document.getElementById('canvas');

	// Get width of window.
	var w = window.innerWidth;

	// Set height to the current height of the canvas since we don't adjust it.
	var h = canvas.height;

	// Assuming only the width will change to be responsive.
	canvas.width = w;

	// To ensure the wheel stays inside the canvas, work out what is the smaller
	// value between width and height, and set the outerRadius to half of that.
	if (w < h) {
		theWheel.outerRadius = (w / 2);
	} else {
		theWheel.outerRadius = (h / 2);
	}

	// In order to keep the wheel in the center of the canvas the centerX and
	// centerY need to be set to the middle point of the canvas.
	theWheel.centerX = (canvas.width / 2);
	theWheel.centerY = (canvas.height / 2);

	// Other possible TODO
	// - Alter the font size.
	// - Adjust inner radius if the wheel has one.

	// Re-draw the wheel.
	theWheel.draw();
}

Cheers,
DouG
its fire error like :
Cannot set property 'outerRadius' of undefined
if (w < h) {
theWheel.outerRadius = (w / 2);
} else {
theWheel.outerRadius = (h / 2);
}