Как реализовать drag & Drop на изображении, меняя его положение - PullRequest
1 голос
/ 17 февраля 2020

Я разработал слайдер, который представляет мне несколько изображений.

Вверху (большое изображение и место, где расположен слайдер) у меня есть исходное изображение в качестве основного изображения.

В внизу у меня есть вторичные изображения (см. изображение ниже).

Есть ли способ перетащить изображение в div, содержащий ползунок, чтобы изменить порядок? В основном я намереваюсь обменять изображение, которое находится в маленькой коробке, с первым изображением в большой коробке.

Могу ли я также изменить порядок маленьких изображений по горизонтали?

Спасибо.

DEMO - Stackblitz

код

 <div class="col-md-6" style="overflow-y: auto;"  (cdkDropListDropped)="drop($event)">
        <div class="drop" [style.border-width.px]="imagens.length > 0 ? 0: 3">
          <div class="abc">
              <ngb-carousel style="outline: none;" id="carousel" #carousel *ngIf="imagens" (slide)="change($event)">
                <ng-template *ngFor="let imgIdx of imagens; let i = index" [id]="i" ngbSlide>
                  <div class="picsum-img-wrapper">
                    <img [src]="imgIdx.Imagem" style="border-radius: 8px;" class="img-responsive Images">
                      </div>                    
                </ng-template>              
              </ngb-carousel>            
          </div>
        </div>
        <div class="row">
          <div class="Upcard" *ngFor="let imgIdx of imagens | slice:1" >
            <img class="img-responsive" [src]="imgIdx.Imagem" style="width: 100%; height: 100%">
          </div>
        </div>
      </div>

Я пытался использовать это, добавляя в html cdkdrag , но нет, это не сработало.

   drop(event: CdkDragDrop<string[]>) {
     moveItemInArray(this.imagens, event.previousIndex, event.currentIndex);
   }

   dropBig(event: CdkDragDrop<string[]>) {
     moveItemInArray(this.imagens, event.previousIndex, 0);
   }

image

1 Ответ

2 голосов
/ 18 февраля 2020

cdk drag and drop - полезно перетаскивать между двумя cdkDropList. Обычно он используется для обмена значениями двух массивов (cdkDropListData из cdkDropList). Итак, вам нужно сначала определить cdkDropList и элементы dragables (cdkDrag)

Итак, сначала измените angular. json, чтобы использовать cdk 8.2.3, - вы используете Angular 8, несмешанные версии -

"@angular/cdk": "^8.2.3",

Затем создайте два массива, imagens и imagens2 (*) и измените ваш. html как -показать, где есть cdkDropList и cdkDrag-

<div class="col-md-6" style="overflow-y: auto;">
    <div class="drop" [style.border-width.px]="imagens.length > 0 ? 0: 3">
        <div class="abc" cdkDropList #dropList="cdkDropList" cdkDropListOrientation="horizontal"
            [cdkDropListData]="imagens" 
            [cdkDropListConnectedTo]="[dragList]" 
            (cdkDropListDropped)="drop($event)">
            <ngb-carousel data-interval="false" style="outline: none;" id="carousel" #carousel *ngIf="imagens"
                (slide)="change($event)">
                <ng-template *ngFor="let imgIdx of imagens; let i = index" [id]="i" ngbSlide>
                    <div class="picsum-img-wrapper" cdkDrag [cdkDragDisabled]="true">
                        <img [src]="imgIdx.Imagem" style="border-radius: 8px;" class="img-responsive Images">
                      </div>
                </ng-template>
            </ngb-carousel>
        </div>
    </div>

    <div class="row" cdkDropList #dragList="cdkDropList" cdkDropListOrientation="horizontal"
        [cdkDropListData]="imagens2" 
        [cdkDropListConnectedTo]="[dropList]" 
        (cdkDropListDropped)="drop($event)">
        <div class="Upcard" *ngFor="let imgIdx of imagens2" cdkDrag>
            <img class="img-responsive" [src]="imgIdx.Imagem" style="width: 100%; height: 100%">
          </div>
        </div>
    </div>

ну, в общем, падение функции похоже на

  drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      transferArrayItem(event.previousContainer.data,
                        event.container.data,
                        event.previousIndex,
                        event.currentIndex);
    }
  }

Но это делает то, что когда вы перетаскиваете изображение с imagens2 на изображения, перетаскиваемое изображение добавляется в массив изображений и удаляется из массива изображений2 - Вы перемещаете изображения -

Если вы хотите обменяться двумя изображениями, вы просто используете соединение. Помните, что нужно изменить только два массива

  drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      const imagen = { ...(event.container.data[event.currentIndex] as any) };
      const previousImagen = {
        ...(event.previousContainer.data[event.previousIndex] as any)
      };
      event.container.data.splice(event.currentIndex, 1, previousImagen);
      event.previousContainer.data.splice(event.previousIndex, 1, imagen);
    }
  }

Ну, если вы не хотите «обмениваться» двумя изображениями, в противном случае удалите из ползунка перетаскиваемое изображение, измените функцию drop. Помните, что event.container.data - это массив, в который вы перетаскиваете imagen (в event.currentIndex), а event.previousContainer.data - это массив, из которого вы перетаскиваете imagen (event.previousIndex дает вам перетаскиваемое изображение)

см. ваш разветвленный стек

(*) Я думаю, что в двух разных массивах я "клонирую" ваш массив, используя

  imagens2 = this.imagens.map(x => ({ ...x }));
...