Winwheel.js example: 2 part Wheel

Here is an example of a 2 part wheel drawn on HTML canvas by the Winwheel.js JavaScript library.


This is achieved by creating a second Winwheel object and positioning it over the top of / inside the first wheel. One wheel acts as the "primary" and has the animation applied to it, the other wheel is the "secondary" which we just update during the animation loop to have the same rotation angle as the primary wheel.


2019-01-01 Note: Currently Winwheel.js does not support animating multiple independent wheels on the same page, nor do I really recommend trying to create games made up of multiple wheels. While I do know how to add multiwheel support to Winwheel.js, experience in helping people to do this over the last year or so has shown that, depending on the options used, the framerate is so bad with as little as three wheels that any game made does not look good and is almost unusable. Best to stick to single wheel uses of Winwheel.js for now.


After choosing a power level and clicking 'Spin' the wheel animates for a few seconds, spinning to a stop with the prize won alerted to the user. You can just pick a power level and click Spin to Spin the wheel again (no need to reset).


This example is included in the Winwheel.js download: /examples/two_part_wheel/index.html





Power
High
Med
Low

Spin

Sorry, your browser doesn't support canvas. Please try another.



The code


The key bits of code used to create this wheel are shown below. To view the full source code used to create this example (including the power selectors and spin button) see the code for this example on Github...


<html>
    <head>
        <title>Code Wheel</title>
        <script src='Winwheel.js'></script>
    </head>
    <body>
        <canvas id='canvas' width='880' height='300'>
            Canvas not supported, use another browser.
        </canvas>
        <script>
			// Need to create the SECONDARY wheel first because on construct the variable which keeps track of the wheel to animate will
			// be set to the last created wheel, and we want the outer one the primary with the animation etc.
			let innerWheel = new Winwheel({
				'numSegments' : 4,
				'outerRadius' : 110,        // Set the outer radius to make the wheel smaller than the outer wheel.
				'segments': [
					{'fillStyle' : '#eae56f', 'text' : 'Inner 1'},
					{'fillStyle' : '#89f26e', 'text' : 'Inner 2'},
					{'fillStyle' : '#7de6ef', 'text' : 'Inner 3'},
					{'fillStyle' : '#e7706f', 'text' : 'Inner 4'}
				]
			});

			// Define the outer wheel, we will treat this as the PRIMARY which means it clears the canvas when drawing and also
			// gets the animaton applied to it. We must callback a function during the animation to move and draw the inner wheel
			// so the 2 wheels appear as one thing on the canvas.
			let outerWheel = new Winwheel({
				'numSegments': 8,
				'textMargin' : 0,
				'outerRadius' : 210,
				'innerRadius' : 110,    // Set inner radius to the size of the inner wheel since the inner part of the wheel
				'segments': [           //   is being drawn by the inner wheel we dont need to draw there.
					{'fillStyle' : '#8C8A42', 'text' : 'Outer 1'},
					{'fillStyle' : '#F2F0A8', 'text' : 'Outer 2'},
					{'fillStyle' : '#519142', 'text' : 'Outer 3'},
					{'fillStyle' : '#B7F7A8', 'text' : 'Outer 4'},
					{'fillStyle' : '#4B898F', 'text' : 'Outer 5'},
					{'fillStyle' : '#B1EFF5', 'text' : 'Outer 6'},
					{'fillStyle' : '#8A4342', 'text' : 'Outer 7'},
					{'fillStyle' : '#F0A9A8', 'text' : 'Outer 8'}
				],
				'animation':
				{
				  'type': 'spinToStop',                     // Define animation more or less as normal, except for the callbackAfter().
				  'duration': 5,
				  'spins': 5,
				  'easing': 'Power3.easeOut',
				  'callbackAfter' : drawInnerWheel,     // Call back after each frame of the animation a function we can draw the inner wheel from.
				  'callbackFinished': alertPrize
				}
			});

			// Call draw on the outerWheel then the inner wheel to ensure that both are rendered on the canvas.
			outerWheel.draw();
			innerWheel.draw(false);   // Pass false to stop it clearing the canvas and wiping the outer wheel.

			// This function is called after the outer wheel has drawn during the animation.
			function drawInnerWheel()
			{
				// Update the rotationAngle of the innnerWheel to match that of the outer wheel - this is a big part of what
				// links them to appear as one 2-part wheel. Call the draw function passing false so the outer wheel is not wiped.
				innerWheel.rotationAngle = outerWheel.rotationAngle;
				innerWheel.draw(false);
			}

			// Called when the animation has finished.
			function alertPrize()
			{
				// The the indicated segments from the 2 wheels.
				let winningInnerSegment = innerWheel.getIndicatedSegment();
				let winningOuterSegment = outerWheel.getIndicatedSegment();

				// Alert the combination of prizes won.
				alert('You won ' + winningInnerSegment.text + ', ' + winningOuterSegment.text);

				// Set things so power and spin button can be clicked again.
				wheelSpinning = false;

				// Remove all colours from the power level indicators.
				document.getElementById('pw1').className = "";
				document.getElementById('pw2').className = "";
				document.getElementById('pw3').className = "";
			}

        </script>
    </body>
</html>

Previous:
< Hollow Wheel
Next:
Examples Index >