将angularjs指令转换为角度10

问题描述

我想在我的角度项目中使用此代码

'use strict';

/**
 * Floating text animation (random)
 */
angular.module('g1b.text-animation',[]).
directive('textAnimation',['$document','$interval','$timeout',function ($document,$interval,$timeout) {
  return {
    restrict: 'A',compile: function () {
      return {
        pre: function () {},post: function (scope,element) {
          var chars = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9'];
          $interval(function () {
            for ( var i = 0; i < Math.floor(Math.random() * 5); i++ ) {
              var character = chars[Math.floor(Math.random() * chars.length)];
              var duration = Math.floor(Math.random() * 15);
              var offset = Math.floor(Math.random() * (45 - duration * 3)) + 3;
              var size = 12 + (15 - duration);
              var span = angular.element('<span class="animated-text" style="right:'+offset+'vw; font-size: '+size+'px; animation-duration:'+duration+'s">'+character+'</span>');
              element.append(span);
              $timeout(function (span) {
                span.remove();
              },duration * 1000,false,span);
            }
          },250);
        }
      };
    }
  };
}]);

它也有一个CSS文件。 此代码基本上是文本动画。 我的问题是我不知道从哪里开始。

这是我要实现的目标: https://rawgit.com/g1eb/angular-text-animation/master/

这是它的npm: https://github.com/g1eb/angular-text-animation

更新

我已经尝试过了,这就是我所拥有的:

@ViewChildren('styleDiv',{read: ElementRef}) children: QueryList<ElementRef>;

  constructor(private renderer: Renderer2,private host: ElementRef) {
  }

  ngOnInit(): void {
  }

  ngAfterViewInit(): void {
    this.animateBackground();
  }

  private animateBackground(): void {
    const renderer = this.renderer;
    const children = this.children;
    const host = this.host;
    const chars = ['a','9'];
    setInterval(() => {
      for (let i = 0; i < Math.floor(Math.random() * 5); i++) {
        const character = chars[Math.floor(Math.random() * chars.length)];
        const duration = Math.floor(Math.random() * 15);
        const offset = Math.floor(Math.random() * (45 - duration * 3)) + 3;
        const size = 12 + (15 - duration);
        const span = '<span class="animated-text" style="right:' + offset + 'vw; font-size: ' +
          +size + 'px; animation-duration:' + duration + 's">' + character + '</span>';
        this.children.first.nativeElement.insertAdjacentHTML('beforeend',span);
        setTimeout(() => {
          // renderer.removeChild(children.first.nativeElement.parentNode,children.first.nativeElement);
        },host,children,renderer);
      }
    },250,renderer);
  }

它可以工作,但是设置超时功能内部确实存在问题。 我可以将跨度添加到dom,但无法将其删除

解决方法

在与编写此指令的人交谈之后,我们决定我将为angular 2+编写一个新指令,并且他应在接下来的几天内批准拉取请求。 新代码应很快在其存储库中可用: https://github.com/g1eb/angular-text-animation

但现在,这是新的指令:

 do.call(cbind,my.list)

