Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Factor out logic common to IE9 and IE<9 gradient renderers into a sha…

…red GradientUtil file, to decrease total code size
  • Loading branch information...
commit 43fc3ab93cd94664869d30960b477de01eca92af 1 parent 63f0285
Jason Johnston authored
View
1  build.xml
@@ -15,6 +15,7 @@
<concat destfile="${build_dir}/script_uncompressed.js">
<fileset file="${src_dir}/PIE_open.js" />
<fileset file="${src_dir}/Util.js" />
+ <fileset file="${src_dir}/GradientUtil.js" />
<fileset file="${src_dir}/Observable.js" />
<fileset file="${src_dir}/Heartbeat.js" />
<fileset file="${src_dir}/OnBeforeUnload.js" />
View
142 sources/BackgroundRenderer.js
@@ -175,134 +175,27 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( {
w = bounds.w,
h = bounds.h,
fill = shape.fill,
- angle = info.angle,
- startPos = info.gradientStart,
stops = info.stops,
stopCount = stops.length,
PI = Math.PI,
- UNDEF,
- startX, startY,
- endX, endY,
- startCornerX, startCornerY,
- endCornerX, endCornerY,
+ GradientUtil = PIE.GradientUtil,
+ perpendicularIntersect = GradientUtil.perpendicularIntersect,
+ distance = GradientUtil.distance,
+ metrics = GradientUtil.getGradientMetrics( el, bounds, info ),
+ angle = metrics.angle,
+ startX = metrics.startX,
+ startY = metrics.startY,
+ startCornerX = metrics.startCornerX,
+ startCornerY = metrics.startCornerY,
+ endCornerX = metrics.endCornerX,
+ endCornerY = metrics.endCornerY,
+ deltaX = metrics.deltaX,
+ deltaY = metrics.deltaY,
+ lineLength = metrics.lineLength,
vmlAngle, vmlGradientLength, vmlColors,
- deltaX, deltaY, lineLength,
stopPx, vmlOffsetPct,
p, i, j, before, after;
- /**
- * Find the point along a given line (defined by a starting point and an angle), at which
- * that line is intersected by a perpendicular line extending through another point.
- * @param x1 - x coord of the starting point
- * @param y1 - y coord of the starting point
- * @param angle - angle of the line extending from the starting point (in degrees)
- * @param x2 - x coord of point along the perpendicular line
- * @param y2 - y coord of point along the perpendicular line
- * @return [ x, y ]
- */
- function perpendicularIntersect( x1, y1, angle, x2, y2 ) {
- // Handle straight vertical and horizontal angles, for performance and to avoid
- // divide-by-zero errors.
- if( angle === 0 || angle === 180 ) {
- return [ x2, y1 ];
- }
- else if( angle === 90 || angle === 270 ) {
- return [ x1, y2 ];
- }
- else {
- // General approach: determine the Ax+By=C formula for each line (the slope of the second
- // line is the negative inverse of the first) and then solve for where both formulas have
- // the same x/y values.
- var a1 = Math.tan( -angle * PI / 180 ),
- c1 = a1 * x1 - y1,
- a2 = -1 / a1,
- c2 = a2 * x2 - y2,
- d = a2 - a1,
- endX = ( c2 - c1 ) / d,
- endY = ( a1 * c2 - a2 * c1 ) / d;
- return [ endX, endY ];
- }
- }
-
- // Find the "start" and "end" corners; these are the corners furthest along the gradient line.
- // This is used below to find the start/end positions of the CSS3 gradient-line, and also in finding
- // the total length of the VML rendered gradient-line corner to corner.
- function findCorners() {
- startCornerX = ( angle >= 90 && angle < 270 ) ? w : 0;
- startCornerY = angle < 180 ? h : 0;
- endCornerX = w - startCornerX;
- endCornerY = h - startCornerY;
- }
-
- // Normalize the angle to a value between [0, 360)
- function normalizeAngle() {
- while( angle < 0 ) {
- angle += 360;
- }
- angle = angle % 360;
- }
-
- // Find the distance between two points
- function distance( p1, p2 ) {
- var dx = p2[0] - p1[0],
- dy = p2[1] - p1[1];
- return Math.abs(
- dx === 0 ? dy :
- dy === 0 ? dx :
- Math.sqrt( dx * dx + dy * dy )
- );
- }
-
- // Find the start and end points of the gradient
- if( startPos ) {
- startPos = startPos.coords( el, w, h );
- startX = startPos.x;
- startY = startPos.y;
- }
- if( angle ) {
- angle = angle.degrees();
-
- normalizeAngle();
- findCorners();
-
- // If no start position was specified, then choose a corner as the starting point.
- if( !startPos ) {
- startX = startCornerX;
- startY = startCornerY;
- }
-
- // Find the end position by extending a perpendicular line from the gradient-line which
- // intersects the corner opposite from the starting corner.
- p = perpendicularIntersect( startX, startY, angle, endCornerX, endCornerY );
- endX = p[0];
- endY = p[1];
- }
- else if( startPos ) {
- // Start position but no angle specified: find the end point by rotating 180deg around the center
- endX = w - startX;
- endY = h - startY;
- }
- else {
- // Neither position nor angle specified; create vertical gradient from top to bottom
- startX = startY = endX = 0;
- endY = h;
- }
- deltaX = endX - startX;
- deltaY = endY - startY;
-
- 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();
- }
-
-
// In VML land, the angle of the rendered gradient depends on the aspect ratio of the shape's
// bounding box; for example specifying a 45 deg angle actually results in a gradient
// drawn diagonally from one corner to its opposite corner, which will only appear to the
@@ -320,10 +213,11 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( {
// For each, we find its pixel offset along the gradient-line; if the offset of a stop is less
// than that of its predecessor we increase it to be equal. We then map that pixel offset to a
// percentage along the VML gradient-line, which runs from shape corner to corner.
- lineLength = distance( [ startX, startY ], [ endX, endY ] );
- vmlGradientLength = distance( [ startCornerX, startCornerY ], perpendicularIntersect( startCornerX, startCornerY, angle, endCornerX, endCornerY ) );
+ p = perpendicularIntersect( startCornerX, startCornerY, angle, endCornerX, endCornerY );
+ vmlGradientLength = distance( startCornerX, startCornerY, p[0], p[1] );
vmlColors = [];
- vmlOffsetPct = distance( [ startX, startY ], perpendicularIntersect( startX, startY, angle, startCornerX, startCornerY ) ) / vmlGradientLength * 100;
+ p = perpendicularIntersect( startX, startY, angle, startCornerX, startCornerY );
+ vmlOffsetPct = distance( startX, startY, p[0], p[1] ) / vmlGradientLength * 100;
// Find the pixel offsets along the CSS3 gradient-line for each stop.
stopPx = [];
View
153 sources/GradientUtil.js
@@ -0,0 +1,153 @@
+/**
+ * Utility functions for handling gradients
+ */
+PIE.GradientUtil = {
+
+ getGradientMetrics: function( el, bounds, gradientInfo ) {
+ var w = bounds.w,
+ h = bounds.h,
+ angle = gradientInfo.angle,
+ startPos = gradientInfo.gradientStart,
+ startX, startY,
+ endX, endY,
+ startCornerX, startCornerY,
+ endCornerX, endCornerY,
+ deltaX, deltaY,
+ p, UNDEF;
+
+ // Find the "start" and "end" corners; these are the corners furthest along the gradient line.
+ // This is used below to find the start/end positions of the CSS3 gradient-line, and also in finding
+ // the total length of the VML rendered gradient-line corner to corner.
+ function findCorners() {
+ startCornerX = ( angle >= 90 && angle < 270 ) ? w : 0;
+ startCornerY = angle < 180 ? h : 0;
+ endCornerX = w - startCornerX;
+ endCornerY = h - startCornerY;
+ }
+
+ // Normalize the angle to a value between [0, 360)
+ function normalizeAngle() {
+ while( angle < 0 ) {
+ angle += 360;
+ }
+ angle = angle % 360;
+ }
+
+ // Find the start and end points of the gradient
+ if( startPos ) {
+ startPos = startPos.coords( el, w, h );
+ startX = startPos.x;
+ startY = startPos.y;
+ }
+ if( angle ) {
+ angle = angle.degrees();
+
+ normalizeAngle();
+ findCorners();
+
+ // If no start position was specified, then choose a corner as the starting point.
+ if( !startPos ) {
+ startX = startCornerX;
+ startY = startCornerY;
+ }
+
+ // Find the end position by extending a perpendicular line from the gradient-line which
+ // intersects the corner opposite from the starting corner.
+ p = PIE.GradientUtil.perpendicularIntersect( startX, startY, angle, endCornerX, endCornerY );
+ endX = p[0];
+ endY = p[1];
+ }
+ else if( startPos ) {
+ // Start position but no angle specified: find the end point by rotating 180deg around the center
+ endX = w - startX;
+ endY = h - startY;
+ }
+ else {
+ // Neither position nor angle specified; create vertical gradient from top to bottom
+ startX = startY = endX = 0;
+ endY = h;
+ }
+ deltaX = endX - startX;
+ deltaY = endY - startY;
+
+ 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 ) / Math.PI * 180
+ )
+ );
+ normalizeAngle();
+ findCorners();
+ }
+
+ return {
+ angle: angle,
+ startX: startX,
+ startY: startY,
+ endX: endX,
+ endY: endY,
+ startCornerX: startCornerX,
+ startCornerY: startCornerY,
+ endCornerX: endCornerX,
+ endCornerY: endCornerY,
+ deltaX: deltaX,
+ deltaY: deltaY,
+ lineLength: PIE.GradientUtil.distance( startX, startY, endX, endY )
+ }
+ },
+
+ /**
+ * Find the point along a given line (defined by a starting point and an angle), at which
+ * that line is intersected by a perpendicular line extending through another point.
+ * @param x1 - x coord of the starting point
+ * @param y1 - y coord of the starting point
+ * @param angle - angle of the line extending from the starting point (in degrees)
+ * @param x2 - x coord of point along the perpendicular line
+ * @param y2 - y coord of point along the perpendicular line
+ * @return [ x, y ]
+ */
+ perpendicularIntersect: function( x1, y1, angle, x2, y2 ) {
+ // Handle straight vertical and horizontal angles, for performance and to avoid
+ // divide-by-zero errors.
+ if( angle === 0 || angle === 180 ) {
+ return [ x2, y1 ];
+ }
+ else if( angle === 90 || angle === 270 ) {
+ return [ x1, y2 ];
+ }
+ else {
+ // General approach: determine the Ax+By=C formula for each line (the slope of the second
+ // line is the negative inverse of the first) and then solve for where both formulas have
+ // the same x/y values.
+ var a1 = Math.tan( -angle * Math.PI / 180 ),
+ c1 = a1 * x1 - y1,
+ a2 = -1 / a1,
+ c2 = a2 * x2 - y2,
+ d = a2 - a1,
+ endX = ( c2 - c1 ) / d,
+ endY = ( a1 * c2 - a2 * c1 ) / d;
+ return [ endX, endY ];
+ }
+ },
+
+ /**
+ * Find the distance between two points
+ * @param {Number} p1x
+ * @param {Number} p1y
+ * @param {Number} p2x
+ * @param {Number} p2y
+ * @return {Number} the distance
+ */
+ distance: function( p1x, p1y, p2x, p2y ) {
+ var dx = p2x - p1x,
+ dy = p2y - p1y;
+ return Math.abs(
+ dx === 0 ? dy :
+ dy === 0 ? dx :
+ Math.sqrt( dx * dx + dy * dy )
+ );
+ }
+
+};
View
131 sources/IE9BackgroundRenderer.js
@@ -47,135 +47,18 @@ PIE.IE9BackgroundRenderer = PIE.RendererBase.newRenderer( {
bounds = this.boundsInfo.getBounds(),
w = bounds.w,
h = bounds.h,
- angle = info.angle,
- startPos = info.gradientStart,
stopsInfo = info.stops,
stopCount = stopsInfo.length,
- PI = Math.PI,
- UNDEF,
- startX, startY,
- endX, endY,
- startCornerX, startCornerY,
- endCornerX, endCornerY,
- deltaX, deltaY, lineLength,
+ metrics = PIE.GradientUtil.getGradientMetrics( el, bounds, info ),
+ startX = metrics.startX,
+ startY = metrics.startY,
+ endX = metrics.endX,
+ endY = metrics.endY,
+ lineLength = metrics.lineLength,
stopPx,
- p, i, j, before, after,
+ i, j, before, after,
svg;
- /**
- * Find the point along a given line (defined by a starting point and an angle), at which
- * that line is intersected by a perpendicular line extending through another point.
- * @param x1 - x coord of the starting point
- * @param y1 - y coord of the starting point
- * @param angle - angle of the line extending from the starting point (in degrees)
- * @param x2 - x coord of point along the perpendicular line
- * @param y2 - y coord of point along the perpendicular line
- * @return [ x, y ]
- */
- function perpendicularIntersect( x1, y1, angle, x2, y2 ) {
- // Handle straight vertical and horizontal angles, for performance and to avoid
- // divide-by-zero errors.
- if( angle === 0 || angle === 180 ) {
- return [ x2, y1 ];
- }
- else if( angle === 90 || angle === 270 ) {
- return [ x1, y2 ];
- }
- else {
- // General approach: determine the Ax+By=C formula for each line (the slope of the second
- // line is the negative inverse of the first) and then solve for where both formulas have
- // the same x/y values.
- var a1 = Math.tan( -angle * PI / 180 ),
- c1 = a1 * x1 - y1,
- a2 = -1 / a1,
- c2 = a2 * x2 - y2,
- d = a2 - a1,
- endX = ( c2 - c1 ) / d,
- endY = ( a1 * c2 - a2 * c1 ) / d;
- return [ endX, endY ];
- }
- }
-
- // Find the "start" and "end" corners; these are the corners furthest along the gradient line.
- // This is used below to find the start/end positions of the CSS3 gradient-line, and also in finding
- // the total length of the VML rendered gradient-line corner to corner.
- function findCorners() {
- startCornerX = ( angle >= 90 && angle < 270 ) ? w : 0;
- startCornerY = angle < 180 ? h : 0;
- endCornerX = w - startCornerX;
- endCornerY = h - startCornerY;
- }
-
- // Normalize the angle to a value between [0, 360)
- function normalizeAngle() {
- while( angle < 0 ) {
- angle += 360;
- }
- angle = angle % 360;
- }
-
- // Find the distance between two points
- function distance( p1, p2 ) {
- var dx = p2[0] - p1[0],
- dy = p2[1] - p1[1];
- return Math.abs(
- dx === 0 ? dy :
- dy === 0 ? dx :
- Math.sqrt( dx * dx + dy * dy )
- );
- }
-
- // Find the start and end points of the gradient
- if( startPos ) {
- startPos = startPos.coords( el, w, h );
- startX = startPos.x;
- startY = startPos.y;
- }
- if( angle ) {
- angle = angle.degrees();
-
- normalizeAngle();
- findCorners();
-
- // If no start position was specified, then choose a corner as the starting point.
- if( !startPos ) {
- startX = startCornerX;
- startY = startCornerY;
- }
-
- // Find the end position by extending a perpendicular line from the gradient-line which
- // intersects the corner opposite from the starting corner.
- p = perpendicularIntersect( startX, startY, angle, endCornerX, endCornerY );
- endX = p[0];
- endY = p[1];
- }
- else if( startPos ) {
- // Start position but no angle specified: find the end point by rotating 180deg around the center
- endX = w - startX;
- endY = h - startY;
- }
- else {
- // Neither position nor angle specified; create vertical gradient from top to bottom
- startX = startY = endX = 0;
- endY = h;
- }
- deltaX = endX - startX;
- deltaY = endY - startY;
-
- 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();
- }
-
- lineLength = distance( [ startX, startY ], [ endX, endY ] );
-
// Find the pixel offsets along the CSS3 gradient-line for each stop.
stopPx = [];
for( i = 0; i < stopCount; i++ ) {
Please sign in to comment.
Something went wrong with that request. Please try again.