Skip to content

Instantly share code, notes, and snippets.

@ethanmuller
Created November 8, 2012 16:03
Show Gist options
  • Save ethanmuller/4039728 to your computer and use it in GitHub Desktop.
Save ethanmuller/4039728 to your computer and use it in GitHub Desktop.
HD Sprite Mixin
This mixin requires three arguments: the standard definition sprite map, the hd sprite map, and the icon you want to use.
Optionally, you can give it X and Y offsets to position it, a width to resize it, or you can center it on the X axis, Y axis, or both.
Use it something like this:
// Create sprite maps
// (Just do this once per sprite sheet)
$general-sd: sprite-map("icons/general/*.png", $spacing: 30px);
$general-hd: sprite-map("hd/icons/general/*.png", $spacing: 60px);
// Plug the maps into the mixin
// (I want to use a file called person-icon.png in my [hd/]icons/general folder)
.person-box {
@include hd-sprite( $general-sd, $general-hd, person-icon );
}
@mixin hd-sprite( $sprite-map-sd, $sprite-map-hd, $icon, $offset-x:0, $offset-y:0, $width: none, $center: none ){
%generate-sprite-image {
// Just ignore this bit.
// It makes sure the sprite is generated before
// its width/height are accessed.
// NOTE: it is never rendered to CSS.
content: sprite-url($sprite-map-sd);
content: sprite-url($sprite-map-hd);
}
// Get width/height of generated sprite image
$sheet-width-sd: image-width(sprite-path($sprite-map-sd));
$sheet-height-sd: image-height(sprite-path($sprite-map-sd));
$sheet-width-hd: image-width(sprite-path($sprite-map-hd));
$sheet-height-hd: image-height(sprite-path($sprite-map-hd));
// Get width/height of the icon we want
$icon-width: image-width(sprite-file($sprite-map-sd, $icon));
$icon-height: image-height(sprite-file($sprite-map-sd, $icon));
// Get aspect ratio of $icon
$aspect-ratio: $icon-width / $icon-height;
// This is the relationship between original/new widths
// If a $width isn't passed, it stays at 1.
$scale-ratio: 1;
@if $width != none { // If width is set...
// Set proper scale ratio
$scale-ratio: $icon-width / $width;
// Rewrite icon width
$icon-width: $width;
// Get new icon height from aspect ratio
$icon-height: round($icon-width / $aspect-ratio);
}
position: relative; // To contain absolutely-positioned :before element
&:before {
content: "\0000a0";
background-repeat: no-repeat;
display: block;
position: absolute;
@if $center == none {
top: $offset-y;
left: $offset-x;
} @else if $center == x {
top: $offset-y;
left: 50%;
margin-left: (-1) * ($icon-width / 2) + $offset-x;
} @else if $center == y {
top: 50%;
left: $offset-x;
margin-top: (-1) * ($icon-height / 2) + $offset-y;
} @else if $center == both {
top: 50%;
left: 50%;
margin-top: (-1) * ($icon-height / 2) + $offset-y;
margin-left: (-1) * ($icon-width / 2) + $offset-x;
}
width: $icon-width; /* icon width */
height: $icon-height; /* icon height */
}
@media (-webkit-max-device-pixel-ratio: 1.49999),
(-o-max-device-pixel-ratio: 3/2),
(-moz-max-device-pixel-ratio: 1.49999),
(max-device-pixel-ratio: 1.49999) {
$x: nth(sprite-position($sprite-map-sd, $icon), 1);
$y: nth(sprite-position($sprite-map-sd, $icon), 2);
&:before {
background-image: sprite-url($sprite-map-sd);
background-position: $x round(($y / $scale-ratio)); // scale down the $y positioning (if icon width is set)
background-size: auto round(( $sheet-height-sd / $scale-ratio ));
}
}
@media (-webkit-min-device-pixel-ratio: 1.5),
(-o-min-device-pixel-ratio: 3/2),
(-moz-min-device-pixel-ratio: 1.5),
(min-device-pixel-ratio: 1.5) {
$x: nth(sprite-position($sprite-map-hd, $icon), 1);
$y: nth(sprite-position($sprite-map-hd, $icon), 2);
&:before {
background-image: sprite-url($sprite-map-hd);
background-position: $x round( ($y / 2) / $scale-ratio );
background-size: auto round(( ($sheet-height-hd / 2) / $scale-ratio ));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment