【问题标题】:Canvas createPattern() and fill() rectangle rendering on mouse move鼠标移动时画布 createPattern() 和 fill() 矩形渲染
【发布时间】:2014-11-07 20:29:32
【问题描述】:

我创建了画布指针错误。它显示目标到所需位置(鼠标位置):

http://jsfiddle.net/conmute/rk276q3g/

问题出在 Firefox 渲染中,(移动鼠标非常快):

http://jsfiddle.net/conmute/rk276q3g/1/

矩形的行为很奇怪,我错过了。谁能指出具体是什么?

ctx.rect(
    // start x,y pair
    patternOffset.x, -p.circle.h/2 - patternOffset.y - 12,
    // end x,y pair
    -p.repeat.w, distance - p.circle.h - 1
);

ctx.fillStyle = pattern;
ctx.fill();

状态更新

我解决了这个问题: http://jsfiddle.net/rk276q3g/2/

通过注释掉 ctx.save() 和 .restore() 并在绘制矩形之前放置箭头图像。

所以实际上我解决了这个问题,但问题是......

问题更新

...如果我在做了一些 ctx.translate(... 和一些图纸之后需要画画怎么办?

我需要使用 ctx.save() 和 .restore() 方法,但这会导致问题。我如何在不评论的情况下完成这项工作?因为当我删除它们时,它解决了问题。

我认为我正确理解了它们的工作原理,但我发现我没有。

更新

似乎通过删除所有ctx.restore()ctx.save() 解决了解决方案,但是当我通过计算先前的位置将translateed 回来之后添加要绘制的部分时,问题再次出现!

请看: http://jsfiddle.net/rk276q3g/5/

【问题讨论】:

  • 我不会使用mousemove 事件来触发绘画,而是使用window.requestAnimationFramemousemove 被触发的频率很高,比浏览器的重绘率还要频繁。
  • @philipp 同意,但问题仍然存在。无论如何,我应该在事件回调中请求每次 requestAnimationFrame (用于鼠标位置)。问题不在于优化,而在于 .rect() 渲染。
  • 我相信@philipp 已经发现了您的问题。你试图用每一个鼠标移动做太多事情。
  • 我查看了代码,对于您想要实现的目标,我看起来非常复杂,您正在为每个循环的模式创建另一个画布,我想您不需要,因为您可以使用你所拥有的环境。你保存了两次上下文,但你从来没有恢复它……总而言之,如果一个人快速移动鼠标,两个位置之间的距离就会增加,并且失败变得可见。我声明当你移动鼠标缓慢时也存在问题,但是因为故障很小,所以你看不到它。是的,性能似乎不是问题。
  • @philipp 你关于保存和恢复状态的评论帮助了我,但我不明白为什么这个保存恢复的东西对我的情况不起作用。请参阅问题的更新。谢谢。

标签: javascript canvas fill picturefill


【解决方案1】:

save()restore() 工作如下:<canvas> 维护其状态堆栈,堆栈中的每个项目代表上下文的所有属性(lineStylestrokeWidthtransform ,……)。通过调用save() 创建一个新的状态项并将其压入堆栈。通过调用restore(),项目从堆栈中弹出,画布的状态设置为堆栈顶部项目的属性。

Here 就是一个很好的例子。

回答您的问题:您需要在翻译和旋转上下文之前保存上下文的状态,以便在堆栈上创建一个新的当前项,您可以根据需要对其进行修改。一旦你完成了繁重的工作并想根据默认值绘制一些东西,你需要恢复状态,每个绘制动作都将基于默认值。

为了不和你发生冲突,我总是按照这种模式编写绘画方法:

function drawSomethingFanzy (ctx) {
    ctx.save();

   //some really awesome drawing here;

   ctx.restore();
}

编辑

我错过了指出save()在堆栈上创建了一个新的Item,但是并没有恢复默认设置,所有设置保持不变,但是被保存了,以后可以restore()-ed。

编辑

我附上了一张结果的屏幕截图,它从小提琴显示在我的电脑上。对我来说这看起来是正确的,所以请张贴一张图片来显示确切的问题是什么,或者你想要实现什么?老实说,我不明白问题是什么。您是指图案填充中的空隙吗?

更新

我只是有一点时间,创造了一个我认为你想要的小提琴here。希望对你有帮助!

【讨论】:

  • 我使用了您的建议,但 ctx.restore() 仍然给我带来麻烦。我究竟做错了什么。请参阅:jsfiddle.net/rk276q3g/3(如果您注释掉所有 ctx.restore() 问题将丢失。似乎 ctx.restore() 是不应该的东 smth (在 Firefox 中))
  • 我通过了,你保存(),翻译(),然后你调用另一个绘图函数,并在其中再次保存()。但是,您只需将状态复制到堆栈中,就不会恢复转换。所以 translate() 仍然适用。
  • 如果我使用一些计算删除restore()translate,同样的问题仍然存在。 @see:jsfiddle.net/rk276q3g/5
猜你喜欢
  • 1970-01-01
  • 2017-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多