Ionic实现动画与SVG的动态背景

来源:互联网 发布:咫尺网络登录 编辑:程序博客网 时间:2024/05/29 03:45



最近我写了一些内容在SVG(可缩放矢量图形),主要是因为他们就是很炫酷效果吸引我。
我已经创建的内容主要是介绍和漂亮的动画的话我一直使用简单的CSS动画和关键帧,所以我想解决一个更真实的问题和创造的东西,看起来真的很酷。


我想要创建的是一个应用程序的背景,它将有一个图形表示的时间或天气。它可能是中午和晴天,多云,夜间,甚至日落(有点像iOS上的默认天气应用)- SVG是一个完美的候选人。由于我们可以用JavaScript来操纵SVG的部分,我们可以从一个单一的SVG和修改它的飞行。如果原来的SVG是一个阳光灿烂的日子,在天空中的云,我们可以删除太阳和改变天空的颜色,使之成为夜间时间,或者我们可以移动到屏幕底部的太阳,使背景橙创建日落效应。


这就是我最终效果的展示:

Time of Day Animation in Ionic


这是一个相当基本的实现,但它很酷,对不对?在未来,我想延长这一点,以便它自动调整时间和天气,但现在它允许您切换之间的各种预定义的设置(白天,晚上,日落,多云)。
在本教程中,我将通过如何使用SVG在ionic创建动态背景。我不会走过实际的SVG创作,只是修改它,所以如果你不熟悉SVG是如何创建的,我建议看第一个:SVG动画ionic。


1、创建新的ionic应用


我们将首先产生一个新的空白ionic应用程序,这样做只运行下面的命令:

ionic start ionic-sunset blank

一旦已经完成生成,你应该使它成为你的工作目录:

cd ionic-sunset

我们只是将SVG动画添加到自动生成的主页上,因此不再需要设置。


2、设置SVG


在我们做任何事情前,这是SVG看起来像插画:

SVG Screenshot


将直接嵌入到应用程序中。


修改 src/pages/home/home.html :

