首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在角组件/ JavaScript中使用徽标滑块TypeScript功能?

如何在角组件/ JavaScript中使用徽标滑块TypeScript功能?
EN

Stack Overflow用户
提问于 2021-01-09 10:25:14
回答 2查看 213关注 0票数 0

因为我对角很陌生,我需要你的帮助。我已经看了很多教程并尝试了很多东西,但是这次我需要将JavaScript函数合并到我的角度组件中。

这是我想要在角内使用的实际滑块(非常感谢SomoKRoceS):

代码语言:javascript
复制
document.getElementsByTagName("body")[0].onload = createAnimation;

  function createAnimation(){

  let e = document.getElementById("logo-gallery"); // Get the element

  var style = document.createElement('style'); // Create styling element
  style.type = 'text/css'; // Append a css type

  // Now create the dynamic keyFrames (that are depend on logo-gallery final width)
  // Notice that the width of e is given to translateX at 100%
  let keyframes = '\
  @keyframes scroll-left {\
      0% {\
          transform: translateX(0);\
      }\
      100% {\
          transform: translateX(-'+e.scrollWidth+'px);\
      }\
  }';
  style.innerHTML = keyframes; // Set innerHTML of the styling element to the keyframe
  document.getElementsByTagName('head')[0].appendChild(style); // append the element to the head of the document as a stylesheet
  e.setAttribute("style","animation: scroll-left 20s linear infinite; animation-iteration-count: infinite;"); // Give the element its animation properties.

}
代码语言:javascript
复制
#logo-gallery-wrapper {
  overflow: hidden;
  position: relative;
}

#logo-gallery {
  margin: 0;
  padding: 0;
  position: relative;
  list-style-type: none;
  display: flex;
}

#logo-gallery .logo-gallery-figure {
  margin: 0;
  padding: 0 1.6rem;
  overflow: hidden;
}

#logo-gallery .logo-gallery-figure img {
  height: auto;
  max-height: 50px;
  position: relative;
  filter: grayscale(1);
  transition: all .4s;
}

#logo-gallery .logo-gallery-figure img:hover {
  filter: grayscale(0);
}
代码语言:javascript
复制
<div id="logo-gallery-wrapper">
  <ul id="logo-gallery">
    <li>
      <figure class="logo-gallery-figure">
        <img src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
    </li>
    <li>
      <figure class="logo-gallery-figure">
        <img src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
    </li>
    <li>
      <figure class="logo-gallery-figure">
        <img src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
    </li>
    <li>
      <figure class="logo-gallery-figure">
        <img src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
    </li>
    <li>
      <figure class="logo-gallery-figure">
        <img src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
    </li>
    <li>
      <figure class="logo-gallery-figure">
        <img src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
    </li>
    <li>
      <figure class="logo-gallery-figure">
        <img src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
    </li>
  </ul>
</div>

实际上,我有一个.css.html.ts文件的组件。HTML和CSS文件的内容属于这里的内容,但现在我需要将JavaScript转换为角。这是我的.ts文件:

代码语言:javascript
复制
import { Component, Input } from '@angular/core';

@Component({
  selector   : 'app-logo-gallery',
  templateUrl: './logo-gallery.component.html',
  styleUrls  : ['./logo-gallery.component.css']
})
export class LogoGalleryComponent {

  @Input()
  logos: string[];

  constructor() {
  }
}

我知道@Component装饰器中有一个动画命令可用,但这是正确的方式吗?如果是,我如何在那里使用它?关键是,我需要以某种方式计算scrollWidth并将其设置为关键帧,否则动画就会出错。

我已经知道可以这样获得元素的宽度:

代码语言:javascript
复制
<ul id="logo-gallery" #logoGallery>

TypeScript类

代码语言:javascript
复制
@ViewChild('logoGallery', {static: false}) logoGallery: ElementRef;

this.logoGallery.nativeElement.offsetWidth

谢谢你的帮忙!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-10 13:14:46

另一种方法是使用角动画。唯一需要考虑的是使用@ViewChildren获取"htmlElement“。如果我可以使用*ngFor,我不喜欢写几个数组,所以我使用一个数组并使用数组编写一个li和另一个。有些人喜欢

有些人喜欢

