Canvas createPattern() and fill() rectangle rendering on mouse move - javascript

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/

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!

Related

Fabricjs does not display the controls correctly

If you change the size/position of the object not manually, but in the code, the controls may not be displayed correctly. For example, I created a square and moved it. If you move the mouse to its old place, the cursor will change and if you start moving the object will move but relative to its new position. If you click on its new location, nothing will happen. This is corrected if you click on a different place on the canvas.
You need to call .setCoords() on your object after changing values like position programmatically.
See the following:
http://fabricjs.com/fabric-gotchas
https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords
This function helped me:
function Moved() {
canvas.discardActiveObject();
canvas.setActiveObject(object)
canvas.discardActiveObject();
canvas.renderAll();
}
It should be called at the end of initialization of the canvas and objects and after each change of location.
It is also better to use renderAll() instead of requestRenderAll() wherever possible.

How can I replace my cursor with a circle instead of drawing it to canvas in p5.js?

The problem: I'm trying to create a simple drawing app using p5.js. Instead of the standard cursor image, I'd like to show a circle at my cursor location that represents the size of the drawing brush.
Potential solution 1: Replace the cursor using the cursor() function native to p5.
Why it doesn't work: The p5 cursor function only takes the following parameters:
ARROW, CROSS, HAND, MOVE, TEXT, or WAIT, or path for image
As such, there's no native way to replace the cursor using the ellipse class.
Potential solution 2: Use the noCursor() function and then draw the circle at the cursor location, while also drawing the background, as such:
var brushSize = 50;
function setup() {
createCanvas(1080,720);
noCursor();
}
function draw() {
background(100);
ellipse(mouseX,mouseY,brushSize);
}
Why it doesn't work: While this solution gets the desired effect i.e. replacing the cursor with a circle the size of the brush, the constantly updating background prevents me from actually drawing to the canvas with the brush when I want to.
Is there some way I can replace the cursor without actually drawing the ellipse to the canvas? Is there any way to save and then instantly reload a canvas in p5? I couldn't find such a method searching through the API docs. Any hints are appreciated.
According to the reference, you can pass a URL into the cursor() function to set an image.
If you want to use an image that you draw, you're going to have to draw them ahead of time and save them to files, and then use those files. Something like this:
cursor('images/ellipse-15.png');
Where ellipse-15.png is an image that you generated ahead of time, to match when brushSize is 15, for example.
Btw P5.js is just setting the cursor CSS property. You can read more about it here.
If you want to go with the noCursor() approach and draw the ellipse yourself, you could draw your drawing to a buffer (the createGraphics() function is your friend) and then draw the ellipse on top of that every frame. I'd still probably use a cross cursor just because there's going to be some annoying lag if you draw it yourself.
Create a circular DIV inside the canvas container and show it on top of the actual canvas.

JavaScript Canvas createPattern

I have problem with canvas createPattern. I have two boxes, both will move after pressing a keyarrow:
Example:
http://jsfiddle.net/wA73R/1/
The problem is that the box background filled by createPattern also is moving. How to avoid that? Is there any solution? The big box is only an example (drawImage is not the good solution for me, I need something that will repeat background image).
Thank you for help
The problem is that the box background filled by createPattern also is moving.
Actually your problem is that the background is not moving - it is static, while you are drawing your rectangle to different positions.
How to avoid that?
The pattern will always be drawn at the coordinate origin, whose actual position is defined by the current transformation. In future you will be able to transform the pattern itself with the setTransform method, but since that currently is not implemented anywhere you instead will have to change the global transformation matrix.
In your case it means, that instead of drawing your rectangle at x/y, you translate the whole context to x/y and draw your rectangle at 0/0 then:
ctx.fillStyle=pattern;
ctx.save();
ctx.translate(boxes[i].x - left , boxes[i].y);
ctx.fillRect(0, 0, boxes[i].width, boxes[i].height);
ctx.restore();
(updated demo)

What is the most efficient way to reset the size of a shape after scaling in PaperJS

I am attempting to create a very simple beacon-like animation in Paper JS. The idea is that a circle starts off very small and totally opaque and then gets larger and more transparent until it disappears and the animation restarts.
I'm using scaling to make the image larger but resetting it to it's original size is becoming problematic and at the moment I have resorted to cloning a second circle to reset it rather than just working with a single shape, there has to be a simpler way of doing this.
I've create a jsFiddle to demonstrate my rough code so far, any help would be appreciated.
http://jsfiddle.net/colethecoder/Y3S9n/1
Paperjs does not store the original Path, nor does it remember any operations that have been applied to reach the current state, so it can be difficult to reset to a previous state. The easiest approach is to use the this.scale that your current code is calculating and when you want to reset do this.circle.scale(1/this.scale); Here is a jsfiddle that way.
FYI, here is the code path for scaling:
Item.scale()
Item.transform()
Item.apply()
Path._apply()
Segment._transformCoordinates()
So the end result is that _transformCoordinates() is called on each of the four segments in the circle, and it simply moves the point coordinates...nothing is remembered to "undo" the scaling later.
Alternatively to remembering the scale yourself, you can use the Path.fitBounds() function to shrink the circles to an arbitrary size...for instance you could save the bounding rectangle right after creating the Circle, and then fitBounds back to that size.
Set item.applyMatrix = false if you don't want to persist transformations alongside item.
For example, the following code linearly (i.e. "additively") animates item.scaling:
var item = new Path.Rectangle({
point: [75, 75],
size: [5, 5],
strokeColor: 'black',
applyMatrix: false
});
function onFrame(event) {
item.scaling += 0.1;
}
The way i approached this issue was attaching a new object called originalBounds to the paper.js shapes immediately after their instantiation. If i needed to play with its size, coming back its original one became fairly trivial.

strokeRect - Canvas drawing with HTML 5

Hi I am playing around with shapes and canvas and I have a question:
So say I have this code that draws a nice rectangle on the canvas:
$("#create_rectangle").bind("click", function() {
if(canvas[0].getContext){
var ctx = canvas[0].getContext('2d');
ctx.strokeRect(50,50,50,50);
}
});
Now I say I want to store a reference to that rectangle so that I can make alteration to it at a later stage. The stokeRect() method does not seem to return any value. How do I reference that particular rectangle that was created?
Well you can't reference it, but you can include it in a draw function which depending your arguments allow you to move/rotate hide etc.
It very depend on what you want to do with this shape.
This tutorial can be helpfull to understand manipulation of shape.
http://simonsarris.com/blog/140-canvas-moving-selectable-shapes
You can't.
Canvas is basically just a canvas. You throw some paint at it, it dries and you're done. You can't take your paint and move it somewhere else—but you can paint over it.
What you may want is SVG. It keeps track of shapes and other assorted things so that you can change them, deal with interactions much more precisely, et cetera.

Categories