HTML Canvas渐变仅显示一种颜色

时间:2018-09-13 05:57:43

标签: javascript html5-canvas linear-gradients

我遇到画布渐变问题,它仅显示我在gradient.__addColorStop__(offset,color)方法中设置的最后一种颜色。

例如,以下是我的一段代码,可以更好地理解:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let gradient = ctx.createLinearGradient(10, 90, 200, 90);
gradient.addColorStop(1 / 10, "black");
gradient.addColorStop(1 / 5, "yellow");
gradient.addColorStop(1 / 1, "red");
let circle1 = new Circle(300, 250, 50, gradient);
circle1.draw(ctx);

该代码仅绘制一个红色圆圈,并且对填充渐变的任何形状都执行相同操作,如果我注释此行gradient.addColorStop(1/1,"red");,然后画布绘制一个黄色圆圈,则仅读取最后一个颜色。我在jsfiddle.net上尝试了相同的代码,并且运行正常,我不知道为什么我的脚本无法正常工作。

PD:Circle是我定义的js对象,效果很好

抱歉,如果我的英语不明白,请告诉我,这是我关于StackOverflow的第一篇文章。 谢谢!

1 个答案:

答案 0 :(得分:1)

CanvasGradients相对于上下文的转换矩阵,而不是您要用其填充的形状。

因此,在您的示例中,由于您正在绘制水平渐变,因此只能在从x:10到x:200的区域中设置此渐变。 x:10之前的像素的值为索引0,x:200之后的像素的索引为1。
由于您要以300,150的半径绘制半径为50的圆,因此圆所能达到的最小x位置为250,该位置位于渐变索引:1之后,因此为纯红色。

以下是发生的情况的直观演示:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let gradient = ctx.createLinearGradient(10, 90, 200, 90);
gradient.addColorStop(1 / 10, "black");
gradient.addColorStop(1 / 5, "yellow");
gradient.addColorStop(1 / 1, "red");

// draw a full rectangle to see how the gradient is actually rendered
ctx.fillStyle = gradient;
ctx.fillRect(0,0,canvas.width,canvas.height);

ctx.beginPath();
ctx.arc(300, 150, 50, 0, Math.PI*2);
ctx.strokeStyle = 'white';
ctx.stroke();
<canvas id="canvas" width="500" height="300"></canvas>

要避免这种情况,您有两种方法:

  • 在正确的坐标处生成CanvasGradient:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// x1 & x2 are set to match the circle's position
let gradient = ctx.createLinearGradient(250, 90, 350, 90);
gradient.addColorStop(1 / 10, "black");
gradient.addColorStop(1 / 5, "yellow");
gradient.addColorStop(1 / 1, "red");

ctx.fillStyle = gradient;

ctx.beginPath();
ctx.arc(300, 150, 50, 0, Math.PI*2);
ctx.fill();
<canvas id="canvas" width="500" height="300"></canvas>

  • 修改上下文的转换矩阵以移动CanvasGradient:

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let gradient = ctx.createLinearGradient(10, 90, 200, 90);
gradient.addColorStop(1 / 10, "black");
gradient.addColorStop(1 / 5, "yellow");
gradient.addColorStop(1 / 1, "red");

ctx.fillStyle = gradient;

ctx.beginPath();
ctx.arc(300, 150, 50, 0, Math.PI*2);
// our arc has been defined at the correct position
// we can now translate the context matrix so that only the fillStyle be moved
ctx.translate(230, 0);
ctx.fill();

// reset the default tranform matrix
ctx.setTransform(1,0,0,1,0,0);
<canvas id="canvas" width="500" height="300"></canvas>