SOURCE CODE: Color Sort by RGB Proximity

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="">
  <title>Color Sort by RGB Proximity | JavaScript Examples | UIZE JavaScript Framework</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <meta name="keywords" content="featured color Uize.Color Uize.Color.Util Uize.Color.xSvgColors"/>
  <meta name="description" content="When you have a limited palette of colors, how can you sort the colors to find the closest matches to a desired color? This example shows you how."/>
  <link rel="alternate" type="application/rss+xml" title="UIZE JavaScript Framework - Latest News" href=""/>
  <link rel="stylesheet" href="../css/page.css"/>
  <link rel="stylesheet" href="../css/page.example.css"/>
  <style tyle="text/css">
    .colorSwatch {
      width: 1px;
      height: 340px;
      float: left;
      cursor: pointer;


<script type="text/javascript" src="../js/Uize.js"></script>

<h1 class="header">
  <a id="page-homeLink" href="../index.html" title="UIZE JavaScript Framework home"></a>
  <a href="../index.html" class="homeLinkText" title="UIZE JavaScript Framework home">UIZE JavaScript Framework</a>

<div class="main">
  <h1 class="document-title">
    <a href="../javascript-examples.html" class="breadcrumb breadcrumbWithArrow">JAVASCRIPT EXAMPLES</a>
    Color Sort by RGB Proximity
    <div class="pageActionsShell">
      <div id="page-actions" class="pageActions"><a href="source-code/color-sort-by-rgb-proximity.html" class="buttonLink">SOURCE</a></div>

  <!-- explanation copy -->

  <div class="explanation">
    <p>This example demonstrates the proximity-based color sorting functionality of the UIZE JavaScript Framework, as implemented in the <a href="../reference/Uize.Color.Util.html"><code>Uize.Color.Util</code></a> module. On the right of the interface is a large rectangle, with a sorted array of colors. On the left of the interface is an RGB color picker, with sliders for selecting levels for the red, green, and blue color channels of an RGB color. As you use the sliders to change your desired color, the finite set of available colors is re-sorted so that the colors most like your desired color are rearranged to be on the left. Additionally, these better matching colors are displayed using wider bars so you can inspect them more closely to make a better choice between the candidates. Color sorting functionality is useful when assisting a user in finding a color from a fixed color palette that is closest to their preferred color.</p>

  <!-- "wireframe" for the UI -->

  <table border="0" cellspacing="0" cellpadding="0" style="margin: auto;">
      <td class="heading">Choose Color</td>
      <td style="width: 20px;"></td>
      <td class="heading">Your Desired Color</td>
      <td style="width: 20px;"></td>
      <td class="heading">Closest Matches From Available Colors (i.e. limited color palette)</td>
      <td id="page_desiredColor"></td>
      <td id="page-desiredColor" style="width: 140px;"></td>
      <td id="page-colorSwatches" style="width: 442px;"></td>

<!-- JavaScript code to generate the color swatches -->

<script type="text/javascript">

Uize.require (
  function () {
    'use strict';

    /*** create the example page widget ***/
      var page = = UizeSite.Page.Example ();

    /*** sort colors and update swatches ***/
      function sortColorSwatches () {
        var desiredColorValue = page.children.desiredColor.get ('value');
        page.setNodeStyle ('desiredColor',{backgroundColor:'#' + desiredColorValue});
        Uize.Color.Util.sort (colors,desiredColorValue);
        for (var colorNo = -1; ++colorNo < totalColors;)
          page.setNodeStyle ('colorSwatch' + colorNo,{backgroundColor:colors [colorNo].to ('#hex')})

    /*** initialize colors ***/
        colorNames = Uize.values (Uize.reverseLookup (Uize.Color.colors)),
          /* NOTE:
            There are some colors that are listed twice, because there are spellings for both en-US and en-GB. Doing the reverse lookup is a simple way of removing dupes, because the duped colors will have the same color values and will overwrite each other in the reverse lookup.
        totalColors = colorNames.length,
        colors = (colorNames,function (colorName) {return Uize.Color (colorName)})
      /* for random colors...
          totalColors = 200,
          colors = (
            function () {return Uize.Color ().setEncoding ('RGB string').random ()}

    /*** build the swatches HTML ***/
        swatchesHtmlChunks = [],
        swatchNodeNames = [],
        colorSwatchesWidth = 442,
        swatchWidths = (totalColors,1),
        remainerToDistribute = colorSwatchesWidth - totalColors,
        midColorNo = totalColors - 1
      while (remainerToDistribute) {
        midColorNo = Math.floor (midColorNo * .67);
        for (var colorNo = -1; remainerToDistribute && ++colorNo <= midColorNo;) {
          swatchWidths [colorNo]++;
      for (var colorNo = -1; ++colorNo < totalColors;) {
        swatchNodeNames.push (swatchNodeName = 'colorSwatch' + colorNo);
        swatchesHtmlChunks.push (
          '<div id="page-' + swatchNodeName + '" class="colorSwatch" style="width: ' + swatchWidths [colorNo] + 'px;"></div>'

    /*** add the RGB reference color picker ***/
      page.addChild ('desiredColor',Uize.Widgets.RgbSliders.Widget,{value:'00aaff',sliderHeight:260,built:false})
        .wire ('Changed.value',sortColorSwatches);

    /*** add the color info widget ***/
      var colorInfo = page.addChild ('colorInfo',Uize.Widgets.ColorInfo.Widget,{built:false});

    /*** wire up the page widget ***/
      page.wireUi ();

    /*** initialization ***/
      colorInfo.setNodeStyle ('',{display:'none'});
      page.setNodeInnerHtml ('colorSwatches',swatchesHtmlChunks.join (''));

      /*** wire up the swatch mouseover and click behaviors ***/
        function updateColorInfo () {colorInfo.set ({})}
        page.wireNode (
            mouseover:function () {Uize.Tooltip.showTooltip (colorInfo.getNode ())},
            mouseout:function () {Uize.Tooltip.showTooltip (colorInfo.getNode (),false)},
            click:function (event) {
              var target = (event);
              Uize.Fade.Factory.fade (
                function (value) {page.children.desiredColor.set ({ (value,'hex')})},
                [ (page.children.desiredColor + '','RGB array')],
                [ (Uize.Dom.Basics.getStyle (target,'backgroundColor'),'RGB array')],
                {curve:Uize.Curve.easeInOutPow (4)}
              updateColorInfo.apply (target);
        page.wireNode (swatchNodeNames,'mouseover',updateColorInfo);

      sortColorSwatches ();