代码语言:javascript
复制
<div #wrapper id="logo-gallery-wrapper">
    <ul #banner id="logo-gallery"  >
    <li #logo>
            <figure class="logo-gallery-figure">
                <img (load)="resize()" src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
        </li>
        <li *ngFor="let i of items;let first=first">
            <figure class="logo-gallery-figure">
                <img  src="https://www.ikea.com/de/de/static/ikea-logo.f88b07ceb5a8c356b7a0fdcc9a563d63.svg">
      </figure>
        </li>
    </ul>
</div>

看到第一个“图像”有一个事件“加载”,这个事件就是让我计算出需要多少元素才能启动动画。

代码语言:javascript
复制
  logoWidth: number = 0;
  items: number[] = [0];
  public player: AnimationPlayer;

  @ViewChild("wrapper") wrapper: ElementRef;
  @ViewChild("logo") logo: ElementRef;
  @ViewChild("banner") banner: ElementRef;

  constructor(private builder: AnimationBuilder) {}


  resize() {
    this.logoWidth = this.logo.nativeElement.getBoundingClientRect().width;
    this.createAnimation();
  }

  createAnimation() {
    if (this.wrapper && this.logo) {
     //width of the "wrapper"
      const totalWidth = this.wrapper.nativeElement.getBoundingClientRect()
        .width;
      //number of element I go to paint
      const element = 2 * Math.floor(totalWidth / this.logoWidth);

      //I go to translate the "half" of the "ul"
      const inc = this.logoWidth * (element / 2);

      //I recalculate the number of elements if you resize the window
      if (this.items.length != element)
        this.items = new Array(element > 0 ? element : 1);

      // the time spend in the animation is proportional to the "total width"
      const time = 9.2 * totalWidth + "ms";

      //create a manual animation
      const myAnimation: AnimationFactory = this.builder.build([
        style({ transform: `translateX(0px)` }),
        animate(time, style({ transform: `translateX(${-inc}px)` }))
      ]);
      this.player = myAnimation.create(this.banner.nativeElement);

      //when finish repeat process
      this.player.onDone(() => {
        this.createAnimation();
      });

      //finally lauch the animation
      this.player.play();
    }
  }

您可以在这一堆闪电战中看到小心!如果您更改了代码,则需要刷新.html以在-else之前执行动画步骤,您可以使导航器崩溃-

另外,您还可以使用mouseover和mouseout暂停/启动动画。

代码语言:javascript
复制
<ul (mouseover)="player.pause()" 
    (mouseout)="player.play()" 
   #banner id="logo-gallery"  >
...
</ul>

更新,如果我们想拥有一系列的imgs和noy,那么会发生什么呢?

技术假设我们有一个数组“重复”。我们需要做两个循环。我们的图像数组称为“徽标”。

代码语言:javascript
复制
<div #wrapper id="logo-gallery-wrapper">
    <ul (mouseover)="player.pause()" (mouseout)="player.play()" #banner id="logo-gallery">
        <li #logo>
            <figure class="logo-gallery-figure">
                <img (load)="resize()" [src]="logos[0].url">
            </figure>
        </li>
        <ng-container *ngFor="let i of repeat;let firstRepeat=first">
            <ng-container *ngFor="let logo of logos;let firstLogo=first">
                <li *ngIf="!firstLogo || !firstRepeat">
                    <figure class="logo-gallery-figure">
                        <img  [src]="logo.url">
                    </figure>
                </li>
            </ng-container>
        </ng-container>
    </ul>
</div>

同样要考虑的是,我们首先编写第一个图像,然后进行这两个循环。这是必要的,因为这是事件中的第一个图像“加载”谁删除动画。不可能在循环中添加,因为我们将更改“重复数组”,这将使我们在每次调整大小时创建一个新的动画。

嗯,这是一个复杂的twoo循环,因为我们不需要绘制这个图像

同样,我们有一个函数createAnimations

代码语言:javascript
复制
createAnimation() {
    if (this.wrapper && this.logo) {

      //calculate the total width
      const totalWidth = this.wrapper.nativeElement.getBoundingClientRect()
        .width;

      //number of copies necesary
      let copies =
        2 * Math.floor(totalWidth / (this.logos.length * this.logoWidth)) + 1;
      //at least must be 2
      if (copies == 1) copies = 2;

      //create an array with somany elements than "copies"
      this.repeat = ".".repeat(copies).split("");

      //we are going to move lo the left only the width of the "first group of images"
      const inc = this.logoWidth * this.logos.length;

      //rest of code similar, but the speed is proportional to inc
      const time = 9.2 * inc+ "ms";
      const myAnimation: AnimationFactory = this.builder.build([
        style({ transform: `translateX(0px)` }),
        animate(time, style({ transform: `translateX(${-inc}px)` }))
      ]);
      this.player = myAnimation.create(this.banner.nativeElement);
      this.player.onDone(() => {
        this.createAnimation();
      });
      this.player.play();
    }
  }

