Skip to content

Commit

Permalink
Implement rendering of background origin and size params in IE<9. Res…
Browse files Browse the repository at this point in the history
…olves issue lojjic#110.
  • Loading branch information
Jason Johnston committed Sep 11, 2011
1 parent c8a3864 commit 0230feb
Show file tree
Hide file tree
Showing 4 changed files with 280 additions and 42 deletions.
92 changes: 77 additions & 15 deletions sources/BackgroundRenderer.js
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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)';
}
Expand All @@ -175,6 +173,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
Expand Down
28 changes: 1 addition & 27 deletions sources/IE9BackgroundRenderer.js
Expand Up @@ -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,
Expand Down
54 changes: 54 additions & 0 deletions tests/background-origin-tests.html
@@ -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>
148 changes: 148 additions & 0 deletions tests/background-size-tests.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.