Html 当上下文转换到中心时,沿画布弧的渐变笔划消失

Html 当上下文转换到中心时,沿画布弧的渐变笔划消失,html,canvas,html5-canvas,linear-gradients,Html,Canvas,Html5 Canvas,Linear Gradients,我对帆布画很陌生。我试着沿着一个圆的弧应用梯度。我可以让它看起来很好,当我画弧与中心偏移从上下文坐标。假设centerX和centerY表示画布的中心。我可以使用context.arc(centerX,centerY,radius,…)获得渐变圆弧 但是,当我试图围绕上下文坐标绘制圆弧时,渐变消失了。例如,我以上面的JSFIDLE示例为例,执行context.translate(centerX,centerY),然后执行context.arc(0,0,radius,…),生成的圆弧上没有任何渐变

我对帆布画很陌生。我试着沿着一个圆的弧应用梯度。我可以让它看起来很好,当我画弧与中心偏移从上下文坐标。假设centerX和centerY表示画布的中心。我可以使用
context.arc(centerX,centerY,radius,…)
获得渐变圆弧

但是,当我试图围绕上下文坐标绘制圆弧时,渐变消失了。例如,我以上面的JSFIDLE示例为例,执行
context.translate(centerX,centerY)
,然后执行
context.arc(0,0,radius,…)
,生成的圆弧上没有任何渐变

Example here: http://jsfiddle.net/N6NMB/

在我的例子中,我需要使用context.rotate()围绕其轴旋转生成的圆,因此我必须平移到中心并围绕(0,0)绘制圆。但我不明白为什么在尝试围绕上下文的(0,0)点绘制圆弧时渐变消失了。任何见解都会非常有用。

因为您正在翻译上下文
centerX
centerY
不再是您想的地方

当你翻译上下文时,你说你希望x和y是新的0,0。因此,现在您的0,0位于画布的中心,因此
centerX
centerY
会因其自身远离中心而偏移

您可以使用以下方法

var grad = context.createLinearGradient(
    -radius,
    radius / 2,
    radius,
    radius / 2
);


上述方法之所以有效,是因为它是在您转换上下文后调用的,因此
centerX
centerY
(如我前面所说)是0,0,这意味着它们不需要在该函数中引用。

您创建的渐变将与实际使用的变换一起绘制

所以,如果你不使用任何变换,不需要怀疑任何事情:定义你要绘制的渐变,你会没事的

如果使用“变换”,则在使用渐变坐标时,必须将其视为相对于点/角度/比例的坐标

为了进一步解释,我修改了您的示例并使用了径向渐变。
我创建了一个标准化渐变:它定义在0.0和1.0半径之间,这意味着它的x和y在[-1;1]中

var eyeGrad = context.createRadialGradient(0, 0, 0, 0, 0, 1.0);
那么要使用渐变,我必须:
1) 平移到我要绘制的图形的中心。
2) 缩放以具有标准化坐标

function drawEye(x, y, r) {
    context.save();
    //translate context to center
    context.translate(x, y);
    // scale to radius
    context.scale(r, r);
    context.beginPath();
    // draw an arc with radius of 1
    context.arc(0, 0, 1, 0, 2 * Math.PI, false);
    context.fillStyle = eyeGrad;
    context.fill();
    context.restore();
}
小提琴在这里:

   http://jsfiddle.net/gamealchemist/N6NMB/3/
结果如下:

drawEye(100, 100, 40);
drawEye(250, 120, 20);

您能解释一下为什么要使用磅秤吗?我尝试在绘制圆弧时删除比例并使用半径,例如context.arc(0,0,r,2*Math.PI,false)。但它只画了一个半径为1px的圆。为什么它会在半径值很大的情况下画这么小的一个圆呢?这个想法是使用与渐变相同的坐标系。所以首先要做的是居中,然后你缩放到使用标准化([0,1])坐标。啊,该死的,我必须在我所有更新的答案上升级我的游戏@gamealchest包括屏幕截图和更多深思熟虑的代码:P+1感谢你这么好地解释+1.
drawEye(100, 100, 40);
drawEye(250, 120, 20);