Skip to content

Instantly share code, notes, and snippets.

@dschnare
Last active December 23, 2015 04:59
Show Gist options
  • Save dschnare/6583996 to your computer and use it in GitHub Desktop.
Save dschnare/6583996 to your computer and use it in GitHub Desktop.
Applies several stretch strategies to a viewport's contents following the examples here: http://msdn.microsoft.com/en-us/library/system.windows.media.stretch.aspx. This snippet requires jQuery.
<!DOCTYPE html>
<html>
<head>
<title>TITLE</title>
<style type="text/css">
html,
body {
margin: 0;
}
.viewport {
overflow: hidden;
position: relative;
}
.viewport .viewport-content {
position: absolute;
}
</style>
</head>
<body>
<div class="viewport stretch--uniformtofill">
<img src="http://www.softendo.com/mario-games/new_mario_forever_pc_2012.jpg"
class="viewport-content" />
</div>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="./stretch.js"></script>
<script type="text/javascript">
//////////////////////////////////////
// Application Supporting Functions //
//////////////////////////////////////
function updateViewports() {
$('.viewport').each(function () {
var $viewport = $(this), $content = $('.viewport-content', this);
// Resize our viewport to be full-browser
// OR the viewport should have its demensions
// set with CSS already.
$viewport.css({
width: $(window).width(),
height: $(window).height()
});
// Apply the stretch strategy to the viewport.
StretchStrategies($viewport, $content);
});
}
/////////////////////////////
// Application Entry Point //
/////////////////////////////
$(function () {
// Setup window rezie handler.
$(window).on('resize', updateViewports);
// Prime the pump (but give time for image to load)
$('.viewport img').load(updateViewports);
});
</script>
</body>
</html>
// Looks for a class of the form 'stretch--[strategyid]' to determine what strategy to apply.
// StretchStrategies($viewport, $content)
// StretchStrategies($viewport, contentDimensions, updateContentFn)
var StretchStrategies = function ($viewport, $content, updateContentFn) {
if (Object($content) === $content) {
var dims = $content;
$content = {
width: function () {
return dims.width;
},
height: function () {
return dims.height;
},
css: function (styles) {
updateContentFn(styles);
}
};
} else {
// Reset any existing width/height styles so we can
// get the natural dimensions of the content.
$content.css({
width: '',
height: ''
});
}
for (var k in StretchStrategies) {
if ($viewport.hasClass('stretch--' + k)) {
// Invoke the stretch strategy on our content
// (returns an object with width and height).
var styles = StretchStrategies[k](
$content.width(), $content.height(),
$viewport.width(), $viewport.height());
// Now center the content within it's viewport.
styles.left = ($viewport.width() - styles.width)/2;
styles.top = ($viewport.height() - styles.height)/2;
// Apply the styles to the content.
$content.css(styles);
// Exit the loop.
break;
}
}
};
// Any new strategy can be added as a property.
// See for examples: http://msdn.microsoft.com/en-us/library/system.windows.media.stretch.aspx
StretchStrategies.none = function (srcWidth, srcHeight, destWidth, destHeight) {
return {
width: srcWidth,
height: srcHeight
};
},
StretchStrategies.fill = function (srcWidth, srcHeight, destWidth, destHeight) {
return {
width: destWidth,
height: destHeight
};
},
StretchStrategies.uniform = function (srcWidth, srcHeight, destWidth, destHeight) {
// Source is portrait.
if (srcWidth < destHeight) {
// If the destination is portrait and has a larger aspect ratio then
// we use the width (smaller dimension).
if (destWidth < destHeight && destHeight/destWidth > srcHeight/srcWidth) {
return {
width: destWidth,
height: destWidth * (srcHeight/srcWidth)
};
// Otherwise we use the height (larger dimension).
} else {
return {
width: destHeight * (srcWidth/srcHeight),
height: destHeight
};
}
// Source is landscape.
} else {
// If destination is landscape and has a larger aspect ratio then
// we use the height (smaller dimension).
if (destHeight < destWidth && destWidth/destHeight > srcWidth/srcHeight) {
return {
width: destHeight * (srcWidth/srcHeight),
height: destHeight
};
// Otherwise we use the width (larger diemsion).
} else {
return {
width: destWidth,
height: destWidth * (srcHeight/srcWidth)
};
}
}
};
StretchStrategies.uniformtofill = function (srcWidth, srcHeight, destWidth, destHeight) {
// Source is portrait.
if (srcWidth < srcHeight) {
// If the destination is portrait and has a larger aspect ratio then
// we use the height (larger dimension).
if (destWidth < destHeight && destHeight/destWidth > srcHeight/srcWidth) {
return {
width: destHeight * (srcWidth/srcHeight),
height: destHeight
};
// Otherwise we use the width (smaller dimension).
} else {
return {
width: destWidth,
height: destWidth * (srcHeight/srcWidth)
};
}
// Source is landscape.
} else {
// If destination is landscape and has a larger aspect ratio then
// we use the width (larger dimension).
if (destHeight < destWidth && destWidth/destHeight > srcWidth/srcHeight) {
return {
width: destWidth,
height: destWidth * (srcHeight/srcWidth)
};
// Otherwise we use the height (smaller diemsion).
} else {
return {
width: destHeight * (srcWidth/srcHeight),
height: destHeight
};
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment