-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Overlay image for object or some way to prevent zoom on object pattern/background #3621
Comments
So you should define as overlay not an image but a fabric.Rect(). fill this fabric.Rect() with this pattern possibly made of one single square with the dotted corner. And then change the rect width/height instead of zooming it. |
@asturur We have 1000s of other objects that sit above the "editable canvas" that are bound to it. We would have to write a bunch of logic to handle re-scaling all of them as well as repositioning them to simulate what zoom already does. |
Where are those dots? over or under the zoomable objects? |
Currently the only option I have is to create a 2nd canvas (2) that I put at a lower z-index with a rect that uses a repeating pattern for those dots. Then tie in all the panning and zooming events that canvas 1 has. When you zoom canvas 1 I have to resize and re position the rect on canvas 2 to match the size and position of the zoomed rect on canvas 1. Unfortunately this gets a bit buggy and I haven't been able to figure out how to accurately represent the absolute size of the rect on canvas 1 after being zoomed on a rect in canvas 2. |
Better you check this code is easier and it will be a future feature: start from renderFill and check the new introduced function that is there. |
Thank you very much for your reply! Will the repeat still continue to fill the space of the object? For our needs the dots still cover the entire "editable canvas". Please see this GIF to show expected behavior. |
yes or would not be a pattern. |
@asturur I have cloned the repo and then checked out HEAD to 700ee14 (send up to group the change on dirty flag (#3564)) and merged your pull in since that was the last commit your pull was compatible with. I ran the build and was able to verify that the flag for scaleWithObject is there. Unfortunately it is still scaling with the object. Am I missing something? This is the code I am using let self = this;
fabric.Image.fromURL('../../../assets/images/dots.png', function(img) {
self.patternSourceCanvas = new fabric.StaticCanvas();
self.patternSourceCanvas.add(img);
self.patternSourceCanvas.renderAll();
self.patternSourceCanvas.setDimensions({
width: img.getWidth(),
height: img.getHeight()
});
self.patternSourceCanvas = self.patternSourceCanvas.getElement();
let pattern = new fabric.Pattern({
source: self.patternSourceCanvas,
repeat: 'repeat'
});
pattern.scaleWithObject = false;
self.floorPlan.item(0).setFill(pattern);
self.floorPlan.renderAll();
}); |
I have been able to simplify this code based off of another demo to fabric.util.loadImage('../../../assets/images/dots.png', function(img) {
let pattern = new fabric.Pattern({
source: img,
scaleWithObject: false
});
self.floorPlan.item(0).setFill(pattern);
self.floorPlan.renderAll();
}); |
So i got confuse between zoom and scale. It's fine the code is still valid. the second way you posted to create the pattern is simpler and is what i would like people to use.
With the code you merged ( that will available in fabric later with a slightly different form but same functionalities ) you have new properties for the pattern:
What you have to do for page zoom is to get zoom value ( canvas.getZoom() ) and set the pattern scaleX and scaleY to Consider also to set that rect instead of item(0) to backgroundImage for the canvas. probably it will save you some headache about not having around during selection. |
Is this the expected code (excluding the comment about item(0). let self = this;
fabric.util.loadImage('../../../assets/images/dots.png', function(img) {
let pattern = new fabric.Pattern({
source: img,
repeat: 'repeat',
scaleWithObject: false
});
pattern.scaleX = 1 / zoomLevel;
pattern.scaleY = 1 / zoomLevel;
self.floorPlan.item(0).setFill(pattern);
self.floorPlan.renderAll();
}); |
Yes but you have to update pattern.scaleX and pattern.scaleY every time you zoom. |
Ah ok. I was able to get the code to semi work by doing something like let self = this;
self.floorPlan.item(0).fill.scaleX = 1 / zoomLevel;
self.floorPlan.item(0).fill.scaleY = 1 / zoomLevel;
self.floorPlan.renderAll(); I found that it works better if I reset the pattern let self = this;
let pattern = self.floorPlan.item(0).fill;
pattern.scaleX = 1 / zoomLevel;
pattern.scaleY = 1 / zoomLevel;
self.floorPlan.item(0).setFill(pattern);
self.floorPlan.renderAll(); However, with each zoom it takes longer and longer to render. Once I start getting to a zoom of about 10 to 13 the whole thing just disappears. |
So there are things to keep in mind. Since that object that keep the pattern is relatively simple, disable cache for it. if it is disappearing is because probably the fabric cache system is creating an enormous canvas for it. |
@asturur Turning off object caching did the trick. Unfortunately this build of fabric seems to have an issue with the way we are loading SVGs vs current but at least we found a solution that is working great. Do you know when the code you have set to merge will be available in the main branch? I can probably push this story off a few weeks if your PR will be available sometime soon. Id also like so say thanks again for taking the time to respond so much. |
Well i have to clear separated text issues first and will take some time. The code will be similar and you should have no problem upgrading since the properties will stay same ( scaleX, scaleY ) Yes this build of fabric was integrating also SVG changes to parse real patterns from svgs. |
I was able to fork and merge using your changes on all files except the 2 you mentioned. If you want to check it out, https://github.com/dvideby0/352-fabric.js SVG issue has been resolved. |
This might be too late but one approach can be to set the pattern as the canvas background color. |
Currently I am working on a project that requires us to use an object on the canvas to represent an "editable canvas". This editable canvas is where you can add, move, remove other shapes. There is some padding that we simulate around the editable canvas and the actual canvas (40px). When zooming we use relative pan to move around and simulate what overflow would be like if the actual canvas was the size of the zoomed canvas. Our issue is that we need to have guides or a "grid" on our editable canvas that remain the same size regardless of zoom. Essentially we would like for it to work just like the canvas overlay where zoom does not affect the overlay's scale while still allowing the editable canvas to scale. By setting repeat, the overlay would simply continue to repeat to fill the "zoomed" size. We have tried using pattern fills to accomplish this and just re-calculating the pattern size with each change in zoom but unfortunately it appears that once you use an svg for a pattern fill it is rasterized and is now distorted by the zoom.
The logic we were trying looks like below where floorPlan.item(0) is our editable canvas
Here is a screen of what we have
the lighter shaded area is our rectangle (editable canvas). When I zoom on the canvas the dots zoom as well. I would like to be able to keep the dots the same size while increasing the surface area of the editable canvas and simply have a repeating pattern continue to fill the zoomed size with dots. Something similar to your flag overlayVpt I believe
The text was updated successfully, but these errors were encountered: