angularjs 教程13

本文将指导您如何在手机猫网页应用中使用CSS和JavaScript动画,通过集成angular-animate.js文件并修改HTML模板,实现CSS过渡动画、CSS关键帧动画以及JavaScript动画,以增强用户体验。

In this final step, we will enhance our phonecat web application by attaching CSS and JavaScript animations on top of the template code we created before.

  1. Reset the workspace to step 12.

    git checkout -f step-12
  2. Refresh your browser or check the app out on Angular's server.

  1. Reset the workspace to step 12.

    git checkout -f step-12
  2. Refresh your browser or check the app out on Angular's server.

Now that everything is set in place for a fully functional web application, we can attach CSS and JavaScript animations to common directives that are used to render our application. AngularJS comes bundled with an additional JavaScript file calledangular-animate.js which, when included into the website and set as a dependency with the application module, will enable animations throughout the application.

Common ng directives automatically trigger hooks for animations to tap into. When an animation is found then the animation will run in between the standard DOM operation that is being issued on the element at the given time (e.g. inserting and removing nodes on ngRepeat or adding and removing classes on ngClass).

The most important changes are listed below. You can see the full diff on GitHub:

How Animations work with ngAnimate

To get an idea of how animations work with AngularJS, please read the AngularJS Animation Guide first.

Template

The changes required within the HTML template code is to link the asset files which define the animations as well as theangular-animate.js file. The animation module, known as ngAnimate, is defined withinangular-animate.js and contains the code necessary to make your application become animation aware.

Here's what needs to changed in the index file:

app/index.html.

 
  1. ...
  2. <!-- jQuery is used for JavaScript animations (include this before angular.js) -->
  3. <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
  4.  
  5. <!-- required module to enable animation support in AngularJS -->
  6. <script src="lib/angular/angular-animate.js"></script>
  7.  
  8. <!-- for JavaScript Animations -->
  9. <script src="js/animations.js"></script>
  10.  
  11. <!-- for CSS Transitions and/or Keyframe Animations -->
  12. <link rel="stylesheet" href="css/animations.css">
  13. ...

Animations can now be created within the CSS code (animations.css) as well as the JavaScript code (animations.js). But before we start, let's create a new module which uses the ngAnimate module as a dependency just like we did before with ngResource.

Module & Animations

app/js/animations.js.

 
  1. angular.module('phonecatAnimations', ['ngAnimate']).
  2. // ...
  3. // this module will later be used to define animations
  4. // ...

And now let's attach this module to our application module...

app/js/app.js.

 
  1. // ...
  2. angular.module('phonecat', [
  3. 'ngRoute',
  4.  
  5. 'phonecatAnimations',
  6. 'phonecatControllers',
  7. 'phonecatFilters',
  8. 'phonecatServices',
  9. ]).
  10. // ...

Now, the phonecat module is animation aware. Let's make some animations!

Animating ngRepeat with CSS Transition Animations

We'll start off by adding CSS transition animations to our ngRepeat directive present on thephone-list.html page. First let's add an extra CSS class to our repeated element so that we can hook into it with our CSS animation code.

app/partials/phone-list.html.

 
  1. <!--
  2. Let's change the repeater HTML to include a new CSS class
  3. which we will later use for animations:
  4. -->
  5. <ul class="phones">
  6. <li ng-repeat="phone in phones | filter:query | orderBy:orderProp"
  7. class="thumbnail phone-listing">
  8. <a href="#/phones/{{phone.id}}" class="thumb"><img ng-src="{{phone.imageUrl}}"></a>
  9. <a href="#/phones/{{phone.id}}">{{phone.name}}</a>
  10. <p>{{phone.snippet}}</p>
  11. </li>
  12. </ul>

Notice how we added the phone-listing CSS class? This is all we need in our HTML code to get animations working.

Now for the actual CSS transition animation code:

