Chapter 20. Color

Table of Contents

1. Overview
2. RGB or Red, Green, Blue
3. Different Ways to Specify Color
3.1. Mixing Colors
3.2. Standard Web Colors
3.3. CSS3 Colors
3.4. Nonstandard Colors
3.5. Opacity
3.6. DHTML with Windows Internet Explorer: Opacity Issues

1. Overview

This chapter gives a brief introduction to the use of colors in OpenLaszlo applications. It explains the various syntaxes that are used to specify color, and gives general guidelines for using color effectively.

OpenLaszlo uses the standard web color definitions, three hexadecimal values in a row, representing red, green, and blue components of a color (all colors can be created by mixing these three primary colors). Computer monitors are comprised of thousands of red, green, and blue dots grouped so closely by threes that our eyes see them as one blended color.

2. RGB or Red, Green, Blue

Each red, blue, or green dot can have a value from 0 to 255. If the red dot is fully "on" at 255, while blue and green are fully "off" at 0, we see red. The RBG color code for red is 255,0,0. Blue is 0,255,0; green is 0,0,255. (Some graphics systems combine an RGB triplet with an 8-bit alpha value, and get a 32-bit color word; in those systems, we think of colors as RGBA.)

Example 20.1. RGB color values

<canvas height="125" width="100%">
  <simplelayout axis="x" spacing="10"/>
  <class name="gView">
    <view height="100" width="100"/>
  </class>     
  <gView id="red" bgcolor="rgb(255,0,0)"/>
  <gView id="blue" bgcolor="rgb(0,255,0)"/>
  <gView id="green" bgcolor="rgb(0,0,255)"/>
</canvas>

3. Different Ways to Specify Color

OpenLaszlo enables coloring in four ways: 0x000000, #000000, rgb(0,0,0), and "black". Using the format 0x000000 only works for explicit assignment; it does not work in CSS. Color assignment using rgb() must be specified with decimal values from 0 - 255.

Coloring of text with fgcolor="foo" is enabled in the same fashion, but with the same limitations.

[Note] Note

CSS values in the style sheet should not be quoted. They are not strings, they are symbolic constants.

Example 20.2. Applying color explicitly and with CSS

<canvas width="100%" height="630" debug="true">
  <debug y="120" height="500"/>

  <stylesheet>
    #vName {
    bgcolorName : blue;
    }
    
    #tName {
    fgcolorName : silver;
    }

    #vHex {
    bgcolorHex : #0000ff;
    }
    
    #tHex {
    fgcolorHex : #c0c0c0;
    }

    #vRGB {
    bgcolorRGB : rgb(0,0,255);
    }
    
    #tRGB {
    fgcolorRGB : rgb(191,191,191);
    }
    
  </stylesheet>

  <view layout="axis: y; spacing: 10">
    <view layout="axis: x; spacing: 10">

      <view id="vName" height="50" width="200" bgcolor="$style{'bgcolorName'}" oninit="Debug.debug('Debug.explainStyleBindings(%w)', this); Debug.explainStyleBindings(this)">
        <text id="tName" fontsize="30" fgcolor="$style{'fgcolorName'}" oninit="Debug.debug('Debug.explainStyleBindings(%w)', this); Debug.explainStyleBindings(this)">style name</text>
      </view>
      <view id="vHex" height="50" width="200" bgcolor="$style{'bgcolorHex'}" oninit="Debug.debug('Debug.explainStyleBindings(%w)', this); Debug.explainStyleBindings(this)">
        <text id="tHex" fontsize="30" fgcolor="$style{'fgcolorHex'}" oninit="Debug.debug('Debug.explainStyleBindings(%w)', this); Debug.explainStyleBindings(this)">style #hex</text>
      </view>
      <view id="vRGB" height="50" width="200" bgcolor="$style{'bgcolorRGB'}" oninit="Debug.debug('Debug.explainStyleBindings(%w)', this); Debug.explainStyleBindings(this)">
        <text id="tRGB" fontsize="30" fgcolor="$style{'fgcolorRGB'}" oninit="Debug.debug('Debug.explainStyleBindings(%w)', this); Debug.explainStyleBindings(this)">style rgb()</text>
      </view>
    </view>
    <view layout="axis: x; spacing: 10">

      <view id="explicitVName" height="50" width="200" bgcolor="blue">
        <text id="explicitTName" fontsize="30" fgcolor="silver">value name</text>
      </view>
      <view id="explicitVHex" height="50" width="200" bgcolor="#0000ff">
        <text id="explicitTHex" fontsize="30" fgcolor="#c0c0c0">value #hex</text>
      </view>
      <view id="explicitVRGB" height="50" width="200" bgcolor="rgb(0,0,255)">
        <text id="explicitTRGB" fontsize="30" fgcolor="rgb(191,191,191)">value rgb()</text>
      </view>
      <view id="explicitVExpression" height="50" width="200" bgcolor="255">
        <text id="explicitTExpression" fontsize="30" fgcolor="${~4144959}">value expr</text>
      </view>
    </view>
  </view>
  
  <script>

  </script>

</canvas>

You can also specify color using a number or an expression. presentValue() is used in the following example to return value according to type as a string.

Example 20.3. Specifying color with a numeric or computed value

<canvas height="150" width="100%">
    <simplelayout spacing="20"/>
    <view id="swatch" width="300" height="100" bgcolor="${color.value}"/>
    <view id="sliders">
        <simplelayout/>
        <slider id="color" width="300" value="0" minvalue="0" maxvalue="0xffffff" type="color"/>
        <text text="${color.presentValue()}"/>
    </view>
</canvas>

3.1. Mixing Colors

To blend a color, combine the RGB values. Red (FF0000) plus blue (0000FF) equals fuchsia (FF00FF):

Example 20.4. Blending Colors

<canvas height="150" width="100%">
  <view name="red" height="100" width="100" bgcolor="0xFF0000"/>
  <view name="blue" x="50" y="50" height="100" width="100" bgcolor="0x0000FF"/>
  <view name="fuchsia" x="50" y="50" height="50" width="50" bgcolor="0xFF00FF"/>
</canvas>

3.2. Standard Web Colors

The 16 basic web colors can be employed by name:

Example 20.5. Named colors

<canvas height="290"> 
    <view x="10" y="10" width="100%" height="100%"> 
        <wrappinglayout axis="y" spacing="10"/> 
        <replicator nodes="$once{['black', 'maroon', 'green', 'navy', 'silver', 'red', 'lime', 'blue', 'gray', 'purple', 'olive', 'teal', 'white', 'fuchsia', 'yellow', 'aqua']}"> 
            <view width="60" height="60" bgcolor="black"> 
                <view x="2%" y="2%" width="96%" height="96%" bgcolor="${parent.data}"> 
                    <text align="center" valign="middle" bgcolor="white" text="${parent.presentAttribute('bgcolor', 'color')}"/> 
                </view> 
            </view> 
        </replicator> 
    </view> 
</canvas>

3.3. CSS3 Colors

In addition to the standard web colors, you can also specify CSS3 colors by name. Click on the color name to see the hex value.

Example 20.6. CSS3 colors

