在值之间混合颜色



我正在尝试像使用帆布弧一样创建时间倒计时,绘图还可以,但是弧线将具有笔触颜色,我想混合。

我绘制弧线的方式是使用0到100之间的数字,基本上是完整的弧,0是什么。当该值超过66及以下(或等于)100以下时,将是绿色和橙色之间的融合,100是绿色,而66是总橙色。65及向下将是橙色和红色之间的混合物,其中总红色为0。

我对从哪里开始,没有关于寻找如何获得价值的研究的想法。

任何人都可以指向正确的方向吗?

这是我到目前为止的代码x)

static color (value)
{
    const StartColor  = 0x66BB6A; // Green
    const MiddleColor = 0xFFA726; // Orange
    const EndColor    = 0xEF5350; // Red  
}

编辑:这是我要寻找的结果。现在,它的工作完全像我想要的那样。欢呼。

https://youtu.be/ier_zmzsaau

当然,使用专用于此的库会更容易。但是,以防万一任何人有兴趣进行数学,您可以将十六进制整数分成组件,然后分别插入每个组件以在特定位置获得颜色:

// break hex integer into components:
const getComonents = (color) => Array.from({length: 3}, (_, i) => Math.floor(color / 16 ** (2 * i) % 16 ** 2))
// interpolate arrays by component
const interpolate = (arr1, arr2, percent) => arr1.map((v, index) => Math.floor(v + (arr2[index] - v) * (percent / 100)))
function colors(value) {
  const StartColor  = 0x11FF11; // Green
  const MiddleColor = 0xFFA726; // Orange
  const EndColor    = 0xEF5350; // Red
  
  let [start, end, v] = value < 50 
      ? [StartColor, MiddleColor, value * 2 ] 
      : [MiddleColor, EndColor, (value - 50) * 2]
  let interpoled = interpolate(getComonents(start), getComonents(end), v)
  
  return interpoled.reduce((n, component, index) => n + component * (16 ** (index * 2)), 0)
}
const canvas = document.getElementById('the_canvas')
const ctx = canvas.getContext('2d')
for (let i = 0; i<100; i++){
  ctx.beginPath();
  
  // padStart is needed to make sure a value of `ff` becomes `0000ff`
  ctx.fillStyle = "#" + colors(i).toString(16).padStart(6, '0')
  ctx.rect(i*5, 0, i*5+5, 300);
  ctx.fill()
}
<canvas id="the_canvas" width="500" height="300"></canvas>

这是我制作的快速小提琴。

var c = document.getElementById("foo");
var i = 0;
var timer = setInterval(function() {
    var ctx = c.getContext("2d");
    ctx.beginPath();
    ctx.arc(75, 75, 50, 0, (i / 100) * Math.PI);
    ctx.strokeStyle = 'RGB('+((100-i)*2)+', '+i+', 0)';
    ctx.stroke();
    if((i / 100) == 2) {
        clearInterval(timer);
        console.log('FULL');
    }
    i++;
}, 100);

注意:此答案是原始版本的晚期和大编辑。第一次尝试之后,我错过了OP意图,OP添加了一个链接,与一个示例相关,从那以后,我打算提供解决方案,因为我对当前的答案不满意,并且练习很有趣。bk_hr>

答案的分解分为两个主要部分:

  1. 将颜色融合(已经有一个答案可以解决此问题,使用库或创建一种插值/混合颜色六角值的方法)
  2. 绘制弧并使用混合颜色

/*
 * blending colors 
 * (borrowed and modified from @mark-meyer answer)
 */
// break hex integer into components:
const getComponents = (color) => Array.from({length: 3}, (_, i) => Math.floor(color / 16 ** (2 * i) % 16 ** 2))
// interpolate arrays by component
const interpolate = (arr1, arr2, percent) => arr1.map((v, index) => Math.floor(v + (arr2[index] - v) * (percent / 100)))
const colorBlend = value => {
  const StartColor  = 0x11FF11; // Green
  const MiddleColor = 0xFFA726; // Orange
  const EndColor    = 0xEF5350; // Red
  
  let [start, end, v] = value < 50 
      ? [StartColor, MiddleColor, value * 2 ] 
      : [MiddleColor, EndColor, (value - 50) * 2]
  let interpoled = interpolate(getComponents(start), getComponents(end), v)
  
  const color = interpoled
  .reduce((n, component, index) => n + component * (16 ** (index * 2)), 0)
  .toString(16).padStart(6, '0')
  return `#${color}`
}
/*
 * draw an arc
 */
const canvas = document.getElementById('canvas1')
const ctx = canvas.getContext('2d')
const size = 30
let p = 0
const grad = ctx.createLinearGradient(size, size, size * 2, size * 2)
grad.addColorStop(0, "#66BB6A")
grad.addColorStop(0.5, "#FFA726")
grad.addColorStop(1, "#EF5350")
ctx.lineWidth = 6
const draw = () => {
  p += 0.01
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  ctx.strokeStyle = colorBlend(p * 50)
  ctx.beginPath()
  ctx.arc(size * 1.5, size * 1.5, size, 1.5 * Math.PI, (1.5 + p) * Math.PI)
  ctx.stroke()
  if (p < 2) {
    window.requestAnimationFrame(draw);
  }
}
window.requestAnimationFrame(draw);
<canvas id="canvas1" width="500" height="500"></canvas>

我假设您要

  • 创建一个基于三种已知颜色的色标-'66BB6A', 'FFA726', 'EF5350'
  • 从域内输入一个数字(0 - 100),并从比例尺中获取新颜色。

Chroma.js是一个不错的JS库,可以制作色标和转换。

const colorScale = chroma.scale(['66BB6A', 'FFA726', 'EF5350']).domain([0,100]);
console.log(colorScale(20).toString())
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = colorScale(20);
ctx.beginPath();
ctx.arc(100, 75, 50, 0, 2 * Math.PI);
ctx.fill();
<script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.0.2/chroma.min.js"></script>
<canvas id="myCanvas"></canvas>

相关内容

  • 没有找到相关文章

最新更新