Playmorph
by Felis Catus
HTML
<div class="button">
<svg id="playpause" width="50" height="50" viewBox="0,0 50,50">
<g id="morph">
<path d="M 19.5,18 30,25 19.5,32 19.5,32 Z"/>
<path d="M 19.5,18 22.5,25 22.5,25 19.5,32 Z"/>
</g>
</svg>
</div>
<div class="test">
</div>
<img src='data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNTAiIHdpZHRoPSI1MCIgdmlld0JveD0iMCAwIDUwIDUwIj48dXNlIHhsaW5rOmhyZWY9IiNtb3JwaCIgeD0iMSIgeT0iMSIgLz48L3N2Zz4='>
<svg xmlns="http://www.w3.org/2000/svg" height="50" width="50" viewBox="0 0 50 50"><use xlink:href="#morph" x="1" y="1" /></svg>
CSS
div.button>svg{
position:absolute;
top:0;
left:0;
}
svg#playpause>g>path {
stroke-linejoin:round;
stroke-width:3;
fill:white;
stroke:white;
}
div.button{
position:absolute;
width:50px;
height:50px;
}
div.test{
position:absolute;
width:50px;
height:50px;
left:100px;
background:rgba(255,0,0,0.5);
}
div.button:before{
display:block;
position:absolute;
background:rgba(0,0,0,.5);
width:100%;
height:100%;
top:0;
left:0;
content:"";
border-radius:5px;
}
div.test:before{
display:block;
position:absolute;
width:100%;
height:100%;
top:0;
left:0;
content:"";
border-radius:5px;
background:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNTAiIHdpZHRoPSI1MCIgdmlld0JveD0iMCAwIDUwIDUwIj48dXNlIHhsaW5rOmhyZWY9IiNtb3JwaCIgeD0iMSIgeT0iMSIgLz48L3N2Zz4=') center no-repeat;
}
div.button>svg, div.button:before{
transition:transform 50ms ease;
}
div.button:active>svg, div.button:active:before{
transform:scale(0.9);
}
img{
left: 125px;
position: absolute;
top: 5px;
}
body{
background:blue;
}
body>svg{
position:absolute;
top:50px;
}
JavaScript
(function setEvents(){
function mkTransition(from,to,steps){
return (function mkClosure(){
var start=parseFloat(from);
var delta=(parseFloat(to)-parseFloat(from))/parseFloat(steps);
return (function doStep(){
return start+=delta;
});
}());
}
function mkTransform(fromPath,toPath,steps){//return path gen
var path1pts=fromPath.split(' ').slice(1,-1);//remove MZ
var path2pts=toPath.split(' ').slice(1,-1);
return (function mkClosure(){
var pathgen=path1pts.map(
function projectFromTo(coord,index){
return coord.split(',').map(function(fld,idx){
return mkTransition(fld,path2pts[index].split(',')[idx],steps)
})
});
return (function mkPath(){
return pathgen.reduce(function c2p(prev,curr){
return prev+' '+curr.reduce(function f2c(prv,crr){
return prv()+','+crr();
});
},'M')+' Z';
});
}());
}
var playing=0;
var intv=0;
var stepcnt=0,stepcnt1=0,stagger=3,steptotal=5;
var play1="M 19.5,18 30,25 19.5,32 19.5,32 Z";
var play2="M 19.5,18 22.5,18 22.5,32 19.5,32 Z";
var pause1="M 19.5,18 22.5,25 22.5,25 19.5,32 Z";
var pause2="M 27.5,18 30.5,18 30.5,32 27.5,32 Z";
var bars=document.querySelectorAll("#playpause>g>path");
document.getElementsByClassName("button")[0].onclick=function(){
playing=1-playing;
if(intv)clearInterval(intv);
stepcnt=0;
if(playing){
var mkPath1=mkTransform(play1,play2,steptotal);
var mkPath2=mkTransform(pause1,pause2,steptotal);
intv=setInterval(function toPause(){
if(stepcnt<steptotal)
bars[0].setAttribute("d",mkPath1());
...