【问题标题】:Lost Rotate position on Drag element with Angular CDK DRAG使用 Angular CDK DRAG 在拖动元素上丢失旋转位置
【发布时间】:2021-02-23 12:35:23
【问题描述】:

我正在尝试使用范围滑块旋转元素,但每次拖动元素时,它都会在拖动时丢失旋转值,并且它还会更改框的位置并将其放在开头。 我附上了一个我在 stackblitz 中创建的简单测试项目的链接,以便我可以重现我遇到的问题。

stackblitz drag and rotate example

有人可以指导我解决问题吗?

我把代码放在这里以防万一有人不能很好地测试项目的链接:

app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";

import { DragDropModule } from "@angular/cdk/drag-drop";

import { AppComponent } from "./app.component";
import { HelloComponent } from "./hello.component";

@NgModule({
  imports: [BrowserModule, FormsModule, DragDropModule],
  declarations: [AppComponent, HelloComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

app.component.ts

import { Component, Renderer2 } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  rotateValue = 0;
  dragPosition = { x: 0, y: 0 };

  constructor(private renderer: Renderer2) {}

  setRotate(value: string) {
    this.rotateValue = Number(value);
    this.renderer.setStyle(
      document.querySelector(".example-box"),
      "transform",
      `rotate(${this.rotateValue}deg)`
    );
  }
}

app.component.html

<h1 class="text-center m-3">Drag And Drop Project</h1>
<hr>

<div class="row m-5">

    <div class="col-sm-7">
        <div class="example-boundary">
            <div class="example-box" cdkDragBoundary=".example-boundary" cdkDrag>
                I can only be dragged within the dotted container
            </div>
        </div>
    </div>

    <div class="col-sm-5">
        <h4>SETTINGS</h4>
        <ul class="list-group mb-3">
            <li class="list-group-item d-flex justify-content-between lh-condensed">
                <div>
                    <h6 class="my-0">Rotate the box</h6>
                    <input #rotation
                   type="range"
                   class="custom-range  my-2"
                    min="-150" max="150"
                    [(ngModel)]="rotateValue"
                   [value]='rotateValue'
                   (change)="setRotate(rotation.value)"
                  >
        </div>
                    <span id="grados" class="text-muted">{{rotateValue}}º</span>
            </li>

        </ul>
    </div>
</div>

app.component.css

.example-box {
  width: 140px;
  height: 140px;
  border: solid 1px #ccc;
  color: rgba(0, 0, 0, 0.87);
  cursor: move;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background: #fff;
  border-radius: 4px;
  margin-right: 25px;
  position: relative;
  z-index: 1;
  box-sizing: border-box;
  padding: 10px;
  transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1);
  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14),
    0 1px 5px 0 rgba(0, 0, 0, 0.12);
}

.example-box:active {
  box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
    0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
}

.example-boundary {
  width: 300px;
  height: 500px;
  max-width: 100%;
  border: dotted #ccc 2px;
}

非常感谢您

【问题讨论】:

    标签: angular angular-material drag-and-drop rotatetransform angular-cdk-drag-drop


    【解决方案1】:

    您遇到的问题是 Cdk Drag 是使用 CSS transform 规则实现的,就像您的自定义旋转一样。 因此,当应用于完全相同的 HTML 元素时,两者基本上是不兼容的。最后一个操作,无论是拖动还是旋转,都会覆盖另一个。

    IMO 最简单的解决方法是将旋转的元素包裹在可拖动的包装器内。

    这里是更新的 StackBlitz: https://stackblitz.com/edit/angular-ivy-ynzavj

    编辑回顾:

    在模板中,我将可旋转的 div 包装为可拖动的(我也使用 [ngStyle] 并完全避免了直接的 DOM 操作,这本身不是问题,但没有必要):

    <div class="example-boundary">
      <div class="box-draggable-wrapper" cdkDragBoundary=".example-boundary" cdkDrag>
        <div class="example-box" [ngStyle]="{'transform':'rotate(' + rotateValue + 'deg)'}" >
          I can only be dragged within the dotted container
        </div>
      </div>
    </div>
    

    box-draggable-wrapper 只需一点 CSS:

    .box-draggable-wrapper {
      width: 140px;
      height: 140px;
      display: block;
      border: none;
    }
    

    组件被清理:

    import { Component } from "@angular/core";
    
    @Component({
      selector: "my-app",
      templateUrl: "./app.component.html",
      styleUrls: ["./app.component.css"]
    })
    export class AppComponent {
      rotateValue = 0;
      dragPosition = { x: 0, y: 0 };
    
      constructor() {}
    
      setRotate(value: string) {
        this.rotateValue = +value;
      }
    }
    

    【讨论】:

      【解决方案2】:

      好吧,我想你已经猜到了,拖动动作会影响盒子的样式,每次拖动盒子时,你之前的旋转值都会丢失。但是,与此同时,您也弄乱了盒子样式,用新的旋转值覆盖了它的当前值,因此每次旋转盒子时盒子位置都会不断重置(删除translate3D 值)。

      您可以通过获取元素的当前样式并在将其重新设置之前将其与您的样式合并来轻松修复您的代码,这将解决位置问题,但是当您再次拖动框时仍然会丢失旋转值。

      好消息是这个错误已经有一个open issue 和一个proposed fix,但坏消息是它们仍然开放。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-23
        • 2020-06-02
        • 2013-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多