Winwheel.js tut: #17 Creating a Wheel with one Image per segment

In this tutorial we will cover how to create a wheel using multiple graphically rich images, where each segment has its own image. Note: this feature is only available from Winwheel version 2.4.

The benefit of creating a wheel using one image per segment over creating the entire wheel out of single image is that it's easy to mix and match the images to make the wheel look different, perahps randomly on loading of the page, or during play by changing the image for one or more segments. If desired, you can use code drawn text on top the segment images to give even more flexability.

This feature is a little more complex than creating a wheel with just a single image (also more CPU intensive), so if you don't need to have a wheel where what is displayed in each segment changes its probably best you look at Winwheel Tutorial #9: Creating a Wheel with an Image which covers creating a wheel out of a single image.

The properties involved for creating a wheel using segment images are:

  1. Winwheel.drawMode
  2. Segment.image
  3. Winwheel.imageDirection or Segment.imageDirection

Explanation and Example

To get the Winwheel code to use the images you need to set the drawMode property to 'segmentImage', then specify the name/path to the images in the image property of each segment. You may also need to set the imageDirection property for each segment, four directions of image are possible, we'll look at this after the example.

The Wheel can only be drawn once the data for the images has been loaded, so there may be a slight delay in between the page loading and the wheel displaying, this will depend on the number of segments/images to load, the size of them, and also on the Internet speed of the device the user is viewing your wheel on. Winhweel.js has smarts to take care of the image loading and drawing of the wheel once the image data has loaded for you.

