timjs / elm-collage Goto Github PK
View Code? Open in Web Editor NEWCreate interactive vector graphics and position them relative to each other
License: BSD 3-Clause "New" or "Revised" License
Create interactive vector graphics and position them relative to each other
License: BSD 3-Clause "New" or "Revised" License
Should we rename path
so that it isn't confused with general Bézier paths?
Possible options are:
polyline
segments
I definitely prefer the first one.
(Was brought up in #4)
view : () -> Html Never
view _ =
Collage.Text.fromString "hamada"
|> Collage.rendered
|> Collage.Render.svg
<body>
<script>
var app = Elm.Main.init({ node: document.querySelector('body') })
</script>
</body>
https://ellie-app.com/4mB5pLNhSJPa1
Using the simplest way to render a string, sometimes some part of the beginning and end of it disappears. When using a string like foobarbaz
, its rendered correctly. But when using, e.g., m
, it is not.
Didn't go over all the characters that work and don't work correctly.
If you need any more details, please tell me.
While trying to add a shadow to a collage I've discovered that the current API simply doesn't provide any gates for me to do that.
Hi, can you release the latest changes please?
I noticed this was listed as a TODO in a comment in the source code, but didn't have its own issue, so I thought I'd open one.
Hi @timjs ,
Overall, I think you've done a great with the library. The Layout
module seems especially useful, though your decision to use rectangular envelopes is slightly troubling. It seems counterintuitive, for instance, that if I try to anchor something to the right of a circle it will lie directly on the edge of said circle, but if I try to anchor something to the top-right of it it will lie a bit above of it. There are also a few things about the Layout
API that are still unclear to me from the documentation. The first is about the operation of the anchors. In particular, if I anchor a circle to the top-right hand corner of the square, will it be the bottom-left hand corner or the center of the circle that gets anchored? The second is what happens to the envelope when you rotate a collage. Does the envelope keep the same dimensions but rotate with the collage? Or do the dimensions change?
That aside, after looking through the documentation I have a few questions and suggestions regarding the naming and API. All of these suggestions are matters of taste and preference, not function, so feel free to implement or ignore them at your discretion. Further, if there is a specific reason that you have done things the way you have that you think I'm missing, please feel free to say so. That said, here are a few of the things I would change about the API:
styled
, traced
and rendered
to shape
, path
and text
. The current names seem confusing to me.LineStyle
and FillStyle
separate arguments to styled
. This largely a matter of personal taste, but it would be more in line with the conventions I've generally seen used in Elm libraries.path
to something more specific like polyline
or segments
. Since you're already using the word "path" as a general descriptor for all line-like objects, I would recommend against also using it to name a function which creates a far more specific object, namely a polyline. This will be especially important, I think, if you ever decide to add curved paths.ngon
to regularPolygon
. In my experience, the term "n-gon" is used synonymously with "polygon" and does not imply any sort of regularity. So, a more explicit name seems preferable.line
and Text.empty
. What are the intended use cases for these?Collage
s, but with text the styling is somehow intrinsic to the Text
object. Unless there is a reason not to, I would rewrite rendered
to have a type signature of TextStyle -> String -> Collage
and rework the helper functions in Collage.Text
to instead be helper functions for constructing TextStyle
s. This way the API is more consistent across the different forms. This would also make it more difficult for people to try to set multiple fonts or styles on text (e.g, right now you could try Text.fromString "foobar" |> Text.color blue |> Text.color red
).Collage.Text
submodule into Collage
. Why are they separated?mouseEnter
, mouseLeave
, mouseOver
and mouseOff
. In fact, I'm still unsure of the difference myself. A comment in the documentation should be sufficient.As I said before, if you have questions about any of these suggestions or I've missed something as to why you did things the way you did, please say so. Otherwise, I hope this feedback is useful the next time you look at making changes to your API.
mouseEnter
, mouseLeave
, mouseOver
and mouseOff
with an example like in the JQuery documentationI have a textfield wrapped in a collage called nodeBox and I want to impose a hitbox on it:
impose nodeBox (trigger hitbox)
Now, an onMouseLeave-event triggered by the hitbox will lead to a defocus/blur of the textfield. As can be seen in the document below, this leads to nasty bugs. I would like the focus to stay in the textfield, regardless of the parent-events.
As I'm no longer using this library and Elm itself, it is time for Elm Collage to get some love from somebody else. Is there anybody willing to take over, maintain the library and help keeping Elm Collage alive?
A way to create Bézier curves would be great! The idea is to add a curve
function which creates a Path
. The resulting path can be traced and closed in the same way as segement
s and line
s.
Note: maybe we'll have to rename path
to polyline
to avoid some confusion, see #10.
I'm not very happy with the current api of the text module, also not very dissatisfied. It is indeed the case that with collages you're styling them "at once" and with text you style them "in parts". It is harder to get text right, because there are so many options. It is not clear to me yet which are the most common we could fit into helper functions. In Collage solid
, dashed
, dotted
etc. fall into this category. They capture the most common styling options for lines: dashing, thickness and colour. More complicated styling can be done by creating a line style.
Let's strive to an API where giving multiple styling options twice is not allowed, as that is something I'm trying to avoid with collages. We need some more examples and feedback to decide on a good api for text.
(First brought up in #4.)
See for example Svg
onMouseMove
is defined but never exposed.
The current "at" function changes the center of the collage to the center of the added collage.
This would mean in the following code that the center of the total is the center of label
shape
|> at topLeft label
However, for things as labels, I would prefer to keep te center of the shape, therefore I would like an addition to your Lay-out functions: the imposeAt, shown below.
This would mean that "at" would need a new name for clarity. I haven't thought of anything except "stackAt", which isn't quite descriptive in my opinion.
-- fore is used for further calcs
at : Anchor msg -> Collage msg -> Collage msg -> Collage msg
at anchor collage host =
stack
[ fore
|> shift (anchor back)
, back
]
-- back is used for further calcs
imposeAt : Anchor msg -> Collage msg -> Collage msg -> Collage msg
imposeAt anchor fore back =
impose
(fore
|> shift (anchor back)
)
back
This is a very long-term feature request, I know, but it would be great to see a canvas backend to this library. I might be able to work on a pull request for this if you're too busy with other work.
When trying to make an invisible hitbox, I used
rectangle 10 10
|> filled transparent
However, this hitbox will not trigger any events.
Using a color with opacity zero however will have the desired effect:
rectangle 10 10
|> filled (uniform (Color.rgba 0 0 0 0))
Please add a default fill style called "invisible" that mimics this behaviour and make a clear distinction with "transparent" in your documentation.
This, off course, would be awesome! Strange things like the top-right of a circle being out of the shape won't happen any more. Two things are important to keep in mind however:
Summarised: awesome to extend envelopes further, but I currently don't have the time and knowledge to implement this myself.
(First brought up in #4.)
####Proposal###
Allow for the ability to add custom html attributes, or a restricted subset thereof (such as class
, style
, id
).
####Rationale####
Aside from styling, global attributes can be useful selectors for various callback methods. This can be necessary when using ports with outside js libs.
For example, the GSAP Draggable lib gives a good number of options for native drag functionality, and works very well with svg elements. It would be nice to be call something like
Draggable.create(".collageClass", {callbacks for class collage})
Draggable.create(".collageAnotherClass", {callbacks for another class collage})
etc
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
to Core.Image (Float, Float) (List (Float, Float)) String
and rendering the points as a polygon clip-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!
Just noticed there doesn't seem to be a link to the module docs right now. That's probably worth adding for the people who stumble across this repo before the docs elm-lang.org.
We already have good pull request #3!
Like in Haskell Diagrams. Currently working on this. See also this comment.
The documentation states that Polygon will auto-close all shapes; however when I was outlining a polygon today, it only traced the line segments which were defined by the list of tuples and didn't auto-close it. I'm new to Elm and Collage - is this expected behavior?
I'm getting below error.
In your source file you claim to not include constructors, but I do need Point to create Paths.
import Collage exposing (..)
Cannot find variable `Collage.Point`.
102| (Collage.Point (0, 0))
^^^^^^^^^^^^^
`Collage` does not expose `Point`.
I'm a bit curious as to your desire to remove svgBox from this module, as having explicitly defined dimensions for a graphical element seems very useful. Is there another way of achieving the same effect without this function that would be preferable?
Additionally, is there any way to set the attributes of the svg object that's generated by svg and svgBox with the current implementation? If not, that's something I'd like to see. I was hoping to be able to get click events bubbled up to parents, but the svg element seems to be blocking their triggers.
Colors do not seemed to be included in your library.
I have tried multiple different colors and even the function rgb
, but none of them gets recognized.
Cannot find variable Collage.red.
50| |> filled (uniform Collage.red )
^^^^^^^^^^^
Collage does not expose red.
This is a reminiscence from the Elm Render library's ShapeStyle
. Note that styled
in Elm Collage is more similar to styledShape
than to filledAndBordered
. I tried to simplify things and merge these to ways to add fill and outline to a shape. It is a hard one to design properly. ShapeStyle
was a record, I made Style
a tuple. Take a look at these two simple fills and outlines:
rectangle 100 50
|> filled (uniform blue)
rectangle 100 50
|> outlined (solid thick (uniform red))
and the three possible options to use styled
with undefined styles:
-- Option 1: separate arguments
rectangle 100 50
|> styled (uniform blue) (solid thick (uniform red))
-- Option 2: tuple
rectangle 100 50
|> styled ( uniform blue, solid thick (uniform red) )
-- Option 3: record
rectangle 100 50
|> styled { fill = uniform blue, line = solid thick (uniform red) }
As for parentheses, it doesn't matter that much. You'll need them anyway in option 1 and option 2. I think option 3 is way to verbose and contains unnecessary information.
Now comes the deliberation: How does it look like when using predefined styles?
--
-- Option 1: separate arguments => create styling functions
--
outlinedAndFilled thickness fillColor =
styled (uniform fillColor) (solid thickness (uniform black))
thinOutlinedAndFilled =
outlinedAndFilled thin
thickOutlinedAndFilled =
outlinedAndFilled thick
triangle 30
|> thickOutlinedAndFilled green
--
-- Option 2: tuple => create new `Style` tuple
--
thinOutlinedAndFilled fillColor =
( uniform fillColor, solid thin (uniform black) )
thickOutlinedAndFilled fillColor =
let
(fill, line) =
thinOutlinedAndFilled fillColor
in
( fill, {line | thickness = thick} )
triangle 30
|> styled (thickOutlinedAndFilled green)
--
-- Option 3: record => create new `Style` record
--
thinOutlinedAndFilled fillColor =
{ fill = uniform fillColor, line = solid thin (uniform black) }
thickOutlinedAndFilled fillColor =
let
old =
thinOutlinedAndFilled fillColor
-- Elm doesn't accept an expression before the bar in records...
old_line =
old.line
in
{ old | line = {old_line | thickness = thick} }
triangle 30
|> styled (thickOutlinedAndFilled green)
I'm not sure any more if using a type alias for a shape style consisting of a tuple or a record is a good idea. Probably good old currying and abstraction are indeed our biggest friends here!
This was brought up in #4.
As is done in Elm Graphics.
Is this needed? Otherwise we should remove Text.empty
.
(Was brought up in #4.)
When placing a hitbox around a shape, I use 'impose' to 'forget' the envelopes of the hitbox in further calculations:
impose hitbox shape
However, onClick messages on this shape do not work anymore, since hitbox is placed on top of it.
I would love to see a feature that works like 'impose', but keeps the the envelopes of the fore.
This will avoid a name clash with Collage.opposite
when imported unqualified.
I'm trying to implement an interactive collage that has a rectangular bounding rectangle, and a few elements on top of it.
Using the given mouse events, I could find the absolute Point
(relative to the client/page) of the events. Is it possible to get the mouse position relative to the origin of the bounding box instead? In other words, how to get the absolution position of the bounding box so that I can calculate the offset?
Thanks for the awesome library!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.