import { Directive, ElementRef, AfterViewInit, Input, OnDestroy } from "@angular/core";
import { AnimationCurve } from "tns-core-modules/ui/enums";
import { Image } from "tns-core-modules/ui/image";
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout/stack-layout";
import { GridLayout, ItemSpec } from "tns-core-modules/ui/layouts/grid-layout";
import { GridUnitType } from "tns-core-modules/ui/layouts/grid-layout";
import { HorizontalAlignment } from "tns-core-modules/ui/enums";
import { Label } from "tns-core-modules/ui/label";
import { View } from "tns-core-modules/ui/core/view";
import { Visibility } from "tns-core-modules/ui/enums";
import { fromFile } from "tns-core-modules/image-source";
import { Color } from "tns-core-modules/ui/text-base/text-base";
import { GestureTypes, TouchGestureEventData, RotationGestureEventData, SwipeGestureEventData, GestureEventData } from "ui/gestures";
import labelModule = require("ui/label");
import * as Toast from "nativescript-toast";
import { RouterExtensions } from "nativescript-angular/router";
import { Config } from "../../../share/config";
import { isAndroid, isIOS, device, screen } from "platform";
/**
* hsf
* 2017-10
*/
@Directive({
selector: "[carousel]"
})
export class CarouselDirective implements AfterViewInit, OnDestroy {
private static animationSpeedDefault: number = 400; // 每一张图片动画的时间
private static autoPlaySpeedDefault: number = 0; // 前一张到后一张中间经历的时间
private container: GridLayout; // 总容器
private carouselSlides: GridLayout; // 图片容器
private totalItems: number = 0; // 图片总张数
// public autoPlayIntervalId: number; // 自动轮播区间
private autoPlayTimeoutId: number; // 自动轮播时间间隔
// private arrowType: number = CarouselArrowTypes.BOLD;
private direction: CarouselDirections = null; // 轮播方向
private currentImage: number = 0; // 当前轮播图
private movingImages: boolean = false; // 是否轮播标志
private indexMoveLeft: number = null; //
private indexMoveRight: number = null; //
private indexMoveCenter: number = null; //
private label: any;
@Input() carousel: any; // 轮播图数据集
@Input() carouselSpeed: number; // 前一张到后一张中间经历的时间
// @Input() carouselArrows: string; //
// @Input() carouselLabelOverlay: boolean; //
@Input() carouselAnimationSpeed: number; // 每一张图片动画的时间
constructor(private elem: ElementRef, private mrouter: RouterExtensions) {
this.container = elem.nativeElement;
}
ngAfterViewInit() {
this.initOptions();
this.initContainer();
this.initImagesLayout();
this.initSlides();
// this.initControls();
this.initAutoPlay();
}
/**
* 初始化
*/
private initOptions() {
// 动画持续时间
if (this.carouselAnimationSpeed && CarouselDirective.isNumeric(this.carouselAnimationSpeed)) {
this.carouselAnimationSpeed = +this.carouselAnimationSpeed;
}
// tslint:disable-next-line:one-line
else {
this.carouselAnimationSpeed = CarouselDirective.animationSpeedDefault;
}
if (this.carouselSpeed && CarouselDirective.isNumeric(this.carouselSpeed)) {
this.carouselSpeed = +(this.carouselSpeed);
}
// tslint:disable-next-line:one-line
else {
this.carouselSpeed = CarouselDirective.autoPlaySpeedDefault;
}
// Set arrow type
// if (this.carouselArrows) {
// switch (this.carouselArrows) {
// case "none":
// this.arrowType = CarouselArrowTypes.NONE;
// break;
// case "small":
// this.arrowType = CarouselArrowTypes.SMALL;
// break;
// case "normal":
// this.arrowType = CarouselArrowTypes.NORMAL;
// break;
// case "bold":
// this.arrowType = CarouselArrowTypes.BOLD;
// break;
// case "narrow":
// this.arrowType = CarouselArrowTypes.NARROW;
// break;
// default:
// }
// }
}
/**
* 初始化布局
*/
private initContainer() {
// this.container.margin = "5";
// this.container.width = 200 ;
// this.container.height = 130;
this.container.horizontalAlignment = "center";
// this.container.verticalAlignment = "middle";
this.container.addRow(new ItemSpec(1, "auto"));
// this.container.addColumn(new ItemSpec(1, "star"));
// this.container.addColumn(new ItemSpec(1, "star"));
}
/**
* 初始化图片容器
*/
private initImagesLayout() {
// this.initOntach();
this.totalItems = this.carousel.length;
this.carouselSlides = new GridLayout();
this.carouselSlides.horizontalAlignment = "center";
// this.carouselSlides.verticalAlignment = "middle";
GridLayout.setColumnSpan(this.carouselSlides, 2);
this.container.addChild(this.carouselSlides);
}
/**
* 获取图片资源,显示图片
*/
private initSlides() {
this.carousel.forEach((slide: CarouselSlide, i: number) => {
let gridLayout = new GridLayout();
gridLayout.addRow(new ItemSpec(1, "auto"));
gridLayout.visibility = i === 0 ? "visible" : "collapse";
if (slide.imageUrl) {
let image: Image = CarouselDirective.generateImageSliderFromUrl(slide.imageUrl);
if (image !== null) {
image.on(GestureTypes.swipe, (args: SwipeGestureEventData) => {
console.log("Swipe Direction: " + args.direction);
if (args.direction === 1) {
this.stopStartAutoplay();
this.swipe(CarouselDirections.DIRECTION_LEFT);
} else if (args.direction === 2) {
this.stopStartAutoplay();
this.swipe(CarouselDirections.DIRECTION_RIGHT);
}
});
image.on(GestureTypes.tap, (args: GestureEventData) => {
console.log(slide.link);
let linkSlice = slide.link.slice(0, 4);
console.log(linkSlice);
if (linkSlice === "http") {
this.mrouter.navigate(["/home/testapi/brokenline", slide.link]);
} else {
this.mrouter.navigate([slide.link]);
}
});
gridLayout.addChild(image);
this.carouselSlides.addChild(gridLayout);
}
if (this.carousel.length > 1) {
this.initCarouselPoint(i, gridLayout);
}
}
// if (slide.image) {
// let image: Image = CarouselDirective.generateImageSliderFromFile(slide.image);
// image.on(GestureTypes.swipe, (args: SwipeGestureEventData) => {
// console.log("Swipe Direction: " + args.direction);
// if (args.direction === 1) {
// this.stopStartAutoplay();
// this.swipe(CarouselDirections.DIRECTION_LEFT);
// } else if (args.direction === 2) {
// this.stopStartAutoplay();
// this.swipe(CarouselDirections.DIRECTION_RIGHT);
// }
// });
// image.on(GestureTypes.tap, (args: GestureEventData) => {
// console.log(slide.link);
// let linkSlice = slide.link.slice(0, 4);
// console.log(linkSlice);
// if (linkSlice === "http") {
// this.mrouter.navigate(["/home/testapi/brokenline", slide.link], {
// transition: {
// name: "slideLeft",
// duration: 100,
// curve: "linear"
// }
// });
// } else {
// this.mrouter.navigate([slide.link], {
// transition: {
// name: "slideLeft",
// duration: 100,
// curve: "linear"
// }
// });
// }
// });
// gridLayout.addChild(image);
// }
});
}
initScrollPoint(stackLayout: StackLayout, pointPngUrl: string, marginLeft: number) {
stackLayout.orientation = "horizontal";
let image1: Image = CarouselDirective.generateImageSliderFromFile(pointPngUrl);
stackLayout.addChild(image1);
stackLayout.width = 32;
stackLayout.height = 32;
stackLayout.marginRight = marginLeft;
stackLayout.horizontalAlignment = "right";
stackLayout.verticalAlignment = "bottom";
}
/**
* 轮播图点的初始化
* @param id
* @param gridLayout
*/
private initCarouselPoint(id: any, gridLayout: GridLayout) {
for (let i = 0; i < this.carousel.length; i++) {
let stackLayout = new StackLayout();
let url = "~/images/carouselpoint1.png";
if (i === this.carousel.length - 1 - id) {
url = "~/images/carouselpoint2.png";
}
this.initScrollPoint(stackLayout, url, i * 17);
gridLayout.addChild(stackLayout);
}
}
/**
* 从url加载图片
* @param src
* @returns {Image}
*/
private static generateImageSliderFromUrl(src: string): Image {
let image: Image = new Image();
image.src = src;
image.className = "carousellayout";
image.stretch = "aspectFill";
image.backgroundColor = "#f5f5f5";
if (screen.mainScreen.heightDIPs === 1280) {
image.height = 260;
} else {
image.height = 120;
}
// console.log("轮播图的scale======================================");
// console.log(screen.mainScreen.scale);
return image;
}
/**
* 从文件加载图片
* @param path
* @returns {Image}
*/
private static generateImageSliderFromFile(path: string): Image {
let image: Image = new Image();
image.imageSource = fromFile(path);
image.className = "slider-image";
return image;
}
/**
*
* @param id
* @returns {any}
*/
private static generateTitleSlider(id: string): Label {
let label = new Label();
label.text = id;
label.fontSize = 20;
// label.color = Color.;
label.textWrap = true;
label.className = "slider-title";
return label;
}
/**
* 自动轮播
*/
private initAutoPlay() {
if (this.carouselSpeed && CarouselDirective.isNumeric(this.carouselSpeed)) {
clearInterval(Config.autoPlayIntervalId);
Config.autoPlayIntervalId = setInterval(() => {
if (this.mrouter.router.url === "/home" && Config.state === 0) {
this.swipe(CarouselDirections.DIRECTION_RIGHT);
// Toast.makeText("轮播图在执行+++").show();
} else {
// Toast.makeText("轮播图在执行---").show();
// clearInterval(Config.autoPlayIntervalId);
}
}, this.carouselSpeed + this.carouselAnimationSpeed);
}
}
/**
* 手势检测停止,4秒后恢复
*/
private stopStartAutoplay() {
if (Config.autoPlayIntervalId) {
clearTimeout(this.autoPlayTimeoutId);
clearInterval(Config.autoPlayIntervalId);
this.autoPlayTimeoutId = setTimeout(() => {
this.swipe(CarouselDirections.DIRECTION_RIGHT);
this.initAutoPlay();
}, 4000);
}
}
/**
* 动画从右到左或从左到右
* @param direction
* @returns {boolean}
*/
private swipe(direction: CarouselDirections) {
if (this.totalItems < 2 || this.movingImages) {
return false;
}
this.direction = direction;
this.movingImages = true;
this.setDirectionValues();
this.animateSlides();
setTimeout(() => this.resetAnimationValues(), this.carouselAnimationSpeed);
}
/**
* 轮播动画
*/
private animateSlides() {
for (let i = 0; i < this.carouselSlides.getChildrenCount(); i++) {
let view: View = this.carouselSlides.getChildAt(i);
let elementWidth = this.elem.nativeElement.getActualSize().width;
view.visibility = [this.indexMoveCenter, this.indexMoveLeft, this.indexMoveRight].indexOf(i) > -1 ? "visible" : "collapse";
this.checkCL(view, i, elementWidth);
this.checkCR(view, i, elementWidth);
this.checkRC(view, i, elementWidth);
this.checkLC(view, i, elementWidth);
}
}
/**
* 中间到左边
* @param view
* @param index
* @param elementWidth
*/
private checkCL(view: View, index: number, elementWidth: number) {
if (this.indexMoveLeft === index) {
view.translateX = 0;
view.animate({
translate: { x: elementWidth, y: 0 },
duration: this.carouselAnimationSpeed,
curve: AnimationCurve.linear
}).catch((e) => {
console.log(e.message);
});
}
}
/**
* 右到中
* @param view
* @param index
* @param elementWidth
*/
private checkRC(view: View, index: number, elementWidth: number) {
if (this.indexMoveCenter === index && this.direction === CarouselDirections.DIRECTION_LEFT) {
view.translateX = -elementWidth;
view.animate({
translate: { x: 0, y: 0 },
duration: this.carouselAnimationSpeed,
curve: AnimationCurve.linear
}).catch((e) => {
console.log(e.message);
});
}
}
/**
* 中到右
* @param view
* @param index
* @param elementWidth
*/
private checkCR(view: View, index: number, elementWidth: number) {
if (this.indexMoveRight === index) {
view.translateX = 0;
view.animate({
translate: { x: -elementWidth, y: 0 },
duration: this.carouselAnimationSpeed,
curve: AnimationCurve.linear
}).catch((e) => {
console.log(e.message);
});
}
}
/**
* 左到中
* @param view
* @param index
* @param elementWidth
*/
private checkLC(view: View, index: number, elementWidth: number) {
if (this.indexMoveCenter === index && this.direction === CarouselDirections.DIRECTION_RIGHT) {
view.translateX = elementWidth;
view.animate({
translate: { x: 0, y: 0 },
duration: this.carouselAnimationSpeed,
curve: AnimationCurve.linear
}).catch((e) => {
console.log(e.message);
});
}
}
/**
* 设定值进行动画
*/
private setDirectionValues() {
switch (this.direction) {
// 右到左
case CarouselDirections.DIRECTION_LEFT:
this.indexMoveLeft = this.currentImage;
this.currentImage = ((this.currentImage === 0 ? this.totalItems : this.currentImage) - 1) % this.totalItems;
this.indexMoveCenter = this.currentImage;
break;
// 左到右
case CarouselDirections.DIRECTION_RIGHT:
this.indexMoveRight = this.currentImage;
this.currentImage = (this.currentImage + 1) % this.totalItems;
this.indexMoveCenter = this.currentImage;
break;
default:
}
}
/**
* 重置
*/
private resetAnimationValues() {
this.indexMoveLeft = null;
this.indexMoveRight = null;
this.indexMoveCenter = null;
this.movingImages = false;
}
/**
*
* @param value
* @returns {boolean}
*/
private static isNumeric(value: any) {
return !isNaN(value - parseFloat(value));
}
ngOnDestroy() {
console.log("ngOnDestroy()执行");
clearTimeout(this.autoPlayTimeoutId);
clearInterval(Config.autoPlayIntervalId);
}
}
enum CarouselDirections {
DIRECTION_LEFT,
DIRECTION_RIGHT
}
export class CarouselSlide {
imageUrl?: string;
image?: string;
id?: string;
link?: string;
}

