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

Warping arbitrary coordinates? #11

Open
fallenartist opened this issue Jul 3, 2017 · 18 comments
Open

Warping arbitrary coordinates? #11

fallenartist opened this issue Jul 3, 2017 · 18 comments

Comments

@fallenartist
Copy link

Hi! Can individual points be controlled/warped with the script? I'm after a result as on the attached pic. Thanks.
screen shot 2017-07-03 at 18 18 47

@benjamminf
Copy link
Owner

benjamminf commented Jul 4, 2017

Achieving this effect is certainly possible with warp.js, but it'll require a bit of math and some knowledge of texture rendering in 2/3D graphics. What you'd want to do is use warp.js to warp the "WORD" SVG, and use texture mapping to project it onto the shape you have above.

This seems like a really interesting problem so I might give it a go and post my results here.

Can I ask how you produced this image? I'd like to inspect those tools to see how they do the math.

@benjamminf
Copy link
Owner

A bit of digging and I found this paper on generalised Barycentric coordinates, which I think would be a better method. It also looks like the method used in Illustrator's Envelope Distort feature. Just leaving this here for future reference.

@fallenartist
Copy link
Author

Yes, the above image was created with AI's Envelope Distort (designer here). I've been scouting the Net for years to find a web based solution but I'm afraid your linked articles are way over my coding abilities to translate it into anything useful.

@fallenartist
Copy link
Author

fallenartist commented Jul 4, 2017

So far, I've found this, this and this (with source code). Maybe it will be of use for you.

@benjamminf
Copy link
Owner

That's all good, I don't expect anyone to be able to, I'm just leaving this here for reference for myself when I get around to tackling the problem. I think it's a useful and interesting feature that I'll probably write it into the library, but it might take a little bit of time – I'll keep this thread updated.

Thanks for the links. I had seen some of them before, but unfortunately they won't accomplish what you're after. What you need is to map a shape to some arbitrary polygon, one which can't be defined by some continuous mathematical function.

@benjamminf
Copy link
Owner

benjamminf commented Jul 5, 2017

After much research, it seems like this is a feature that's disappointingly exclusive to Illustrator. Good news is I know roughly how they've implemented it, but it's quite mathematically complex so it's going to take some time to wrap my head around it. Just leaving these resources here for reference:

@benjamminf
Copy link
Owner

benjamminf commented Jul 6, 2017

Success! I have created a proof of concept that works surprisingly well!

Things to note:

  • I don't believe this is a perfect implementation that matches Illustrator. It's possible that Illustrator uses a more advanced algorithm that produces better distortions, but for this library, simple cases like yours works fine.
  • The implementation requires forming a rectangle for the "fitting" shape first, then distorting it's points later. This differs to Illustrator in that they just directly fit the shape, but it appears their implementation recreates the rectangle automatically. I'll look into implementing the same.
  • This proof of concept does not support curves. Ultimately I'd like the library to accept an SVG shape to be used as the "fitting" shape, so I'd need to get curves to work as well. Not sure how to go about this one at this point, but I'll be looking into it.

@fallenartist
Copy link
Author

Wow, looks good! I'll play with it and report any issues.

As for Illustrator, it looks like envelope distortion, including built in presets, always creates a mesh grid around the object's bounding box, then applies a deformation. The grid is based on bezier curves – even straight lines are converted to curves (when using a custom drawn simple shape as a guide like in my first example above).

screen shot 2017-07-06 at 11 42 03

screen shot 2017-07-06 at 12 00 47

Interestingly, there's a Fidelity setting, where you can control the precision of distortion, so I guess it's a raster based effect.

screen shot 2017-07-06 at 11 58 16

In order to get a distorted vector, you need to Expand the effect. Fidelity=100:

screen shot 2017-07-06 at 12 08 40

And Fidelity=0:

screen shot 2017-07-06 at 12 09 18

@benjamminf
Copy link
Owner

