nativescript——轮播图组件

时间:2022-08-30 23:36:13

nativescript——轮播图组件

nativescript——轮播图组件

nativescript——轮播图组件

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. String&period;Format用法

    http://blog.csdn.net/yohop/article/details/2534907 1.作为参数   名称 说明   Format(String, Object) 将指定的 Stri ...

  2. Log4J 配置文件全属性详解

    第一步:加入log4j-1.2.8.jar到lib下. 第二步:在CLASSPATH下建立log4j.properties.内容如下: 1 log4j.rootCategory=INFO, stdou ...

  3. android中的HttpURLConnection和HttpClient实现app与pc数据交互

    自学android的这几天很辛苦,但是很满足,因为每当学到一点点知识点都会觉得很开心,觉得今天是特别有意义的,可能这个就是一种莫名的热爱吧. 下面来说说今天学习的HttpURLConnection和H ...

  4. getUTCHours

    getUTCMinutes() 方法可根据世界时 (UTC) 返回时间的分钟字段. function timeFormat(ms){ ; var date = new Date(ms), h = da ...

  5. Spring-----8、深入理解容器中的bean

    转载自:http://blog.csdn.net/hekewangzi/article/details/45648687

  6. YUI 和路径相关的参数与module加载之间的关系

    相关参数默认值 使用YUI, 我们可以配置一些和路径相关参数,如base.root.comboBase.cdn, combine.path.fullpath等属性的配置均会影响到YUI的module加 ...

  7. Java高级特性之枚举

    在Java SE5之前,我们要使用枚举类型时,通常会使用static final 定义一组int常量来标识,代码如下 public static final int MAN = 0; public s ...

  8. &lbrack;C&num;&period;net&rsqb;SQL参数传入空值报错解决方案

    C#中的null与SQL中的NULL是不一样的,SQL中的NULL用C#表示出来就是DBNull.Value. 注意:SQL参数是不能接受C#的null值的,传入null就会报错. SqlComman ...

  9. Derek解读Bytom源码-孤块管理

    作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...

  10. python怎样压缩和解压缩ZIP文件

    https://zhidao.baidu.com/question/1498409764366387259.html