<svg viewBox="0 0 800 600" preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="ringMask">
<rect class="ringMask" x="463.7" y="166.3" fill="#FF0606" width="148" height="312"/>
</clipPath>
<linearGradient id="speakerGrad" gradientUnits="userSpaceOnUse" x1="287.0869" y1="227.6745" x2="533.7535" y2="385.6746">
<stop offset="0" style="stop-color:#0BD3F6"/>
<stop offset="1" style="stop-color:#2998D5"/>
</linearGradient>
</defs>
<g id="wholeIcon">
<g id="innerGroup">
<g clip-path="url(#ringMask)">
<ellipse id="outerRing" fill="none" stroke="url(#speakerGrad)" stroke-width="32" stroke-miterlimit="10" cx="338" cy="320.5" rx="128" ry="90"/>
<circle id="innerRing" fill="url(#speakerGrad)" cx="342.5" cy="320.5" r="71.3"/>
</g>
<polygon id="speakerEnd" fill="none" points="430,449 352,367 286,367 286,273 352,273 430,193.7 "/>
<polygon id="speakerStart" fill="url(#speakerGrad)" points="430,449 352,367 352,367 352,273 352,273 430,193.7 "/>
</g>
<ellipse id="outline" fill="none" stroke="url(#speakerGrad)" stroke-width="32" stroke-miterlimit="10" cx="400" cy="320.5" rx="200" ry="200"/>
<circle id="hit" fill="rgba(34,123,45,0)" cx="400" cy="320" r="223"/>
</g>
</svg>
body {
background-color:#FFF;
overflow: hidden;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
svg{
width:100%;
height:100%;
visibility:hidden;
}
#hit{
cursor:pointer;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
var xmlns = "http://www.w3.org/2000/svg",
xlinkns = "http://www.w3.org/1999/xlink",
select = function(s) {
return document.querySelector(s);
},
selectAll = function(s) {
return document.querySelectorAll(s);
},
outerRing = select('#outerRing'),
innerRing = select('#innerRing'),
speakerStart = select('#speakerStart'),
speakerStartPath = "430,449 352,367 352,367 352,273 352,273 430,193.7 ",
speakerEnd = select('#speakerEnd'),
hit = select('#hit'),
ringMask = select('.ringMask')
TweenMax.set('svg', {
visibility: 'visible'
})
TweenMax.set('#wholeIcon', {
transformOrigin:'50% 50%',
scale:0.6
})
TweenMax.set('#innerGroup', {
transformOrigin:'50% 50%',
x:-15
})
var tl = new TimelineMax({paused:true});
tl.to(outerRing, 1, {
attr:{
ry:128,
cx:'+=60'
},
ease:Expo.easeOut
})
.to(innerRing, 0.8, {
attr:{
cx:'+=56'
},
ease:Expo.easeOut
},'-=0.8')
.to(ringMask, 0.7, {
attr:{
x:'-=30'
},
ease:Expo.easeOut
},'-=1')
.to(speakerStart, 0.7, {
x:'-=30',
morphSVG:{shape:speakerEnd},
ease:Expo.easeOut
},'-=1')
.to('#innerGroup', 1, {
x:0,
ease:Expo.easeOut
},'-=1')
.addPause()
.to(outerRing, 1, {
attr:{
ry:90,
cx:'-=60'
},
ease:Elastic.easeOut.config(0.8, 0.8)
})
.to(innerRing, 0.8, {
attr:{
//ry:128,
cx:'-=56'
},
ease:Elastic.easeOut.config(0.6, 0.6)
},'-=0.8')
.to(ringMask, 0.7, {
attr:{
x:'+=30'
},
ease:Expo.easeOut
},'-=1')
.to(speakerStart, 0.7, {
x:'+=30',
morphSVG:{shape:speakerStartPath},
ease:Expo.easeOut
},'-=1')
.to('#innerGroup', 1, {
x:-15,
ease:Expo.easeOut
},'-=1')
hit.onclick = function(e){
if(tl.time() == tl.duration()){
tl.play(0);
} else {
tl.resume()
}
}
This Pen doesn't use any external CSS resources.