Winwheel.js tutorial: #13 Getting the segment (prize) pointed to


In this tutorial I will show you how to get the segment / prize pointed to after the spinning has stopped, or at any time, by using the getIndicatedSegment() or getIndicatedSegmentNumber() methods.


The getIndicatedSegment() function returns a reference to the segment object located under the pointer so you can get information from it such as the name or change any of its values. The getIndicatedSegmentNumber() just returns the position in the segments array of the wheel that is pointed to.


There are a number of things you might want to use this information for, for example confirming with the user the details of the prize they have won by using the text property of the segment in a alert, or perhaps changing the colour of the segment, or altering some other property of it.



FIRST: Ensure pointerAngle matches prize indicator location


One thing you must do before trying to get the indicated segment (or use any feature of the wheel dependent on the pointer location) is ensure that the pointerAngle property of the wheel matches the location of the prize pointer. If not then what the user sees on the screen and what you tell them / record they have won will be different.


See tutorial #10 Prize Pointers and Wheel Backgrounds about creating prize pointers.


The default pointerAngle is 0, meaning that the code thinks the prize pointer / indicator is at the top of the wheel in the 12 o'clock position. Any time you have the pointer anywhere else around the wheel, for example on the right side, ensure that pointerAngle is set to the angle around the wheel where the pointer is, so for this example 90 degrees.


For the locations top, right, bottom, and left the value to set the pointerAngle to is pretty easy to figure out; these are 0, 90, 180, 270. For other angles around the wheel this can be a little bit more tricky. Refer to the Angle Guide image on the right for help.


Note the Angle guide image is also available from the Winwheel.js Tutorials & Documentation index page, and as well as using it work out the location of the prize pointer it can be useful for working out segment sizes and even as base layer in Photoshop when creating image wheels.


Using the Pointer Guide

In order to help with development and debugging there is a helpful little feature of the wheel called the pointerGuide. It draws a line from the center of the wheel out past the edge at the angle the pointerAngle is set to so you can double-check that the pointerAngle property of the wheel matches where your prize pointer is located.


To turn on the pointer guide, just set the display property of the pointerGuide to true after the wheel has been created then call the draw function of the wheel, for example: theWheel.pointerGuide.display = true; theWheel.draw();


Alternatively you can pass the properties of the pointerGuide in to the Winwheel constructor as part of the JSON structure, setting display : true there and also specifying other properties of the pointerGuide such as the strokeStyle (line colour) and lineWidth as seen in the following example.


<script>
    let theWheel = new Winwheel({
        'numSegments'  : 4,
		'pointerAngle' : 45,	// Ensure this is set correctly
        'segments'     :		//    use pointerGuide to help.
        [
            {'fillStyle' : '#eae56f', 'text' : 'Segment 1'},
            {'fillStyle' : '#89f26e', 'text' : 'Segment 2'},
            {'fillStyle' : '#7de6ef', 'text' : 'Segment 3'},
            {'fillStyle' : '#e7706f', 'text' : 'Segment 4'}
        ],
		'pointerGuide' :		// Turn pointer guide on.
		{
			'display'     : true,
			'strokeStyle' : 'red',
			'lineWidth'   : 3
		}
    });
</script>
Canvas not supported, use another browser.

Remember to turn off the pointerGuide by removing the code to display it once you have completed creating your wheel.
OK. Now on with the getIndicatedSegment examples...



Alert segment text (prize name)


In this example I use the getIndicatedSegment() function after the spinning has stopped to create an alert informing the user of the prize won by using the text of the segment.


<script>
    let theWheel = new Winwheel({
        'numSegments'    : 8,
        'outerRadius'    : 170,
        'segments'       :
        [
           {'fillStyle' : '#eae56f', 'text' : 'Prize 1'},
           {'fillStyle' : '#89f26e', 'text' : 'Prize 2'},
           {'fillStyle' : '#7de6ef', 'text' : 'Prize 3'},
           {'fillStyle' : '#e7706f', 'text' : 'Prize 4'},
           {'fillStyle' : '#eae56f', 'text' : 'Prize 5'},
           {'fillStyle' : '#89f26e', 'text' : 'Prize 6'},
           {'fillStyle' : '#7de6ef', 'text' : 'Prize 7'},
           {'fillStyle' : '#e7706f', 'text' : 'Prize 8'}
        ],
        'animation' :
        {
            'type'     : 'spinToStop',
            'duration' : 5,
            'spins'    : 8,

            // Remember to do something after the animation has finished specify callback function.
            'callbackFinished' : 'alertPrize()',

            // During the animation need to call the drawTriangle() to re-draw the pointer each frame.
            'callbackAfter' : 'drawTriangle()'
        }
    });

    // This function called after the spin animation has stopped.
    function alertPrize()
    {
        // Call getIndicatedSegment() function to return pointer to the segment pointed to on wheel.
        let winningSegment = theWheel.getIndicatedSegment();

        // Basic alert of the segment text which is the prize name.
        alert("You have won " + winningSegment.text + "!");
    }

    // Function to draw pointer using code (like in a previous tutorial).
    drawTriangle();

    function drawTriangle()
    {
        // Get the canvas context the wheel uses.
        let ctx = theWheel.ctx;

        ctx.strokeStyle = 'navy';     // Set line colour.
        ctx.fillStyle   = 'aqua';     // Set fill colour.
        ctx.lineWidth   = 2;
        ctx.beginPath();              // Begin path.
        ctx.moveTo(170, 5);           // Move to initial position.
        ctx.lineTo(230, 5);           // Draw lines to make the shape.
        ctx.lineTo(200, 40);
        ctx.lineTo(171, 5);
        ctx.stroke();                 // Complete the path by stroking (draw lines).
        ctx.fill();                   // Then fill.
    }

</script>


Canvas not supported    Reset



Changing the colour of the winning segment


In this next example I use the getIndicatedSegmentNumber() function when the spinning stops to change the colour (fillStyle) of the winning segment to yellow and gray all the others.


I also play a sound when the spinning has stopped, which is something you might want to do to make the winning more rewarding for the user. This is achieved using the HTML5 audio tag and a little bit of JavaScript to play the file.


In this example the pointer is located to the right, so as you can see in the code it is important to specify where the pointer is around the wheel by setting the pointerAngle property.



// To add audio use HTML5 audio tag, also give it Id so can get DOM object with
// javascript to play the sound in the function called after spinning has stopped.
<audio id="winsound">
    <source src="winbeat.mp3" />
</audio>

<script>
    let colourWheel = new Winwheel({
        'numSegments'    : 8,
        'outerRadius'    : 170,
        'canvasId'       : 'colourCanvas',
        'pointerAngle'   : 90,              // Remember to specify if not default of 0 degrees.
        'segments'       :
        [
           {'fillStyle' : '#eae56f', 'text' : 'Prize 1'},
           {'fillStyle' : '#89f26e', 'text' : 'Prize 2'},
           {'fillStyle' : '#7de6ef', 'text' : 'Prize 3'},
           {'fillStyle' : '#e7706f', 'text' : 'Prize 4'},
           {'fillStyle' : '#eae56f', 'text' : 'Prize 5'},
           {'fillStyle' : '#89f26e', 'text' : 'Prize 6'},
           {'fillStyle' : '#7de6ef', 'text' : 'Prize 7'},
           {'fillStyle' : '#e7706f', 'text' : 'Prize 8'}
        ],
        'animation' :
        {
            'type'     : 'spinToStop',
            'duration' : 5,
            'spins'    : 8,

            // To do something after the animation has finished specify callback function.
            'callbackFinished' : 'winAnimation()',

            // During the animation need to call function to re-draw triangle.
            'callbackAfter' : 'drawColourTriangle()'
        }
    });

    // This function called after the spin animation has stopped.
    function winAnimation()
    {
        // Get the audio with the sound it in, then play.
        let winsound = document.getElementById('winsound');
        winsound.play();

        // Get the number of the winning segment.
        let winningSegmentNumber = colourWheel.getIndicatedSegmentNumber();

        // Loop and set fillStyle of all segments to gray.
        for (let x = 1; x < colourWheel.segments.length; x ++) {
            colourWheel.segments[x].fillStyle = 'gray';
        }

        // Make the winning one yellow.
        colourWheel.segments[winningSegmentNumber].fillStyle = 'yellow';

        // Call draw function to render changes.
        colourWheel.draw();

        // Also re-draw the pointer, otherwise it disappears.
        drawColourTriangle();
    }

    drawColourTriangle();

    // Draw pointer on canvas, this time on the right.
    function drawColourTriangle()
    {
        // Get context used by the wheel.
        let ctx = colourWheel.ctx;

        ctx.strokeStyle = 'navy';  // Set line colour.
        ctx.fillStyle   = 'aqua';  // Set fill colour.
        ctx.lineWidth   = 2;
        ctx.beginPath();           // Begin path.

        ctx.moveTo(390, 174);      // Move to initial position.
        ctx.lineTo(390, 226);      // Draw lines to make the shape.
        ctx.lineTo(360, 200);
        ctx.lineTo(390, 175);
        ctx.stroke();              // Complete the path by stroking (draw lines).
        ctx.fill();
    }

</script>


Canvas not supported    Reset

Previous:
< #12 Animation - More Details
Next:
#14: Setting the Prize to be won before spinning >