HTML Canvas渐变只显示一种颜色
HTML Canvas gradient only show one color
我在使用 Canvas 渐变时遇到问题 它只显示我在 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");
然后 canvas 绘制一个黄色圆圈,仅读取最后一种颜色.我在 jsfiddle.net 上尝试了相同的代码并且运行良好,我不知道为什么我的脚本无法运行。
PD:Circle 是我定义的一个 js 对象,并且运行良好
对不起我的英语,如果 post 不明白请告诉我,这是我在 Whosebug 上的第一个 post。
谢谢!
CanvasGradients 是相对于上下文的变换矩阵的,而不是相对于您要填充的形状。
因此在您的示例中,由于您正在绘制水平渐变,因此您仅在从 x:10 到 x:200 的区域中设置此渐变。 x:10 之前的像素将具有索引 0 处的值,x:200 之后的像素将具有索引 1 处的值。
由于您在 300,150 处绘制半径为 50 的圆,因此您的圆将达到的最小 x 位置为 250,这是在渐变 index: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>
我在使用 Canvas 渐变时遇到问题 它只显示我在 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");
然后 canvas 绘制一个黄色圆圈,仅读取最后一种颜色.我在 jsfiddle.net 上尝试了相同的代码并且运行良好,我不知道为什么我的脚本无法运行。
PD:Circle 是我定义的一个 js 对象,并且运行良好
对不起我的英语,如果 post 不明白请告诉我,这是我在 Whosebug 上的第一个 post。 谢谢!
CanvasGradients 是相对于上下文的变换矩阵的,而不是相对于您要填充的形状。
因此在您的示例中,由于您正在绘制水平渐变,因此您仅在从 x:10 到 x:200 的区域中设置此渐变。 x:10 之前的像素将具有索引 0 处的值,x:200 之后的像素将具有索引 1 处的值。
由于您在 300,150 处绘制半径为 50 的圆,因此您的圆将达到的最小 x 位置为 250,这是在渐变 index: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>