HTML Canvas渐变仅显示一种颜色 [英] HTML Canvas gradient only show one color

查看:69
本文介绍了HTML Canvas渐变仅显示一种颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用画布渐变时遇到问题,它仅显示我在 gradient .__ addColorStop __(offset,color)方法上设置的最后一种颜色.

I'm having problems with Canvas gradient it only shows the last color that I set on gradient.__addColorStop__(offset,color) method.

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

For example here is a piece of my code to understand better:

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上尝试了相同的代码,并且运行正常,我不知道为什么我的脚本无法正常工作.

That code only draw a red circle and do the same with any shape filled with the gradient, if i comment this line gradient.addColorStop(1/1,"red");then canvas draw a yellow circle, only read the last color. I tried the same code on jsfiddle.net and works perfectly, i dont know why my script wont work.

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

PD: Circle is a js object that i defined and works perfectly

对不起,我的英语语言,如果该帖子听不懂,请告诉我,这是我在StackOverflow上的第一篇帖子.谢谢!

Sorry for my english, if the post doesn't understand please tell me, is my first post on StackOverflow. Thanks!

推荐答案

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

CanvasGradients are relative to the context's transformation matrix, not to the shape you'll fill it with.

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

So in your example, since you are drawing an horizontal gradient, you set this gradient only in an area that goes from x:10 to x:200. Pixels before x:10 will have the value at index 0, and the ones after x:200 the one at index 1.
Since you are drawing your circle at 300,150 with a radius of 50, the minimal x position your circle will attain is 250, which is after your gradient index:1 and hence solid red.

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

Here is a visual demo of what happens:

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>

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

To circumvent this, you have two ways:

  • 在正确的坐标处生成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>

这篇关于HTML Canvas渐变仅显示一种颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