app/css/animations.css

 
  1. .phone-listing.ng-enter,
  2. .phone-listing.ng-leave,
  3. .phone-listing.ng-move {
  4. -webkit-transition: 0.5s linear all;
  5. -moz-transition: 0.5s linear all;
  6. -o-transition: 0.5s linear all;
  7. transition: 0.5s linear all;
  8. }
  9.  
  10. .phone-listing.ng-enter,
  11. .phone-listing.ng-move {
  12. opacity: 0;
  13. height: 0;
  14. overflow: hidden;
  15. }
  16.  
  17. .phone-listing.ng-move.ng-move-active,
  18. .phone-listing.ng-enter.ng-enter-active {
  19. opacity: 1;
  20. height: 120px;
  21. }
  22.  
  23. .phone-listing.ng-leave {
  24. opacity: 1;
  25. overflow: hidden;
  26. }
  27.  
  28. .phone-listing.ng-leave.ng-leave-active {
  29. opacity: 0;
  30. height: 0;
  31. padding-top: 0;
  32. padding-bottom: 0;
  33. }

As you can see our phone-listing CSS class is combined together with the animation hooks that occur when items are inserted info and removed from the list:

  • The ng-enter class is applied to the element when a new phone is added to the list and rendered on the page.
  • The ng-move class is applied when items are moved around in the list.
  • The ng-leave class is applied when they're removed from the list.

The phone listing items are added and removed depending on the data passed to theng-repeat attribute. For example, if the filter data changes the items will be animated in and out of the repeat list.

Something important to note is that when an animation occurs, two sets of CSS classes are added to the element:

  1. a "starting" class that represents the style at the beginning of the animation
  2. an "active" class that represents the style at the end of the animation

The name of the starting class is the name of event that is fired (like enter, move or leave) prefixed with ng-. So anenter event will result in a class called ng-enter.

The active class name is the same as the starting class's but with an -active suffix. This two-class CSS naming convention allows the developer to craft an animation, beginning to end.

In our example above, elements expand from a height of 0 to 120 pixels when items are added or moved, around and collapsing the items before removing them from the list. There's also a nice fade-in and fade-out effect that also occurs at the same time. All of this is handled by the CSS transition declarations at the top of the example code above.

Although most modern browsers have good support for CSS transitions and CSS animations, IE9 and earlier do not. If you want animations that are backwards-compatible with older browsers, consider using JavaScript-based animations, which are described in detail below.

Animating ngView with CSS Keyframe Animations

Next let's add an animation for transitions between route changes in ngView.

To start, let's add a new CSS class to our HTML like we did in the example above. This time, instead of theng-repeat element, let's add it to the element containing the ng-view directive. In order to do this, we'll have to make some small changes to the HTML code so that we can have more control over our animations between view changes.

app/index.html.

 
  1. <div class="view-container">
  2. <div ng-view class="view-frame"></div>
  3. </div>

With this change, the ng-view directive is nested inside a parent element with aview-container CSS class. This class adds a position: relative style so that the positioning of theng-view is relative to this parent as it animates transitions.

With this in place, let's add the CSS for this transition animation to our animations.css file:

app/css/animations.css.

 
  1. .view-container {
  2. position: relative;
  3. }
  4.  
  5. .view-frame.ng-enter, .view-frame.ng-leave {
  6. background: white;
  7. position: absolute;
  8. top: 0;
  9. left: 0;
  10. right: 0;
  11. }
  12.  
  13. .view-frame.ng-enter {
  14. -webkit-animation: 0.5s fade-in;
  15. -moz-animation: 0.5s fade-in;
  16. -o-animation: 0.5s fade-in;
  17. animation: 0.5s fade-in;
  18. z-index: 100;
  19. }
  20.  
  21. .view-frame.ng-leave {
  22. -webkit-animation: 0.5s fade-out;
  23. -moz-animation: 0.5s fade-out;
  24. -o-animation: 0.5s fade-out;
  25. animation: 0.5s fade-out;
  26. z-index:99;
  27. }
  28.  
  29. @keyframes fade-in {
  30. from { opacity: 0; }
  31. to { opacity: 1; }
  32. }
  33. @-moz-keyframes fade-in {
  34. from { opacity: 0; }
  35. to { opacity: 1; }
  36. }
  37. @-webkit-keyframes fade-in {
  38. from { opacity: 0; }
  39. to { opacity: 1; }
  40. }
  41.  
  42. @keyframes fade-out {
  43. from { opacity: 1; }
  44. to { opacity: 0; }
  45. }
  46. @-moz-keyframes fade-out {
  47. from { opacity: 1; }
  48. to { opacity: 0; }
  49. }
  50. @-webkit-keyframes fade-out {
  51. from { opacity: 1; }
  52. to { opacity: 0; }
  53. }
  54.  
  55. /* don't forget about the vendor-prefixes! */

