I try to write a little plugin, to open modal boxes in a more organic fashion, therefore I have decided to animate the clip-path property.
Now this code only works in chrome: http://codepen.io/meodai/pen/GgGzYo?editors=011
It looks like firefox does not support polygon()
in the clip-path property. Safari & Mobile Safari do struggle with it as well.
Is there a similarly easy way to make this work in Firefox and Safari and Mobile Safari as well? Any idea how I could approach this problem?
Here is a working example:
var $ov = $('.overlay');
$(document).on('click touchstart', '.inner', function(){
var coords, coordArray, coordsString;
coords = this.getBoundingClientRect();
coordArray = [
Math.floor(parseInt(coords.left)) + 'px ' + Math.floor(parseInt(coords.top)) + 'px',
Math.ceil((parseInt(coords.left) + parseInt(coords.width))) + 'px ' + Math.ceil(parseInt(coords.top)) + 'px',
Math.ceil((parseInt(coords.left) + parseInt(coords.width))) + 'px ' + Math.ceil((parseInt(coords.top) + parseInt(coords.height) )) + 'px',
Math.ceil(parseInt(coords.left)) + 'px ' + Math.floor((parseInt(coords.top) + parseInt(coords.height) )) + 'px'
];
coordsString = 'polygon(' + coordArray[0] + ',' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
setTimeout(function(){
$ov.addClass('show');
},50);
setTimeout(function(){
coordsString = 'polygon(0% 0%,' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
},100);
setTimeout(function(){
coordsString = 'polygon(0% 0%,100% 0%,' + coordArray[2] + ',' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
},180);
setTimeout(function(){
coordsString = 'polygon(0% 0%,100% 0%,100% 100%,' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
},260);
setTimeout(function(){
coordsString = 'polygon(0% 0%,100% 0%,100% 100%,0 100%)';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
},340);
// reverse
setTimeout(function(){
coordsString = 'polygon(0% 0%,100% 0%,100% 100%,' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
},1500);
setTimeout(function(){
coordsString = 'polygon(0% 0%,100% 0%,' + coordArray[2] + ',' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
},1580);
setTimeout(function(){
coordsString = 'polygon(0% 0%,' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
},1640);
setTimeout(function(){
coordsString = 'polygon(' + coordArray[0] + ',' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
},1740);
setTimeout(function(){
$ov.removeClass('show');
},2000);
});
body, html {
background: silver;
}
.grid {
float: left;
width: 25%;
height: 25vw;
box-shizing: border-box;
position: relative;
}
.inner {
position: absolute;
top: 10px;
left: 10px;
bottom: 10px;
right: 10px;
background: #ddd;
-webkit-transition: background-color 111ms;
transition: background-color 111ms;
}
.inner:hover {
background: #fff;
}
.overlay {
opacity: 0;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: #fff;
pointer-events: none;
box-sizing: border-box;
padding: 20px;
}
.overlay.show {
opacity: 1;
will-change: clip-path;
-webkit-transition: clip-path 200ms;
transition: clip-path 200ms;
-webkit-transition: -webkit-clip-path 200ms;
transition: -webkit-clip-path 200ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="grid">
<div class="inner"></div>
</div>
<div class="overlay"></div>
You might want to take a look at svgs as you can animate the points of a polygon and morph it to the desired shape.
DEMO
DEMO With images and titles
This demo uses the snap.svg library to make the squares and manipulate them on the click event.It is currently not finished and there are some bugs but you should get the idea.
I totaly refactored the code, thanks to rlemon for helping me get it way better. I tested it in latest FF and Chrome and a user reported it works on an iphone with safari.
The items are made with polygons, a square polygon is added on click and it's points are animated one by one to be featured.
var items = [
[ 1, 1,24, 1,24,24, 1,24],
[26, 1,49, 1,49,24,26,24],
[51, 1,74, 1,74,24,51,24],
[76, 1,99, 1,99,24,76,24],
[ 1, 26,24, 26,24,49, 1,49],
[26, 26,49, 26,49,49,26,49],
[51, 26,74, 26,74,49,51,49],
[76, 26,99, 26,99,49,76,49],
[ 1, 51,24, 51,24,74, 1,74],
[26, 51,49, 51,49,74,26,74],
[51, 51,74, 51,74,74,51,74],
[76, 51,99, 51,99,74,76,74],
[ 1, 76,24, 76,24,99, 1,99],
[26, 76,49, 76,49,99,26,99],
[51, 76,74, 76,74,99,51,99],
[76, 76,99, 76,99,99,76,99]
],
item = [],points= [],i, p=[],open = 0,
s = Snap().attr({viewBox:"0 0 100 100","fill":"#585247"});
function runAnimations(el) {
if( !animationSequences.length ) return;
var sequence = animationSequences.shift();
el.animate(sequence,120,mina.linear, runAnimations.bind(null,el));
}
function register(x,i) {
item[i] = s.polygon(items[i]);
item[i].click(function () {
var featured = s.polygon(items[i]).attr({"fill":"#585247"});
p = items[i];
animationSequences = [
{"points": p[0]/2+","+p[1]/2+","+p[2]+","+p[3]+","+p[4]+","+p[5]+","+p[6]+","+p[7]},
{"points": p[0]/3+","+p[1]/3+",100,0,100,100,"+p[6]+","+p[7]},
{"points": p[0]/4+","+p[1]/4+",100,0,100,100,0,100"},
{"points": "0,0,100,0,100,100,0,100"},
];
runAnimations(featured);
featured.animate({"fill":"#ACA696"},300);
featured.click(function(){
this.stop().animate({"points":p,"fill":"#585247"},200,mina.linear,featured.remove);
});
});
}
items.forEach(register);
*{margin:0;padding:0;}
body{background:#E3DFD2;}
svg{display:block;}
<script src="http://thisisa.simple-url.com/js/snapsvg.js"></script>
Clip-path only supports numbers for point values, it looks like you are using percentages/pixel scales which is why it will be failing in firefox.
Change to integer values:
coordsString = 'polygon(0 0,123 0,' + coordArray[2] + ',' + coordArray[3] + ')';
$ov.css({
'-webkit-clip-path': coordsString,
'clip-path': coordsString
});
You will need to remove pixel references from the coordArray and calculate actual int values from the percentages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With