CanvasによるHue描画

icon 項目のみ表示/展開表示の切り替え

概要

 Canvasにより色相(Hue)の円を描画するサンプルです。
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
</head>
<body>
<canvas id="t1" width="280" height="240">
</canvas>
<script type="text/javascript">

  var HSL=function(){
    this.h;
    this.s;
    this.l;
  }

  HSL.prototype.rgb2hsl=function(r,g,b){
    var max=Math.max(r,g,b);
    var min=Math.min(r,g,b);
    var h,s,l;
    if(max==min)
      h=0;
    else{
     if(r==max)
       h=60*(g-b)/(max-min);
     if(g==max)
       h=60*(b-r)/(max-min)+120;
     if(b==max)
       h=60*(r-g)/(max-min)+240;
    }
    if(h<0)
      h+=360;
    var s;
    var l=(max+min)/2;
    if(max==min)
      s=0;
    else{
      if(l<=127)
        s=(max-min)/(max+min);
      else
        s=(max-min)/(510-max-min);
    }
    this.h=Math.round(h);
    this.s=Math.round(s*100);
    this.l=Math.round(l/255*100);
  }

  var RGB=function(){
    this.r;
    this.g;
    this.b;
  }

  RGB.prototype.set=function(r,g,b){
    this.r=r;
    this.g=g;
    this.b=b;
  }

  RGB.prototype.toString=function(){
    var t="#";
    if(this.r<16)
      t=t+"0"+this.r.toString(16);
    else
      t=t+this.r.toString(16);
    if(this.g<16)
      t=t+"0"+this.g.toString(16);
    else
      t=t+this.g.toString(16);
    if(this.b<16)
      t=t+"0"+this.b.toString(16);
    else
      t=t+this.b.toString(16);
    return t;
  }

  RGB.prototype.hsl2rgb=function(h,s,l){
    var max,min;
    var r,g,b;
    if(h==360)
      h=0;
    if(l<50){
      max=2.55*(l+l*(s/100));
      min=2.55*(l-l*(s/100));
    }else{
      max=2.55*(l+(100-l)*(s/100));
      min=2.55*(l-(100-l)*(s/100));
    }
    if(h<60){
      r=max;
      g=min+(max-min)*(h/60);
      b=min;
    }else if(60<=h && h<120){
      r=min+(max-min)*((120-h)/60);
      g=max;
      b=min;
    }else if(120<=h && h<180){
      r=min;
      g=max;
      b=min+(max-min)*((h-120)/60);
    }else if(180<=h && h<240){
      r=min;
      g=min+(max-min)*((240-h)/60);
      b=max;
    }else if(240<=h && h<300){
      r=min+(max-min)*((h-240)/60);
      g=min;
      b=max
    }else if(300<=h && h<360){
      r=max;
      g=min;
      b=min+(max-min)*((360-h)/60);
    }
    this.r=Math.round(r);
    this.g=Math.round(g);
    this.b=Math.round(b);
  }

  // Hueを示す円を表示
  function hslCircleHue(ctx,cx,cy,l){
    var rgb=new RGB;
    for(var y=-100;y<100;y++){
      var sx=Math.round(Math.sqrt(100*100-y*y));
      for(var x=-sx;x<sx;x++){
        var s=100;
        var h=Math.atan2(y,x)*180/Math.PI;
        if(h<0)
          h+=360;
        rgb.hsl2rgb(h,s,l);
        var t="rgb("+rgb.r+","+rgb.g+","+rgb.b+")";
        ctx.strokeStyle = t;
        ctx.fillStyle = t;
        ctx.fillRect(x+cx,y+cy,1,1);
      }
    }
    ctx.strokeStyle = "black";
    for(var q=0;q<360;){
      var rq=q*Math.PI/180;
      var x1=100*Math.cos(rq)+cx;
      var y1=100*Math.sin(rq)+cy;
      var x2=110*Math.cos(rq)+cx;
      var y2=110*Math.sin(rq)+cy;
      ctx.beginPath();
      ctx.moveTo(x1,y1);
      ctx.lineTo(x2,y2);
      ctx.closePath();
      ctx.stroke();
      q+=60;
    }
    ctx.fillStyle = "black";
    ctx.font="16px serif";
    ctx.fillText("0",114+cx,4+cy);
    ctx.fillText("60",57+cx,108+cy);
    ctx.fillText("120",-67+cx,108+cy);
    ctx.fillText("180",-138+cx,4+cy);
    ctx.fillText("240",-67+cx,-100+cy);
    ctx.fillText("300",57+cx,-100+cy);
  }

  window.onload = function(){
    var canvas1 = document.getElementById('t1');
    if (canvas1.getContext){
      var ctx1 = canvas1.getContext('2d');
      hslCircleHue(ctx1,140,120,50);
    }
  }
</script>
</body>
</html>
ソースファイルのダウンロード(hue.zip)