Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refinements to text-shadow blur algorithm to better match browsers ac…

…ross range of blur radii. Set width of each text-shadow to prevent wrapping/alignment issues. Adjust for the element's border-width when positioning shadows.
  • Loading branch information...
commit 7f4922cdc7440f42ada6c94c4d089526e7927239 1 parent bc3a28f
Jason Johnston authored
Showing with 55 additions and 25 deletions.
  1. +45 −16 sources/TextShadowRenderer.js
  2. +10 −9 tests/text-shadow-tests.html
View
61 sources/TextShadowRenderer.js
@@ -9,7 +9,7 @@ PIE.TextShadowRenderer = PIE.RendererBase.newRenderer( {
boxZIndex: 7,
boxName: 'text-shadow',
- textStyles: [ 'fontSize', 'fontFamily', 'fontStyle', 'fontWeight', 'letterSpacing', 'lineHeight', 'textDecoration' ],
+ textStyles: [ 'fontSize', 'fontFamily', 'fontStyle', 'fontWeight', 'letterSpacing', 'lineHeight', 'textDecoration', 'textAlign' ],
needsUpdate: function() {
return this.styleInfos.textShadowInfo.changed();
@@ -25,40 +25,69 @@ PIE.TextShadowRenderer = PIE.RendererBase.newRenderer( {
var el = this.targetElement,
currentStyle = el.currentStyle,
box = this.getBox(),
- shadowProps = this.styleInfos.textShadowInfo.getProps(),
+ si = this.styleInfos,
+ shadowProps = si.textShadowInfo.getProps(),
i = shadowProps.length,
textStyles = this.textStyles,
getLength = PIE.getLength,
+ bounds = this.boundsInfo.getBounds(),
+ borderProps = si.borderInfo.getProps(),
+ borderWidths = borderProps && borderProps.widths,
+ borderTopWidth = borderWidths ? borderWidths['t'].pixels( el ) : 0,
+ borderLeftWidth = borderWidths ? borderWidths['l'].pixels( el ) : 0,
filterPrefix = 'progid:DXImageTransform.Microsoft.',
- props, shadowEl, shadowStyle, color, blur, glow, j;
+ math = Math,
+ round = math.round,
+ props, shadowEl, shadowStyle, color, blur, blurLog, glow, opacity, j;
- box.style.width = this.boundsInfo.getBounds().w;
box.innerHTML = '';
while( i-- ) {
props = shadowProps[ i ];
- shadowEl = doc.createElement( 'span' );
+ shadowEl = doc.createElement( 'shadow' );
+ shadowStyle = shadowEl.style;
color = props.color;
blur = props.blur.pixels( el );
- glow = blur > 3 ? ( Math.ceil( blur / 4 ) ) : 0;
- shadowStyle = shadowEl.style;
+ if ( blur ) {
+ blurLog = math.log( blur );
+
+ // Decrease the blur size to line up more closely with other browsers
+ if ( blur > 2 ) {
+ blur -= .75 + blur / 4;
+ }
+ else if ( blur > 1 ) {
+ blur = 1.5;
+ }
+
+ // For blurs over a threshold we must add a small amount of glow before blurring
+ // to keep the color from getting washed out.
+ glow = blur > 8 ? blurLog : 0;
+
+ // Calculate opacity; all blurs are adjusted down to a baseline and then multiplied
+ // by the alpha value from the specified text-shadow color.
+ opacity = math.max( ( blur > 8 ? 55 - blurLog * 2 : 70 + blur * 2 ), 1 ) * color.alpha();
+
+ shadowStyle.filter = 'alpha(opacity=' + opacity + ') ' +
+ ( glow ? filterPrefix + 'Glow(Strength=' + glow + ',Color=' + color.hexValue( el ) + ') ' : '' ) +
+ filterPrefix + 'Blur(PixelRadius=' + ( blur - glow ) + ',MakeShadow=false)';
+ }
+
shadowStyle.position = 'absolute';
- shadowStyle.left = props.xOffset.pixels( el ) - blur + getLength( currentStyle.paddingLeft ).pixels( el );
- shadowStyle.top = props.yOffset.pixels( el ) - blur + getLength( currentStyle.paddingTop ).pixels( el );
+ shadowStyle.left = props.xOffset.pixels( el ) - round(blur) + borderLeftWidth +
+ getLength( currentStyle.paddingLeft ).pixels( el );
+ shadowStyle.top = props.yOffset.pixels( el ) - round(blur) + borderTopWidth +
+ getLength( currentStyle.paddingTop ).pixels( el );
+ shadowStyle.width = bounds.w;
+ shadowStyle.height = bounds.h;
+ // Copy the original text's styles to the shadow element
j = textStyles.length;
while( j-- ) {
shadowStyle[ textStyles[ j ] ] = currentStyle[ textStyles[ j ] ];
}
- shadowStyle.color = color.colorValue( el );
-
- if ( blur ) {
- shadowStyle.filter = 'alpha(opacity=' + Math.max( 75 - ( blur * 2 ), 10 ) * color.alpha() + ') ' +
- (glow ? filterPrefix + 'Glow(Strength=' + ( glow ) + ', Color=' + color.hexValue( el ) + ') ' : '') +
- filterPrefix + 'Blur(PixelRadius=' + ( blur - glow ) + ', MakeShadow=false)';
- }
+ shadowStyle.color = color.colorValue( el );
shadowEl.innerText = el.innerText;
box.appendChild( shadowEl );
}
View
19 tests/text-shadow-tests.html
@@ -17,7 +17,7 @@
padding: .5em;
margin: .25em;
font-size: 20px;
- /*border-radius: 3px;*/
+ border-radius: 3px;
behavior: url(../build/PIE_uncompressed.htc);
}
#w3c1 {background: #CCF; color: blue; text-shadow: #333 0.1em 0.1em}
@@ -62,17 +62,18 @@
<script type="text/javascript">
- for(var i=1; i<10; i++) {
- document.write('<div class="tester" style="text-shadow: 4px 4px ' + i + 'px #000">Text shadow blur radius ' + i + '</div>')
+ var n = 25;
+ for(var i=1; i<n; i++) {
+ document.write('<div class="tester" style="height: 25px; text-shadow: 4px 4px ' + i + 'px #000">Text shadow blur radius ' + i + '</div>')
}
- for(var i=1; i<10; i++) {
- document.write('<div class="tester" style="text-shadow: 0 0 ' + i + 'px #F00">Text shadow blur radius ' + i + '</div>')
+ for(var i=1; i<n; i++) {
+ document.write('<div class="tester" style="height: 25px; text-shadow: 4px 4px ' + i + 'px #F00">Text shadow blur radius ' + i + '</div>')
}
- for(var i=1; i<10; i++) {
- document.write('<div class="tester" style="text-shadow: 0 0 ' + i + 'px #00F">Text shadow blur radius ' + i + '</div>')
+ for(var i=1; i<n; i++) {
+ document.write('<div class="tester" style="height: 25px; text-shadow: 0 0 ' + i + 'px #00F">Text shadow blur radius ' + i + '</div>')
}
- for(var i=1; i<10; i++) {
- document.write('<div class="tester" style="text-shadow: 0 0 ' + i + 'px #0F0">Text shadow blur radius ' + i + '</div>')
+ for(var i=1; i<n; i++) {
+ document.write('<div class="tester" style="height: 25px; text-shadow: 0 0 ' + i + 'px #0F0">Text shadow blur radius ' + i + '</div>')
}
</script>
Please sign in to comment.
Something went wrong with that request. Please try again.