【问题标题】:Different cdk-drag-preview animation based on drop container基于 drop 容器的不同 cdk-drag-preview 动画
【发布时间】:2020-03-22 08:33:47
【问题描述】:

我试图在释放拖动的组件时根据放置容器获得不同的动画。 基本上,我有两个 cdkDropList。一个是卡片列表(多个可拖动元素),另一个是卡片查看器,只有一个元素,大小是两倍。用户可以将卡片从列表中拖到查看器中,以获得更好的视图。

当用户拖动卡片,然后释放它时,可能有两种情况:

  • 卡片在查看器上方。然后卡片必须进行动画处理,以便在缩放到新尺寸时滑入查看器。
  • 卡片未在查看器上方。然后卡片必须滑回其在列表中的原始位置,同时保持其大小。

您可以使用以下 css 为卡片滑动到其目标位置设置动画:

.cdk-drag-animating {
  transition: transform 300ms cubic-bezier(0, 0, 0.2, 1);
}

到目前为止,一切都很好。 但是,我现在必须添加一个条件 css 规则,添加一个“transform: scale(2);”如果放置容器是查看器。

这就是我卡住的地方!

我试图避免直接 DOM 访问,遵循角度指南,所以我想在卡片动画时向卡片添加一个类。但是CDK似乎没有办法获得预览/动画组件的引用!

我已经设法获得了目标大小和拖动组件,在我的组件 ts 中有以下代码:

  onDragEnter(event: CdkDragEnter) {
    if (_.contains(event.container.element.nativeElement.classList,"large")){
      this.targetSize= "large";
    } else {
      this.targetSize= "medium";
    }
  }      
  onDragRelease(event: CdkDragRelease) {
    this.renderer.addClass(event.source.element.nativeElement, this.targetSize);
  }

但是,这个引用是拖动对象,而不是预览对象!当在动画上放置一个很长的计时器以允许我检查它时,我可以看到以下 DOM 元素:

    <div _ngcontent-auk-c7="" cdkdrag="" class="cdk-drag large" 
ng-reflect-data="[object Object]" style="display: none;">...</div>

    <div _ngcontent-auk-c7="" cdkdrag="" class="cdk-drag cdk-drag-preview cdk-drag-animating" 
ng-reflect-data="[object Object]" style="touch-action: none; -webkit-user-drag: none; -webkit-tap-highlight-color: transparent; user-select: none; width: 135px; height: 175px; transform: translate3d(415px, 84px, 0px); pointer-events: none; margin: 0px; position: fixed; top: 0px; left: 0px; z-index: 1000;" dir="ltr"><!----><div _ngcontent-auk-c7="" class="card-holder medium"><app-card-base _ngcontent-auk-c7="" _nghost-auk-c8="" ng-reflect-card="[object Object]" ng-reflect-size="medium"><div _ngcontent-auk-c8="" class="card-container medium flip-front" ng-reflect-klass="card-container" ng-reflect-ng-class="medium,flip-front">...</div>

如您所见,我们有两个元素,一个具有正确的类“large”,但在“display:none”上,第二个具有类“cdk-drag-preview cdk-drag-animating”,但不是新的“大”类。

因此,由于我无法向第二个元素添加类,因此我无法使其有条件地更改其动画... 一个奇怪的副作用是新的类“large”被添加到卡中,并且未来这张卡的 cdk-drag-preview 将拥有“large”类!但是,这并不好,因为它似乎表明我应该在拖动开始之前开始上课,而我不知道用户是否真的会将它拖动到查看器 dropList..

TL;DR:

  • 我需要根据 dropList 的目标动态添加一个类到 cdk-drag-preview。
  • cdk-drag-preview 似乎无法在任何 cdk-drag 事件中被引用
  • 因此,一旦开始拖动,我就无法将我的类添加到其中并更改最终动画。

【问题讨论】:

    标签: angular drag-and-drop css-animations angular-cdk


    【解决方案1】:

    好吧,这不是我真正想要的,但它确实有效..

    在 cdkDragReleased 事件中,我使用“document.querySelector”获得 cdkDragPreview 元素的引用...

    我不认为它遵循 Angular 的指导方针,但至少我做到了,现在我的卡片动画可以根据目标 DropList 正确缩放..

      onDragRelease(event: CdkDragRelease) {
        const preview = new ElementRef<HTMLElement>(document.querySelector(".cdk-drag.cdk-drag-preview"));
        this.renderer.addClass(preview.nativeElement, this.targetSize);
      }
    

    【讨论】:

      【解决方案2】:

      HTML

      (cdkDropListEntered)="cdkDropListEntered($event)"
      (cdkDropListExited)="cdkDropListExited($event)"
      

      打字稿

        cdkDropListEntered(event: CdkDragEnter<string[]>) {
          const preview = new ElementRef<HTMLElement>(document.querySelector('.cdk-drag.cdk-drag-preview'));
          this.renderer.addClass(preview.nativeElement, 'class-name');
        }
      
        cdkDropListExited(event: CdkDragExit<string[]>) {
          const preview = new ElementRef<HTMLElement>(document.querySelector('.cdk-drag.cdk-drag-preview'));
          this.renderer.removeClass(preview.nativeElement, 'class-name');
        }
      

      【讨论】:

        猜你喜欢
        • 2021-02-04
        • 2020-03-14
        • 1970-01-01
        • 2020-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多