Open blaineylab opened 6 years ago
Clipping would be a very nice addition to Elm Collage! Currently I've no plans to implement it myself however. It should be not that hard to add. Svg already has support for it as you already observed I think. A good interface to introduce clipping would be good. Obviously pull requests are always welcome!
Did you check if the functions in Collage.Layout
can help you with this btw? Also, can you embed (a link to) an image showing what you like to do? Really helps brainstorming I think!
PS: Good to hear you like the library!
I didn't see a way to make a clipping mask using Collage.Layout
but I may have missed something. I guess the ability to include html
might allow clipping something in the Svg
package, then bringing it in? But it would be nice to have a uniform interface.
Here are examples of the source image and program.
What do you think would be the best svg to generate? Not very familiar with the spec but it looks like creating a <clipPath>
and including it by reference might be a more standard alternative to the clip-path
attribute.
Thanks for the pictures, helps a lot! Collage.Layout
cannot do this yet indeed.
So what are the possibilities to implement it? If I summarise your ideas correctly we have:
clip-path
attribute to the generated Collage<clipPath>
tag and reference it in the generated CollageIs that correct?
Some inspiration for a functional interface:
From what I can glean from this documentation, you use the clip-path
attribute to reference a <clipPath>
tag containing all of the actual information about what to clip, similar to how gradients are defined in a separate tag from where they are actually used. So it looks like there's really only one option for how to implement this.
Also, would it be worthwhile to implement <mask>
while we're at it?
One question is how exactly we want clip paths to be specified. In SVG, a clipping path is just a collection of arbitrary SVG elements (i.e. Collage
s). This very straightforward and flexible, but it also means passing in a lot of unnecessary information since color doesn't matter and 99% of the time you're just passing in filled shapes anyway. It would be much cleaner to be able to just specify a clip path using a list of Shape
s, but that doesn't give us anyway to specify rotations or relative positions, which is important for clipping. We could define an entirely new API, built around something like
type alias ClipPath = Transform { shape : Shape }
but that would require us to basically reimplement all of the transforming functions (shift
, scale
, etc) on ClipPath
. This could be made a little less painful if those functions were made more generic, but that would probably require exposing Transform
(Elm still doesn't have typeclasses right?) and would be a breaking change. Also, masks usually make use of gradient and pattern fills, so if we want to support masks as well we'd need to somehow incorporate those into the API.
Given the can of worms that a bespoke API would open, I'm inclined to suggest we just implement clip paths using Collage
, at least until the next major version.
I'll have give this an extra thought. Haven't use the library for some time (about half a year 🙈), going to do that soon. Probably I'll have some more ideas about what the best way to go will be.
The ClipPath
type alias looks compelling. But because of the abstraction sealing of Elm this will be hard indeed...
Are there plans to support some forms of clip paths?
My use case is cropping a sprite sheet, for which I ended up patching
Core.Image (Float, Float) String
toCore.Image (Float, Float) (List (Float, Float)) String
and rendering the points as a polygonclip-path
attribute, e.g.,clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
.PS: this library is great in practice, and edifying to patch!