Last active
May 2, 2016 13:55
-
-
Save MiniXC/ff3dfb0c5e4902888f21d91617163fce to your computer and use it in GitHub Desktop.
Clip-Path Polyfill: Only works for "clip-path: inset" and absolute/fixed elements. Depends on polyfill.js (https://philipwalton.github.io/polyfill).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Dependends on: https://philipwalton.github.io/polyfill | |
* Only works for: | |
* -> clip-path: inset | |
* -> absolute/fixed positioned elements | |
*/ | |
function ClipPath() { | |
var rectVals, rectElements, //read by setRectOnElements, set by init | |
polyfill = new Polyfill({ | |
declarations: ['clip-path:*'] | |
}); | |
//converts % to px | |
var toPx = function(value, ref) { | |
//ref is either width or height | |
if ((value + '').indexOf('%') > -1) { | |
return parseInt(value.replace('%', '')) / 100 * ref + 'px'; | |
} else { | |
//for auto 0 or a px value | |
return value; | |
} | |
}; | |
/* | |
* loops through all elements affected by clip-path | |
* and gives them a valid clip | |
*/ | |
var setRectOnElements = function() { | |
var len = rectElements.length; | |
for (var i = 0; i < len; i++) { | |
//calculate the values relative to the element | |
var currentElement = rectElements[i], | |
elemHeight = currentElement.offsetHeight, | |
elemWidth = currentElement.offsetWidth, | |
//calculate clip values from clip-path | |
top = rectVals[0], | |
left = elemWidth - parseInt(toPx(rectVals[1], elemWidth) | |
.replace('px', '')) + 'px', | |
bottom = rectVals[0] + rectVals[2], | |
right = rectVals[3], | |
//convert %-values to px | |
relTop = toPx(top, elemHeight), | |
relLeft = toPx(left, elemWidth), | |
relBottom = toPx(bottom, elemHeight), | |
relRight = toPx(right, elemWidth), | |
//delimiter | |
d = ', ', | |
//let's put everything together | |
rectString = (relTop + d + relLeft + d + relBottom + d + relRight); | |
currentElement.style.clip = 'rect(' + rectString + ')'; | |
} | |
}; | |
//sets rectVals and rectElements to be used by setRectOnElements | |
var init = function(rule) { | |
//read properties | |
var prop = rule.getDeclaration()['clip-path']; | |
if (prop.indexOf('inset') > -1) { | |
prop = prop.replace('inset(', '').replace(')', ''); | |
rectVals = prop.split(' '); | |
} | |
//iterate over all matching elements | |
rectElements = document.querySelectorAll(rule.getSelectors()); | |
setRectOnElements(); | |
}; | |
//registers the polyfill handler | |
var register = function() { | |
polyfill.doMatched(function(rules) { | |
rules.each(function(rule) { | |
init(rule); | |
}); | |
}); | |
}; | |
this.register = register; | |
this.rerun = setRectOnElements; | |
} | |
window.addEventListener('load', function() { | |
var clip = new ClipPath(); | |
clip.register(); | |
window.addEventListener('resize', function() { | |
clip.rerun(); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment