0

Iv`e created canvas pointer error. It shows a target to desired location (mouse position):

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

The problem is in Firefox rendering, (move mouse very fast):

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

rectangle acts weirdly, and i am missing smth. Can anybody point what exactly?

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();

Status update

I fixed this issue: http://jsfiddle.net/rk276q3g/2/

By commenting out ctx.save() and .restore() and placing arrow image before drawing the rectangle.

So actually i fixed this issue, But the thing is...

Question update

... what if i need to draw after i did some ctx.translate(... and some drawings?

I need to use ctx.save() and .restore() methods, but it cause a problems. How can i do this work without commenting them? Cause when i remove them it solves problem.

I thought that i understand properly how they work, but i see that i don't.

Update

It appears that by removing all ctx.restore() and ctx.save() solves the solution, but when i add my part to be drawn after i translateed back by calculating previous position, problem appears again!

Please see: http://jsfiddle.net/rk276q3g/5/

Roman M. Koss
  • 970
  • 1
  • 15
  • 33
  • 2
    I would not use the `mousemove` event to trigger the painting, use `window.requestAnimationFrame` instead. `mousemove` is triggered very often, more often than the repaint rate of the browser. – philipp Sep 16 '14 at 13:44
  • @philipp Agree, but problem still remains. In any case i should request every time requestAnimationFrame inside event callback (for mouse position). Question is not about optimizing, it is about .rect() rendering. – Roman M. Koss Sep 16 '14 at 14:19
  • I believe @philipp has identified your problem. You are trying to do too much with every mousemove. – markE Sep 16 '14 at 17:35
  • I looked through the code, and I looks quite complicated for what you like to achieve, you are creating a another canvas for the pattern each loop and I guess you do not need to, since you can use the context you have in place. You are saving the context twice, but you never restore it… All in all, If one moves the mouse fast, the distance between the two positions grows and the failure becomes visible. I state that the problem also exists when you move the mouse slow, but one just cannot see it, since the failure is very small. And yes, performance does not seem to be the issue. – philipp Sep 16 '14 at 18:05
  • @philipp your comment about saving and restoring state helped me out, but i don't understand why this save-restore thing is not working for my case. See update of question please. Thank you. – Roman M. Koss Nov 03 '14 at 01:08

1 Answers1

0

The save() and restore() work as follows: The <canvas> maintains a stack of its state and each item in the stack represents all the attributes of the context (lineStyle, strokeWidth, transform, …). By calling save() a new item of the state is created and pushed onto stack. By calling restore() the item is popped from the stack and the state of the canvas is set to the properties from the item on top of the stack.

Here is a good example.

To answer your question: You need to save the state of the context before you translate and rotate it, to create a new current item on the stack, which you can modify to your needs. Once you've done the heavy lifting and want to draw some things based on the default values, you need to restore the state and every paint action will be based on default values.

To not run into conflicts as you do, I always write painting methods following this pattern:

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

   //some really awesome drawing here;

   ctx.restore();
}

Edit

I have missed to point out that save() creates a new Item on the stack, but does not restore the default settings, all settings remain unchanged, but are saved and can be restore()-ed later on.

Edit

I attached a screenshot of the result which shows up at my computer from fiddle. For me that looks correct, so could please post a picture that shows what the exact problem is, or what you would like to achieve? I honestly do not get what the problem is. Do you mean the gaps in the pattern fill?

Update

I just had a moment and created a fiddle of what I think you want here. I hope it helps!

enter image description here

philipp
  • 15,947
  • 15
  • 61
  • 106
  • I used your suggestions, but ctx.restore() still give me troubles. What am i doing wrong. See: http://jsfiddle.net/rk276q3g/3/ (if you comment out all ctx.restore() the problem will be missing. Seems like ctx.restore() is dong smth that shouldt'n (in Firefox)) – Roman M. Koss Nov 03 '14 at 22:51
  • I stepped through, you save (), translate(), then you call another drawing function and therein you save() again. But by that you just copy the state to the stack, you do not restore the transform. So translate() is still applied. – philipp Nov 04 '14 at 17:55
  • The same issue remains if i remove `restore()` and `translate` back using some calculations. @see: http://jsfiddle.net/rk276q3g/5/ – Roman M. Koss Nov 06 '14 at 18:05