Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

rradonic
Copy link

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:

quadrilateral

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.

@ericdrowell
Copy link
Owner

This is very cool! I'll look closer into this soon.

@ericdrowell
Copy link
Owner

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({
radius: 5,
fill: 'red',
distortion: [0, 0, 10, 50, 10, 100, 0, 10]
});

What doyou think?

@rradonic
Copy link
Author

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.

@ericdrowell
Copy link
Owner

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!

@rradonic
Copy link
Author

Awesome, I'll be interested in hearing it! And let me know if I can help of course.

@yechoua
Copy link

yechoua commented Jun 20, 2014

When does this featur will be available?
I really whant to use it. Did you integrate this feature with the ability to place the points "on the fly" ?
it can be really interesting. (check also the pull request conflict ;-) )

@rradonic
Copy link
Author

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.

@confile
Copy link

confile commented Nov 26, 2014

I also wondering if something is going on here. @ericdrowell could you please make a statement?

@yechoua
Copy link

yechoua commented Dec 1, 2014

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 :
http://stackoverflow.com/questions/26118032/kineticjs-image-shape-layer-distortion

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.
really, if it's helped you, think about help me to finish this function.
have a good day and "sorry for my english"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants