--- In svg-developers@yahoogroups.com, "ddailey" <[EMAIL PROTECTED]> wrote: > > (Apologies for the cross-posting but there are folks in each place who are not in both, and relevance might exist for folks in either place) > > I started wondering yesterday if I could make a color wheel. > > In the page at http://srufaculty.sru.edu/david.dailey/svg/newstuff/ rainbow.svg > (You'll have to use either Opera or IE/ASV owing to the SMIL) > > I started with a simple rainbow and worked on through until I had a spectal doughnut (which was sort of what I wanted), but I encountered several problems on route that I thought might be interesting to discuss. The problems (with labels) are discussed a bit in the document above, but some additional explanation seems appropriate: > > A. The basic spectrum itself is just a gradient with six stops (at RYGCB and M). Interpolation between any pair of those stops, I reasoned would avoid the boundaries of the nonlinearlity in RGB - HSB space. It is, accordingly, conjectured that fewer than six stops in the gradient will not produce a rainbow without leaving out certain values of hue. > > This plot is sufficient to drive a real-estate conserving color picker such as seen at http://srufaculty.sru.edu/david.dailey/svg/ rainbow.svg where the Hue plot is expanded as "fine tuning" below. HSB plots seem to work for humans better than RGB plots but the ones used by Photoshop and other apps take up too much room on screen. The natural question here arises that the plot is not balanced for the human perceiver, where equal distances in RGB space are not perceived as equal in perceptual space. What woud the natural generalization to something like CIEXYZ be? > > B. The stops used (with SMIL animation) in the animation below have been manually copied and pasted. The <use> element only allows graphics elements, groups, other uses and svg's, but oftentimes it would be nice to be able to reuse parts of filters, gradients and the like. With all the examples on the above page that re-copy several flocks of <stop>s does anyone see a way, short of script, to save on the keystrokes and file size? -
Look into documentation on XML. To write something once and use it multiple times in a document you can define entities in an internal subset in a document type declaration. Another option would be XSLT. A gradient can also reuse the stops of another gradient by giving it an xlink:href attribute referencing the other gradient. > > C. The animation of the second rainbow consists of six separate animations which (like addition modulo 6) roll colors in synchrony across the six stops. The animation is not, however smooth. The topic is quite reminiscent of the discussion of cylindrical rotation at http://srufaculty.sru.edu/david.dailey/svg/SVGOpen2008/ edges_of_plausibility.htm . Is there a way to make that rolling smooth? Does it also not seem rather wasteful of markup to have to create six separate <animate> tags each with six values inside to accomplish a relatively simple thing? - You could animate the gradient's x1 and x2 values, and set spreadMethod to "repeat". > > D. The smooth looking animation just uses a trick: make two cycles of the entire spectrum (12 stops in a gradient); make a rectangle twice the size of the view-window (defined by a clipPath) to which the 12-stop gradient is applied, and then drag the rectangle through the clipPath using SMIL. It works, but it seems so troublingly inelegant. - See my comment on C. > > E. An obvious approach to making a color wheel would be to use a radial gradient rather than a linear one. (Again it would be nice to be able to reuse all those stops defined in the linear gradient along with the embedded animations since the only difference is that we're changing the container (the gradient) of those stops.) The hassle is that the color bands emanate outward from the center of the gradient. (I'm reminded of the radial blur in Photoshop that allows directionality to either be "spin" or "zoom" -- wouldn't it be nice to just have a flag on our radial gradients that converts the layout from spin (the default) to zoom (in which the stops would be layed out radially rather than concentrically)? - A lot of drawing applications can create this kind of gradient, but it's not included in SVG yet. It's such a basic feature that I'm sure it will be added to a future version of the SVG specification, but for now I don't see an elegant way to emulate it. > > Anyway, I first decided to experiment with making a circle with a hole in it. The first approach just created two half circular arc segments (using the "a" subcommand of "d" in <path>. Stick those two things together and fill each with an animated radial gradient -- rather fun! > > F. It was troubling to think that I might need to glue multiple shapes together to accomplish what I wanted, so I first drew a single path (using multiple M subcommands) just to remind myself that I could do it that way. I have been troubled for some time that > 1) it appears that to draw a single path with a hole in it one needs to define a clipPath like so: > <clipPath id="CP"> > <path d="M 180 300 A 120 40 0 1 1 180 301 M 258 294 A 45 15 0 1 1 258 295" clip-rule="evenodd"/> > </clipPath> > and apply that to the region that has been painted by the gradient, rather than to just paint the above path with a fill. Am I right about that? How troubling, if so. - You don't need a clip path. You can use the path and apply the fill. But you have to either use different sweep flags for the outer and inner subpaths, or use fill-rule="evenodd" > 2. in the above path, it seems that in order to get a region with a hole in it, the coordinates 258,294 and 258, 295, for example, cannot be the same -- some small difference must be declared. The problem, of course with that is that zooming in will reveal a small rectangularity in our otherwise curvilinear world. - For an elliptic arc with equal start and end points the center point would not be well defined. But to draw a full ellipse you can break it up into at least two path segments: <path d="M 180 300 a 120 40 0 1 1 240 0 a 120 40 0 0 1 -240 0 z M 258 294 a 45 15 0 1 0 90 0 a 45 15 0 0 0 -90 0 z" fill-rule="evenodd"/> > > G. Abandoning hope that a gradient will be found to fill the doughnut of F2 with a rainbow, I just went ahead and carved six little bites of a doughnut (each 60 degrees wide). I only had to build one, but then I had to rotate and reposition it. The hassle with doing this through markup is that one has to do the trig in one's head. The hassle with doing it with script is that one has to use script. I went ahead and filled it with the radial gradient since it looks a bit like Venetian glass. > > H. Finally, I just used six custom made linear gradients to apply to each of the six doughnut bites. A lot of work for a color wheel, and as you can see, the edges are not very smooth. - This could be improved on by using more than six fragments. Javascript could be used to subdivide the ring until either the user agent's screen resolution or color depth would make it impossible to see further divisions. > > Can anyone think of a better approach? - I can think of one other approach, but I don't think it is a better one. You could use six slices in the colors red, yellow, green, cyan, blue, and magenta, and then apply a feGaussianBlur to smooth the color wheel out. But since the blur operates in cartesian coordinates, the angular blur would be stronger at the inner edge than at the outer, so this doesn't create a perfect color wheel either, and filters are resource-intensive and a bit much for such a simple task. > > Q. The questions are embedded in the letters next to each topic. I used script to append strings into new <text> elements cloned from the letters themselves. Might there be an easier way to provide context sensitive explanations? - There are the title and desc elements. But as far as my knowledge goes, not even one SVG user agent makes the content of desc elements accessible, except by viewing the whole source code, and not all user agents show the content of title elements as tooltip on mouseover. You could use a CSS stylesheet with *.tooltip { visibility:hidden; } g:hover > *.tooltip { visibility:visible; } The explanations would be put into groups of class "tooltip" which are put into one group with the elements they provide information about. On mouseover the tooltip appears. But with this method you can't put the tooltips on top of all other elements, because each tooltip has to be grouped with its base element. A better option is to use set elements to make the tooltips visible, when the base element is moused-over, but that doesn't work in firefox. With all these methods you don't have automatic positioning and line- wrapping, or an automatically sized background rectangle contrasting with the text color. For a nice and easy solution one might write a script which automatically fetches all title and desc elements, and creates an interface for viewing them. This would of course only be easy after the script was written, but then it could be reused whenever needed. > > cheers > David > > > > > > [Non-text portions of this message have been removed] > ------------------------------------ ----- To unsubscribe send a message to: [EMAIL PROTECTED] -or- visit http://groups.yahoo.com/group/svg-developers and click "edit my membership" ----Yahoo! Groups Links <*> To visit your group on the web, go to: http://groups.yahoo.com/group/svg-developers/ <*> Your email settings: Individual Email | Traditional <*> To change settings online go to: http://groups.yahoo.com/group/svg-developers/join (Yahoo! ID required) <*> To change settings via email: mailto:[EMAIL PROTECTED] mailto:[EMAIL PROTECTED] <*> To unsubscribe from this group, send an email to: [EMAIL PROTECTED] <*> Your use of Yahoo! Groups is subject to: http://docs.yahoo.com/info/terms/