(*)为了检查是否一切顺利,我们可以将.css样式更改为overflow:scroll,并添加这一行,以确保计算好了“副本”和"inc“

与通常一样,具有更改的新stackblitz

更新和..。有不同宽度的徽标是什么?

在这种情况下,我们将更改.html。我们用徽标做一个循环,用重复做另一个循环。

代码语言:javascript
复制
<div #wrapper id="logo-gallery-wrapper">
    <ul (mouseover)="player.pause()" (mouseout)="player.play()" #banner id="logo-gallery">
        <li *ngFor="let logo of logos" #logo>
            <figure class="logo-gallery-figure">
                <img (load)="loaded()" [src]="logo.url">
      </figure>
        </li>
        <ng-container *ngFor="let i of repeat">
                <li *ngFor="let logo of logos">
                    <figure class="logo-gallery-figure">
                        <img  [src]="logo.url">
          </figure>
                </li>
        </ng-container>
    </ul>
</div>

请注意,在本例中,(load)事件调用加载了一个函数。其思想是,在这个函数中增加一个变量- -picsLoaded-当所有的徽标被加载时,我们计算出总宽度。确保我们需要使用ViewChildren,而不是ViewChild

代码语言:javascript
复制
  totalLogoWidth: number = 0;
  picsLoaded=0;
  @ViewChildren("logo") logo: QueryList<ElementRef>;

 loaded()
  {
    this.picsLoaded++;
    if (this.picsLoaded==this.logos.length)
    {
      let totalWidth=0;
      this.logo.forEach(x=>{
        totalWidth+=x.nativeElement.getBoundingClientRect().width;
      })
      this.totalLogoWidth=totalWidth
      this.createAnimation()
    }
  }

现在,只更新函数createAnimation以使用totalLogoWidth而不是this.logos.length*this.logoWidth。

代码语言:javascript
复制
  createAnimation() {
    if (this.wrapper && this.logo) {
      const totalWidth = this.wrapper.nativeElement.getBoundingClientRect()
        .width;
      //in this case "copies" is simply Math.floor +1
      let copies =Math.floor(totalWidth / (this.totalLogoWidth)) + 1;
      this.repeat = ".".repeat(copies).split("");
      const inc = this.totalLogoWidth;
      const time = 9.2 * inc + "ms";
      const myAnimation: AnimationFactory = this.builder.build([
        style({ transform: `translateX(0px)` }),
        animate(time, style({ transform: `translateX(${-inc}px)` }))
      ]);
      this.player = myAnimation.create(this.banner.nativeElement);
      this.player.onDone(() => {
        this.createAnimation();
      });
      this.player.play();
    }
  }

另一个stackblitz

票数 1
EN

Stack Overflow用户

发布于 2021-01-09 10:41:19

您可以将js函数放入组件中。演示

代码语言:javascript
复制
import { Component, OnInit } from "@angular/core";

function createAnimation() {
  let e = document.getElementById("logo-gallery");
  var style = document.createElement("style");
  style.type = "text/css";
  let keyframes =
    "@keyframes scroll-left { 0% {transform: translateX(0);}100% {transform: translateX(-" +
    e.scrollWidth +
    "px); }}";
  style.innerHTML = keyframes;
  document.getElementsByTagName("head")[0].appendChild(style);
  e.setAttribute(
    "style",
    "animation: scroll-left 20s linear infinite; animation-iteration-count: infinite;"
  );
}
@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  name = "Angular";
  ngOnInit() {
    createAnimation();
  }
}

但是我通常不选择使用函数作为我选择将一个css放在组件css 演示中的方式。

代码语言:javascript
复制
@keyframes scroll-left 
{
   0% {transform: translateX(0)}
  100% {transform: translateX(var(--m,100%))}
}

并给css动画

代码语言:javascript
复制
#logo-gallery {
  animation: scroll-left 20s linear infinite; 
  animation-iteration-count: infinite;
}

还有Viwchild

代码语言:javascript
复制
 @ViewChild('logoGallery', {static: false}) logoGallery: ElementRef;
    
      ngAfterViewInit(): void {
        let element=this.logoGallery.nativeElement;  
        element.style.setProperty('--m',element.scrollWidth+"px");
      }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65641547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档