Skip to content

Instantly share code, notes, and snippets.

@megclaypool
Last active May 18, 2018 15:31
Show Gist options
  • Save megclaypool/9aedb72bce69b5adfe33c745873ebf69 to your computer and use it in GitHub Desktop.
Save megclaypool/9aedb72bce69b5adfe33c745873ebf69 to your computer and use it in GitHub Desktop.
Dynamic button background resizer (Javascript) This script measures the rendered height of a button element (which, if someone puts long content in the button, might render taller than planned for!). Then it stretches and repositions the button back
// This script measures the rendered height of a button element (which, if someone puts long content in the button, might render taller than planned for!). Then it stretches and repositions the button background image sprite based on the rendered height so that the button looks as it should. The numbers come from the button sprite at https://essentialaccess.org/themes/essentialaccess/dist/images/button_sprite.jpg but could be rejiggered for any sprite as long as all the sprite sections were of a consistent height.
// Notes:
// From Algebra 2, you may remember function transformations (No? Huh...) When you're trying to graph a transformed function, first you apply the dilation (stretching/shrinking) and then the translation (scooting). Similarly, first we'll do the background-size and then the background-position.
// For the purposes of this script, the css background-size property takes two arguments: width and height. The width of te sprite I'm using is 2px. We divide the actual height of our element by the height of an individual sprite element (the one I'm using has 33px high sprites). This gives us a scale factor, which we multiply with the total height of our original sprite image, to stretch or shrink it so that the new height of an individual sprite element matches the actual height of our element.
// Then all we have to do is scoot the background image so that the correct part is on top of our element. (That's the only part of the background image that we'll be able to see.) I'm adding classes to my html that I'm checking for in this script. The class tells me which of the sprites on the strip I want to use. This particular sprite image is 2px wide and 198px long, with 33px long sections that are (respectively) purple, red, orange/yellow, green, teal, and blue. We'll count starting at 0, so if I want purple I won't scoot it at all; if I want blue I'll need to scoot down 5 spaces. (I don't know why down is negative but right is also negative. That doesn't match how I learned coordinates, but I just have to remember to smile and nod and do it their (wrong) way ;)
function buttonBackground() {
// these numbers come from the sprite image I'm using. Different sprites will need different numbers to match.
var totalImageHeight = 198;
var backgroundWidth = 2;
var indvidualSpriteHeight = 33;
var buttons = document.getElementsByClassName('button-dynamic');
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
var backgroundOffset = 0;
if (button.classList.contains('button-purple')) {
backgroundOffset = 0;
}
if (button.classList.contains('button-red')) {
backgroundOffset = -1;
}
if (button.classList.contains('button-yellow')|button.classList.contains('button-dirty-yellow')) {
backgroundOffset = -2;
}
if (button.classList.contains('button-green')) {
backgroundOffset = -3;
}
if (button.classList.contains('button-teal')) {
backgroundOffset = -4;
}
if (button.classList.contains('button-blue')) {
backgroundOffset = -5;
}
// console.log("The backgroundOffset is now " + backgroundOffset);
var buttonHeight = button.offsetHeight;
var backgroundHeight = totalImageHeight * buttonHeight / indvidualSpriteHeight;
var verticalBackgroundPosition = backgroundOffset * buttonHeight;
button.style.backgroundSize = backgroundWidth + "px " + backgroundHeight + "px";
// console.log("The new background size is: ", button.style.backgroundSize);
button.style.backgroundPosition = "0 " + verticalBackgroundPosition + "px";
// console.log("The new background position is: ", button.style.backgroundPosition);
}
}
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded', buttonBackground);
} else {
buttonBackground();
}
window.addEventListener('resize', buttonBackground);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment