最近我写了一些内容在SVG(可缩放矢量图形),主要是因为他们就是很炫酷效果吸引我。 我已经创建的内容主要是介绍和漂亮的动画的话我一直使用简单的CSS动画和关键帧,所以我想解决一个更真实的问题和创造的东西,看起来真的很酷。
我想要创建的是一个应用程序的背景,它将有一个图形表示的时间或天气。它可能是中午和晴天,多云,夜间,甚至日落(有点像iOS上的默认天气应用)- SVG是一个完美的候选人。由于我们可以用JavaScript来操纵SVG的部分,我们可以从一个单一的SVG和修改它的飞行。如果原来的SVG是一个阳光灿烂的日子,在天空中的云,我们可以删除太阳和改变天空的颜色,使之成为夜间时间,或者我们可以移动到屏幕底部的太阳,使背景橙创建日落效应。
这就是我最终效果的展示:
这是一个相当基本的实现,但它很酷,对不对?在未来,我想延长这一点,以便它自动调整时间和天气,但现在它允许您切换之间的各种预定义的设置(白天,晚上,日落,多云)。 在本教程中,我将通过如何使用SVG在ionic创建动态背景。我不会走过实际的SVG创作,只是修改它,所以如果你不熟悉SVG是如何创建的,我建议看第一个:SVG动画ionic。
1、创建新的ionic应用
我们将首先产生一个新的空白ionic应用程序,这样做只运行下面的命令:
ionic start ionic-sunset blank
一旦已经完成生成,你应该使它成为你的工作目录:
cd ionic-sunset
我们只是将SVG动画添加到自动生成的主页上,因此不再需要设置。
2、设置SVG
在我们做任何事情前,这是SVG看起来像插画:
将直接嵌入到应用程序中。
修改 src/pages/home/home.html :
<ion-content>
<svg class="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>
<linearGradient id="linear-gradient" x1="375" y1="1334" x2="375" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#fff"/>
<stop offset="1" stop-color="#50a7dd"/>
</linearGradient>
</defs>
<title>sunsetsvg</title>
<rect id="Sky-2" data-name="Sky" class="cls-1" width="750" height="1334"/>
<g id="Sun" data-name="Sun">
<circle class="cls-2" cx="385" cy="335.7" r="315.74"/>
<circle class="cls-3" cx="385" cy="335.7" r="180.56"/>
</g>
<g id="Clouds">
<path id="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"/>
<path id="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"/>
<path id="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"/>
<path id="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'
})
export class HomePage {
timeOfDay: Date = new Date();
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>
<div class="controls">
<button color="light" ion-button (click)="setDay()">Day</button>
<button color="light" ion-button (click)="setCloudy()">Cloudy</button>
<button color="light" ion-button (click)="setSunset()">Sunset</button>
<button color="light" ion-button (click)="setNight()">Night</button>
</div>
<svg class="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>
<linearGradient id="linear-gradient" x1="375" y1="1334" x2="375" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#fff"/>
<stop offset="1" stop-color="#50a7dd"/>
</linearGradient>
</defs>
<title>sunsetsvg</title>
<rect id="Sky-2" data-name="Sky" class="cls-1" width="750" height="1334"/>
<g id="Sun" data-name="Sun">
<circle class="cls-2" cx="385" cy="335.7" r="315.74"/>
<circle class="cls-3" cx="385" cy="335.7" r="180.56"/>
</g>
<g id="Clouds">
<path id="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"/>
<path id="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"/>
<path id="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"/>
<path id="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>
<div class="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: 1px 1px 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'
})
export class HomePage {
timeOfDay: Date = new Date();
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');
});
}
}
结论: 当前的例子是非常简单的,这个例子是功能的演示,但不会做太多的效果展示。我相信你们有很多想法,可以实现更多的风格的天气更有趣的效果。