<canvas height="674"> 
  <view name="container" x="2" y="2" width="100%" height="100%"> 
    <attribute name="colorNames"/> 
    <attribute name="displayMode" value="0"/> 
    <attribute name="_memo" value="[]"/> 
    <method name="RGBtoHSV" args="rgb"> 
      var hsv = _memo[rgb]; 
      return hsv ? hsv : (_memo[rgb] = LzColorUtils.tohsv(rgb)); 
    </method> 
    <method name="HSVcompare" args="a, b"><![CDATA[ 
      var hsva = this.RGBtoHSV(lz.colors[a]); 
      var hsvb = this.RGBtoHSV(lz.colors[b]); 
      if (hsva.h == hsvb.h) { 
      if (hsva.s == hsvb.s) { 
      if (hsva.v == hsvb.v) { 
      return 0; 
      } 
      return hsva.v > hsvb.v ? 1 : -1; 
      } 
      return hsva.s > hsvb.s ? 1 : -1; 
      } 
      return hsva.h > hsvb.h ? 1 : -1; 
    ]]></method> 
    <handler name="onconstruct"> 
      var cn=[]; 
      for (var k in lz.colors) { 
        // This makes sure we don't pick up attributes that aren't 
        // names of colors... 
        if (!isNaN(lz.colors[k])) { cn.push(k); } 
      } 
      cn.sort(function (a, b) { return container.HSVcompare(a, b);}); 
      this.setAttribute('colorNames', cn); 
    </handler> 
    <wrappinglayout axis="y" spacing="2"/> 
    <replicator nodes="${parent.colorNames}"> 
      <view width="150" height="30" bgcolor="black" ondata="inset.display.setAttribute('text', data)"> 
        <view name="inset" x="1" y="1" width="${parent.width - 2}" height="${parent.height - 2}" bgcolor="${parent.data}"> 
          <attribute name="mode" value="${container.displayMode}"/> 
          <handler name="onclick"> 
            if (lz.Keys.isKeyDown("shift")) { 
            container.setAttribute('displayMode', (this.mode + 1) % 4); 
            } else { 
            this.setAttribute('mode', (this.mode + 1) % 4); 
            } 
          </handler> 
          <text name="display" align="center" valign="middle" bgcolor="white"> 
            <handler name="onmode" reference="parent" args="mode"> 
              switch (mode) { 
              case 1: 
              this.format("#%06X", parent.bgcolor); 
              break; 
              case 2: 
              this.setAttribute('text', LzColorUtils.torgb(parent.bgcolor)); 
              break; 
              case 3: 
              var hsv = container.RGBtoHSV(parent.bgcolor); 
              this.format("h:%.0d\xB0 s:%.0d%% v:%.0d%%", hsv.h, hsv.s*100, hsv.v*100); 
              break; 
              default: 
              this.setAttribute('text', parent.presentAttribute('bgcolor', 'color')); 
              break; 
              } 
            </handler> 
          </text> 
        </view> 
      </view> 
    </replicator> 
  </view> 
</canvas>

3.4. Nonstandard Colors

To specify any color other than the standard web colors or CSS3 colors, which are usable by name, use hex codes or rgb(). With rgb(), you can specify values as decimal or as percents.

Example 20.7. Nonstandard colors

<canvas height="200" width="100%">
  <simplelayout axis="y"/>
  <text>using hex values</text>
  <view>
    <simplelayout axis="x"/>
    <view width="50" height="50" bgcolor="#220099"/>
    <view width="50" height="50" bgcolor="#770011"/>
    <view width="50" height="50" bgcolor="#0022ff"/>
    <view width="50" height="50" bgcolor="#ff2200"/>
    <view width="50" height="50" bgcolor="#00ff22"/>
  </view>
  <text>same thing using rgb()</text>
  <view>
    <simplelayout axis="x"/>
    <view width="50" height="50" bgcolor="rgb(34,0,153)"/>
    <view width="50" height="50" bgcolor="rgb(119,0,17)"/>
    <view width="50" height="50" bgcolor="rgb(0,34,255)"/>
    <view width="50" height="50" bgcolor="rgb(255,34,0)"/>
    <view width="50" height="50" bgcolor="rgb(0,255,34)"/>
  </view>
  <text>same thing using rgb() %</text>
  <view>
    <simplelayout axis="x"/>
    <view width="50" height="50" bgcolor="rgb(13%,00%,60%)"/>
    <view width="50" height="50" bgcolor="rgb(47%,00%,07%)"/>
    <view width="50" height="50" bgcolor="rgb(00%,13%,100%)"/>
    <view width="50" height="50" bgcolor="rgb(100%,13%,00%)"/>
    <view width="50" height="50" bgcolor="rgb(00%,100%,13%)"/>
  </view>