Thanks for the detailed information and screenshots, it's really handy. From what I can see, the presets are like pre-made custom shapes, but some use a mesh for inner points (fig 1 and 3). The proof of concept doesn't (probably) support inner points, given the algorithm used. However it might with a little tweaking, since it still uses the same concept of barycentric coordinates.

You're right in that it always warps the target shape from it's bounding box. The proof of concept actually does this too – you'll notice the control points form the bounding box of the SVG when created. Illustrator seems to automatically figure this out for you when using custom shapes, so I'd like to implement the same. I have an algorithm in my head that I'm pretty sure will work, just need to sit down and try it out.

As for the fidelity, good to see my implementation does pretty much the same thing. I was worried they'd be a bit more clever with it! Fidelity for warp.js is essentially what the interpolate method is for. You'll see at the top of the proof of concept I'm interpolating the SVG – this is basically the "fidelity" option.

@fallenartist
Copy link
Author

I've added custom font with bounding box detection and it works nicely.

One question – what does magnitude do?

@benjamminf
Copy link
Owner

That's cool! That magnitude variable wasn't necessary, I just had it there to make the code a bit cleaner.

@razvanphp
Copy link

razvanphp commented Feb 23, 2018

Sorry to hijack this issue, but my question is rather similar: would it be possible to achieve this warping effect from photoshop (so 2d), for an image (logo)? Here's what I mean:

screen shot 2018-02-23 at 21 39 51

Thanks in advance!

@natew
Copy link

natew commented Jun 3, 2018

Wow, what a lucky stroke. Am looking for the exact effect @razvanphp posted, funny enough and couldn't believe how close this thread gets me. I'll post if I get anything going.

@benjamminf
Copy link
Owner

@razvanphp @natew I completely missed this back in Feb... GitHub no longer puts issue updates in my feed 👎so I miss them.

The fisheye or bulge effect you're after is a different effect altogether than the envelope distort. But thankfully it's actually much easier. I'm building this effect into the library, but I'm not sure how long it'll be until I complete it. In the meantime, here's a good reference if you're capable of the heavy math. It describes a fisheye effect on a pixel shader, but it's exactly the same thing for this library (though replace the word "pixel" with "path point").

@jboarman
Copy link

@benjamminf Do you accept bounties?! 💰 😁 💰

I'm looking for a solution that works with a bounding SVG as the "fitting" shape that includes curves. Is that something you are still aiming to implement?

As a potential workaround, if one were to approximate a curved bounding shape with a series of small segments / control points, would you expect that to render a passable "curved" distortion? Or would you expect the warped distortion to have negative visual anomalies using this workaround method for curved fittings?

@benjamminf
Copy link
Owner

@jboarman unfortunately these days I have no time outside of my full time job :(

I'm looking for a solution that works with a bounding SVG as the "fitting" shape that includes curves. Is that something you are still aiming to implement?

Yes that's been the goal. There's still considerable work to be done to get this built into the library so I wouldn't hold my breath for it. Even though it's been well over a year since I've touched this project I still keep it in mind, but I have no plans or timelines.

As a potential workaround, if one were to approximate a curved bounding shape with a series of small segments / control points, would you expect that to render a passable "curved" distortion? Or would you expect the warped distortion to have negative visual anomalies using this workaround method for curved fittings?

This should work pretty well I'd say, depending on how small you make your line segments. I think the problem will be making the "squared" version of the fitting shape. With the example code in this thread it requires starting with a rectangular shape that the cartesian plane can be mapped to, then later distorting those points to the original shape it was. My intention was to write an algorithm to "square" your shapes for you, but I never got around to that. You may have to explore this yourself, as a shape with many points may be hard to manually "square".

@PavelLaptev
Copy link

@benjamminf made a concept with control points on your example above — https://pavellaptev.github.io/warp-svg/
Also, thank you for the great job you did

@benjamminf
Copy link
Owner

@PavelLaptev that's really awesome!! Such a nice interface, amazing work mate

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

No branches or pull requests

6 participants