nativescript——轮播图组件的更多相关文章

  1. 原生JS面向对象思想封装轮播图组件

    原生JS面向对象思想封装轮播图组件 在前端页面开发过程中,页面中的轮播图特效很常见,因此我就想封装一个自己的原生JS的轮播图组件.有了这个需求就开始着手准备了,代码当然是以简洁为目标,轮播图的各个功能 ...

  2. reactjs-swiper react轮播图组件基于swiper

    react轮播图组件基于swiper demo地址:http://reactjs-ui.github.io/reactjs-swiper/simple.html 1. 下载安装 npm install ...

  3. 03 uni-app框架学习:轮播图组件的使用

    1.轮播图组件的使用 参照官方文档 2.在页面上加入这个组件 3.在页面中引去css样式 并编写样式 ps:upx单位是什么 简单来说 就相当于小程序中的rpx 是一个自适应的单位 会根据屏幕宽度自动 ...

  4. Vue2 轮播图组件 slide组件

    Vue2原生始轮播图组件,支持宽度自适应.高度设置.轮播时间设置.左右箭头按钮控制,圆点按钮切换,以及箭头.圆点按钮是否显示. <v-carousel :slideData="slid ...

  5. vue移动音乐app开发学习(三):轮播图组件的开发

    本系列文章是为了记录学习中的知识点,便于后期自己观看.如果有需要的同学请登录慕课网,找到Vue 2.0 高级实战-开发移动端音乐WebApp进行观看,传送门. 完成后的页面状态以及项目结构如下: 一: ...

  6. taro 自定义 轮播图组件

    1.代码 components/MySwiper/index.js /** * 轮播图组件 */ import Taro, { Component } from '@tarojs/taro'; imp ...

  7. 使用原生js将轮播图组件化

    代码地址如下:http://www.demodashi.com/demo/11316.html   这是一个轮播图组件,这里是代码地址,需要传入容器的id和图片地址,支持Internet Explor ...

  8. vue自定义轮播图组件 swiper

    1.banner 组件 components/Banner.vue <!-- 轮播图 组件 --> <template> <div class="swiper- ...

  9. bootstrap轮播图组件

    一.轮播图组件模板(官方文档) <div id="carousel-example-generic" class="carousel slide" dat ...

