Skip to content

Instantly share code, notes, and snippets.

@bfncs
Last active May 25, 2016 01:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bfncs/90ae0de3174e608465f6 to your computer and use it in GitHub Desktop.
Save bfncs/90ae0de3174e608465f6 to your computer and use it in GitHub Desktop.
Demo: Different page transitions based on clicked anchor with smoothState.js

Demo: Different page transitions based on clicked anchor with smoothState.js

This demo shows how to switch transitions based on initiating link with smoothState.js. This solution has been inspired by @pudgereyem's comment on smoothState.js #143.

You can view the demo here.

The demo implements a crude idea of viewports that are horizontally aligned to determine the needed animation: every anchor has a numeric data-target paramter that represents the needed viewport while every scene element provides a numeric data-viewport parameter that reprents the current viewport. If the viewport requested for the clicked target is larger then the current viewport, the scene element is moved to the left, else to the right.

The logic to determine the wanted animation is implemented in the onBefore callback, the animations themselves are defined as pure CSS animations. Please feel free to take this as a starting point to implement you own animation logic.

Install

To install this demo, copy all files to the root of your local webserver.

Alternatively, you can use the builtin static webserver.

  1. Install Node.js dependencies: npm install
  2. Start webserver npm start
  3. You can now access the demo site under http://localhost:8080

If you need to change the used port to PORT, try npm config set smoothstate-transitions-demo:port PORT.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Home</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="main">
<ul class="nav">
<li><a href="page-left.html" data-target="-1">Left</a></li>
<li><a href="index.html" data-target="0">Home</a></li>
<li><a href="page-right.html" data-target="1">Right</a></li>
</ul>
<div class="sceneElement" data-viewport="0">
<h1>Home page</h1>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no
sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est
Lorem ipsum dolor sit amet.</p>
<p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu
feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril
delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
</div>
</div>
<!-- Scripts -->
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/smoothState.js/0.7.2/jquery.smoothState.min.js"></script>
<script src="main.js"></script>
</body>
</html>
(function ($) {
'use strict';
$(document).ready(function () {
// Init here.
var $body = $('body'),
$main = $('#main'),
$site = $('html, body'),
transition = 'fade',
smoothState;
smoothState = $main.smoothState({
onBefore: function($anchor, $container) {
var current = $('[data-viewport]').first().data('viewport'),
target = $anchor.data('target');
current = current ? current : 0;
target = target ? target : 0;
if (current === target) {
transition = 'fade';
} else if (current < target) {
transition = 'moveright';
} else {
transition = 'moveleft';
}
},
onStart: {
duration: 400,
render: function (url, $container) {
$main.attr('data-transition', transition);
$main.addClass('is-exiting');
$site.animate({scrollTop: 0});
}
},
onReady: {
duration: 0,
render: function ($container, $newContent) {
$container.html($newContent);
$container.removeClass('is-exiting');
}
},
}).data('smoothState');
});
}(jQuery));
{
"name": "smoothstate-transitions-demo",
"version": "1.0.0",
"description": "Demo: Switch transitions based on initiating link with smoothState.js",
"author": "Marc Löhe",
"license": "MIT",
"devDependencies": {
"http-server": "^0.8.5"
},
"config": {
"port": "8080"
},
"scripts": {
"start": "http-server ./ -p $npm_package_config_port"
}
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>First</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="main">
<ul class="nav">
<li><a href="page-left.html" data-target="-1">Left</a></li>
<li><a href="index.html" data-target="0">Home</a></li>
<li><a href="page-right.html" data-target="1">Right</a></li>
</ul>
<div class="sceneElement" data-viewport="-1">
<h1>Left page</h1>
<p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu
feugiat nulla facilisis.</p>
<p>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus
est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et
justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores
duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna
no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit
amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
erat.</p>
</div>
</div>
<!-- Scripts -->
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/smoothState.js/0.7.2/jquery.smoothState.min.js"></script>
<script src="main.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Second</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="main">
<ul class="nav">
<li><a href="page-left.html" data-target="-1">Left</a></li>
<li><a href="index.html" data-target="0">Home</a></li>
<li><a href="page-right.html" data-target="1">Right</a></li>
</ul>
<div class="sceneElement" data-viewport="1">
<h1>Right page</h1>
<p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea
commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat,
vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit
praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p>
<p>Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer
possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod
tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
</div>
</div>
<!-- Scripts -->
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/smoothState.js/0.7.2/jquery.smoothState.min.js"></script>
<script src="main.js"></script>
</body>
</html>
#main {
max-width: 720px;
margin: 0 auto;
padding: 2em 1em;
}
.nav {
margin: 0;
padding: 0;
list-style: none;
}
.nav:before {
content: 'Navigation: ';
}
.nav li {
display: inline;
margin: 0 .4em;
}
@-webkit-keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-webkit-keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@-webkit-keyframes moveInFromLeft {
0% {
opacity: 0;
-webkit-transform: translateX(-100px);
transform: translateX(-100px);
}
100% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
@keyframes moveInFromLeft {
0% {
opacity: 0;
-webkit-transform: translateX(-100px);
transform: translateX(-100px);
}
100% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
@-webkit-keyframes moveOutToLeft {
0% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
100% {
opacity: 0;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
}
@keyframes moveOutToLeft {
0% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
100% {
opacity: 0;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
}
@-webkit-keyframes moveInFromRight {
0% {
opacity: 0;
-webkit-transform: translateX(100px);
transform: translateX(100px);
}
100% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
@keyframes moveInFromRight {
0% {
opacity: 0;
-webkit-transform: translateX(100px);
transform: translateX(100px);
}
100% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
@-webkit-keyframes moveOutToRight {
0% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
100% {
opacity: 0;
-webkit-transform: translateX(50%);
transform: translateX(50%);
}
}
@keyframes moveOutToRight {
0% {
opacity: 1;
-webkit-transform: translateX(0);
transform: translateX(0);
}
100% {
opacity: 0;
-webkit-transform: translateX(50%);
transform: translateX(50%);
}
}
.sceneElement {
-webkit-animation-duration: .4s;
animation-duration: .4s;
transition-timing-function: ease-in;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
.is-exiting .sceneElement {
transition-timing-function: ease-out;
}
#main[data-transition=fade] .sceneElement {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
}
#main[data-transition=fade] .is-exiting .sceneElement {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
}
#main[data-transition=moveleft] .sceneElement {
-webkit-animation-name: moveInFromLeft;
animation-name: moveInFromLeft;
}
#main[data-transition=moveleft].is-exiting .sceneElement {
-webkit-animation-name: moveOutToRight;
animation-name: moveOutToRight;
}
#main[data-transition=moveright] .sceneElement {
-webkit-animation-name: moveInFromRight;
animation-name: moveInFromRight;
}
#main[data-transition=moveright].is-exiting .sceneElement {
-webkit-animation-name: moveOutToLeft;
animation-name: moveOutToLeft;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment