Typescript:计算线性渐变任意比例颜色值

需求:

     这两天打算画一个环形进度条,进度从0到100%采用渐变颜色,涉及到各线段颜色取值变化,如果在CSS中,我们可以用linear-gradient达到目的。但遗憾的是,这里用的是ts,需要对每一线段进行赋值,找了半天发现没有这种现成的函数,自己写一个好了。

 实现:

//startColor、endColor线性渐变开始结束颜色,progress比例
function CalcColor(startColor: String, endColor: String, progress: number) :string{
  const startRed: number = parseInt(startColor.substring(1, 3), 16);
  const endRed: number = parseInt(endColor.substring(1, 3), 16);
  //计算红色
  const red: number = Math.floor(endRed + (startRed - endRed) * progress);

  const startGreen: number = parseInt(startColor.substring(3, 5), 16);
  const endGreen: number = parseInt(endColor.substring(3, 5), 16);
  //计算绿色
  const Green: number = Math.floor( endGreen + (startGreen - endGreen) * progress);

  const startBlue: number = parseInt(startColor.substring(5), 16);
  const endBlue: number = parseInt(endColor.substring(5), 16);
  //计算蓝色
  const Blue: number = Math.floor(endBlue + (startBlue - endBlue) * progress);
  
  //拼接成颜色代码
  const result = "#" + red.toString(16).padStart(2,"0") + Green.toString(16).padStart(2,"0") + Blue.toString(16).padStart(2,"0");
  console.log(result);
  //debugger;
  return result;
}

根据绘制的角度计算颜色,赋值即可~

接下来是画圆圈

onMounted(() => {
  const canvas: HTMLCanvasElement = document.getElementById(
    "myCanvas"
  ) as HTMLCanvasElement;
  if (canvas && canvas.getContext != null) {
    var van = canvas.getContext("2d")!;

    drawRing();

    function drawRing() {
      // 清除矩形内所有内容
      van.clearRect(0, 0, canvas.width, canvas.height);
      var i: number;
      var radiusInner: number = 100;
      var radiusOuter: number = 105;
      var offSetX: number = 110;
      var offSetY: number = 110;
      for (i = 0; i < 360; i += 10) {
        van.beginPath();
        //设置线宽
        van.lineWidth = 10;
        van.lineCap = "round";

        // 设置画笔颜色
        van.strokeStyle = CalcColor("#FA6400", "#FEDB65", i / 360);
        //计算绘制线段起始位置
        var startPoint = CalcCoordinate(i, radiusInner, offSetX, offSetY);
        //计算绘制线段结束位置
        var endPoint = CalcCoordinate(i, radiusOuter, offSetX, offSetY);
        //绘制线段
        van.moveTo(startPoint.x, startPoint.y);
        van.lineTo(endPoint.x, endPoint.y);
        // 执行绘制
        van.stroke();
        // 关闭此次绘制
        van.closePath();
      }
    }
  } else {
    console.log("Canvas为空");
    alert("不支持");
  }
});

计算绘制起始位置函数

 

//计算坐标
function CalcCoordinate(angle: number, radius: number, offSetX: number, offSetY: number) {
  var hudu = (Math.PI / 180) * angle;
  const x: number = radius * Math.sin(hudu) + offSetX;
  const y: number = radius * Math.cos(hudu) + offSetY;
  return { x: x, y: y };
}

 

HTML部分,也是有坑

<template>
  <canvas id="myCanvas" width="280" height="280"></canvas>
</template>
<style scoped>
#myCanvas {
  width: 280px;
  height: 280px;
}
</style>

 虽然我在#myCanvas设置了长宽度,但是canvas这个标签长宽并未生效,必须设置它的属性width和height才行,不然你绘制的图形都是变形。刚碰到这个问题挺郁闷的~~

 

总结:

  实现圆形进度条的时候,想倒是蛮简单的,但是代码实现时,却处处碰壁,看来要想做全栈,还有一段路要走,呜呼~

posted @ 2022-08-23 15:46  iDream2016  阅读(196)  评论(0编辑  收藏  举报