What is the precise explanation of box-shadow and -moz-box-shadow in CSS? - shadow

I find the explanations of CSS's box-shadow and -moz-box-shadown somewhat imprecise.
http://www.w3.org/TR/2010/WD-css3-background-20100612/#the-box-shadow
The third length is a blur distance.
Negative values are not allowed. If
the blur value is zero, the shadow's
edge is sharp. Otherwise, the larger
the value, the more the shadow's edge
is blurred.
The fourth
length is a spread distance. Positive
values cause the shadow shape to
expand in all directions by the
specified radius. Negative values
cause the shadow shape to contract.
Is it true that the fourth length will use the same color (the darkest shade), and repeat that for the specified width? So it won't be smoothly blurring out?
Can it achieving specifying the rate of blurring or the rate of fading out...?
Does someone know very precisely how they exactly work?

Well, imagine that the box shadow starts as a box, the same size as the content, of the specified shadow colour (say black for argument's sake).
This box starts life the same size and shape as the content, and right behind it - so, essentially, invisible.
The two distance values will shift it up, down, left or right - so that it will "peek" out from behind the content. At this point, it will still be a box of the same size as its content, and will have sharp edges.
The spread value will cause this box to expand by the specified amount - so it will be bigger or smaller than its content box. Visually, the higher the spread, the further "back" the shadow appears (it gives the illusion that the box is a long way away from the surface that it's casting its shadow on).
The blur value simply causes the edges to blur smoothly into the background, fading from the shadow colour to the background colour.
HTH

I'm not a web/CSS programmer, but I needed a box-shadow algorithm that looked like CSS's, and decided to find out how it works.
I used CSSmatic's online box-shadow tool for the comparisons below.
The algorithm seems to have 2 steps.
Step 1: Vectorized scale and shift
As shown, a 27px CSS spread inset means the shape is scaled to have dimensions 27*2 pixels smaller. This is inverted for outline box-shadows (e.g. 27*2 pixels larger).
The horizontal/vertical offsets are self-explanatory.
Step 2: Gaussian blur
History
Mozilla developer David Baron wrote a detailed article on CSS box-shadow implementations here.
Up until 2011, there was no standard meaning for the CSS blur radius. It could correspond to different algorithms and parameters in different web browsers:
Different browsers ... have historically done different things
for the same blur radius, both in terms of blurring algorithm and what
the radius means for that algorithm (i.e., how blurry a given radius
makes things). .... Over the past year, the CSS and HTML specifications
have changed (for CSS) to define what this blur radius means or (for
HTML) so that they agree with each other on this definition.
Those historic differences could explain the purpose of the moz- prefix (which you mentioned) and webkit- prefix. These likely specify alternative box-shadow parameters for Mozilla and WebKit-based browsers to use.
I expect these prefixed versions are now deprecated, due to standardization, but may be used for compatibility with older browsers.
Standardization
According to Baron there is now a precise, standard definition of the box-shadow blur radius:
The blur effect is now defined by css3-background and by HTML to be a
Gaussian blur with the standard deviation (σ) equal to half the given blur radius, with allowance for reasonable approximation error.
A mathematician could expand that into an exact formula.
Visual approximation
With some trial-and-error in GIMP, I found that a Gaussian blur radius obtained by multiplying the CSS blur parameter by 5/3 (1.6666...), then rounding up to the nearest integer, produces a very close visual approximation (to CSS in Firefox 50):
7px CSS blur (Firefox 50) ~~ ceil(7 * 5/3.0) = 12.0 Gaussian radius in GIMP
30px CSS blur (Firefox 50) ~~ ceil(30 * 5/3.0) = 50.0 Gaussian radius in GIMP
75px CSS blur (Firefox 50) ~~ ceil(75 * 5/3.0) = 125.0 Gaussian radius in GIMP
Implementation
Ivan Kuckir shares some fast Gaussian blur algorithms.

Related

How can I prevent CSS background-colour "bleed" around my SVG images?

I have an SVG file which I display white normally, or red when the user hovers over it. This is made by having transparent areas of the image and using the following CSS & HTML:
a>img{background:#fff;width:32px;height:32px}
a:hover>img{background:#900}
<img src="blah.svg">
The problem is that I sporadically get very thin borders of white (or red) around the image. Different browsers/zoom levels/devices show different borders - sometimes none, sometimes some, sometimes all of them.
This would appear to suggest that the SVG file isn't quite "filling" the img tag.
I might assume that the problem is that the SVG isn't quite square, so it's not stretching perfectly to 32x32 pixels, but sometimes I get borders on all four sides, so it can't be that simple. (And indeed the SVG file has a viewbox of "0 0 195 195" and doesn't appear to have any points outside of that range.
It's worth noting that changing the dimensions to 39x39 pixels (a perfect divisor of 195) doesn't fix the issue, not that I expected it to, due to the vector nature of SVG.
Fiddle: http://jsfiddle.net/3wtazst8/1/
Any suggestions?
Thanks
I know this is over a year old, but I was having the same issue and considered Paul LeBeau's advice regarding extending outside the viewBox. Below is an example showing the issue and the fix.
Icons with background colors showing issue and showing fix
The badge icon does not show the bleed, while the medal icon does.
Side-by-side image of icons within viewBox and extended beyond viewBox
Viewing the left SVG in Illustrator, the background of the image goes to the very edge of the viewBox.
Viewing the right SVG in Illustrator, the background of the image extends beyond the edge of the viewBox.
Fixing your SVG so the background extends beyond viewBox will fix your issue.

Kinetic js canvas lines and shapes blurred at centre, but gets crisp when nearing the edges

Here is the plunkr
http://plnkr.co/edit/05OtTgW78wibGz57Lrao
When the viewport width variable is set to 1366.
In the plunkr when u move the cursor near the centre u will see the lines are almost gray and is blurred. But when moved near the edges it is crisp and black.
But in the same case when the viewport width is set to 1000 currently it is commented in plunkr. The lines are crisp at all the places, edges , centre.
This scenario applies to all drawing and not only the lines any thing i draw in the centre is bit dull while on the edges it is sharp at certain width of the stage.
Another issue here is eventhough i have specified the vertical lines as dashed it comes as as continuous lines, again this also depends on the viewport height mentioned.
Anyone has any insights on this???
To your second question...
Here's how to get your missing vertical dashed line:
Eliminate viewLinesVert entirely.
Eliminate context.closePath()
And your vertical line will become dashed.
BTW, Firefox doesn't yet support context.setLineDash, so your app fails in FF.
To your first question...
Your lines will become a bit clearer if you use context.lineWidth=1.0.
Yes, I did notice your vertical line becomes slightly blurred at certain positions.
In IE, the blur happens as the vertical line approaches the far right side.
In Chrome, the blur happens more towards the middle and occurs for a much larger area.
Quite frankly, I don't know why, but it's probably due to anti-aliasing of the dashes.
Yes, I did notice your horizontal line is [Ok | Blurred | OK | Blurred] as it moves.
That is definitely due to anti-aliasing of the horizontal line.
I also tried your code in the latest KineticJS version 4.7.2 and the blurs are still present.
However...
When I recreate your code in native canvas (not KineticJS), the blurring does not occur in either the vertical or horizontal line--except when the lines are moving (this is unrelated motion blur).
So.....
Detail your problem and submit a bug report:
https://github.com/ericdrowell/KineticJS/issues?direction=desc&sort=created&state=open
Its just because I used the floating point coordinate in stage width...
Got the answer from the kinetic js community.. thanks

Line Width in Canvas

Well, if I draw a line with an odd value of lineWidth in HTML5 Canvas I get a blurred line and I know the reason for this problem.
Now, I want to know the solutions to overcome this. I already know a solution for this and which i couldn't implement now. So, please comment on any other solution for this problem.
My Solution :
If you have to draw a line with an odd numbered width, then you will have to offset the center of your line by 0.5 up or down. That way rendering will happen at boundary of pixel and not in middle, and you will always have a sharp line with no residue at the end edges.
Let me know if any other solutions other than the above
Happily (and Sadly) you have correctly implemented "pixel-snapping" when you add/subtract .5 pixels to get your lines to align with pixel boundaries. Unlike Photoshop, there is no option to automatically pixel snap in canvas. ...I feel your pain!

Is there such a thing as fractional pixel?

I just started helping some work colleagues with some web design. Nothing major, but I have a problem with styled menu elements that are supposed to fill div area allocated and I noticed that whilst I can tweak width settings in ff by adding decimal points in them I noticed that in chromium, the gap between the last styled element and the div border is huge. I Checked the size and realised that chromium is showing the size(S) in rounded integer value. Anyone have any idea as to why this is?
There is no such thing as fractional pixel. Pixel is the smallest screen unit.
The thing you're experiencing happens because of the browsers math engines. Some of them round the decimal pixel part up to the next integer, and some of them floor it down.
To avoid that just define your pixels without decimal points. If you want to make the 2 elements visually closer you can play around with colors, for example - if you give a darker border to some elements they will seem to be closer - http://jsfiddle.net/fDbUj/

Generate random coordinates from area outside of a rectangle?

I'm working on a simple tutorial, and I'd like to randomly generate the positions of the red and green boxes in the accompanying images anywhere inside the dark gray area, but not in the white area. Are there any particularly elegant algorithms to do this? There are some hackish ideas I have that are really simple (continue to generate while the coordinates are not outside the inside rectangle, etc.), but I was wondering if anyone had come up with some neat solutions.
Thanks for any help!
Simplicity is a sort of elegance in its own right, so I agree with Jon: take a Monte Carlo approach and continue sampling until you get a valid value.
If you wanted to guarantee that you'd never place the red or green squares inside the white box, you could use the following simple algorithm:
Determine the height hS and width wS of the square you're placing.
Divide the gray area into 8 rectangular regions R = {R1, R2, ... R8}, defined by the white box. (Imagine a tic-tac-toe grid with the white box at the center; this defines the surrounding eight regions.)
Let P(S is placed in Ri) = A(Ri) / A(R), where A(Ri) is the area in which the center of S can be placed: that is, a region which is of area (hRi - hS) · (wRi - wS).
Select a region according to the above probabilities. Then select a point in that region from a uniform distribution of the available x- and y-coordinates.
Done!
I would personally go with the simple "keep sampling until you get a valid value" approach unless there's a chance that you'll have a very large white rectangle against a grey rectangle which isn't much bigger. To me, simpler is almost always better.
An alternative would be to work out how many possible pixels there will be, and generate a random number in that range. Then effectively number the pixels from top left to bottom right. Work out whether the given random sample is in the top section, the bottom section or the middle (which you can do by just seeing if it's less than the first pixel on the top line of the white rectangle, or less than the first pixel on the line below the white rectangle). Once you've worked that out, it's a simple matter of working out the row, then the pixel within the row. This isn't hugely hard, but it is pretty fiddly and easy to get wrong. Note that this is determining a single random pixel: as you're generating large squares, you should consider the range of valid pixels for the top left corner of the square, and find a sample in that range.