</canvas>

3.5. Opacity

In OpenLaszlo, a view has a color and an opacity which are handled separately. The opacity attribute ranges from 0 (transparent) to 1 (opaque).

Example 20.8. Color and opacity

<canvas height="110" width="100%">
  <simplelayout axis="x" spacing="4"/>
  <class name="fader">
    <view height="100" width="100">
      <handler name="onclick"> immediateparent.animate('opacity', -.20, 25, true); </handler>
      <handler name="onmouseout"> immediateparent.animate('opacity', 1, 2500, false); </handler>
    </view>

  </class>
  <fader name="houston" bgcolor="0xFF0000">
    <text text="Comet"/>
  </fader>
  <fader name="sacramento" bgcolor="0x800080">
    <text fgcolor="0xFFFFFF" text="Monarch"/>
  </fader>
  <fader name="seattle" bgcolor="0x008000">
    <text text="Storm"/>
  </fader>
  <text multiline="true"> 
    Click on a view to reduce its opacity.<br/> 
    Mouse out to restore 100% opacity. 
  </text>
</canvas>

When a view's opacity is set to 0, the visible attribute of that view turns to false.

3.6. DHTML with Windows Internet Explorer: Opacity Issues

3.6.1. Internet Explorer: overflow="visible" Doesn't Work with opacity

If you use the IE alpha-filter to set the opacity, the overflow will always be changed to hidden. The example below provides a workaround for this issue:

   <canvas >
      <!-- the image will be clipped in IE DHTML due to nested opacity --> 
      <view opacity=".6" width="150" height="60" bgcolor="red"> 
         <view width="${canvas.width}" height="60" resource="http:Unbenannt.png" stretches="both"/> 
      </view> 
      
      <!-- Moving the image to be a sibling fixes the issue--> 
      <view y="200" opacity=".6" width="150" height="60" bgcolor="red"/> 
      <view y="200" opacity=".6" width="${canvas.width}" height="60" resource="http:Unbenannt.png" stretches="both"/> 
   </canvas>

3.6.2. Internet Explorer 7 DHTML Doesn't honor view opacity for stacked (overlayed) views

If you have a shadow view that uses a partial opacity setting underneath another view to create a shadow effect, the topmost view overlaying the shadow disappears in Windows Internet Explorer 7, using DHTML. The following example shows the problem:

   <canvas width="100%" height="100%" validate="false" debug="true" proxied="false" bgcolor="0x00aaaa"> 
      <view width="300" height="100"> 
         <view width="300" height="100" bgcolor="black" opacity="0.3"/> 
         <view width="150" height="50" bgcolor="red"/> 
      </view> 
      <button text="Click me" onclick="canvas.setAttribute('opacity', 0.50)"/> 
   </canvas>

In this test, the red view and the button disappear when the button is clicked, instead of receiving 50% opacity. You can work around this issue in Internet Explorer 7 DHTML to get the same effect, as follows:

   <canvas width="100%" height="100%" validate="false" debug="true" proxied="false" bgcolor="0x00aaaa">
      <simplelayout/>
      <!-- This example hides the red box when the button is clicked in IE DHTML -->
      <view width="300" height="100" name="root">
         <view width="300" height="100" bgcolor="black" opacity="0.3"/>
         <view width="150" height="50" bgcolor="red"/>
      </view>
      <button text="Click me" onclick="root.setAttribute('opacity', 0.50)"/>
      <!-- By avoiding nesting views with opacity, we can get the same effect and it works in IE DHTML-->
      <view width="300" height="100" name="container">
         <view width="300" height="100" bgcolor="black" opacity="0.3"/>
         <view width="300" height="100" name="root">
            <view width="150" height="50" bgcolor="red"/>
         </view>
      </view>
      <button text="Click me" onclick="container.root.setAttribute('opacity', 0.50)"/>
   </canvas>