2016-05-23 17 views
0

對於我正在嘗試製作自己的線性漸變代碼的項目。而且我設法走得相當遠,但是,它並不完美。有些地方的漸變看起來不應該如此。用於canvas的javascript自定義漸變有一些錯誤

請參閱以下代碼,其中colorStops是漸變中的停止點。它應該在交通燈中顯示紅色,黃色和綠色之間的漸變。

gradientSlider = { 
 
     colorStops: ["#b30000", "#ffff1a", "#00e600"], 
 
     minValue: 0, 
 
     maxValue: 100, 
 
     init: function(canvas) { 
 
     this.canvas = canvas; 
 
     this.ctx = canvas.getContext("2d"); 
 
     this.width = canvas.width; 
 
     this.height = canvas.height; 
 
     this.colors = this.calculateHexColorForStep(); 
 
     this.draw(); 
 
     }, 
 
     draw: function() { 
 
     pixelWidth = this.width/this.maxValue; 
 
     for (i = 0; i < this.maxValue; i++) { 
 
      this.ctx.beginPath(); 
 
      this.ctx.rect(i * pixelWidth, 0, pixelWidth, this.height); 
 
      this.ctx.fillStyle = this.colors[i]; 
 
      this.ctx.fill(); 
 
     } 
 
     }, 
 
     calculateHexColorForStep: function() { 
 
     result = []; 
 
     stepsPerGradient = this.maxValue/(this.colorStops.length - 1); 
 

 
     for (i = 0; i < this.colorStops.length - 1; i++) { 
 
      percentIncrease = 100/stepsPerGradient/100; 
 

 
      firstColor = this.colorStops[i]; 
 
      targetColor = this.colorStops[i + 1]; 
 

 
      firstColorDecArray = this.tools.parseColor(firstColor); 
 
      targetColorDecArray = this.tools.parseColor(targetColor); 
 

 
      for (j = 0; j <= stepsPerGradient; j++) { 
 
      if (j == 0) { 
 
       result.push(firstColor); 
 
      } else if (j == stepsPerGradient) { 
 
       result.push(targetColor); 
 
      } else { 
 
       stepColorDecArray = [firstColorDecArray[0] + (percentIncrease * j) * (targetColorDecArray[0] - firstColorDecArray[0]), 
 
       firstColorDecArray[1] + (percentIncrease * j) * (targetColorDecArray[1] - firstColorDecArray[1]), 
 
       firstColorDecArray[2] + (percentIncrease * j) * (targetColorDecArray[2] - firstColorDecArray[2]) 
 
       ]; 
 
       result.push(this.tools.decimalToHex(stepColorDecArray)); 
 
      } 
 
      } 
 
     } 
 

 
     return result; 
 
     }, 
 
     tools: { 
 
     parseColor: function(hexColorString) { 
 
      var m; 
 
      m = hexColorString.match(/^#([0-9a-f]{6})$/i)[1]; 
 
      if (m) { 
 
      return [parseInt(m.substring(0, 2), 16), parseInt(m.substring(2, 4), 16), parseInt(m.substring(4, 6), 16)]; 
 
      } 
 
     }, 
 
     decimalToHex: function(decimalNumberArray) { 
 
      //TODO fikse tall under ti - alltid to plasser 
 
      var results = []; 
 

 
      results[1] = Math.round(decimalNumberArray[0]).toString(16); 
 
      results[2] = Math.round(decimalNumberArray[1]).toString(16); 
 
      results[3] = Math.round(decimalNumberArray[2]).toString(16); 
 

 
      for (var i = 1; i <= results.length; i++) { 
 
      if (!(isNaN(results[i]))) { 
 
       if (results[i] < 10) { 
 
       results[i] = "0" + results[i]; 
 
       } 
 
      } 
 
      } 
 

 
      return "#" + results[1] + results[2] + results[3]; 
 
     } 
 
     } 
 
    } 
 

 
\t \t //get the canvas element 
 
\t \t var canvasElm = document.querySelector("canvas"); 
 
\t \t //initialize the slider 
 
\t \t gradientSlider.init(canvasElm);
<canvas id="gradient-slider" width="600" height="200" class="gradientslider"></canvas>

回答

2

我的解決辦法是功能tools.decimalToHex的一個固定的版本。錯誤是您將結果數組視爲數組數組而不是字符串數組。

decimalToHex : function(decimalNumberArray){ 
     var results = []; 

     // Maybe check if number is in range 0 - 255, before converting to string? 
     results[0] = Math.round(decimalNumberArray[0]).toString(16); 
     results[1] = Math.round(decimalNumberArray[1]).toString(16); 
     results[2] = Math.round(decimalNumberArray[2]).toString(16); 

     for (var i = 0; i<results.length; i++) { 
       if(results[i].length < 2) { 
        results[i] = "0" + results[i]; 
       } 
     } 

     return "#" + results[0] + results[1] + results[2]; 
    } 

相應的jsfiddle:https://jsfiddle.net/8xr4zujj/4/

+0

多一點清理版本:https://jsfiddle.net/8xr4zujj/5/。開始內循環(stepsForGradient)的新運行時避免添加相同的顏色值。 – eoma

+0

謝謝eoma!保持好的東西:)看到你在pilsprog我猜。 – Piddien