如何在角度10中实现3d滑块

时间:2020-09-20 12:53:14

标签: angular

我对Angle非常陌生,我想创建一个3D旋转式滑块,例如this。我该如何解决这个问题? 请查看链接以更好地说明问题

function rotateLeft(){
  if(on == 0){
    $('.p_slider__item:nth-of-type(' + pos + ')').animate({'left':'200px'},200)
    $('.p_slider__item:nth-of-type(' + pos + ')').css('z-index','0')
    $('.p_slider__item:nth-of-type(' + pos2 + ')').animate({'left':'-200px'},200)
    setTimeout (function(){
      $('.p_slider__item:nth-of-type(' + pos2 + ')').css({'transform':'scale(0.6)','opacity':'0.8','webkit-filter':'blur(2px)','z-index':'1'});
      pos++;pos2++;pos3++;
      if(pos > 3){pos = 1}if(pos2 > 3){pos2 = 1;}if(pos3 > 3){pos3 = 1;}
    },400)
    $('.p_slider__item:nth-of-type(' + pos3 + ')').animate({'left':'0px'},200)
    $('.p_slider__item:nth-of-type(' + pos3 + ')').css({'transform':'scale(1)','opacity':'1','webkit-filter':'blur(0px)','z-index':'2'})
    setTimeout (function(){
      on = 0; // Accept clicks again
    },time)
  }
}

3 个答案:

答案 0 :(得分:2)

google是我们的朋友,在this David DeSandro's article中,您拥有所有的“成分”。是的,是CSS和javascript,但您可以轻松将其翻译为Angular

要获取单元格,请使用viewChild和ViewChildren

  @ViewChild('carousel') carousel:ElementRef
  @ViewChildren('carousel__cell') cells:QueryList<ElementRef>

我们需要一些辅助变量:

  selectedIndex = 0;
  cellWidth:number;
  cellHeight:number;
  isHorizontal:boolean = true;
  rotateFn = this.isHorizontal ? 'rotateY' : 'rotateX';
  radius:number
  theta:number;

  get cellCount()
  {
    return this.cells.length;
  }

现在创建一个函数initCarousel

  initCarousel() {
    this.theta = 360 / this.cellCount;
    const cellSize = this.isHorizontal ? this.cellWidth : this.cellHeight;
    this.radius = Math.round( ( cellSize / 2) / Math.tan( Math.PI / this.cellCount ) );
    this.cells.forEach((cell:ElementRef,i:number)=>
    {
       if (i<this.cellCount)
       {
           cell.nativeElement.style.opacity=1
           const cellAngle=this.theta*i;
           cell.nativeElement.style.transform = this.rotateFn + '(' + cellAngle + 'deg) translateZ(' + this.radius + 'px)';
       }
       else
       {
        cell.nativeElement.style.opacity = 0;
        cell.nativeElement.style.transform = 'none';

       }
    })
    this.rotateCarousel();
  }

我们在ngAfterViewInit中调用

  ngAfterViewInit()
  {
    this.cellWidth = this.carousel.nativeElement.offsetWidth;
    this.cellHeight = this.carousel.nativeElement.offsetHeight;
    this.initCarousel()
  }

您可以在stackblitz

中看到

已更新确实,问题是关于“伪3d”的问题,它更容易。我们需要应用变换比例尺和位置,因此,我们可以拥有类似

的功能
  getStyle(index:number)
  {
    if (!this.cellCount)
       return null;
    const angle=(index-this.selectedIndex)*2*Math.PI/this.cellCount
    const scale=((75)+25*Math.cos(angle))/100
    return {
      left:-75+150*Math.sin(angle)+'px',
      transform:'scale('+scale+')',
      position:'absolute',
      "z-index":Math.floor(100*scale)
    }
  }

并应用于轮播

<div class="carousel" style="position:relative">
  <div *ngFor="let i of [0,1,2,3,4,5,6]" class="carousel__cell" 
     [ngStyle]="getStyle(i)">{{i}}
  </div>
</div>

更新2 使用Angular动画。好吧,这似乎是我们想要实现的最后一个轮播。对于特定情况,我们可以例如定义了9个位置,位置0,2和7处有3张图像

