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. CentOS 6.5 通过命令行安装发送邮件

    1.安装sendmail: yum install sendmail 2.安装mailx: yum install mailx -y 3.编辑发送的配置文件: vi /etc/mail.rc #在最后 ...

  2. 用python程序来画花

    from turtle import * import time setup(600,800,0,0) speed(0) penup() seth(90) fd(340) seth(0) pendow ...

  3. [Java反射机制]用反射改进简单工厂模式设计

    如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取 ...

  4. p-value

    p-value p-value翻译为假定值,假设几率.我们在生物信息中通常使用p值方法(P-Value, Probability, Pr)来做检验.那么p-value是什么呢?其实P-value就是一 ...

  5. Property 'id' not found on type java.lang.String

    改为 忘写了$符,取不出来,因此报错!

  6. MariaDB/MySQL中的变量

    在MySQL/MariaDB中有好几种变量类型:用户自定义变量.系统变量.一般的临时变量(即本地变量,或称为局部变量). 1.用户变量 用户变量是基于会话的,也是基于用户的,所以我觉得称之为会话变量更 ...

  7. 如何在mac上搭建sqli-labs

    近期想学习sql注入,但是一来网络上的资料参差不齐,难以系统的学习:二来随着程序员安全意识的提高,这种完全可以避免的注入漏洞越来越少见了,所以难以找一个合适的网站练手,于是乎,sqli-labs这种实 ...

  8. beta冲刺总结-咸鱼

    前言:emmmmmmm冲刺总结应该可以吐槽了?我发誓后面几篇冲刺我是很努力用正经语言描述了!!!!! 心得:emmmmm,说真的--到beta冲刺的时候才是真正感受到了组队的存在,基本上隔三差五就约一 ...

  9. TRY

  10. 算法第四版学习笔记之优先队列--Priority Queues

    软件:DrJava 参考书:算法(第四版) 章节:2.4优先队列(以下截图是算法配套视频所讲内容截图) 1:API 与初级实现 2:堆得定义 3:堆排序 4:事件驱动的仿真 优先队列最重要的操作就是删 ...