Nothing crazy here! Just a simple fade in and fade out effect between pages. The only out of the ordinary thing here is that we're using absolute positioning to position the next page (identified viang-enter) on top of the previous page (the one that has the ng-leave class) while performing a cross fade animation in between. So as the previous page is just about to be removed, it fades out while the new page fades in right on top of it. Once the leave animation is over then element is removed and once the enter animation is complete then theng-enter and ng-enter-active CSS classes are removed from the element rendering it to be position itself with its default CSS code (so no more absolute positioning once the animation is over). This works fluidly so that pages flow naturally between route changes without anything jumping around.

The CSS classes applied (the start and end classes) are much the same as with ng-repeat. Each time a new page is loaded the ng-view directive will create a copy of itself, download the template and append the contents. This ensures that all views are contained within a single HTML element which allows for easy animation control.

For more on CSS animations, see the Web Platform documentation.

Animating ngClass with JavaScript

Let's add another animation to our application. Switching to our phone-detail.html page, we see that we have a nice thumbnail swapper. By clicking on the thumbnails listed on the page, the profile phone image changes. But how can we change this around to add animations?

Lets think about it first, basically when you click on a thumbnail image, you're changing the state of the profile image to reflect the newly selected thumbnail image. The best way to specify state changes within HTML is to use classes. Much like before, how we used a CSS class to specify an animation, this time the animation will occur whenever the CSS class itself changes.

Whenever a new phone thumbnail is selected, the state changes and the .active CSS class is added to the matching profile image and the animation plays.

Let's get started and tweak our HTML code on the phone-detail.html page first:

app/partials/phone-detail.html.

 
  1. <!-- We're only changing the top of the file -->
  2. <div class="phone-images">
  3. <img ng-src="{{img}}"
  4. class="phone"
  5. ng-repeat="img in phone.images"
  6. ng-class="{active:mainImageUrl==img}">
  7. </div>
  8.  
  9. <h1>{{phone.name}}</h1>
  10.  
  11. <p>{{phone.description}}</p>
  12.  
  13. <ul class="phone-thumbs">
  14. <li ng-repeat="img in phone.images">
  15. <img ng-src="{{img}}" ng-mouseenter="setImage(img)">
  16. </li>
  17. </ul>

Just like with the thumbnails, we're using a repeater to display all the profile images as a list, however we're not animating any repeat-related animations. Instead, we're keeping our eye on the ng-class directive since whenever theactive class is true then it will be applied to the element and will render as visible. Otherwise, the profile image is hidden. In our case, there is always one element that has the active class, and, therefore, there will always be one phone profile image visible on screen at all times.

When the active class is added to the element, the active-add and theactive-add-active classes are added just before to signal AngularJS to fire off an animation. When removed, theactive-remove and the active-remove-active classes are applied to the element which in turn trigger another animation.

You may be thinking that we're just going to create another CSS-enabled animation. Although we could do that, let's take the opportunity to learn how to create JavaScript-enabled animations with theanimation() module method.

