Animated Unsubscribe Page

HTML
<div class="container"> <svg id="svg" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 590 484.7"> <g id="blobs"> <path id="blob-1" d="M545.5,299c0,80.3-28.6,150.4-126.4,139.4-63.2-7.1-109.3-37.3-142.6-37.3-45.7,0-105.4,29.3-146.8,22.2-69-11.7-85.3-66.8-85.3-135.8,0-56.3,25.5-99.9,46.2-140.8,18.3-36.1,55.9-97.8,125.1-100.5,53.3-2.1,97.4,50.5,138.4,74.2,49.9,28.8,98.4-1.8,126,1.3C537.9,127.9,545.5,265.5,545.5,299Z" fill="#eddfeb"/> <path id="blob-3" d="M55.1,300.7c0,80.3,27.4,150.4,121,139.4,60.5-7.1,104.7-37.3,136.5-37.3,43.8,0,100.9,29.3,140.5,22.2,66-11.7,81.7-66.8,81.7-135.8,0-56.3-16.2-103.6-36.1-144.5-17.6-36.1-54.9-97.4-121.2-100.1-51-2.1-100.1,53.8-139.4,77.5-47.8,28.8-94.3-1.8-120.7,1.3C62.4,129.6,55.1,267.1,55.1,300.7Z" fill="#eddfeb"/> </g> <g id="confetti" class="confetti"> <rect x="284" y="230.4" width="17.7" height="17.67" rx="4" ry="4" fill="#543093"/> <rect x="284" y="230.4" width="17.7" height="17.67" rx="4" ry="4" fill="#543093"/> <rect x="285.4" y="231.7" width="17.7" height="17.67" rx="4" ry="4" fill="#fff"/> <rect x="285.4" y="231.7" width="17.7" height="17.67" rx="4" ry="4" fill="#fff"/> <rect x="285.4" y="230.1" width="17.7" height="17.67" rx="4" ry="4" fill="#d960ae"/> <rect x="285.4" y="230.1" width="17.7" height="17.67" rx="4" ry="4" fill="#d960ae"/> <rect x="285.4" y="231.7" width="17.7" height="17.67" rx="4" ry="4" fill="#f3c1df"/> <rect x="285.4" y="231.7" width="17.7" height="17.67" rx="4" ry="4" fill="#f3c1df"/> <circle cx="294.1" cy="241.3" r="9.7" fill="#543093"/> <circle cx="294.1" cy="243.6" r="12" fill="none" stroke="#fff" stroke-miterlimit="10" stroke-width="2"/> <circle cx="294.2" cy="243.6" r="12" fill="#fff"/> <circle cx="294.2" cy="243.6" r="12" fill="none" stroke="#fff" stroke-miterlimit="10" stroke-width="2"/> <circle cx="294.2" cy="243.6" r="12" fill="none" stroke="#d960ae" stroke-miterlimit="10" stroke-width="2"/> <circle cx="294.2" cy="243.6" r="12" fill="none" stroke="#d960ae" stroke-miterlimit="10" stroke-width="2"/> <circle cx="295.9" cy="242.1" r="12" fill="none" stroke="#543093" stroke-miterlimit="10" stroke-width="2"/> <circle cx="295.9" cy="242.1" r="12" fill="none" stroke="#543093" stroke-miterlimit="10" stroke-width="2"/> <circle cx="294.1" cy="241.3" r="9.7" fill="#d960ae"/> <circle cx="294.1" cy="241.3" r="9.7" fill="#d960ae"/> <circle cx="292.9" cy="241.3" r="9.7" fill="#fff"/> <circle cx="294.1" cy="241.3" r="9.7" fill="#d960ae"/> <circle cx="294.1" cy="241.3" r="9.7" fill="#543093"/> <circle cx="294.1" cy="241.3" r="9.7" fill="#d960ae"/> <circle cx="294.1" cy="241.3" r="9.7" fill="#543093"/> <circle cx="294.1" cy="241.3" r="9.7" fill="#543093"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#f3c1df"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#543093"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#d960ae"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#f3c1df"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#fff"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#543093"/> <path d="M300.9,243.1l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.1Z" fill="#d960ae"/> <path d="M300.9,243.1l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.1Z" fill="#f3c1df"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#543093"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#d960ae"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#f3c1df"/> <path d="M300.9,243.2l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.2Z" fill="#fff"/> <path d="M300.9,243.1l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.1Z" fill="#d960ae"/> <path d="M300.9,243.1l-3-3a1.5,1.5,0,0,1,0-2.1l3-3a2,2,0,0,0,.3-2.5,1.9,1.9,0,0,0-2.9-.3l-3.1,3.1a1.5,1.5,0,0,1-2.1,0l-3-3a2,2,0,0,0-2.5-.3,1.9,1.9,0,0,0-.3,2.9l3.1,3.1a1.5,1.5,0,0,1,0,2.1l-3,3a2,2,0,0,0-.3,2.5,1.9,1.9,0,0,0,2.9.3l3.1-3.1a1.5,1.5,0,0,1,2.1,0l3.1,3.1a1.9,1.9,0,0,0,2.9-.3A2,2,0,0,0,300.9,243.1Z" fill="#f3c1df"/> </g> <g id="envelope"> <path id="Background" d="M452.9,376.3a26.1,26.1,0,0,1-25.5,20.8H162.6a26.1,26.1,0,0,1-26-26V193.2a26.1,26.1,0,0,1,26-26H427.4a26.1,26.1,0,0,1,26,26V371.1a25.9,25.9,0,0,1-.5,5.2" fill="#d960ae" stroke="#543093" stroke-miterlimit="10" stroke-width="5"/> <g id="paper-group"> <rect id="paper" x="157.3" y="87.6" width="275.3" height="266.33" rx="26" ry="26" fill="#fff" stroke="#543093" stroke-miterlimit="10" stroke-width="5"/> <g id="face"> <g id="mouth"> <path id="mouth-scared" d="M275,220a18.7,18.7,0,0,1,35.9.1" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> <path id="mouth-sad" d="M258.8,231.9c3.9-14.5,17.7-25.2,34-25.2s30.3,10.8,34.1,25.4" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> <path id="mouth-worry" d="M271.1,218.7c10-11.1,28.2-15,43.6-9.4" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> <path id="mouth-happy" d="M259.3,207c3.9,14.5,17.7,25.2,34,25.2s30.3-10.8,34.1-25.4" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> <g id="mouth-laughing"> <path id="open-mouth" d="M323.8,208.3c3.9,0,6.7,3.9,5.9,7.9a37.5,37.5,0,0,1-73.5,0c-0.9-4.1,2-7.9,5.9-7.9h61.7Z" fill="#543093" opacity="0.98"/> <path id="tongue" d="M293.2,241.1c6.9,0,13.1-2.3,17.3-5.9a2.1,2.1,0,0,0,.5-2.6c-3.1-5.8-9.9-9.8-17.8-9.8s-14.7,4-17.8,9.8a2.1,2.1,0,0,0,.5,2.5C280,238.8,286.2,241.1,293.2,241.1Z" fill="#d960ae"/> </g> </g> <g id="eye-group"> <g id="eyes" class="eyes"> <ellipse id="eye-right" cx="349" cy="172.8" rx="11.2" ry="13.8" fill="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5" /> <ellipse id="eye-left" cx="235.5" cy="172.8" rx="11.2" ry="13.8" fill="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5" /> <path id="eyebrow-sad-right" d="M341.9,133.7c2.6,5.3,14.8,14.1,24.3,14.7" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> <path id="eyebrow-sad-left" d="M240.7,133.7c-2.6,5.3-14.8,14.1-24.3,14.7" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> </g> <g id="eyes-laughing"> <path id="eye-laughing-right" d="M332.2,174c0-8.3,7.5-15,16.8-15s16.8,6.7,16.8,15" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> <path id="eye-laughing-left" d="M218.7,174c0-8.3,7.5-15,16.8-15s16.8,6.7,16.8,15" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> </g> <g id="eyebrows-happy"> <path id="eyebrow-happy-right" d="M366.2,146.3c-2.6-5.3-14.8-14.1-24.3-14.7" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> <path id="eyebrow-happy-left" d="M216.4,146.3c2.6-5.3,14.8-14.1,24.3-14.7" fill="none" stroke="#543093" stroke-linecap="round" stroke-miterlimit="10" stroke-width="5"/> </g> </g> </g> </g> <path id="back" d="M451.9,186.7S322.4,288.2,313.4,294.1s-27,5.8-36.9,0S137.9,186.5,137.9,186.5a23.6,23.6,0,0,0-1.3,6.7V371.1a26.1,26.1,0,0,0,26,26H427.4a26,26,0,0,0,26-26V193.2C453.4,190.7,452.5,188.9,451.9,186.7Z" fill="#f3c1df" stroke="#543093" stroke-miterlimit="10" stroke-width="5"/> <g id="shadow"> <path id="shadow-3" d="M263.3,279.7s11.3-8.1,13.1-9.3c9.9-6.5,27-5.8,36.9,0,1.7,1,13.5,9.3,13.5,9.3" fill="none" stroke="#eddfeb" stroke-linejoin="bevel" stroke-width="7"/> <path id="shadow-2" d="M430.2,193.3L313.4,282.2a26.1,26.1,0,0,1-36.8,0L159.8,193.3V201l116.8,90.6c7.9,5.7,26.9,6.4,37,0l116.6-90.9v-7.4Z" fill="#eddfeb"/> </g> <path id="shadow-1" d="M425.2,381.5h-262c-14.1,0-24.2-11-24.2-24.4v13.2c0,13.4,10.1,24.3,24.2,24.3h262c12.7,1.2,23.9-8.4,25.2-19.5a42.8,42.8,0,0,0,.5-4.9V358.1a14.7,14.7,0,0,1-.5,3.9C448,373.1,437.6,381.5,425.2,381.5Z" fill="#d960ae" opacity="0.5"/> <g id="Front"> <path id="Front-2" data-name="Front" d="M139.8,381.9s127.5-99.5,136.5-105.4,27-5.8,36.9,0S449.8,382.1,449.8,382.1" fill="none" stroke="#543093" stroke-miterlimit="10" stroke-width="5"/> <path id="Front-3" data-name="Front" d="M225.4,315.3s41.9-33,51-38.9,27-5.8,36.9,0S355,307.9,355,307.9" fill="#f3c1df" stroke="#543093" stroke-miterlimit="10" stroke-width="5"/> </g> </g> </svg> <div class="bottom"> <h2 class="title">Do you want to unsubscribe?</h2> <p class="subtitle">If you unsubscribe, you will stop receiving our weekly newsletter. <p/> <div class="buttons"> <button id="unsubscribe">Unsubscribe</button> <button id="cancel">Cancel</button> <button id="go-back">Go back</button> </div> </div> </div>
SCSS
body { width: 100vw; height: 100vh; background: #fefefe; color: #373737; margin: 0; padding: 0; background: #543093; background: -moz-linear-gradient(45deg, #543093 32%, #d960ae 100%); background: -webkit-linear-gradient(45deg, #543093 32%, #d960ae 100%); background: linear-gradient(45deg, #543093 32%, #d960ae 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#543093", endColorstr="#d960ae", GradientType=1 ); } * { box-sizing: border-box; font-family: "Cabin", Arial, sans-serif; } .container { width: 600px; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); top: 50%; left: 50%; margin: 0; position: absolute; background: #fefefe; display: flex; align-items: center; justify-content: flex-start; flex-direction: column; padding-bottom:30px; box-shadow: 5px 10px 40px 0 rgba(0, 0, 0, 0.2); border-radius: 5px; } svg { max-width: 90%; } .bottom { text-align: center; margin-top: 0em; max-width: 70%; h2 { font-family: "Rokkitt", sans-serif; letter-spacing: 0.05em; font-size: 30px; line-height: 1.2; text-align: center; margin: 0 auto 0.25em; } p { color: #777; letter-spacing: 0.1em; font-size: 16px; line-height: 1.4; margin: 0 auto 2em; } } .buttons { width: 100%; display: flex; justify-content: center; flex-wrap: wrap; align-items: center; button { padding: 10px 30px; font-size: 20px; background-color: #d960ae; border: 0; cursor: pointer; border-radius: 4px; letter-spacing: 0.1em; color: #ffffff; margin-right: 20px; margin-bottom: 15px; transition: all 0.25s ease-in-out; &:hover { background-color: darken(#d960ae, 10%); } &#cancel { margin-right: 0; color: #333; background-color: #eddfeb; &:hover { background-color: darken(#eddfeb, 10%); } } &#go-back { display: none; } &:focus { border: none; outline: 0; } } } #blob-3, #blob-2, #mouth-happy, #mouth-sad, #eyebrow-happy-left, #eyebrow-happy-right, #eyes-laughing, #open-mouth, #tongue, #mouth-scared { display: none; } @media (max-width: 699px) { .container { width: 90%; } .bottom { margin-top: 1em; max-width:90%; } } @media (max-width: 399px) { .container { padding: 20px; } .bottom { // margin-top: 0em; // max-width: 90%; h2 { font-size: 24px; } } .buttons { flex-direction: column; button { margin-right: 0; } } svg { padding-top: 0; } }
ES6
var windowWidth = window.innerWidth; var windowHeight = window.innerHeight; function setWindowSize() { windowWidth = window.innerWidth; windowHeight = window.innerHeight; }; window.addEventListener('resize', setWindowSize); var eyes = document.querySelectorAll(".eyes"); var cursorPos = { x: 0, y: 0 }; window.addEventListener("mousemove", mousemove); window.addEventListener("touchmove", touchmove); function mousemove(e) { cursorPos = { x: e.clientX, y: e.clientY }; if (!clicked) { eyes.forEach(function(el) { eyeFollow.init(el); }) } } function touchmove(e) { cursorPos = { x: e.targetTouches[0].offsetX, y: e.targetTouches[0].offsetY }; if (!clicked) { eyes.forEach(function(el) { eyeFollow.init(el); }) } } var eyeFollow = (function() { function getOffset(el) { el = el.getBoundingClientRect(); return { x: el.left + window.scrollX, y: el.top + window.scrollY }; } function moveEye(eye) { var eyeOffset = getOffset(eye); var bBox = eye.getBBox(); var centerX = eyeOffset.x + bBox.width / 2; var centerY = eyeOffset.y + bBox.height / 2; var percentTop = Math.round((cursorPos.y - centerY) * 100 / windowHeight); var percentLeft = Math.round((cursorPos.x - centerX) * 100 / windowWidth); eye.style.transform = `translate(${percentLeft/5}px, ${ percentTop/5}px)` } return { init: (el) => { moveEye(el); } }; })(); var clicked, cancelled; var animate = (function() { var select = function(el) { return document.getElementById(el); }; var svg = select("svg"), blob1 = select("blob-1"), blob3 = select("blob-3"), envelope = select("envelope"), eyeGroup = select("eye-group"), paper = select("paper-group"), mouth = select("mouth"), mouthHappy = select("mouth-happy"), mouthScared = select("mouth-scared"), mouthSad = select("mouth-sad"), eyeLeft = MorphSVGPlugin.convertToPath(select("eye-left")), eyeRight = MorphSVGPlugin.convertToPath(select("eye-right")), eyeLaughingLeft = select("eye-laughing-left"), eyeLaughingRight = select("eye-laughing-right"), eyebrowHappyLeft = select("eyebrow-happy-left"), eyebrowHappyRight = select("eyebrow-happy-right"), eyebrowSadLeft = select("eyebrow-sad-left"), eyebrowSadRight = select("eyebrow-sad-right"), mouthWorry = select("mouth-worry"), openMouth = select("open-mouth"), tongue = select("tongue"), unsubscribeButton = select("unsubscribe"), cancelButton = select("cancel"), goBackButton = select("go-back"); var confettis = document.querySelectorAll('#confetti > *'); var title = document.querySelector('.title'), subtitle = document.querySelector('.subtitle'); var masterTl = new TimelineMax(); unsubscribeButton.addEventListener("mouseover", willUnsubscribe); cancelButton.addEventListener("mouseover", willCancel); unsubscribeButton.addEventListener("touchstart", willUnsubscribe); cancelButton.addEventListener("touchstart", willCancel); unsubscribeButton.addEventListener("click", hasUnsubscribed); cancelButton.addEventListener("click", hasCancelled); unsubscribeButton.addEventListener("mouseout", initFace); cancelButton.addEventListener("mouseout", initFace); unsubscribeButton.addEventListener("touchleave", initFace); cancelButton.addEventListener("touchleave", initFace); goBackButton.addEventListener("click", goBack); function animateBlob() { var speed = 10; var tlBlob = new TimelineMax({repeat:-1}); tlBlob.to(blob1, speed, {morphSVG:blob3, ease: Power0.easeNone}) .to(blob1, speed, {morphSVG:blob1, ease: Power0.easeNone}); } function makeConfetti() { var speed = 3; var confettiTl = new TimelineMax({ paused:true }); confettis.forEach(function(el) { var angle = random(0, 360); var delay = random(0, 6); var opacity = random(0.5, 1); var tl = new TimelineMax({delay: delay}); var posX = Math.cos(angle * Math.PI / 180) * 250; var posY = Math.sin(angle * Math.PI / 180) * 250; TweenMax.set(el,{autoAlpha:1}); tl.to(el, speed, {x:posX, y: posY, ease:Power0.easeOut, rotation:360, repeat:-1}); confettiTl.add(tl, 0); }); return confettiTl; } //Envelope animations function happyJump() { var speed = 0.15; var happyJumpTl = new TimelineMax({repeat:-1, repeatDelay: 1, delay:0.5, paused:true}); happyJumpTl.to(envelope, speed, {y:-20, ease: Power0.easeNone}) .to(envelope, speed, {y:0, ease: Power0.easeNone}) .to(envelope, speed, {y:-10, ease: Power0.easeNone}) .to(envelope, speed, {y:0, ease: Power0.easeNone}) .to(envelope, speed, {y:-5, ease: Power0.easeNone}) .to(envelope, speed, {y:0, ease: Power0.easeNone}); return happyJumpTl; } function shake() { var speed = 0.1; var shakeTl = new TimelineMax({repeat:-1, paused:true}); shakeTl.to(envelope, speed, {x:-1, ease: Power0.easeNone}) .to(envelope, speed, {x:1, ease: Power0.easeNone}); return shakeTl; } var doJump = happyJump(); var doShake = shake(); var addConfetti = makeConfetti(); function willUnsubscribe() { masterTl.add(doShake.play()); var speed = 0.2; TweenMax.to(mouthWorry, speed, {morphSVG:mouthScared, ease: Power0.easeNone}); TweenMax.to(paper, speed, {y:15}); TweenMax.to(eyeGroup, speed, {y:5}); TweenMax.to(mouth, speed, {y:5}); TweenMax.to(eyebrowSadLeft, speed, {y:5}); TweenMax.to(eyebrowSadRight, speed, {y:5}); }; function willCancel() { var speed = 0.2; TweenMax.to(mouthWorry, speed, {morphSVG:mouthHappy, ease: Power0.easeNone}); TweenMax.to(eyebrowSadLeft, speed, {morphSVG:eyebrowHappyLeft, ease: Power0.easeNone}); TweenMax.to(eyebrowSadRight, speed, {morphSVG:eyebrowHappyRight, ease: Power0.easeNone}); TweenMax.to(mouth, speed, {y:10}); TweenMax.to(eyebrowSadLeft, speed, {y:-10}); TweenMax.to(eyebrowSadRight, speed, {y:-10}); }; function hasUnsubscribed() { var speed = 0.2; TweenMax.to(mouthWorry, speed, {morphSVG:mouthSad, ease: Power0.easeNone}); TweenMax.to(eyeGroup, speed, {y:15}); TweenMax.to(eyebrowSadLeft, speed, {y:10}); TweenMax.to(eyebrowSadRight, speed, {y:10}); title.innerHTML = "We are sad to see you go!"; subtitle.innerHTML = "You have been unsubscribed and will no longer hear from us."; unsubscribeButton.style.display = 'none'; cancelButton.style.display = 'none'; goBackButton.style.display = 'block'; clicked = true; masterTl.remove(doShake); }; function hasCancelled() { masterTl.add(doJump.play()); masterTl.add(addConfetti.play()); var speed = 0.1; TweenMax.to(eyeLeft, speed, {morphSVG:eyeLaughingLeft, ease: Power0.easeNone}); TweenMax.to(eyeLeft, speed, {stroke:'#543093', fill:'none', ease: Power0.easeNone}); TweenMax.to(eyeRight, speed, {morphSVG:eyeLaughingRight, ease: Power0.easeNone}); TweenMax.to(eyeRight, speed, {stroke:'#543093', fill:'none', ease: Power0.easeNone}); TweenMax.to(mouthWorry, speed, {morphSVG:openMouth, ease: Power0.easeNone}); TweenMax.to(mouthWorry, speed, {fill:'#543093', stroke:'none', ease: Power0.easeNone}); TweenMax.to(tongue, speed, {css:{display:'block'}, ease: Power0.easeNone}); TweenMax.to(eyeGroup, speed, {y:10}); TweenMax.to(eyebrowSadLeft, speed, {y:0}); TweenMax.to(eyebrowSadRight, speed, {y:0}); title.innerHTML = "Thanks for staying with us!"; subtitle.innerHTML = "You will continue receiving our weekly newsletter. Yay!"; unsubscribeButton.style.display = 'none'; cancelButton.style.display = 'none'; goBackButton.style.display = 'block'; clicked = true; cancelled = true; }; function initFace() { masterTl.remove(doShake); if (!clicked) { var speed = 0.1; TweenMax.to(mouthWorry, speed, {morphSVG:mouthWorry, ease: Power0.easeNone}); TweenMax.to(mouthWorry, speed, {fill:'none', stroke:'#543093', ease: Power0.easeNone}) TweenMax.to(tongue, speed, {css:{display:'none'}, ease: Power0.easeNone}) TweenMax.to(eyebrowSadLeft, speed, {morphSVG:eyebrowSadLeft, ease: Power0.easeNone}); TweenMax.to(eyebrowSadRight, speed, {morphSVG:eyebrowSadRight, ease: Power0.easeNone}); TweenMax.to(paper, speed, {y:0}); TweenMax.to(eyeGroup, speed, {y:0}); TweenMax.to(mouth, speed, {y:0}); TweenMax.to(eyebrowSadLeft, speed, {y:0}); TweenMax.to(eyebrowSadRight, speed, {y:0}); TweenMax.to(eyeLeft, speed, {morphSVG:eyeLeft, ease: Power0.easeNone}); TweenMax.to(eyeLeft, speed, {stroke:'none', fill:'#543093', ease: Power0.easeNone}); TweenMax.to(eyeRight, speed, {morphSVG:eyeRight, ease: Power0.easeNone}); TweenMax.to(eyeRight, speed, {stroke:'none', fill:'#543093', ease: Power0.easeNone}); } }; function goBack() { clicked = false; cancelled = false; initAnimations(); masterTl.remove(doJump); masterTl.remove(addConfetti); confettis.forEach(function(el) { TweenMax.set(el, {x:0, y: 0, rotation:0}); }); title.innerHTML = "Do you want to unsubscribe?"; subtitle.innerHTML = "If you unsubscribe, you will stop receiving our weekly newsletter."; unsubscribeButton.style.display = 'block'; cancelButton.style.display = 'block'; goBackButton.style.display = 'none'; }; function initAnimations() { clicked = false; initFace(); animateBlob(); } return { init: () => { initAnimations(); } }; })(); document.addEventListener("DOMContentLoaded", animate.init()); function random(min, max) { if (max == null) { max = min; min = 0; } return Math.random() * (max - min) + min; }
Expand for more options Login