Articles Archive
Articles Search
Director Wiki
 

Director 7: color object

June 21, 1999
by Zac Belado

My parachute is color (#rgb, 203,129,201)

One of the more subtle difficulties that frequently appears when using Director is how to reference specific colors when you change palettes. The rich, deep navy blue in one palette can quickly become replaced with a vibrant yellow in another. And even if you don't switch palettes, there wasn't, until Director 7, a quick and easy way to refer to colors without knowing the palette position of a color. Start working in 24 bits and suddenly specifying colors becomes a nightmare. Thankfully the ever-diligent engineers at Macromedia have now provided, in Director 7, a quick and intelligible way to reference and modify colors. Director 7 adds two new Lingo elements to help you manage color in your movies: the color () function and the color datatype.

Mood Indigo?

The color datatype in Director works with either 24-bit colors (RGB) or 8-bit colors (indexed palettes). 24 bit colors are represented by three values (from 0 to 255) that represent the red, green and blue components of the color; 8 bits for each color for a total of 24 bits. These values can be either float decimals or integers. 8-bit colors are represented by an integer value from 0 to 255 that indicate the color's position in the current palette.

For example the red that is used in the Director Online logo is represented by the rgb values of 204, 0 and 0. So to represent the "DOUG red" color we could use

rgb (240,0,0)

And, in a standard Director indexed palette the color white is in position 0 and the color black is in the last position, 255. To represent white using a palette index we would use

paletteIndex (0)

Oddly enough, considering the web focus of Director, there isn't a hexadecimal colorType, but you can easily convert a hex color value to rgb and palette indexes by providing the hex value as a string to the rgb () command instead of the three color components. A paletteIndex can then be generated by referring to the color's paletteIndex property.

put rgb("CC0000")
-- rgb( 204, 0, 0 )
put rgb("CC0000").paletteIndex
-- 71

You can provide the hex color with or without the proceeding # symbol. If you have an #rgb or #paletteIndex color then you can use the hexString () function to return the hexidecimal value of the color.

thisOtherColor = rgb(255,0,51)
put hexString(thisOtherColor)
-- "#FF0033"
thisOtherColor.colorType = #paletteIndex
put hexString(thisOtherColor)
-- "#FF0033"

You can also append the function to the end of the object as you can with other Director 7 objects.

thisOtherColor = rgb(255,0,51)
put thisOtherColor.hexString()
-- "#FF0033"

To get the nearest palette index value of an #rgb color all you need do is access its paletteIndex property.

thisOtherColor = rgb(121,234,23)
put thisOtherColor.paletteIndex
-- 113

A #paletteIndex color does not have a corresponding rgb property though.

thisColor = paletteIndex(34)
put thisColor.rgb
<script error: Three parameters expected>

Despite this omission, a #paletteIndex color does, in fact, have distinct red, green and blue properties

thisColor = paletteIndex(34)
put thisColor.red
-- 255
put thisColor.green
-- 0
put thisColor.blue
-- 51

as does an rgb color.

This is not a major inconvenience since you can easily convert color from one type to another by modifying the color's colorType property.

thisOtherColor = rgb(255,0,51)
put thisOtherColor.colorType
-- #rgb
thisOtherColor.colorType = #paletteIndex
put thisOtherColor
-- paletteIndex( 34 )
thisOtherColor.colorType = #rgb
put thisOtherColor
-- rgb( 255, 0, 51 )

Colors are, at this point, either #rgb or #paletteIndex colorTypes.

Director also puts a cap on the values you assign to a color so that they are never more than 255. So if you do something silly like assign the red and green color values of a color to 999, Director will cap them at 255 when it actually creates the color.

sprite(4).color=rgb(999,999,0)
put sprite(4).color
-- rgb( 255, 255, 0 )

color (); the appendix of Lingo functions.

Director 7 also includes another function, color () (not to be confused with the color property, that you can use to create either #rgb or #paletteIndex color objects. It would appear that the function is actually included in preparation for a time when Director will include color models other than RGB and indexed color. At the moment though it appears to do nothing that you can't accomplish using the rgb () and paletteIndex () commands...only with more keystrokes.

Getting one's hands dirty

So why don't we try to do something with all this newfound trivia.

The application that leaps to mind immediately is to try and construct an RGB color selector that uses three sliders to indicate the red, green and blue components of a color and then displays the "mixed" color in a large "color chip".

What the application will need to do is take a value from a slider and transmit that value to a color chip. The color chip will be set to one of the three colors in our display model (red, green or blue) and will modify its own color based on the value it receives from the slider. The color chip will then send its color value to a final chip that will "mix" the values of each of the three color chips to make a full 24 bit RGB color.

So the application will need three behaviors

  1. a behavior for the slider that will calculate a value based on the maximum allowable value (in this case 255 which is the maximum color value allowed per channel in a 24 bit color) and the distance that the slider can move (in this case the width of the underlying graphic that represents the gauge)
  2. a behavior for the color chip that will store which of the three colors it represents, modify its own color and then send this value to the mixer chip
  3. a behavior for the mixer chip that receives a broadcasted value, modifies its own color based on the color channel and value and then displays the color values for the user's edification.

The slider

The first part of the slider's functionality is provided by the Constrain to Line behavior that ships with Director 7. This behavior simply ensures that the sprite remains in a single horizontal plane and that it can only move in one direction relative from its starting location. We want it to move only to the right of its starting location.

We need to add another behavior to the sprite in order to calculate the new color values based on the slider's position and also to transmit those values to the sprite that has the color chip.

The behavior will have 6 properties

So when the sprite appears on stage we'll store a reference to its sprite and its initial horizontal location and then calculate the pInterval value.

on beginSprite me

  pMysprite = sprite (the spriteNum of me)
  pInterval = pRange.float / pMaxDistance
  pStart = pMySprite.locH

end

Then, while the user is dragging the sprite we'll calculate a new color value and then send it to the target sprite.

on mouseDown me

  -- while the mouse is down broadcast a
  -- value to the color chip

  repeat while the mouseDown
    
    thisLoc = pMySprite.locH
    delta = thisLoc - pStart
    broadcastValue = pInterval * delta
    
    sendSprite (pBroadcastSprite, #newColorValue, broadcastValue)
    
    updateStage
    
  end repeat

end

To calculate the color value we simply find the current location (the locH), subtract it from the starting location (pStart) and then multiply this by the interval value (pInterval) that we calculated in the beginSprite method. We then use the sendSprite command to transmit this value to the color chip.

If you are not familiar with it, sendSprite is a very useful and simple way for sprites to send data to each other. The format for the command is

sendSprite (<target sprite number>, #<method name> ¬
  {, <optional parameters>})

So in this case the slider sprite will be sending data to the newColorValue method (see below) of the pBroadcastSprite sprite with a parameter that is the new color value that was just calculated. As you can see above that "translates" to the Lingo command

sendSprite (pBroadcastSprite, #newColorValue, broadcastValue)

One thing to note is that every single behavior attached to the sprite will be targeted by this command so if you have more than one behavior with similarly named methods (for instance two behaviors that both have a newColorValue method) then all the behaviors will receive and act upon the data you send.

The color chip

All our color chip needs to do is wait patiently to receive a broadcast from the slider and then transform itself into a new color. As well it will need to pass this color value on to the mixer chip.

The color chip behavior has three properties

The behavior only has one functional method, the newColorValue method that is called by the slider behavior. Notice that this behavior has no hooks for user input. The entire cascading set of data transmissions is initiated by a mouseDown event in the slider sprite and the other two behaviors simply react to that data and transmit new data down the communication chain.

on newColorValue me, broadcastValue

  -- take the value from the slider and
  -- change this sprites color

  case (pColorChannel) of
    "red":
      newColor = color(#rgb, broadcastValue,0,0)
    "green":
      newColor = color(#rgb, 0,broadcastValue,0)
    "blue":
      newColor = color(#rgb, 0,0,broadcastValue)
  end case

  pMySprite.color = newColor

  -- send the new value to the main color chip
  sendSprite (pSendSprite, #changeColor, pColorChannel, broadcastValue)

end

This method does two things. Based on the color channel that this chip represents it creates a new color based on the value transmitted. It then modifies its own color and then uses the sendSprite command to send this color to the mixer chip.

The mixer chip

The ultimate target in our small communications chain is the mixer chip that will mix together all three color values to make a 24 bit RGB color. This behavior has 4 properties.

The behavior has two functional methods. The first, changeColor, takes the channel name and value broadcast from the color chip and stores this data. It then takes the values of the three color properties adn uses them to generate a new RGB color.

on changeColor me, colorChannel, broadcastValue

  -- change the color value that gets sent
  -- from the rgb chips

  case (colorChannel) of
    "red":
      pRed = broadcastValue
    "green":
      pGreen = broadcastValue
    "blue":
      pBlue = broadcastValue
  end case

  pMySprite . color = color(#rgb, pRed, pGreen, pBlue)

  displayValues me

end

The second method simply uses the conversion functions and properties of the sprites color to display the current color information for the user.

on displayValues me

  -- display the color values in the on screen
  -- text fields this is all hard coded field values

  member("hexValue").text = "Hex:" && pMySprite.color.hexString()
  member("paletteValue").text = "Palette Index:" && pMySprite.color.paletteIndex.string

  member("redValue").text = "Red:" && pMySprite.color.red.string
  member("greenValue").text = "Green:" && pMySprite.color.green.string
  member("blueValue").text = "Blue:" && pMySprite.color.blue.string

end

Try it for yourself

Sample code is available for download in Mac or PC formats. As well you can download a Mac or PC archive that has a slightly modified version of this movie. It not only lets you mix colors but you can also copy the RGB or HEX values to the clipboard for use in your own code. To use it create a DOUG folder in your Director 7 Xtras folder and then copy the movie into the DOUG folder. The next time you start Director you will be able to select the movie from the Xtras: DOUG menu.

Before Director 7 this sort of application would have been extremely difficult to create. With the new color dataType and functions it is a breeze. In fact, you can even create more attractive and functional color pickers like the one created by Jim Collins (55 K).

Zac Belado is a programmer, web developer and rehabilitated ex-designer based in Vancouver, British Columbia. He currently works as an Application Developer for a Vancouver software company. His primary focus is web applications built using ColdFusion. He has been involved in multimedia and web-based development, producing work for clients such as Levi Straus, Motorola and Adobe Systems. As well, he has written for the Macromedia Users Journal and been a featured speaker at the Macromedia Users Convention.

Copyright 1997-2024, Director Online. Article content copyright by respective authors.