<ion-content>
 
    <svgclass="background"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"viewBox="0 0 750 1334">
      <defs>
        <style>
          .cls-1 {
            fill: url(#linear-gradient);
          }
 
          .cls-2 {
            fill: #fefbdf;
            opacity: 0.07;
          }
 
          .cls-3 {
            fill: #ffda71;
          }
 
          .cls-4, .cls-5 {
            fill: #fff;
          }
 
          .cls-4 {
            opacity: 0.95;
          }
        </style>
        <linearGradientid="linear-gradient"x1="375"y1="1334"x2="375"gradientUnits="userSpaceOnUse">
          <stopoffset="0"stop-color="#fff"/>
          <stopoffset="1"stop-color="#50a7dd"/>
        </linearGradient>
      </defs>
      <title>sunsetsvg</title>
      <rectid="Sky-2"data-name="Sky"class="cls-1"width="750"height="1334"/>
      <gid="Sun"data-name="Sun">
        <circleclass="cls-2"cx="385"cy="335.7"r="315.74"/>
        <circleclass="cls-3"cx="385"cy="335.7"r="180.56"/>
      </g>
      <gid="Clouds">
        <pathid="Cloud"class="cls-4"d="M303.24,920.47c9.53-6.84,15.35-16,15.35-26,0-18.94-20.8-34.66-48.16-37.83,0-.2,0-0.39,0-0.59,0-28.13-29.43-50.93-65.74-50.93-31.76,0-58.27,17.45-64.4,40.65A156.9,156.9,0,0,0,116.74,844c-58.3,0-105.56,31.51-105.56,70.37s47.26,70.37,105.56,70.37c22.56,0,43.45-4.72,60.61-12.75,10.15,19.11,43.41,33.12,82.91,33.12,47.56,0,86.11-20.31,86.11-45.37C346.37,943,329,928.31,303.24,920.47Z"/>
        <pathid="Cloud-2"data-name="Cloud"class="cls-5"d="M714.81,520.89c0-19.94-38.95-36.37-89.12-38.62,3.74-4.4,5.79-9.17,5.79-14.16,0-22-39.8-39.81-88.89-39.81-45.55,0-83.1,15.35-88.27,35.13-13.56-5.18-30.92-8.51-50-9.1-10.25-10.15-27-16.77-45.95-16.77-31.19,0-56.48,17.93-56.48,40,0,0.42,0,.84,0,1.26-19.2,9.08-31.53,23.07-31.53,38.79,0,27.36,37.31,49.54,83.33,49.54,20.06,0,38.45-4.21,52.83-11.23a33.31,33.31,0,0,0,35.73,9.44c11.07,22.73,38.54,38.83,70.7,38.83,20,0,38.26-6.26,51.83-16.47,8.79,9.95,23.5,16.47,40.17,16.47,26.92,0,48.74-17,48.74-38a30.14,30.14,0,0,0-1.5-9.38C688.94,551.06,714.81,537.14,714.81,520.89Z"/>
        <pathid="Cloud-3"data-name="Cloud"class="cls-4"d="M303.24,351c9.53-6.84,15.35-16,15.35-26,0-18.94-20.8-34.66-48.16-37.83,0-.2,0-0.39,0-0.59,0-28.13-29.43-50.93-65.74-50.93-31.76,0-58.27,17.45-64.4,40.65a156.9,156.9,0,0,0-23.56-1.76c-58.3,0-105.56,31.51-105.56,70.37s47.26,70.37,105.56,70.37c22.56,0,43.45-4.72,60.61-12.75,10.15,19.11,43.41,33.12,82.91,33.12,47.56,0,86.11-20.31,86.11-45.37C346.37,373.53,329,358.87,303.24,351Z"/>
        <pathid="Cloud-4"data-name="Cloud"class="cls-5"d="M657.61,1201.29c9.53-6.84,15.35-16,15.35-26,0-18.94-20.8-34.66-48.16-37.83,0-.2,0-0.39,0-0.59,0-28.13-29.43-50.93-65.74-50.93-31.76,0-58.27,17.45-64.4,40.65a156.9,156.9,0,0,0-23.56-1.76c-44.93,0-83.29,18.71-98.53,45.08-30.67,13.75-50.29,34.78-50.29,58.36,0,41.42,60.52,75,135.19,75,41.79,0,79.14-10.52,103.94-27,14.64,6.08,33.12,9.71,53.21,9.71,47.56,0,86.11-20.31,86.11-45.37C700.74,1223.79,683.38,1209.13,657.61,1201.29Z"/>
      </g>
    </svg>
 
</ion-content>


让我们打破在SVG上面的重要组件。我们有一个直线渐变定义,我们使用的是天空–梯度过渡从蓝色到白色,让我们只是改变一种颜色(即改变蓝顶橙将日落的效果)。这种梯度并运用于sky-2矩形覆盖整个背景。
接下来,我们有一组圆组成的太阳-有太阳本身,然后在太阳周围的一个较大的圆圈,给它一点辉光/镜头耀斑效应。
然后我们有一组由自定义路径定义的三个云。我们将得到所有这些对象的引用,并以某种方式修改它们(它们的风格或位置)来达到我们想要的结果。

三.添加时间
在我们开始操作SVG本身之前,我们将把时间叠加到SVG上,并设置一些样式。虽然没有太多的时间功能内置到应用程序中,我们将使用日期FNS包来帮助我们的时间格式。我没有很多时间玩日期FNS还,但它似乎是一个更轻的替代时刻进行时间管理。


安装日期FNS你将需要运行下面的命令。

npm install date-fns --save

然后,我们将建立在home.ts文件我们需要的一切。


修改 src/pages/home/home.ts:

import{ Component } from '@angular/core';
import{ NavController } from 'ionic-angular';
import* as dateFns from 'date-fns';
 
@Component({
  selector:'page-home',
  templateUrl:'home.html'
})
exportclass HomePage {
 
    timeOfDay: Date = newDate();
    timeString: string = '12:00';
 
    constructor(public navCtrl: NavController) {
 
    }
 
    ionViewDidLoad(){
 
        this.timeString = dateFns.format(this.timeOfDay,'h:mm A');
 
    }
 
}


我们从日期FNS包装进口的功能,然后我们用这个格式我们的约会对象转换成一个字符串,将看起来像这样:早上7:35。
现在让我们添加到我们的模板。

修改 src/pages/home/home.html :

<ion-content>
 
    <divclass="controls">
        <buttoncolor="light"ion-button (click)="setDay()">Day</button>
        <buttoncolor="light"ion-button (click)="setCloudy()">Cloudy</button>
        <buttoncolor="light"ion-button (click)="setSunset()">Sunset</button>
        <buttoncolor="light"ion-button (click)="setNight()">Night</button>
    </div>
 
    <svgclass="background"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"viewBox="0 0 750 1334">
      <defs>
        <style>
          .cls-1 {
            fill: url(#linear-gradient);
          }
 
          .cls-2 {
            fill: #fefbdf;
            opacity: 0.07;
          }
 
          .cls-3 {
            fill: #ffda71;
          }
 
          .cls-4, .cls-5 {
            fill: #fff;
          }
 
          .cls-4 {
            opacity: 0.95;
          }
        </style>
        <linearGradientid="linear-gradient"x1="375"y1="1334"x2="375"gradientUnits="userSpaceOnUse">
          <stopoffset="0"stop-color="#fff"/>
          <stopoffset="1"stop-color="#50a7dd"/>
        </linearGradient>
      </defs>
      <title>sunsetsvg</title>
      <rectid="Sky-2"data-name="Sky"class="cls-1"width="750"height="1334"/>
      <gid="Sun"data-name="Sun">
        <circleclass="cls-2"cx="385"cy="335.7"r="315.74"/>
        <circleclass="cls-3"cx="385"cy="335.7"r="180.56"/>
      </g>
      <gid="Clouds">
        <pathid="Cloud"class="cls-4"d="M303.24,920.47c9.53-6.84,15.35-16,15.35-26,0-18.94-20.8-34.66-48.16-37.83,0-.2,0-0.39,0-0.59,0-28.13-29.43-50.93-65.74-50.93-31.76,0-58.27,17.45-64.4,40.65A156.9,156.9,0,0,0,116.74,844c-58.3,0-105.56,31.51-105.56,70.37s47.26,70.37,105.56,70.37c22.56,0,43.45-4.72,60.61-12.75,10.15,19.11,43.41,33.12,82.91,33.12,47.56,0,86.11-20.31,86.11-45.37C346.37,943,329,928.31,303.24,920.47Z"/>
        <pathid="Cloud-2"data-name="Cloud"class="cls-5"d="M714.81,520.89c0-19.94-38.95-36.37-89.12-38.62,3.74-4.4,5.79-9.17,5.79-14.16,0-22-39.8-39.81-88.89-39.81-45.55,0-83.1,15.35-88.27,35.13-13.56-5.18-30.92-8.51-50-9.1-10.25-10.15-27-16.77-45.95-16.77-31.19,0-56.48,17.93-56.48,40,0,0.42,0,.84,0,1.26-19.2,9.08-31.53,23.07-31.53,38.79,0,27.36,37.31,49.54,83.33,49.54,20.06,0,38.45-4.21,52.83-11.23a33.31,33.31,0,0,0,35.73,9.44c11.07,22.73,38.54,38.83,70.7,38.83,20,0,38.26-6.26,51.83-16.47,8.79,9.95,23.5,16.47,40.17,16.47,26.92,0,48.74-17,48.74-38a30.14,30.14,0,0,0-1.5-9.38C688.94,551.06,714.81,537.14,714.81,520.89Z"/>
        <pathid="Cloud-3"data-name="Cloud"class="cls-4"d="M303.24,351c9.53-6.84,15.35-16,15.35-26,0-18.94-20.8-34.66-48.16-37.83,0-.2,0-0.39,0-0.59,0-28.13-29.43-50.93-65.74-50.93-31.76,0-58.27,17.45-64.4,40.65a156.9,156.9,0,0,0-23.56-1.76c-58.3,0-105.56,31.51-105.56,70.37s47.26,70.37,105.56,70.37c22.56,0,43.45-4.72,60.61-12.75,10.15,19.11,43.41,33.12,82.91,33.12,47.56,0,86.11-20.31,86.11-45.37C346.37,373.53,329,358.87,303.24,351Z"/>
        <pathid="Cloud-4"data-name="Cloud"class="cls-5"d="M657.61,1201.29c9.53-6.84,15.35-16,15.35-26,0-18.94-20.8-34.66-48.16-37.83,0-.2,0-0.39,0-0.59,0-28.13-29.43-50.93-65.74-50.93-31.76,0-58.27,17.45-64.4,40.65a156.9,156.9,0,0,0-23.56-1.76c-44.93,0-83.29,18.71-98.53,45.08-30.67,13.75-50.29,34.78-50.29,58.36,0,41.42,60.52,75,135.19,75,41.79,0,79.14-10.52,103.94-27,14.64,6.08,33.12,9.71,53.21,9.71,47.56,0,86.11-20.31,86.11-45.37C700.74,1223.79,683.38,1209.13,657.61,1201.29Z"/>
      </g>
    </svg>
 
    <divclass="time">{{timeString}}</div>
</ion-content>

我们已经在底部添加了时间字符串,我们还增加了一些按钮来触发我们下一步将要创建的SVG函数。
现在,我们只需要添加一个小造型,所以一切显示,因为它应该。


修改 src/pages/home/home.scss :

page-home {
 
    .scroll-content {
        display: flex;
        align-items:center;
        justify-content:center;
    }
 
    .time {
        z-index:1;
        font-size:3em;
        font-weight:bold;
        color:#fff;
        text-shadow:1px1px 2px #8e8e8e;
    }
 
    .background {
        position:absolute;
    }
 
    .controls {
        position:absolute;
        top:10px;
        z-index:1;
        opacity:0.2;
    }
 
}


修改 src/pages/home/home.ts:

import{ Component, Renderer } from '@angular/core';
import{ NavController } from 'ionic-angular';
import* as dateFns from 'date-fns';
 
@Component({
  selector:'page-home',
  templateUrl:'home.html'
})
exportclass HomePage {
 
    timeOfDay: Date = newDate();
    timeString: string = '12:00';
 
    sky: any;
    entireSun: any;
    allClouds: any;
    clouds: any;
 
    constructor(public navCtrl: NavController, public renderer: Renderer) {
 
    }
 
    ionViewDidLoad(){
 
        this.timeString = dateFns.format(this.timeOfDay,'h:mm A');
 
        this.sky = document.querySelector('linearGradient [offset="1"]');
        this.entireSun = document.querySelector('#Sun');
        this.clouds = document.querySelectorAll('#Clouds path');
 
        this.setTransitions();
 
    }
 
    setTransitions(){
 
        this.renderer.setElementStyle(this.sky,'transition','1s linear');
        this.renderer.setElementStyle(this.entireSun,'transition','1s linear');
 
        this.clouds.forEach((cloud) => {
            this.renderer.setElementStyle(cloud,'transition','1s linear');
        });
 
    }
 
    setNight(){
 
        this.renderer.setElementAttribute(this.sky,'stop-color','#141944');
        this.renderer.setElementAttribute(this.entireSun,'transform','translate(1, 2000)');
        this.renderer.setElementAttribute(this.entireSun,'opacity','1');
 
        this.clouds.forEach((cloud) => {
            this.renderer.setElementStyle(cloud,'fill','#fff');
            this.renderer.setElementStyle(cloud,'opacity','0.2');
        });
 
    }
 
    setDay(){
 
        this.renderer.setElementAttribute(this.sky,'stop-color','#50a7dd');
        this.renderer.setElementAttribute(this.entireSun,'opacity','1');
        this.renderer.setElementAttribute(this.entireSun,'transform','translate(1, 1)');
 
        this.clouds.forEach((cloud) => {
            this.renderer.setElementStyle(cloud,'fill','#fff');
            this.renderer.setElementStyle(cloud,'opacity','1');
        });
 
    }
 
    setSunset(){
 
        this.renderer.setElementAttribute(this.entireSun,'transform','translate(1, 1000)');
        this.renderer.setElementAttribute(this.entireSun,'opacity','1');
        this.renderer.setElementAttribute(this.sky,'stop-color','#e2905a');
 
        this.clouds.forEach((cloud) => {
            this.renderer.setElementStyle(cloud,'fill','#e2c1d8');
            this.renderer.setElementStyle(cloud,'opacity','0.4');
        });
 
    }
 
    setCloudy(){
        this.renderer.setElementAttribute(this.sky,'stop-color','#cecece');
        this.renderer.setElementAttribute(this.entireSun,'transform','translate(1, 1)');
        this.renderer.setElementAttribute(this.entireSun,'opacity','0.2');
 
        this.clouds.forEach((cloud) => {
            this.renderer.setElementStyle(cloud,'fill','#fff');
            this.renderer.setElementStyle(cloud,'opacity','1');
        });
    }
 
}

结论:
  当前的例子是非常简单的,这个例子是功能的演示,但不会做太多的效果展示。我相信你们有很多想法,可以实现更多的风格的天气更有趣的效果。