Based on this design: https://dribbble.com/shots/1933701-Liquid-Radio-Button
A Pen by Ryan LaBar on CodePen.
| <svg viewBox="0 0 800 600" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |
| <defs> | |
| <filter id="goo"> | |
| <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur"></feGaussianBlur><feColorMatrix in="blur" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo"></feColorMatrix> | |
| <feBlend in="SourceGraphic" in2="goo"></feBlend> | |
| </filter> | |
| <linearGradient x1="0%" y1="0%" x2="100%" y2="100%" id="linearGradient-1"> | |
| <stop stop-color="#C25068" offset="0%"></stop> | |
| <stop stop-color="#9E3B5C" offset="100%"></stop> | |
| </linearGradient> | |
| </defs> | |
| <rect id="Rectangle" fill="url(#linearGradient-1)" x="0" y="0" width="800" height="600"></rect> | |
| <g class="gooey" transform="translate(330.000000, 230.000000)" fill="#FFFFFF"> | |
| <circle class="dropTop" r="10" cx="70" cy="12"></circle> | |
| <circle class="drop" r="40" cx="70" cy="70"></circle> | |
| <circle class="drops drop0" r="40" cx="70" cy="70"></circle> | |
| <circle class="drops drop1" r="40" cx="70" cy="70"></circle> | |
| <circle class="drops drop2" r="40" cx="70" cy="70"></circle> | |
| <circle class="drops drop3" r="40" cx="70" cy="70"></circle> | |
| <circle class="drops drop4" r="40" cx="70" cy="70"></circle> | |
| <path class="ring0" d="M70,140 C31.3400675,140 0,108.659932 0,70 C0,31.3400675 31.3400675,0 70,0 C108.659932,0 140,31.3400675 140,70 C140,108.659932 108.659932,140 70,140 Z M70,129.552239 C102.889793,129.552239 129.552239,102.889793 129.552239,70 C129.552239,37.1102067 102.889793,10.4477612 70,10.4477612 C37.1102067,10.4477612 10.4477612,37.1102067 10.4477612,70 C10.4477612,102.889793 37.1102067,129.552239 70,129.552239 Z" id="Combined-Shape"></path> | |
| <path class="ring" d="M70,140 C31.3400675,140 0,108.659932 0,70 C0,31.3400675 31.3400675,0 70,0 C108.659932,0 140,31.3400675 140,70 C140,108.659932 108.659932,140 70,140 Z M70,129.552239 C102.889793,129.552239 129.552239,102.889793 129.552239,70 C129.552239,37.1102067 102.889793,10.4477612 70,10.4477612 C37.1102067,10.4477612 10.4477612,37.1102067 10.4477612,70 C10.4477612,102.889793 37.1102067,129.552239 70,129.552239 Z" id="Combined-Shape"></path> | |
| <circle class="toggler" fill= | |
| "rgba(255,255,255,0)" r="120" cx="70" cy="70"></circle> | |
| </g> | |
| </svg> | |
| <form> | |
| <input tabindex="-1" id="boom" name="boom" type="checkbox"> | |
| <div></div> | |
| </form> | |
| <p class="bottom">Based on <a href="https://dribbble.com/shots/1933701-Liquid-Radio-Button" target="_blank">this dribbble shot</a>.</p> |
| var check = new TimelineMax({paused:true}); | |
| var uncheck = new TimelineMax({paused:true}); | |
| check | |
| .set('.ring', {opacity:1}) | |
| .set('.drops', {opacity:0}) | |
| .set('.ring0', {opacity:0}) | |
| .set('.drop', {opacity:0, y:-32, scale:.4, x:0, transformOrigin:"50%, 0%"}) | |
| .set('.ring', {transformOrigin:"50%, 50%"}) | |
| .set('.dropTop', {opacity:1,scale:.2, transformOrigin:"50%, 0%"}) | |
| .add('sync') | |
| .to('.ring', .17, { scaleY:.95}, 'sync') | |
| .to('.dropTop', .1, { scale:1, y:.5, ease:Power0.easeNone}, 'sync') | |
| .to('.dropTop', .1, { scale:.3, ease:Power0.easeNone}, 'sync +=.08') | |
| .to('.dropTop', .08, {transformOrigin:"50%, 40%", scale:0, ease:Power0.easeNone}, 'sync +=.181') | |
| .set('.drop', { opacity:1, ease:Power0.easeNone}, 'sync') | |
| .to('.drop', .17, { y:0, ease:Power1.easeIn}, 'sync') | |
| .to('.drop', .08, {scale:.9, ease:Power0.easeNone}, 'sync +=.02') | |
| .to('.ring', 2, {transformOrigin:"50%, 50%", scaleY:1, ease:Elastic.easeOut.config(.8, .1)}, 'sync +=.14') | |
| .to('.drop', 1.8, {transformOrigin:"50%, 10%", scale:1, ease:Elastic.easeOut.config(.8, .14)}, 'sync +=.14') | |
| uncheck | |
| .set('.ring0', {opacity:1}) | |
| .set('.drop', {opacity:0}) | |
| .set('.ring', {opacity:0}) | |
| .set('.drops', {opacity:1}) | |
| .set('.drop0', {rotation:'40deg',transformOrigin:"50%, 50%"}) | |
| .set('.drop1', {rotation:'112deg',transformOrigin:"50%, 50%"}) | |
| .set('.drop2', {rotation:'175deg',transformOrigin:"50%, 50%"}) | |
| .set('.drop3', {rotation:'-110deg',transformOrigin:"50%, 50%"}) | |
| .set('.drop4', {rotation:'-35deg',transformOrigin:"50%, 50%"}) | |
| .add('uncheck') | |
| .to('.drops', .2, {transformOrigin:"50%, 50%", scaleX:.5, scaleY:.3,}) | |
| .staggerTo('.drops', .2, { cycle:{ | |
| x:[45, 59, 14, -62, -35], | |
| y:[-46, 29, 62, 15, -55], | |
| }}, '0.0184', 'uncheck+=.1') | |
| .to('.ring0', .2, {transformOrigin:"50%, 50%", scale:1.05}, 'uncheck+=.1') | |
| .add('last') | |
| .to('.ring0', 2, {transformOrigin:"50%, 50%", scale:1, ease:Elastic.easeOut.config(.8, .1)}, 'last') | |
| .to('.drops', .2, {scaleY:.1, scaleX:.3},'last+=0'); | |
| check.timeScale(1.27); | |
| uncheck.timeScale(1.14); | |
| $('.toggler').click(function(){ | |
| if (!$('#boom').is(':checked')){ | |
| check.play(0); | |
| $('#boom').prop('checked', true); | |
| } else{ | |
| uncheck.play(0); | |
| $('#boom').prop('checked', false); | |
| } | |
| }); |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js"></script> |
| html{height:100%;} | |
| body{ | |
| background:linear-gradient(to bottom right, #fff, #f0f0f0); | |
| text-align:center; | |
| min-height:600px; | |
| position:relative; | |
| height:100%; | |
| width:100%; | |
| } | |
| .bottom{ | |
| position:absolute; | |
| font-size:12px; | |
| bottom:0; | |
| right:0; | |
| left:0; | |
| color:rgba(#000, .4); | |
| a{color:rgba(#000, .4); | |
| transition:.27s; | |
| &:hover{ | |
| color:#C25068; | |
| } | |
| } | |
| } | |
| svg{ | |
| max-width:600px; | |
| margin-top:40px; | |
| box-shadow:0px 5px 22px rgba(black, .27) | |
| } | |
| svg .gooey{ | |
| filter:url('#goo'); | |
| } | |
| svg .drop, svg .dropTop, svg .drops{ | |
| opacity:0; | |
| } | |
| svg .toggler{cursor:pointer;} | |
| #boom{ | |
| position:absolute; | |
| top:-1000px; | |
| left:-1000px; | |
| opacity:0; | |
| & + div:before{content:"unchecked"; | |
| color:rgba(#000, .4);} | |
| &:checked + div:before{content:'checked'} | |
| } | |