在构造函数中注入AnimationBuilder

  constructor(private builder: AnimationBuilder) {}

并定义为变量

  private player: AnimationPlayer;
  timer = 1000;
  animates = [0, 2, 7];

我们定义了一个辅助变量

  movements = [
    { pos: 0, right: [1, 2], left: [8, 7] },
    { pos: 2, right: [3, 4, 5, 6, 7], left: [1, 0] },
    { pos: 7, right: [8, 0], left: [6, 5, 4, 3, 2] }
  ];

这个想法是手动创建动画,因此,例如一个元素位于pos = 0,然后单击“右键”,我们创建2个动画以到达位置1,2

是一些复杂的功能,我要发表评论

  animateViews(direction: string) {
    //with each element of the array [0,2,7]
    this.animates.forEach((x: number, index: number) => {
      //get the item and the mov
      const mov = this.movements.find(m => m.pos == x);
      const item = this.itemsView.find((_x, i) => i == index);

      //create an array of animations
        const animations = mov[direction].map(m => {
          const angle = (m * 2 * Math.PI) / 9;
          const scale = (75 + 25 * Math.cos(angle)) / 100;
          const applystyle = {
            left: -75 + 150 * Math.sin(angle) + "px",
            transform: "scale(" + scale + ")",
            position: "absolute",
            "z-index": Math.floor(100 * scale)
          };
          return animate(
            this.timer / mov[direction].length + "ms",
            style(applystyle)
          );
        });

        //we create the animation with builder.build
        const myAnimation = this.builder.build(animations);

        //the animation is applied to the element
        this.player = myAnimation.create(item.nativeElement);

        //when finished, change the value of the array [0,2,7]
        this.player.onDone(
          () =>
            (this.animates[index] = mov[direction][mov[direction].length - 1])
        );
        this.player.play();
    });
  }

new stackblitz

更新3 *:要理解这些公式,可以用纸和笔,并使用一些数学方法:想象一个半径为“ r”的圆周。从中心画一条垂直线,并在圆周上标记一个点。从垂直线到将点与圆周角连接的直线沿顺时针方向的角度称为“角度”。

left=r*Math.sin(angle)-width_of_img/2

对于比例尺,我们需要记住,当“角度”为0时,比例尺为1,而当“角度”为180度时,比例尺为0.5(或另一个介于1和0之间的数字-越少,深度越大)。将“ minScale”调用为此值。这意味着Math.cos(0)= 1比例为1,Math.cos(180degrees)=-1比例为minScale。所以

 scale=(1+minScale)/2+(1-minScale)/2*Math.cos(angle)

答案 1 :(得分:-1)

当您刚接触Angular时,建议您使用一种第三方组件的方法:

  1. 搜索适合您需求的Angular组件或具有可帮助您构建组件的工具的Angular框架。
  2. 将其导入到您的项目中(使用npm install ...)。通常,几乎第3方组件都会指导您如何安装自身。
  3. 将已安装的组件导入到项目的.module.ts文件中,然后使用它。

答案 2 :(得分:-1)

这可能对您有帮助

https://github.com/Wlada/angular-carousel-3d

如果使用Bower,只需运行bower install angular-carousel-3d。如果不是,请从以下github存储库下载文件angular-swipe.js,carousel-3d.css和carouse3d.js:

Angular Swipe
Angular Carousel 3D

注意:您也可以下载和使用压缩后的版本。

将这些文件添加到您的代码中:

<link href="carousel-3d.css" rel="stylesheet" type="text/css" />
<script src="angular.js"></script>
<script src="angular-swipe.js"></script>
<script src="carousel-3d.js"></script>

将angular-carousel-3d模块作为依赖项添加到您的应用程序模块中:

angular.module('MyApp', ['angular-carousel-3d']);

在您的模板中: 将carousel-3d属性添加到任何元素。 用对象数组添加ng-model 添加carousel3d-slide指令和ng-repeat渲染幻灯片

<div carousel3d ng-model="arrayOfObjects">
    <div carousel3d-slide ng-repeat="slide in app.slides track by $index">
        <figure>
            <img ng-src="{{slide.src}}" alt=""/>
            <figcaption ng-bind="slide.caption"></figcaption>
        </figure>
    </div>
</div>