# lojjic/PIE

Fix for issue #64: Prevent rounding in BgPosition calculation and add…

`… special-case logic for perfectly horizontal/vertical angles to prevent them from getting slightly off.`
1 parent 04ed5d5 commit c5352d16e0ce4ee69c1def1cb08dfbe455c58cdc Jason Johnston committed Sep 3, 2010
Showing with 43 additions and 13 deletions.
1. +15 −7 sources/BackgroundRenderer.js
2. +9 −5 sources/BgPosition.js
 @@ -156,8 +156,8 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( { // Positioning - find the pixel offset from the top/left and convert to a ratio // The position is shifted by half a pixel, to adjust for the half-pixel coordorigin shift which is // needed to fix antialiasing but makes the bg image fuzzy. - pxX = bgPos.x + bwL + 0.5; - pxY = bgPos.y + bwT + 0.5; + pxX = Math.round( bgPos.x ) + bwL + 0.5; + pxY = Math.round( bgPos.y ) + bwT + 0.5; fill.position = ( pxX / elW ) + ',' + ( pxY / elH ); // Repeating - clip the image shape @@ -192,6 +192,7 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( { stops = info.stops, stopCount = stops.length, PI = Math.PI, + UNDEF, startX, startY, endX, endY, startCornerX, startCornerY, @@ -247,7 +248,7 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( { // Normalize the angle to a value between [0, 360) function normalizeAngle() { - if( angle < 0 ) { + while( angle < 0 ) { angle += 360; } angle = angle % 360; @@ -301,8 +302,14 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( { deltaX = endX - startX; deltaY = endY - startY; - if( angle === undefined ) { - angle = -Math.atan2( deltaY, deltaX ) / PI * 180; + if( angle === UNDEF ) { + // Get the angle based on the change in x/y from start to end point. Checks first for horizontal + // or vertical angles so they get exact whole numbers rather than what atan2 gives. + angle = ( !deltaX ? ( deltaY < 0 ? 90 : 270 ) : + ( !deltaY ? ( deltaX < 0 ? 180 : 0 ) : + -Math.atan2( deltaY, deltaX ) / PI * 180 + ) + ); normalizeAngle(); findCorners(); } @@ -313,8 +320,9 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( { // drawn diagonally from one corner to its opposite corner, which will only appear to the // viewer as 45 degrees if the shape is equilateral. We adjust for this by taking the x/y deltas // between the start and end points, multiply one of them by the shape's aspect ratio, - // and get their arctangent, resulting in an appropriate VML angle. - vmlAngle = Math.atan2( deltaX * w / h, deltaY ) / PI * 180; + // and get their arctangent, resulting in an appropriate VML angle. If the angle is perfectly + // horizontal or vertical then we don't need to do this conversion. + vmlAngle = ( angle % 90 ) ? Math.atan2( deltaX * w / h, deltaY ) / PI * 180 : ( angle + 90 ); // VML angles are 180 degrees offset from CSS angles vmlAngle += 180;
 @@ -4,6 +4,10 @@ * @param {Array.} tokens The tokens making up the background position value. */ PIE.BgPosition = (function() { + + var length_fifty = new PIE.Length( '50%' ); + + function BgPosition( tokens ) { this.tokens = tokens; } @@ -21,7 +25,6 @@ PIE.BgPosition = (function() { var tokens = this.tokens, len = tokens.length, length_zero = PIE.Length.ZERO, - length_fifty = new PIE.Length( '50%' ), type_ident = PIE.Tokenizer.Type.IDENT, type_length = PIE.Tokenizer.Type.LENGTH, type_percent = PIE.Tokenizer.Type.PERCENT, @@ -76,7 +79,8 @@ PIE.BgPosition = (function() { }, /** - * Find the coordinates of the background image from the upper-left corner of the background area + * Find the coordinates of the background image from the upper-left corner of the background area. + * Note that these coordinate values are not rounded. * @param {Element} el * @param {number} width - the width for percentages (background area width minus image width) * @param {number} height - the height for percentages (background area height minus image height) @@ -88,11 +92,11 @@ PIE.BgPosition = (function() { pxY = vals[3].pixels( el, height ); return { - x: Math.round( vals[0] === 'right' ? width - pxX : pxX ), - y: Math.round( vals[2] === 'bottom' ? height - pxY : pxY ) + x: vals[0] === 'right' ? width - pxX : pxX, + y: vals[2] === 'bottom' ? height - pxY : pxY }; } }; return BgPosition; -})(); +})();
 @@ -13,6 +13,7 @@ overflow: hidden; background:url(border.png); position: relative; + z-index: 0; zoom: 1; } @@ -167,7 +168,18 @@ -pie-background: linear-gradient(45deg, red, yellow, green, blue); } - + #lineup p { + border: 0; + width: 40%; + height: 50px; + margin-right: 0; + border-radius: 0; + background: -moz-linear-gradient(center bottom,rgb(170,222,249) 0%,rgb(63,158,210) 100%); + -pie-background: linear-gradient(center bottom,rgb(170,222,249) 0%,rgb(63,158,210) 100%); + } + #lineup2 { + margin-left: 0; + } @@ -215,5 +227,11 @@

Multiple color stops along linear gradient

+
+

Lining up (issue 64)

+

element 1

+

element 2

+
+