zoukankan      html  css  js  c++  java
  • nativescript(angular2)——轮播图组件

    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;
    }
  • 相关阅读:
    【leetcode】236. 二叉树的最近公共祖先
    【leetcode】230. 二叉搜索树中第K小的元素
    【leetcode】309. 最佳买卖股票时机含冷冻期
    【leetcode】306. 累加数
    【leetcode】304. 二维区域和检索
    spring-framework源码编译及导入
    Java8-函数式接口理解及测试
    Mac编译RocketMQ 4.1.0
    首记
    JS表单验证
  • 原文地址:https://www.cnblogs.com/husfBK/p/8882195.html
Copyright © 2011-2022 走看看