The example code below shows a basic example of how to create the wheel out of Segment images. Code drawn text is also used in the segments.

    let theWheel = new Winwheel({
        'numSegments'       : 8,              // Specify number of segments.
        'outerRadius'       : 160,            // Set outer radius so wheel fits inside the background.
        'drawText'          : true,           // Code drawn text can be used with segment images.
        'textFontSize'      : 14,
        'textOrientation'   : 'curved',
        'textAlignment'     : 'inner',
        'textMargin'        : '80',
        'textFontFamily'    : 'monospace',
        'textStrokeStyle'   : 'black',
        'textLineWidth'     : 3,
        'textFillStyle'     : 'white',
        'drawMode'          : 'segmentImage', // Must be segmentImage to draw wheel using one image per segemnt.
        'segments'          :                 // Define segments including image and text.
           {'image' : 'jane.png',  'text' : 'Jane'},    // Specify image for segment along with text.
           {'image' : 'tom.png',   'text' : 'Tom'},
           {'image' : 'mary.png',  'text' : 'Mary'},
           {'image' : 'alex.png',  'text' : 'Alex'},
           {'image' : 'sarah.png', 'text' : 'Sarah'},
           {'image' : 'bruce.png', 'text' : 'Bruce'},
           {'image' : 'rose.png',  'text' : 'Rose'},
           {'image' : 'steve.png', 'text' : 'Steve'}
        // Then specify animation to use as normal etc.

So the segment images on the left are used to create the wheel on the right.

jane tom mary alex sarah bruce rose steve Canvas not supported, please user another browser.

The imageDirection option explained

In the above example, all the segment images were coming IN from the North, with the wide bit at the outside of the wheel (at the top of the image) and the point at the bottom of the segment, touching the center point of the wheel. This is the default direction that the wheel assumes the segment images are orientationed in.

It is possible to create a wheel using images one of 4 directions, these are North, East, South, and West (N,E,S,W). It is named like this because the segments are located North, East, South, and West of the center point of the wheel as seen in the diagram to the right.

You can create the entire wheel out of images orientated in one direction; the Winwheel.js code takes care of positioning them around the wheel to make a complete circle. Or you can use a mix of images orientated in the four N,E,S,W directions.

If you want to use anything other than north, you must specify the imageDirection property, either globally for the whole wheel, or for each segment if its different for some of them.

Canvas not supported, please user another browser.

    let theWheel = new Winwheel({
        'numSegments'    : 8,
        'outerRadius'    : 160,
        'drawMode'       : 'segmentImage',
        'imageDirection' : 'S',          // Specify segments are South orientated globally for whole wheel.
        'segments'       :
           {'image' : 'jane.png',  'text' : 'Jane'},
           {'image' : 'tom.png',   'text' : 'Tom'},
           {'image' : 'mary.png',  'text' : 'Mary', 'imageDirection' : 'E'},  // This image is different.
           {'image' : 'alex.png',  'text' : 'Alex'},
           {'image' : 'sarah.png', 'text' : 'Sarah'},
           {'image' : 'bruce.png', 'text' : 'Bruce'},
           {'image' : 'rose.png',  'text' : 'Rose'},
           {'image' : 'steve.png', 'text' : 'Steve'}

You may find that for your Winwheel project that it's best to create the segment images in one of the other directions than the default of north; this will likey depend on the orientation of any text and other visual elements making up the image for the segments, or it could just be personal preference. Just go with whatever makes it easiest for you in your image editing program and the wheel you are creating.

Using code-drawn text on the segment images

If desired, you can use code-drawn text with image wheels rather than text which is part of the image. This gives you even more flexibility by being able to combine graphically rich images with dynamic text rendered by code which can easily be changed.

This was shown in the first example above where the names of the people were ouput using code drawn text. If you need more details about the text options available, see Winwheel Tutorial #6: Text Alignment and Orientation and the tutorial after that on Colours, Lines, and Fonts.

Changing the image for a segment - the right way

If you want to change the image for a segment after the intial creation of the wheel, the correct way to do this is to call the changeImage(image, imageDirection) function which takes care of loading the image data for the segment and then re-drawing the wheel so the change appears for the specified segment.

Just trying to change the 'image' property of the segment to the url of the new image will not work.

    let theWheel = new Winwheel({ ... etc ... });

    // Change image for a segment after the wheel creation.
    theWheel.segments[2].changeImage('newImage.png');            // Change image for segment 2.

    // Note: the second parameter, imageDirection is optional.

For advanced developers, if you already have a JavaScript image object somehwhere in memory with the image data loaded, you can change the imgData property of the segment to that and then redraw the wheel to make the change.

How I create the segment images

1) To create a wheel using segment images I find the best first step is create the wheel using the 'code' drawing mode, setting the number of segments, size and and radius as wanted. Using the code mode to get things right at this stage could save you a lot of re-work later if the size is wrong or things don't align; its a lot easier to adjust a few numbers in the wheel parameters than re-do all the segment images!

I often find I need to rotate the wheel backwards slightly to get the segments located north, south, east, west to sit centered over the 0 degrees, 90, 180, or 270 degree locations. Remember you can do this with the rotationAngle property of the wheel, the value will need to be half of the segment size. To calculate this you can divide 360 by the number of segments in your wheel, provied they are all the same size, and then divide that by 2 to get half the size of one segment.

2) Then take a screenshot of this and use it as a background layer in an image editing program to help create a template for the segment images, deleting all but one segment and cropping the image to carefully fit bounds of it. I then use this as a layer in photoshop either above or below the graphics for the segment.

This template is in one of the 4 directions of North, South, East, West and usually depends on what orientation the text and other visual elements I am going to put in the the segment is. Normally I don't create wheels out of mixture of directions.

The area outside the segment in the image must have a transparent background. Anything else outside of the bounds of the segment will overlay the segment next to it when the wheel is put together by the code.

3) I then decorate the border of the segment in the image keeping this as a top layer in photoshop. Remember that when the wheel is put together from these segment images the edges will touch, so you might want to make the border on the insides of the segment half of the thickness as the outside, or not have a line so when they segments come together they form a nice joined shape.

4) Next on other layers underneath, I populate the segment image with the graphics I want to appear on the segment. I could also include text here.

5) Finally I save the image out as a png.

I then simply repeat steps 4 and 5 to create all the segment images I want for the wheel.

I'm no graphic designer or Photostop expert, so you might come up with a better way to create your image assets for the wheel. This is just the process I followed to create the images for the example at the start of this tutorial. Have Fun!

< #16 Creating Pie graphs
#18 Displayng Pins >