我还进行了一些更改:

  1. 文本现在是彩虹色。
  2. 为最大字体大小添加了可自定义的用例输入:[maxFontSize] =“ 30”
  3. 添加了彩虹色输入。如果用户只想要一种颜色,则可以通过一种颜色 颜色或其他类似方案: [colorSchemeArray] =“ ['#000”]
  4. 为浮动文本在背景中的位置添加了输入。

这是指令的CSS(应该使用指令位于组件的CSS文件中):

import {AfterViewInit,Directive,ElementRef,Input,Renderer2} from '@angular/core';

@Directive({
  selector: '[sbzTextAnimation]'
})
export class NgxSbzTextAnimationDirective implements AfterViewInit {
  @Input() maxFontSize = 20;
  @Input() colorSchemeArray: string[];
  @Input() position: 'left' | 'right' = 'right';

  constructor(private elementRef: ElementRef,private renderer: Renderer2) {
  }

  ngAfterViewInit(): void {
    this.init();
    this.animateBackground();
  }

  private init(): void {
    this.colorSchemeArray = this.colorSchemeArray
      ? this.colorSchemeArray
      : [
        '#63b598','#ce7d78','#ea9e70','#a48a9e','#c6e1e8','#648177','#0d5ac1','#f205e6','#1c0365','#14a9ad','#4ca2f9','#a4e43f','#d298e2','#6119d0','#d2737d','#c0a43c','#f2510e','#651be6','#79806e','#61da5e','#cd2f00','#9348af','#01ac53','#c5a4fb','#996635','#b11573','#4bb473','#75d89e','#2f3f94','#2f7b99','#da967d','#34891f','#b0d87b','#ca4751','#7e50a8',];
  }

  private animateBackground(): void {
    // need to access them in the setTimeout function
    const renderer = this.renderer;
    const elementRef = this.elementRef;

    const chars = [...Array(26)].map((e,i) => (i + 10).toString(36));

    setInterval(() => {
      for (let i = 0; i < Math.floor(Math.random() * 5); i++) {
        const duration = Math.floor(Math.random() * 15);
        const offset = Math.floor(Math.random() * (45 - duration * 3)) + 3;
        const size = 12 + (this.maxFontSize - duration);
        const color = this.colorSchemeArray[Math.floor(Math.random() * this.colorSchemeArray.length)];

        const span = renderer.createElement('span');
        span.innerText = chars[Math.floor(Math.random() * chars.length)];
        renderer.addClass(span,'animated-text');

        renderer.setStyle(span,'color',color);
        renderer.setStyle(span,this.position,`${offset}vw`);
        renderer.setStyle(span,'font-size',`${size}px`);
        renderer.setStyle(span,'animation-duration',`${duration}s`);
        renderer.setStyle(span,color);

        renderer.appendChild(elementRef.nativeElement,span);
        setTimeout(() => {
          renderer.removeChild(elementRef.nativeElement,elementRef.nativeElement.firstChild);
        },duration * 1000,false,elementRef,renderer);
      }
    },250);
  }
}

这是一个完整的工作演示: https://stackblitz.com/edit/floating-text-animation?file=src/app/app.component.html

更新: 这是npm上最终指令的链接: https://www.npmjs.com/package/ngx-sbz-text-animation

,

您也可以将rxjs与Scheduler一起使用,这样可以使动画稍微平滑一些。

 interval(250)
   .pipe(
    // tap(_ => console.log("started..")),mergeMap(_ =>
      from([...Array(Math.floor(Math.random() * 5))]).pipe(
        observeOn(asyncScheduler)
      )
    ),map(_ => this.getMap()),tap(({ span }) =>
      this.elementRef.nativeElement.insertAdjacentHTML("beforeend",span)
    ),mergeMap(({ duration }) =>
      of(null).pipe(
        delay(duration * 1000),tap(_ =>
          renderer.removeChild(
            this.elementRef.nativeElement,this.elementRef.nativeElement.firstChild
          )
        )
      )
    ),takeUntil(this._destroy$)
  )
  .subscribe();

添加了一种方法:

getMap(): { span: string; duration: number } {
  const character = this.chars[Math.floor(Math.random() * this.chars.length)];
  const duration = Math.floor(Math.random() * 15);
  const offset = Math.floor(Math.random() * (45 - duration * 3)) + 3;
  const size = 12 + (this.maxFontSize - duration);
  const color = this.colorSchemeArray[
    Math.floor(Math.random() * this.colorSchemeArray.length)
  ];
  return {
    duration,span: `<span class="animated-text" style="color: ${color};${
      this.position
    }: ${offset}vw; font-size: ${size}px; animation-duration:${
     duration}s">${character}</span>`
};

}

创建一个主题_destory $和OnDestroy方法:在takeUntil中使用以进行垃圾回收 我使用的调度程序是asyncScheduleranimationFrameScheduleranimationFrameScheduler更好,但需要对删除进行调整