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

Added radial-gradient incl svg and canvas #12

Closed
wants to merge 3 commits into from
Closed

Added radial-gradient incl svg and canvas #12

wants to merge 3 commits into from

Conversation

superstructor
Copy link
Contributor

This is an experimental first attempt at radial gradient support. Please don't merge this as it is far from ready. Just if you have some time would be happy to receive any feedback or ideas on the general concept, syntax of the radial-gradient function etc =)

Before being merged I expect to do a lot of refactoring and bug fixes. I'm still learning Stylus so sorry if some of the code is a bit of a mess.

For the radial-gradient function I'm aiming to be as close to w3c syntax as reasonably possible.

It generates four main types of radial gradients as output

  • w3c aka the -vendor-radial-gradient(...) style e.g. mozilla / chrome > 10 / ie10 / safari 6
  • old webkit aka the -webkit-gradient(radial, ...) style e.g. safari 5 incl ipad/iphone / chrome < 10
  • canvas e.g. ie5.5-8
  • svg e.g. ie9 / opera

Generally it works as a proof of concept, but no two types look exactly the same yet for simple cases, and can look wildly different for more complex cases.

For the simple case of radial-gradient(green, yellow):

w3c and svg is easy.

For old webkit and canvas you need to know the intended radius of the circle in pixels.

I've tried the syntax radial-gradient(green, yellow 30px) where a final color stop with a pixel offset to also taken to be the radius. This is what compass appears to do. It works OK for the simple cases except may be confusing as in pure CSS radial-gradient(green, yellow 30px) is not the same as radial-gradient(green, yellow 100%) applied to a box 30px by 30px in any browser I tested.

After trying the final color stop as radius solution I'm not sure its the best way. Maybe simply using the w3c syntax "size/shape" optional argument to determine the radius e.g. radial-gradient(position, size/shape, stops...) instead would be better.

For canvas where you have a radius smaller than the containing box but not the boxes dimensions simply generating an image the size of the radius then setting the boxs background-color to the final color stop color to fill the remaining space works OK. I think a similar technique could also work for an alternative linear gradient syntax ?

Things get more interesting with elliptical shapes or implicit sizing (e.g. "farthest side", "closest corner") support.

Explicitly sized elliptical shapes should be easy enough to draw with canvas and possibly SVG, but I havn't tried yet.

Implicitly sized elliptical shapes, or circles obviously require knowledge of the size of the containing box which is a difficult problem.

For boxes that the browser determines the size of I don't think it is possible as e.g. dynamic content could change the size of the box on every page.

For boxes that have an explicit size defined at some level in the stylus is it possible to traverse the stylus parse tree to find the closest ancestor width and height properties ?

Otherwise what do you think of an additional argument to the radial-gradient function to specify the size of the box in cases where implicit sizing is used ? This means radial-gradient(green, yellow) would not generate an image unless you specified the size of the box. I'm not sure what that would look like yet. Radius could be optionally explicitly defined as well or calculated from the box size.

Lastly is it possible to pass stylus tuples as arguments to JS functions and access all the values ? When I tried doing that and had a look with node-inspector it appeared as if I only had access to the first value.

Thanks for the awesome foundation you've built with Stylus and Nib. I'm really enjoying the power of this language.

Cheers
Isaac

@tj
Copy link
Collaborator

tj commented May 15, 2011

cool man, I'll have to take a closer look and review it soon

@superstructor
Copy link
Contributor Author

I'm thinking a syntax based on w3c with the addition of a box size to the radius size argument with final fallback to final color stop.

So it would look like
radial-gradient(posX posY, radiusX radiusY boxX boxY, stops...) or the alternative
radial-gradient(posX posY, shape sizing boxX boxY, stops...)

Of course many of the arguments are optional and there are many variations of those two.

I've started writing a normalize-radial-gradient function that will process the arguments and calculate the box / radius / background position as best as possible with the available information. Its broken at the moment. I hope to get my branch back to generating images again with more test cases in the next few days when I have time. I'm hopeful that with the new approach and having more sizing info I'll be able to coax most outputs into looking very similar for many cases.

Cheers
Isaac

@flying-sheep
Copy link

soo, what’s keeping you? I’d love to npm install nib@0.2.0 with radial gradients

svg += '<rect x="0" y="0" width="100%" height="100%" fill="url(#grad)" />'
svg += '</svg>'

'url(%s)' % gradient-data-uri-svg(svg)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exposed method

gradient-data-uri-svg

is a really good idea, although I would just make it _data-uri-svg_ as it can take any SVG file, not just gradients. I like the idea of being able to write SVG in my stylus files for specific use cases to my design to generate a data URI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I agree some kind of generalized SVG support would be nice.

SVG could be used for lots of things, like icons, border images, list style images, even logos etc obviously.

Composing short SVGs in stylus could be handy, it might be nice if we could avoid writing the doctype boilerplate per call.

I think stylus might already natively supporting in-lining external SVG files. It might also be a nice feature in nib to be able to inline Jade files automatically compiled to SVG data URIs with the ability to pass view variables from stylus.

@superstructor
Copy link
Contributor Author

soo, what’s keeping you? I’d love to npm install nib@0.2.0 with radial gradients

I look forward to it too =)

What I still need to complete to have this considered for merging:

  • simple gradients look mostly the same already, but the radius is slightly larger than it should be on the PNG rendering
  • complex gradients can look quite different between CSS, PNG and SVG e.g.
 radial-gradient(40% 40%, circle closest-side, green, yellow 150px)
 radial-gradient(60% 60%, circle contain, yellow, green 75%, rgba(255,255,255,0) 150px)
 radial-gradient(center, 80px 40px, white, black 150px)

@elf-pavlik
Copy link

any progress on this one by any chance? =)

  • bump

@superstructor
Copy link
Contributor Author

It would be ideal to have #33 merged first, then I'll rebase, re-write on top of it, clean it up, add some tests and squash all my commits into one so its a clean diff.

@mhemesath
Copy link

@superstructor Let me know if there are any changes you want me to make to that pull request. It's been a while, so I'm sure a fresh perspective will bring something up.

@superstructor
Copy link
Contributor Author

Will re-write SVG/canvas radial support based on #94, which will implement pure CSS3 radial gradients, when it is merged.

@mizzao
Copy link

mizzao commented Oct 14, 2013

I'm confused at the state of this issue. Does nib currently have a radial-gradient mixin or not? Getting a weird output when trying to use it.

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

Successfully merging this pull request may close these issues.

None yet

7 participants