-
Notifications
You must be signed in to change notification settings - Fork 753
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
Image distortion implementation #514
base: master
Are you sure you want to change the base?
Conversation
This is very cool! I'll look closer into this soon. |
Hi again! I was just looking at this pull request again - what do you think about creating a new distortion transformation that all nodes can use, not just images? Currently KineticJS supports translate, rotate, scale, and skew. We could do something like this: var circle = new Kinetic.Circle({ What doyou think? |
I think it's a great idea! You'll notice that in the current implementation of image distortion, I check for the distortion parameter at the beginning of drawFunc in the Image prototype, and if it's found I skip the rest of the function and call _drawDistorted instead, where I draw the image myself. This isn't the nicest way to do it, as it doesn't leverage the existing code in drawFunc. I'd like to rely on existing code as much as possible, and making this a basic KineticJS transformation sounds like the right way to achieve that. There's an issue though: this isn't actually one affine transformation, it's four different ones, one for each triangular section of the image. I notice that, in nodes, you apply all of the node's transformations to a single matrix m, via the functions in Kinetic.Transform. This will need to be implemented differently, as it can't be applied to the same matrix. The way it's done right now is at draw time. I save the context's currently active transformation with context.save(), then I do my thing, and then I restore everything with context.restore(). I do that four times, for the four triangular sections, each with its own transformation. To integrate this with Kinetic.Node, I could add a new field to go along with the others (scale, rotation, etc.), calling it distortion or something, where I can store distortion coordinates like the ones you suggested above, and add a method to the Kinetic.Transform prototype, which calculates the four transformations based on these coordinates. Then, at draw time, I can apply these transformations before calling the shape's draw function, and undo them after the drawing. What do you think? Is there a logical place to do this stuff right before drawing a shape? Maybe a function common to all shapes that calls the actual shape's drawing function? The drawScene function in Kinetic.Shape looks like it might be a good place to do this. |
I'll take a crack at integrating the distortion transform into Node sometime this weekend and I'll let you know what I find. Stay tuned! |
Awesome, I'll be interested in hearing it! And let me know if I can help of course. |
When does this featur will be available? |
Hey guys, Just wondering about the current state of the project. I see the hiatus message, which I assume is from Eric, on the project's main GitHub page. The message is a bit out of date, saying he's taking a hiatus until July 2014, and it's now November. I see other people have been committing a bunch recently, has the project changed leadership? In either case, my other question is about this pull request. Is there still interest for an image distortion implementation? If so, I imagine this pull request will need to be modified to work with the new version of Kinetic. |
I also wondering if something is going on here. @ericdrowell could you please make a statement? |
I actually make something about it for the actual version BUT it won't work properly, if someone whant to take a look on this : I know it's not really clean but it's work, I havn't add the support of changing the src (the distortion don't want to work after that), in the post you can find the source and other stuff. |
I've added a new option to the Kinetic.Image constructor, called 'distortion'.
You pass in a function that returns four points. It's a function so that the points can potentially change each time the image is rendered. If you think it would be useful, the option could be modified to also accept four points directly, to save on the overhead of a function call if the points never change.
If the option is not passed to the Kinetic.Image constructor, I fall back to the regular image rendering behavior of KineticJS.
The rendering code starts by splitting the polygon formed by the four target points into four triangles, like this:
The middle point is where the bimedians (drawn in light gray) meet. The triangles are drawn in black.
I assign (u,v) vertex coordinates to these target points (x,y), so that the four corners of the image are mapped to the four outside points of the target quadrilateral, and the middle of the image is mapped to the intersection of the bimedians inside of the target quadrilateral.
To render the triangles, I find the transformation matrix I need by solving the system of equations determined by the three texture coordinates (source), and the three KineticJS coordinates (target). I save the canvas context's current state, apply the transformation, render only the current triangular section of the image (using clipping), and restore the canvas context's previous state. This is done once for each triangle.