随机推荐

  1. ListView属性及divider设置分割线

    给ListView设置分割线,只需设置如下两个属性: android:divider="#000" //设置分割线显示颜色 android:dividerHeight=" ...

  2. linux小白成长之路9————打包部署SpringBoot项目

    [内容指引] SpringBoot项目介绍: 打包SpringBoot项目: 1.pom.xml: 2.application.properties配置: 3.application-dev.prop ...

  3. (译文)React----React应用程序流式服务端渲染

    好处 React16推出了流式服务端渲染,它允许你并行地分发HTML片段.这样可以让渲染 出的首字节有意义的内容给用户速度更快. (例子1,上面部分是一次性转换,下面是流渲染,两种方式) 而且相对re ...

  4. 网络1712--c语言嵌套循环作业总结

    1.助教有话说 首先,每周一篇的博客作业是很有必要的:编程的过程不仅仅是会敲几行代码.能够通过PTA就大吉大利了,你更应该做到的是梳理代码思路,通过与他人代码思路的比对,取其精华,进而不断进阶,才能逐 ...

  5. C语言博客作业--数组

    一.PTA实验作业 题目1.求整数序列中出现次数最多的数 1.本题PTA提交列表 2.设计思路 定义整形变量n,max,count分别表示整数个数,出现次数最大值,出现次数.定义循环变量i,j. 输入 ...

  6. Beta阶段敏捷冲刺报告-DAY2

    Beta阶段敏捷冲刺报告-DAY2 Scrum Meeting 敏捷开发日期 2017.11.3 会议时间 13:00 会议地点 微信群 参会人员 项目组全体成员 会议内容 打包问题修复, 爬虫优化, ...

  7. Git学习使用

    1.注册码云并建立远程仓库 2.安装git 3.使用eclipse egit 推送以及克隆 建立本地仓库,成功后如图 推送项目至本地仓库与远程仓库 使用右键菜单team-share 选项,与仓库关联后 ...

  8. win7开启wifi

    在启用本地共享连接时,出现的错误! 我已经建了一个无线临时网络,来启用共享用来上网的!Internet连接共享访问被启用时,出现了一个错误(null)?而且这错误也会在系统日志里留下记录,都是些莫名其 ...

  9. iOS开发UIKit框架-可视化编程-XIB

    1. Interface Builder 可视化编程 1> 概述 GUI : 图形用户界面(Graphical User Interface, 简称GUI, 又称图形化界面) 是指采用图形方式显 ...

  10. iOS开发之Objective-C与JavaScript的交互

    UIWebView是iOS最常用的SDK之一,它有一个stringByEvaluatingJavaScriptFromString方法可以将javascript嵌入页面中,通过这个方法我们可以在iOS ...