-
-
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
fabric 2.4.0 - issue using clipPath when using toJSON / loadFromJSON. #5266
Comments
I have managed to get it working by removing the previous clipPath before hitting the loadFromJSON, then setting it again once the image has been added to the canvas using the reviveropt. |
I have the same error. But I can't solve the problem. When I click the 'load from JSON' button, Uncaught TypeError: e.shouldCache is not a function Is it a bug? Or should I use the 'reviveropt' of the loadfromJSON when I use 'clipPath' ? Thank you in advance. |
I have the same question. How could I make it. |
I have managed to get it working, too. I used callback function to set clipPath again. I hope the bug is fixed in ver 2.4.1. |
I think the problem has the origin in the loadFromJson() because it enlivens the image in json format to a fabric object. However, he observes that this image has a clipPath and tries to draw the clipPath which may raise this error because the clipPath probably remains in json format and not a fabric object |
|
Oh..you are great! |
I have one problem. |
@TsuchiyaMasahiro it seems to me that you have set clipPath with "absolutePositioned: true" and by doing so you have the clip path fixed realtive to canvas instead of the clipped object, and that applies to both canvas (despite your statement "In the first canvas (='c1'), I can move the Rect, and according to the position of the Rect, the clipped image is shown" which was not been confirmed). Please confirm if:
However, i have to say that maybe i didn't understand well your issue and i am a bit confused because you are using the same variable "clipPath" to be added to the canvas and also to be used has clip. Wait, now i understand you are talking of the "Rect" and not the image!!! Ok, without understanding what it really happens i could try to guess that in the first canvas, the fabric object (added in line 22 - canvas.add(clipPath);) and the clipping object (added in line 26 - clipPath: clipPath) share the same variable and maybe i am saying a big mistake but they are pointing to the same reference, if you change any setting of the variable, for example setting "clipPath.name = 'xpto'" you are applying it to both objects. And what happens in the second canvas? There is no relation between this objects. I don't know if you were trying to solve this with the 'clip_id' and 'clip_target' but you should not forget to pass that properties in toJSON(['clip_id', 'clip_target']) |
@rikkarv Sorry, my poor English explanation... Can you understand my problem? |
You have to keep the previous solution ("object.clipPath = arg1[0];") to avoid the error that gave origin to this issue. However, after loading the json, in his callback you have to replace the clipPath and say: "now you have to look to that fabric object - the rectangle - and see where he is going to". At this point and after making things working, i have to say that this is not a issue from library point of view. I understand what @TsuchiyaMasahiro pretends to achieve and i agree that this could be a very nice feature to implement, but it is not a issue like the one that gave origin to this conversation. In fact the loadFromJson() with clipping has to be fixed in source code because it raises an error that seems to be "solved" with the temporary workaround proposed. |
@TsuchiyaMasahiro i think my english is the worst in the planet, you don't have to be sorry and i think, never the less, that we are making progresses |
We can replace the:
for:
Here, the main point is to avoid the error "Uncaught TypeError: path.shouldCache is not a function" EDIT: this doesn't work you really have to set a fabric object |
wow, excellent ! |
@TsuchiyaMasahiro thank you for your kind words. |
@TsuchiyaMasahiro i recommend setting canvas to "preserveObjectStacking: true" because previously when we moved the clipped object towards the clipping area it was ok but when it was the clipping area moving towards the clipped object it was not working |
@rikkarv Thank you for your kind advice. |
@rikkarv hello! When I try this code.
Error comes when it runs to
|
@shenguan can you please provide a fiddle? What object are you using as clipPath? |
I forgot fabric.Image had its own version of fromObject method. (remember that if you need to clip images with RECTANGLES you can also use the crop functionality) |
@rikkarv I found my error.
which case my error when |
None of these worked for me. May be my case was different. If my case is applicable to you then you can implement this. I realised when you are loading the json on a different device with different width and height, scaling is applied on each and every object so that your design fits the new canvas size. Now when scaling the objects, make sure to also scale the clipPath. Otherwise the image will get bounce off the clip path. This is how i fixed it. NB: Make sure you include the canvas width and height when saving the json data: eg: var scaleFactor = Math.min(newCanvasWidth/oldCanvasWidth, newCanvasHeight/oldCanvasHeight)
var objects = canvas.getObjects();
for (var i in objects) {
objects[i].scaleX = objects[i].scaleX * scaleFactor;
objects[i].scaleY = objects[i].scaleY * scaleFactor;
objects[i].left = objects[i].left * scaleFactor;
objects[i].top = objects[i].top * scaleFactor;
// Now this willl fix the clip path on the new canvas size
if(Object.hasOwn(objects[i],"clipPath") && objects[i].clipPath){
objects[i].clipPath.scaleX = objects[i].clipPath.scaleX * scaleFactor;
objects[i].clipPath.scaleY = objects[i].clipPath.scaleY * scaleFactor;
objects[i].clipPath.left = objects[i].clipPath.left * scaleFactor;
objects[i].clipPath.top = objects[i].clipPath.top * scaleFactor;
}
objects[i].setCoords();
}
var obj = canvas.backgroundImage;
if(obj){
obj.scaleX = obj.scaleX * scaleFactor;
obj.scaleY = obj.scaleY * scaleFactor;
}
canvas.discardActiveObject();
canvas.renderAll();
canvas.calcOffset(); //You can create a function, copy the code and call it after canvas.loadFromJSON |
seems to me that setting the clipPath's originX/Y to center will do the same wrok with less overhead |
I haven't tried that. But i can see that centering it will give you a different positioning if the original positioning wasn't centered. |
Version
2.4.0
Test Case
http://jsfiddle.net/danwilsonme/Da7SP/3071/
Information about environment
Version 69.0.3497.100 (Official Build) (64-bit)
Steps to reproduce
Once image has loaded, click the to JSON button, throws the error "Uncaught TypeError: path.shouldCache is not a function" in console.
Expected Behavior
To duplicate the clipPath using to toJSON / loadFromJSON methods.
Actual Behavior
Uncaught TypeError: path.shouldCache is not a function
at klass._drawClipPath (fabric.js:13565)
at klass.drawObject (fabric.js:13555)
at klass.renderCache (fabric.js:13459)
at klass.render (fabric.js:13437)
at klass._renderObjects (fabric.js:7513)
at klass.renderCanvas (fabric.js:7463)
at klass.renderAll (fabric.js:9574)
at fabric.js:12227
at klass._setBgOverlay (fabric.js:12248)
Any suggestions?
The text was updated successfully, but these errors were encountered: