Skip to content

Instantly share code, notes, and snippets.

@CodeMyUI
Created January 9, 2017 04:50
Show Gist options
  • Save CodeMyUI/548eee55032088b3c3ebdf0ea448e3ad to your computer and use it in GitHub Desktop.
Save CodeMyUI/548eee55032088b3c3ebdf0ea448e3ad to your computer and use it in GitHub Desktop.
Responsive bodymovin modal / page transition
<div id="bodymovin"></div>
<button id="close" name="close">╳</button>
<div class="modal">
<div class="modal__content">
<h1>Bodymovin modal</h1>
<p>For this animation to stretch, set the BodyMovin rendererSettings to preserveAspectRatio: 'none'.</p>
</div>
</div>

Responsive bodymovin modal / page transition

Make a bodymovin animation responsive to its container (in this case the viewport) by setting the BodyMovin rendererSettings to preserveAspectRatio: 'none'.

A Pen by Jonas Sandstedt on CodePen.

License.

// Declare the animation container and parameter to be used in the animation
var animContainer = document.getElementById('bodymovin');
// The animation data exported from Adobe After Effects
var animationData = {"assets":[],"v":"4.3.0","ddd":0,"layers":[{"ddd":0,"ind":0,"ty":1,"nm":"blob__yellow","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[540,540,0]},"a":{"k":[540,540,0]},"s":{"k":[{"i":{"x":[0.222,0.222,0.667],"y":[1,1,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p222_1_0p167_0p167","0p222_1_0p167_0p167","0p667_0p667_0p167_0p167"],"t":4,"s":[0,0,100],"e":[100,100,100]},{"t":15}]}},"hasMask":true,"masksProperties":[{"cl":true,"inv":false,"mode":"a","pt":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":4,"s":[{"i":[[26.858,-3.247],[25.249,-14.754],[-5.297,-33],[-16.249,-9.037],[-28.885,-3.379],[-21,-2.703],[-40.627,14.108],[-1.297,12],[7.283,17.874],[17.465,10.855]],"o":[[-19,2.297],[-25.249,14.754],[5.297,33],[14.667,8.157],[28.885,3.379],[21,2.703],[17.679,-6.139],[3.22,-29.802],[-8.734,-21.435],[-22.887,-14.224]],"v":[[476,432.703],[431.249,460.246],[379.703,490],[426.333,512.843],[462.115,534.621],[501,518.297],[551.321,547.139],[565.297,516],[575.717,473.126],[521.887,477.224]]}],"e":[{"i":[[145.748,0],[141.126,-140.618],[22.297,-160],[-7.41,-117.525],[-128.115,-71.621],[-127.399,0],[-141.321,102.861],[0,194.556],[64.283,87.874],[138.363,82.457]],"o":[[-214.963,0],[-141.795,141.284],[-17.361,124.581],[3.667,58.158],[116.055,64.879],[236.39,0],[145.858,-106.163],[0,-112.43],[-95.835,-131.005],[-116.724,-69.561]],"v":[[506,3.703],[219.249,247.246],[9.703,488],[92.333,749.842],[72.115,1023.621],[526,936.297],[953.321,953.139],[978.297,592],[1063.717,236.126],[768.887,177.224]]}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":21,"s":[{"i":[[145.748,0],[141.126,-140.618],[22.297,-160],[-7.41,-117.525],[-128.115,-71.621],[-127.399,0],[-141.321,102.861],[0,194.556],[64.283,87.874],[138.363,82.457]],"o":[[-214.963,0],[-141.795,141.284],[-17.361,124.581],[3.667,58.158],[116.055,64.879],[236.39,0],[145.858,-106.163],[0,-112.43],[-95.835,-131.005],[-116.724,-69.561]],"v":[[506,3.703],[219.249,247.246],[9.703,488],[92.333,749.842],[72.115,1023.621],[526,936.297],[953.321,953.139],[978.297,592],[1063.717,236.126],[768.887,177.224]]}],"e":[{"i":[[281.812,0],[0,0],[0,-256],[0,-126.158],[0,0],[-271.5,0],[0,0],[0,148.875],[0,156.126],[0,0]],"o":[[-281.812,0],[0,0],[0,256],[0,126.158],[0,0],[271.5,0],[0,0],[0,-148.875],[0,-156.126],[0,0]],"v":[[501.812,0.016],[-0.001,-0.004],[-0.297,416],[0,845.842],[0.115,1079.621],[532.5,1080.297],[1080.036,1079.997],[1080.047,652.875],[1079.967,268.126],[1080.012,-0.026]]}]},{"t":32}]},"o":{"k":100},"x":{"k":0},"nm":"Mask 1"}],"sw":1080,"sh":1080,"sc":"#f4e097","ip":4,"op":33,"st":4,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":1,"nm":"blob__white","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[540,540,0]},"a":{"k":[540,540,0]},"s":{"k":[{"i":{"x":[0.222,0.222,0.667],"y":[1,1,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p222_1_0p167_0p167","0p222_1_0p167_0p167","0p667_0p667_0p167_0p167"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"t":11}]}},"hasMask":true,"masksProperties":[{"cl":true,"inv":false,"mode":"a","pt":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[26.858,-3.247],[25.249,-14.754],[-5.297,-33],[-16.249,-9.037],[-28.885,-3.379],[-21,-2.703],[-40.627,14.108],[-1.297,12],[7.283,17.874],[17.465,10.855]],"o":[[-19,2.297],[-25.249,14.754],[5.297,33],[14.667,8.157],[28.885,3.379],[21,2.703],[17.679,-6.139],[3.22,-29.802],[-8.734,-21.435],[-22.887,-14.224]],"v":[[476,432.703],[431.249,460.246],[379.703,490],[426.333,512.843],[462.115,534.621],[501,518.297],[551.321,547.139],[565.297,516],[575.717,473.126],[521.887,477.224]]}],"e":[{"i":[[145.748,0],[141.126,-140.618],[22.297,-160],[-7.41,-117.525],[-128.115,-71.621],[-127.399,0],[-141.321,102.861],[0,194.556],[64.283,87.874],[138.363,82.457]],"o":[[-214.963,0],[-141.795,141.284],[-17.361,124.581],[3.667,58.158],[116.055,64.879],[236.39,0],[145.858,-106.163],[0,-112.43],[-95.835,-131.005],[-116.724,-69.561]],"v":[[506,3.703],[219.249,247.246],[9.703,488],[92.333,749.842],[72.115,1023.621],[526,936.297],[953.321,953.139],[978.297,592],[1063.717,236.126],[768.887,177.224]]}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":17,"s":[{"i":[[145.748,0],[141.126,-140.618],[22.297,-160],[-7.41,-117.525],[-128.115,-71.621],[-127.399,0],[-141.321,102.861],[0,194.556],[64.283,87.874],[138.363,82.457]],"o":[[-214.963,0],[-141.795,141.284],[-17.361,124.581],[3.667,58.158],[116.055,64.879],[236.39,0],[145.858,-106.163],[0,-112.43],[-95.835,-131.005],[-116.724,-69.561]],"v":[[506,3.703],[219.249,247.246],[9.703,488],[92.333,749.842],[72.115,1023.621],[526,936.297],[953.321,953.139],[978.297,592],[1063.717,236.126],[768.887,177.224]]}],"e":[{"i":[[281.812,0],[0,0],[0,-256],[0,-126.158],[0,0],[-271.5,0],[0,0],[0,148.875],[0,156.126],[0,0]],"o":[[-281.812,0],[0,0],[0,256],[0,126.158],[0,0],[271.5,0],[0,0],[0,-148.875],[0,-156.126],[0,0]],"v":[[501.812,0.016],[-0.001,-0.004],[-0.297,416],[0,845.842],[0.115,1079.621],[532.5,1080.297],[1080.036,1079.997],[1080.047,652.875],[1079.967,268.126],[1080.012,-0.026]]}]},{"t":28}]},"o":{"k":100},"x":{"k":0},"nm":"Mask 1"}],"sw":1080,"sh":1080,"sc":"#ffffff","ip":0,"op":33,"st":0,"bm":0,"sr":1}],"ip":0,"op":33,"fr":60,"w":1080,"h":1080};
var params = {
container: animContainer,
renderer: 'svg',
loop: false,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio:'none'
}
};
// Load the bodyMovin animation
var anim = bodymovin.loadAnimation(params);
// Add class to the body to use some transition on the text in CSS
var body = document.body;
var close = document.getElementById('close');
body.classList.add("open");
// bodymovin event listener for when the animation
// is complete (the animation autostarts)
// if we open the modal, then
anim.addEventListener("complete", function() {
if (anim.playDirection == -1) {
// The modal is closed,
// so we restart the animation
// instead of having an extra trigger
// to open the modal again (just for demo purpose)
anim.setDirection(1);
anim.play();
body.classList.remove("completed");
} else {
// The modal is open, which triggers the content transitions
body.classList.add("open");
body.classList.add("completed");
}
});
// When clicking the cross,
// the animation reverses to close the modal
close.addEventListener("click", function() {
anim.setDirection(-1);
anim.play();
body.classList.remove("open");
})
<script src="http://codepen.io/sandstedt/pen/ZOarxj"></script>
@import url(https://fonts.googleapis.com/css?family=Roboto:100);
* { box-sizing: border-box; }
html, body {
height: 100%;
}
body {
background-color: #89E9C2;
margin: 0px;
overflow: hidden;
font-family: "Roboto", sans-serif;
font-weight: 100;
}
#bodymovin {
width: 100%;
height: 100%;
display: block;
overflow: hidden;
transform: translate3d(0, 0, 0);
text-align: center;
opacity: 1;
}
#close {
// initial state for the close button transition
transition: opacity 0.4s ease 0.1s, color 0.2s, transform 0.2s;
opacity: 0;
border: none;
background: none;
position: fixed;
top: 1em;
right: 1em;
font-size: 2em;
padding: 1em;
cursor: pointer;
z-index: 1;
}
// show the close button when the modal is open
.open #close {
opacity: 1;
}
#close:focus {
outline: none;
transform: scale(1.1);
}
.modal {
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
&__content {
// Set the initial state for the content transition
opacity: 0;
transform: scale(0.8) translate3D(0,-20px,0);
transition: opacity 0.2s, transform 0.8s cubic-bezier(.09,.52,.25,1);
text-align: center;
display: flex;
align-items: center;
flex-direction: column;
padding: 1em;
}
h1 {
text-transform: uppercase;
letter-spacing: 0.4em;
}
p {
max-width: 25em;
line-height: 1.9;
}
}
// Make the content transitions when the modal is open
.open .modal {
&__content {
opacity: 1;
transform: scale(1) translate3D(0,0,0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment