var COREHTML5 = COREHTML5 || {}

// Constructor........................................................

COREHTML5.Slider = function(strokeStyle, fillStyle,
                            knobPercent, hpercent, vpercent) {
   this.trough = new COREHTML5.RoundedRectangle(strokeStyle, fillStyle,
                        hpercent || 95,  // horizontal size percent
                        vpercent || 55); // vertical size percent

   this.knobPercent = knobPercent || 0;
   this.strokeStyle = strokeStyle ? strokeStyle : 'gray';
   this.fillStyle = fillStyle ? fillStyle : 'skyblue';
   
   this.SHADOW_COLOR = 'rgba(100, 100, 100, 0.8)';
   this.SHADOW_OFFSET_X = 3;
   this.SHADOW_OFFSET_Y = 3;

   this.HORIZONTAL_MARGIN = 2 * this.SHADOW_OFFSET_X;
   this.VERTICAL_MARGIN   = 2 * this.SHADOW_OFFSET_Y;

   this.KNOB_SHADOW_COLOR    = 'yellow';
   this.KNOB_SHADOW_OFFSET_X = 1;
   this.KNOB_SHADOW_OFFSET_Y = 1;
   this.KNOB_SHADOW_BLUR     = 0;

   this.KNOB_FILL_STYLE   = 'rgba(255,255,255,0.45)';
   this.KNOB_STROKE_STYLE = 'rgba(0, 0, 150, 0.45)';

   this.context = document.createElement('canvas').getContext('2d');
   this.changeEventListeners = [];

   this.createDOMElement();
   this.addMouseHandlers();

   return this;
}

// Prototype..........................................................

COREHTML5.Slider.prototype = {

   // General functions to override...................................

   createDOMElement: function () {
      this.domElement = document.createElement('div');
      this.domElement.appendChild(this.context.canvas);
   },

   appendTo: function (elementName) {
      document.getElementById(elementName).
         appendChild(this.domElement);

      this.setCanvasSize();
      this.resize();
   },

   setCanvasSize: function () {
      var domElementParent = this.domElement.parentNode;

      this.context.canvas.width = domElementParent.offsetWidth;
      this.context.canvas.height = domElementParent.offsetHeight;
   },
   
   resize: function() {
      this.cornerRadius = (this.context.canvas.height/2 -
                           2*this.VERTICAL_MARGIN)/2;

      this.top    = this.HORIZONTAL_MARGIN;
      this.left   = this.VERTICAL_MARGIN;

      this.right  = this.left + this.context.canvas.width -
                    2*this.HORIZONTAL_MARGIN;

      this.bottom = this.top + this.context.canvas.height -
                    2*this.VERTICAL_MARGIN;

      this.trough.resize(this.context.canvas.width,
                         this.context.canvas.height);

      this.knobRadius = this.context.canvas.height/2 -
                        this.context.lineWidth*2;
   },

   // Event Handlers..................................................

   addMouseHandlers: function() {
      var slider = this; // Let div's event handlers access this object
      
      this.domElement.onmouseover = function(e) {
         slider.context.canvas.style.cursor = 'crosshair';
      };
   
      this.domElement.onmousedown = function(e) {
         var mouse = slider.windowToCanvas(e.clientX, e.clientY);

         e.preventDefault();

         if (slider.mouseInTrough(mouse) ||
             slider.mouseInKnob(mouse)) {

            slider.knobPercent = slider.knobPositionToPercent(mouse.x);
            slider.fireChangeEvent(e);
            slider.erase();
            slider.draw();
            slider.dragging = true;

         }
      };
      
      window.addEventListener('mousemove', function(e) {
         var mouse = null,
             percent = null;

         e.preventDefault();

         if (slider.dragging) {
            mouse = slider.windowToCanvas(e.clientX, e.clientY);
            percent = slider.knobPositionToPercent(mouse.x);

            if (percent >= 0 && percent <= 1.0) {
               slider.fireChangeEvent(e);
               slider.erase();
               slider.draw(percent);
            }
         }
      }, false);
      
      window.addEventListener('mouseup', function(e) {
         var mouse = null;

         e.preventDefault();

         if (slider.dragging) {
            slider.fireChangeEvent(e);
            slider.dragging = false;
         }
      }, false);
   }, 

   // Change Events...................................................

   fireChangeEvent: function(e) {
      for (var i=0; i < this.changeEventListeners.length; ++i) {
         this.changeEventListeners[i](e);
      }
   },

   addChangeListener: function (listenerFunction) {
      this.changeEventListeners.push(listenerFunction);
   },
   
   // Utility Functions...............................................

   mouseInKnob: function(mouse) { 
      var position = this.knobPercentToPosition(this.knobPercent);
      this.context.beginPath();
      this.context.arc(position, this.context.canvas.height/2,
                       this.knobRadius, 0, Math.PI*2);

      return this.context.isPointInPath(mouse.x, mouse.y);
   },

   mouseInTrough: function(mouse) {
      this.context.beginPath();
      this.context.rect(this.left, 0,
         this.right - this.left, this.bottom);

      return this.context.isPointInPath(mouse.x, mouse.y);
   },
    
   windowToCanvas: function(x, y) {
      var bbox = this.context.canvas.getBoundingClientRect();

      return {
         x: x - bbox.left * (this.context.canvas.width  / bbox.width),
         y: y - bbox.top  * (this.context.canvas.height / bbox.height)
      };
   },

   knobPositionToPercent: function(position) {
      var troughWidth = this.right - this.left - 2*this.knobRadius;
      return (position - this.left - this.knobRadius)/ troughWidth;
   },
   
   knobPercentToPosition: function(percent) {
      if (percent > 1) percent = 1;
      if (percent < 0) percent = 0;
      var troughWidth = this.right - this.left - 2*this.knobRadius;
      return percent * troughWidth + this.left + this.knobRadius;
   },

   // Drawing Functions...............................................

   fillKnob: function (position) {
      this.context.save();

      this.context.shadowColor   = this.KNOB_SHADOW_COLOR;
      this.context.shadowOffsetX = this.KNOB_SHADOW_OFFSET_X;
      this.context.shadowOffsetY = this.KNOB_SHADOW_OFFSET_Y;
      this.context.shadowBlur    = this.KNOB_SHADOW_BLUR;

      this.context.beginPath();

      this.context.arc(position,
                       this.top + ((this.bottom - this.top) / 2),
                       this.knobRadius, 0, Math.PI*2, false);

      this.context.clip();

      this.context.fillStyle = this.KNOB_FILL_STYLE;
      this.context.fill();
      this.context.restore();
   },

   strokeKnob: function () {
      this.context.save();
      this.context.lineWidth = 1;
      this.context.strokeStyle = this.KNOB_STROKE_STYLE;
      this.context.stroke();
      this.context.restore();
   },

   drawKnob: function (percent) {
      if (percent < 0) percent = 0;
      if (percent > 1) percent = 1;

      this.knobPercent = percent;
      this.fillKnob(this.knobPercentToPosition(percent));
      this.strokeKnob();
   },
   
   drawTrough: function () {
      this.context.save();
      this.trough.fillStyle = this.fillStyle;
      this.trough.strokeStyle = this.strokeStyle;
      this.trough.draw(this.context);
      this.context.restore();
   },
   
   draw: function (percent) {
      this.context.globalAlpha = this.opacity;

      if (percent === undefined) {
         percent = this.knobPercent;
      }

      this.drawTrough();
      this.drawKnob(percent);
   },

   erase: function() {
      this.context.clearRect(
         this.left - this.knobRadius, 0 - this.knobRadius,
         this.context.canvas.width  + 4*this.knobRadius,
         this.context.canvas.height + 3*this.knobRadius);
   }
};

//..................这是一个滑动条和圆角配合使用的例子...............................

