Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
step-14 Animations
Browse files Browse the repository at this point in the history
- Add animations to the application:
  - Animate changes to the phone list, adding, removing and reordering phones with `ngRepeat`.
  - Animate view transitions with `ngView`.
  - Animate changes to the main phone image in the phone detail view.
- Showcase three different kinds of animations:
  - CSS transition animations.
  - CSS keyframe animations.
  - JavaScript-based animations.
  • Loading branch information
petebacondarwin authored and gkalpak committed Nov 5, 2018
1 parent ad5993c commit f15c630
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 7 deletions.
67 changes: 67 additions & 0 deletions app/app.animations.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* Animate `ngRepeat` in `phoneList` component */
.phone-list-item.ng-enter,
.phone-list-item.ng-leave,
.phone-list-item.ng-move {
overflow: hidden;
transition: 0.5s linear all;
}

.phone-list-item.ng-enter,
.phone-list-item.ng-leave.ng-leave-active,
.phone-list-item.ng-move {
height: 0;
margin-bottom: 0;
opacity: 0;
padding-bottom: 0;
padding-top: 0;
}

.phone-list-item.ng-enter.ng-enter-active,
.phone-list-item.ng-leave,
.phone-list-item.ng-move.ng-move-active {
height: 120px;
margin-bottom: 20px;
opacity: 1;
padding-bottom: 4px;
padding-top: 15px;
}

/* Animate view transitions with `ngView` */
.view-container {
position: relative;
}

.view-frame {
margin-top: 20px;
}

.view-frame.ng-enter,
.view-frame.ng-leave {
background: white;
left: 0;
position: absolute;
right: 0;
top: 0;
}

.view-frame.ng-enter {
animation: 1s fade-in;
z-index: 100;
}

.view-frame.ng-leave {
animation: 1s fade-out;
z-index: 99;
}

@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}

@keyframes fade-out {
from { opacity: 1; }
to { opacity: 0; }
}

/* Older browsers might need vendor-prefixes for keyframes and animation! */
43 changes: 43 additions & 0 deletions app/app.animations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

angular.
module('phonecatApp').
animation('.phone', function phoneAnimationFactory() {
return {
addClass: animateIn,
removeClass: animateOut
};

function animateIn(element, className, done) {
if (className !== 'selected') return;

element.css({
display: 'block',
position: 'absolute',
top: 500,
left: 0
}).animate({
top: 0
}, done);

return function animateInEnd(wasCanceled) {
if (wasCanceled) element.stop();
};
}

function animateOut(element, className, done) {
if (className !== 'selected') return;

element.css({
position: 'absolute',
top: 0,
left: 0
}).animate({
top: -500
}, done);

return function animateOutEnd(wasCanceled) {
if (wasCanceled) element.stop();
};
}
});
16 changes: 15 additions & 1 deletion app/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ body {

h1 {
border-bottom: 1px solid gray;
margin-top: 0;
}

/* View: Phone list */
Expand All @@ -28,7 +29,7 @@ h1 {
/* View: Phone detail */
.phone {
background-color: white;
border: 1px solid black;
display: none;
float: left;
height: 400px;
margin-bottom: 2em;
Expand All @@ -37,6 +38,19 @@ h1 {
width: 400px;
}

.phone:first-child {
display: block;
}

.phone-images {
background-color: white;
float: left;
height: 450px;
overflow: hidden;
position: relative;
width: 450px;
}

.phone-thumbs {
list-style: none;
margin: 0;
Expand Down
1 change: 1 addition & 0 deletions app/app.module.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// Define the `phonecatApp` module
angular.module('phonecatApp', [
'ngAnimate',
'ngRoute',
'core',
'phoneDetail',
Expand Down
9 changes: 8 additions & 1 deletion app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
<title>Google Phone Gallery</title>
<link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="app.animations.css" />

<script src="lib/jquery/dist/jquery.js"></script>
<script src="lib/angular/angular.js"></script>
<script src="lib/angular-animate/angular-animate.js"></script>
<script src="lib/angular-resource/angular-resource.js"></script>
<script src="lib/angular-route/angular-route.js"></script>
<script src="app.module.js"></script>
<script src="app.config.js"></script>
<script src="app.animations.js"></script>
<script src="core/core.module.js"></script>
<script src="core/checkmark/checkmark.filter.js"></script>
<script src="core/phone/phone.module.js"></script>
Expand All @@ -21,7 +26,9 @@
</head>
<body>

<div ng-view></div>
<div class="view-container">
<div ng-view class="view-frame"></div>
</div>

</body>
</html>
6 changes: 5 additions & 1 deletion app/phone-detail/phone-detail.template.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<img ng-src="{{$ctrl.mainImageUrl}}" class="phone" />
<div class="phone-images">
<img ng-src="{{img}}" class="phone"
ng-class="{selected: img === $ctrl.mainImageUrl}"
ng-repeat="img in $ctrl.phone.images" />
</div>

<h1>{{$ctrl.phone.name}}</h1>

Expand Down
3 changes: 2 additions & 1 deletion app/phone-list/phone-list.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
<!--Body content-->

<ul class="phones">
<li ng-repeat="phone in $ctrl.phones | filter:$ctrl.query | orderBy:$ctrl.orderProp" class="thumbnail">
<li ng-repeat="phone in $ctrl.phones | filter:$ctrl.query | orderBy:$ctrl.orderProp"
class="thumbnail phone-list-item">
<a href="#!/phones/{{phone.id}}" class="thumb">
<img ng-src="{{phone.imageUrl}}" alt="{{phone.name}}" />
</a>
Expand Down
4 changes: 2 additions & 2 deletions e2e-tests/scenarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ describe('PhoneCat Application', function() {
});

it('should display the first phone image as the main phone image', function() {
var mainImage = element(by.css('img.phone'));
var mainImage = element(by.css('img.phone.selected'));

expect(mainImage.getAttribute('src')).toContain('img/phones/nexus-s.0.jpg');
});

it('should swap the main image when clicking on a thumbnail image', function() {
var mainImage = element(by.css('img.phone'));
var mainImage = element(by.css('img.phone.selected'));
var thumbnails = element.all(by.css('.phone-thumbs img'));

thumbnails.get(2).click();
Expand Down
1 change: 1 addition & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = function(config) {

files: [
'lib/angular/angular.js',
'lib/angular-animate/angular-animate.js',
'lib/angular-resource/angular-resource.js',
'lib/angular-route/angular-route.js',
'../node_modules/angular-mocks/angular-mocks.js',
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
"license": "MIT",
"dependencies": {
"angular": "1.7.x",
"angular-animate": "1.7.x",
"angular-resource": "1.7.x",
"angular-route": "1.7.x",
"bootstrap": "3.3.x"
"bootstrap": "3.3.x",
"jquery": "3.3.x"
},
"devDependencies": {
"angular-mocks": "1.7.x",
Expand Down

0 comments on commit f15c630

Please sign in to comment.