app/js/animations.js.

 
  1. angular.module('phonecatAnimations', ['ngAnimate'])
  2.  
  3. .animation('.phone', function() {
  4. return {
  5. addClass : function(element, className, done) {
  6. if(className != 'active') {
  7. return;
  8. }
  9. element.css({
  10. position: 'absolute',
  11. top: 500,
  12. left: 0,
  13. display: 'block'
  14. });
  15. jQuery(element).animate({
  16. top: 0
  17. }, done);
  18.  
  19. return function(cancel) {
  20. if(cancel) element.stop();
  21. };
  22. },
  23. removeClass : function(element, className, done) {
  24. if(className != 'active') return;
  25. element.css({
  26. position: 'absolute',
  27. left: 0,
  28. top: 0
  29. });
  30. jQuery(element).animate({
  31. top: -500
  32. }, done);
  33.  
  34. return function(cancel) {
  35. if(cancel) element.stop();
  36. };
  37. }
  38. };
  39. });

Note that we're using jQuery to implement the animation. jQuery isn't required to do JavaScript animations with AngularJS, but we're going to use it because writing your own JavaScript animation library is beyond the scope of this tutorial. For more on jQuery.animate, see thejQuery documentation.

Important: Be sure to use jQuery version 1.10.x. AngularJS does not yet support jQuery 2.x.

The addClass and removeClass callback functions are called whenever an a class is added or removed on the element that contains the class we registered, which is in this case.phone. When the .active class is added to the element (via theng-class directive) the addClass JavaScript callback will be fired withelement passed in as a parameter to that callback. The last parameter passed in is thedone callback function. The purpose of done is so you can let Angular know when the JavaScript animation has ended by calling it.

The removeClass callback works the same way, but instead gets triggered when a class is removed from the element.

Within your JavaScript callback, you create the animation by manipulating the DOM. In the code above, that's what theelement.css() and the element.animate() are doing. The callback positions the next element with an offset of500 pixels and animates both the previous and the new items together by shifting each item up500 pixels. This results in a conveyor-belt like animation. After theanimate function does its business, it calls done.

Notice that addClass and removeClass each return a function. This is anoptional function that's called when the animation is cancelled (when another animation takes place on the same element) as well as when the animation has completed. A boolean parameter is passed into the function which lets the developer know if the animation was cancelled or not. This function can be used to do any cleanup necessary for when the animation finishes.

Summary

There you have it! We have created a web app in a relatively short amount of time. In theclosing notes we'll cover where to go from here.

带开环升压转换器和逆变器的太阳能光伏系统 太阳能光伏系统驱动开环升压转换器和SPWM逆变器提供波形稳定、设计简单的交流电的模型 Simulink模型展示了一个完整的基于太阳能光伏的直流到交流电力转换系统,该系统由简单、透明、易于理解的模块构建而成。该系统从配置为提供真实直流输出电压的光伏阵列开始,然后由开环DC-DC升压转换器进行处理。升压转换器将光伏电压提高到适合为单相全桥逆变器供电的稳定直流链路电平。 逆变器使用正弦PWM(SPWM)开关来产生干净的交流输出波形,使该模型成为研究直流-交流转换基本操作的理想选择。该设计避免了闭环和MPPT的复杂性,使用户能够专注于光伏接口、升压转换和逆变器开关的核心概念。 此模型包含的主要功能: •太阳能光伏阵列在标准条件下产生~200V电压 •具有固定占空比操作的开环升压转换器 •直流链路电容器,用于平滑和稳定转换器输出 •单相全桥SPWM逆变器 •交流负载,用于观察实际输出行为 •显示光伏电压、升压输出、直流链路电压、逆变器交流波形和负载电流的组织良好的范围 •完全可编辑的结构,适合分析、实验和扩展 该模型旨在为太阳能直流-交流转换提供一个干净高效的仿真框架。布局简单明了,允许用户快速了解信号流,检查各个阶段,并根据需要修改参数。 系统架构有意保持模块化,因此可以轻松扩展,例如通过添加MPPT、动态负载行为、闭环升压控制或并网逆变器概念。该模型为进一步开发或整合到更大的可再生能源模拟中奠定了坚实的基础。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值