Permalink
Browse files

Implement rendering of background origin and size params in IE<9. Res…

…olves issue #110.
  • Loading branch information...
1 parent c8a3864 commit 0230feb91715e53ed6831432e07bec18926b4e42 Jason Johnston committed Sep 11, 2011
Showing with 280 additions and 42 deletions.
  1. +77 −15 sources/BackgroundRenderer.js
  2. +1 −27 sources/IE9BackgroundRenderer.js
  3. +54 −0 tests/background-origin-tests.html
  4. +148 −0 tests/background-size-tests.html
@@ -121,7 +121,7 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( {
*/
positionBgImage: function( shape, index ) {
var me = this;
- PIE.Util.withImageSize( shape.fill.src, function( size ) {
+ PIE.Util.withImageSize( shape.fill.src, function( imgSize ) {
var el = me.targetElement,
bounds = me.boundsInfo.getBounds(),
elW = bounds.w,
@@ -131,15 +131,13 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( {
// update executed, make sure that's not the case to avoid divide-by-zero error
if( elW && elH ) {
var fill = shape.fill,
- si = me.styleInfos,
- border = si.borderInfo.getProps(),
- bw = border && border.widths,
- bwT = bw ? bw['t'].pixels( el ) : 0,
- bwR = bw ? bw['r'].pixels( el ) : 0,
- bwB = bw ? bw['b'].pixels( el ) : 0,
- bwL = bw ? bw['l'].pixels( el ) : 0,
- bg = si.backgroundInfo.getProps().bgImages[ index ],
- bgPos = bg.bgPosition ? bg.bgPosition.coords( el, elW - size.w - bwL - bwR, elH - size.h - bwT - bwB ) : { x:0, y:0 },
+ bg = me.styleInfos.backgroundInfo.getProps().bgImages[ index ],
+ bgAreaSize = me.getBgAreaSize( bg.bgOrigin ),
+ adjustedImgSize = ( bg.bgSize || PIE.BgSize.DEFAULT ).pixels(
+ me.targetElement, bgAreaSize.w, bgAreaSize.h, imgSize.w, imgSize.h
+ ),
+ bgOriginXY = me.getBgOriginXY( bg.bgOrigin ),
+ bgPos = bg.bgPosition ? bg.bgPosition.coords( el, bgAreaSize.w - adjustedImgSize.w, bgAreaSize.h - adjustedImgSize.h ) : { x:0, y:0 },
repeat = bg.imgRepeat,
pxX, pxY,
clipT = 0, clipL = 0,
@@ -149,24 +147,24 @@ 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 = Math.round( bgPos.x ) + bwL + 0.5;
- pxY = Math.round( bgPos.y ) + bwT + 0.5;
+ pxX = Math.round( bgOriginXY.x + bgPos.x ) + 0.5;
+ pxY = Math.round( bgOriginXY.y + bgPos.y ) + 0.5;
fill.position = ( pxX / elW ) + ',' + ( pxY / elH );
// Set the size of the image. We have to actually set it to px values otherwise it will not honor
// the user's browser zoom level and always display at its natural screen size.
fill['size']['x'] = 1; //Can be any value, just has to be set to "prime" it so the next line works. Weird!
- fill['size'] = size.w + 'px,' + size.h + 'px';
+ fill['size'] = adjustedImgSize.w + 'px,' + adjustedImgSize.h + 'px';
// Repeating - clip the image shape
if( repeat && repeat !== 'repeat' ) {
if( repeat === 'repeat-x' || repeat === 'no-repeat' ) {
clipT = pxY + 1;
- clipB = pxY + size.h + clipAdjust;
+ clipB = pxY + adjustedImgSize.h + clipAdjust;
}
if( repeat === 'repeat-y' || repeat === 'no-repeat' ) {
clipL = pxX + 1;
- clipR = pxX + size.w + clipAdjust;
+ clipR = pxX + adjustedImgSize.w + clipAdjust;
}
shape.style.clip = 'rect(' + clipT + 'px,' + clipR + 'px,' + clipB + 'px,' + clipL + 'px)';
}
@@ -176,6 +174,70 @@ PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( {
/**
+ * For a given background-origin value, return the dimensions of the background area.
+ * @param {String} bgOrigin
+ */
+ getBgAreaSize: function( bgOrigin ) {
+ var me = this,
+ el = me.targetElement,
+ bounds = me.boundsInfo.getBounds(),
+ elW = bounds.w,
+ elH = bounds.h,
+ w = elW,
+ h = elH,
+ borders, getLength, cs;
+
+ if( bgOrigin !== 'border-box' ) {
+ borders = me.styleInfos.borderInfo.getProps();
+ if( borders && ( borders = borders.widths ) ) {
+ w -= borders[ 'l' ].pixels( el ) + borders[ 'l' ].pixels( el );
+ h -= borders[ 't' ].pixels( el ) + borders[ 'b' ].pixels( el );
+ }
+ }
+
+ if ( bgOrigin === 'content-box' ) {
+ getLength = PIE.getLength;
+ cs = el.currentStyle;
+ w -= getLength( cs.paddingLeft ).pixels( el ) + getLength( cs.paddingRight ).pixels( el );
+ h -= getLength( cs.paddingTop ).pixels( el ) + getLength( cs.paddingBottom ).pixels( el );
+ }
+
+ return { w: w, h: h };
+ },
+
+
+ /**
+ * For a given background-origin value, return the x/y position of the origin
+ * from the top-left of the element bounds.
+ * @param {String} bgOrigin
+ */
+ getBgOriginXY: function( bgOrigin ) {
+ var me = this,
+ el = me.targetElement,
+ x = 0,
+ y = 0,
+ borders, getLength, cs;
+
+ if( bgOrigin !== 'border-box' ) {
+ borders = me.styleInfos.borderInfo.getProps();
+ if( borders && ( borders = borders.widths ) ) {
+ x += borders[ 'l' ].pixels( el );
+ y += borders[ 't' ].pixels( el );
+ }
+ }
+
+ if ( bgOrigin === 'content-box' ) {
+ getLength = PIE.getLength;
+ cs = el.currentStyle;
+ x += getLength( cs.paddingLeft ).pixels( el );
+ y += getLength( cs.paddingTop ).pixels( el );
+ }
+
+ return { x: x, y: y };
+ },
+
+
+ /**
* Draw the linear gradient for a gradient layer
* @param {Element} shape
* @param {Object} info The object holding the information about the gradient
@@ -60,33 +60,7 @@ PIE.IE9BackgroundRenderer = PIE.RendererBase.newRenderer( {
}).join(' ') : '0 0';
},
- getBgAreaSize: function( bgOrigin ) {
- var me = this,
- el = me.targetElement,
- bounds = me.boundsInfo.getBounds(),
- elW = bounds.w,
- elH = bounds.h,
- w = elW,
- h = elH,
- borders, getLength, cs;
-
- if( bgOrigin !== 'border-box' ) {
- borders = me.styleInfos.borderInfo.getProps();
- if( borders && ( borders = borders.widths ) ) {
- w -= borders[ 'l' ].pixels( el ) + borders[ 'l' ].pixels( el );
- h -= borders[ 't' ].pixels( el ) + borders[ 'b' ].pixels( el );
- }
- }
-
- if ( bgOrigin === 'content-box' ) {
- getLength = PIE.getLength;
- cs = el.currentStyle;
- w -= getLength( cs.paddingLeft ).pixels( el ) + getLength( cs.paddingRight ).pixels( el );
- h -= getLength( cs.paddingTop ).pixels( el ) + getLength( cs.paddingBottom ).pixels( el );
- }
-
- return { w: w, h: h };
- },
+ getBgAreaSize: PIE.BackgroundRenderer.prototype.getBgAreaSize,
getGradientSvg: function( info, bgWidth, bgHeight ) {
var el = this.targetElement,
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Tests for background-origin</title>
+ <style>
+ .test {
+ width: 200px;
+ height: 100px;
+ border: 10px dotted #C9C;
+ padding: 10px;
+ border-radius: 30px;
+ behavior: url(../build/PIE.htc);
+ }
+
+ .border-box {
+ background: #CCF url(border.png) border-box no-repeat;
+ -pie-background: #CCF url(border.png) border-box no-repeat;
+ }
+ .border-box-br {
+ background: #CCF url(border.png) border-box no-repeat 100% 100%;
+ -pie-background: #CCF url(border.png) border-box no-repeat 100% 100%;
+ }
+ .padding-box {
+ background: #CCF url(border.png) padding-box no-repeat;
+ -pie-background: #CCF url(border.png) padding-box no-repeat;
+ }
+ .padding-box-br {
+ background: #CCF url(border.png) padding-box no-repeat 100% 100%;
+ -pie-background: #CCF url(border.png) padding-box no-repeat 100% 100%;
+ }
+ .content-box {
+ background: #CCF url(border.png) content-box no-repeat;
+ -pie-background: #CCF url(border.png) content-box no-repeat;
+ }
+ .content-box-br {
+ background: #CCF url(border.png) content-box no-repeat 100% 100%;
+ -pie-background: #CCF url(border.png) content-box no-repeat 100% 100%;
+ }
+ </style>
+</head>
+<body>
+ <h1>Tests for background-origin</h1>
+
+ <div class="test border-box">origin = border-box</div>
+ <div class="test border-box-br">origin = border-box</div>
+
+ <div class="test padding-box">origin = padding-box</div>
+ <div class="test padding-box-br">origin = padding-box</div>
+
+ <div class="test content-box">origin = content-box</div>
+ <div class="test content-box-br">origin = content-box</div>
+
+</body>
+</html>
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Tests for background-size</title>
+ <style>
+ .test {
+ width: 25%;
+ height: 100px;
+ border: 10px dotted #C9C;
+ padding: 10px;
+ border-radius: 30px;
+ behavior: url(../build/PIE.htc);
+ }
+
+ .normal {
+ background: #CCF url(border.png) no-repeat;
+ -pie-background: #CCF url(border.png) no-repeat;
+ }
+ .normal-br {
+ background: #CCF url(border.png) no-repeat 100% 100%;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100%;
+ }
+ .contain {
+ background: #CCF url(border.png) no-repeat 0 0 / contain;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / contain;
+ }
+ .contain-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / contain;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / contain;
+ }
+ .contain-border {
+ background: #CCF url(border.png) no-repeat 0 0 / contain border-box;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / contain border-box;
+ }
+ .contain-border-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / contain border-box;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / contain border-box;
+ }
+ .contain-content {
+ background: #CCF url(border.png) no-repeat 0 0 / contain content-box;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / contain content-box;
+ }
+ .contain-content-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / contain content-box;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / contain content-box;
+ }
+ .cover {
+ background: #CCF url(border.png) no-repeat 0 0 / cover;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / cover;
+ }
+ .cover-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / cover;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / cover;
+ }
+ .cover-border {
+ background: #CCF url(border.png) no-repeat 0 0 / cover border-box;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / cover border-box;
+ }
+ .cover-border-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / cover border-box;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / cover border-box;
+ }
+ .cover-content {
+ background: #CCF url(border.png) no-repeat 0 0 / cover content-box;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / cover content-box;
+ }
+ .cover-content-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / cover content-box;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / cover content-box;
+ }
+ .scale-px {
+ background: #CCF url(border.png) no-repeat 0 0 / 50px;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / 50px;
+ }
+ .scale-px-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / 50px;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / 50px;
+ }
+ .scale-100pct {
+ background: #CCF url(border.png) no-repeat 0 0 / 100%;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / 100%;
+ }
+ .scale-100pct-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / 100%;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / 100%;
+ }
+ .scale-100pct-50pct {
+ background: #CCF url(border.png) no-repeat 0 0 / 100% 50%;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / 100% 50%;
+ }
+ .scale-100pct-50pct-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / 100% 50%;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / 100% 50%;
+ }
+ .scale-50pct-100pct {
+ background: #CCF url(border.png) no-repeat 0 0 / 50% 100%;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / 50% 100%;
+ }
+ .scale-50pct-100pct-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / 50% 100%;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / 50% 100%;
+ }
+ .scale-50px-90pct {
+ background: #CCF url(border.png) no-repeat 0 0 / 50px 90%;
+ -pie-background: #CCF url(border.png) no-repeat 0 0 / 50px 90%;
+ }
+ .scale-50px-90pct-br {
+ background: #CCF url(border.png) no-repeat 100% 100% / 50px 90%;
+ -pie-background: #CCF url(border.png) no-repeat 100% 100% / 50px 90%;
+ }
+ </style>
+</head>
+<body>
+ <h1>Tests for background-size</h1>
+
+
+ <div class="test normal">natural size</div>
+ <div class="test normal-br">natural size, bottom right</div>
+
+ <div class="test contain">contain</div>
+ <div class="test contain-br">contain, bottom right</div>
+ <div class="test contain-border">contain, border-box</div>
+ <div class="test contain-border-br">contain, border-box, bottom right</div>
+ <div class="test contain-content">contain, content-box</div>
+ <div class="test contain-content-br">contain, content-box, bottom right</div>
+
+ <div class="test cover">cover</div>
+ <div class="test cover-br">cover, bottom right</div>
+ <div class="test cover-border">cover, border-box</div>
+ <div class="test cover-border-br">cover, border-box, bottom right</div>
+ <div class="test cover-content">cover, content-box</div>
+ <div class="test cover-content-br">cover, content-box, bottom right</div>
+
+ <div class="test scale-px">50px</div>
+ <div class="test scale-px-br">50px, bottom right</div>
+ <div class="test scale-100pct">100%</div>
+ <div class="test scale-100pct-br">100%, bottom right</div>
+ <div class="test scale-100pct-50pct">100% 50%</div>
+ <div class="test scale-100pct-50pct-br">100% 50%, bottom right</div>
+ <div class="test scale-50pct-100pct">50% 100%</div>
+ <div class="test scale-50pct-100pct-br">50% 100%, bottom right</div>
+ <div class="test scale-50px-90pct">50px 90%</div>
+ <div class="test scale-50px-90pct-br">50px 90%, bottom right</div>
+
+
+
+</body>
+</html>

0 comments on commit 0230feb

Please sign in to comment.