var colorPatchContext = document.getElementById('colorPatchCanvas').
                           getContext('2d'),

    redSlider   = new COREHTML5.Slider('rgb(0,0,0)',
                                       'rgba(255,0,0,0.8)', 0),

    blueSlider  = new COREHTML5.Slider('rgb(0,0,0)', 
                                       'rgba(0,0,255,0.8)', 1.0),

    greenSlider = new COREHTML5.Slider('rgb(0,0,0)', 
                                       'rgba(0,255,0,0.8)', 0.25),

    alphaSlider = new COREHTML5.Slider('rgb(0,0,0)', 
                                       'rgba(255,255,255,0.8)', 0.5);

redSlider.appendTo('redSliderDiv');
blueSlider.appendTo('blueSliderDiv');
greenSlider.appendTo('greenSliderDiv');
alphaSlider.appendTo('alphaSliderDiv');

// Functions..........................................................

function updateColor() {
   var alpha = new Number((alphaSlider.knobPercent).toFixed(2));
   var color = 'rgba('
      + parseInt(redSlider.knobPercent * 255) + ','
      + parseInt(greenSlider.knobPercent * 255) + ','
      + parseInt(blueSlider.knobPercent * 255) + ','
      + alpha + ')';

   colorPatchContext.fillStyle = color;

   colorPatchContext.clearRect(0,0,colorPatchContext.canvas.width,
                               colorPatchContext.canvas.height);

   colorPatchContext.fillRect(0,0,colorPatchContext.canvas.width,
                               colorPatchContext.canvas.height);

   colorPatchContext.font = '18px Arial';
   colorPatchContext.fillStyle = 'white';
   colorPatchContext.fillText(color, 10, 40);

   alpha = (alpha + 0.2 > 1.0) ? 1.0 : alpha + 0.2;
   alphaSlider.opacity = alpha;
}

// Event Handlers.....................................................

redSlider.addChangeListener( function() { 
   updateColor();
   redSlider.fillStyle = 'rgb(' +
      (redSlider.knobPercent * 255).toFixed(0) + ', 0, 0)';
});

greenSlider.addChangeListener( function() { 
   updateColor();
   greenSlider.fillStyle = 'rgb(0, ' + 
      (greenSlider.knobPercent * 255).toFixed(0) + ', 0)';
});

blueSlider.addChangeListener( function () {
   updateColor();
   blueSlider.fillStyle = 'rgb(0, 0, ' + 
      (blueSlider.knobPercent * 255).toFixed(0) + ')';
});

alphaSlider.addChangeListener( function() { 
   updateColor();
   alphaSlider.fillStyle = 'rgba(255, 255, 255, ' + 
      (alphaSlider.knobPercent * 255).toFixed(0) + ')';

   alphaSlider.opacity = alphaSlider.knobPercent;
});

// Initialization.....................................................

redSlider.fillStyle   = 'rgb(' +
   (redSlider.knobPercent * 255).toFixed(0)   + ', 0, 0)';

greenSlider.fillStyle = 'rgb(0, ' +
   (greenSlider.knobPercent * 255).toFixed(0) + ', 0)';

blueSlider.fillStyle  = 'rgb(0, 0, ' +
   (blueSlider.knobPercent * 255).toFixed(0)  + ')';

alphaSlider.fillStyle = 'rgba(255, 255, 255, ' +
   (alphaSlider.knobPercent * 255).toFixed(0) + ')';

alphaSlider.opacity = alphaSlider.knobPercent;

alphaSlider.draw();
redSlider.draw();
greenSlider.draw();
blueSlider.draw();







    <div id='redSliderDiv'   class='slider'></div>
    <div id='greenSliderDiv' class='slider'></div>
    <div id='blueSliderDiv'  class='slider'></div>
    <div id='alphaSliderDiv' class='slider'></div>
    
    <canvas id='colorPatchCanvas' width='220' height='120'>
       Canvas not supported
    </canvas>