Bagaimana untuk melaksanakan fungsi seret dan lepas dalam rxjs Angular? Artikel berikut akan memperkenalkan kepada anda cara melaksanakan seret dan lepas menggunakan Angular digabungkan dengan rxjs saya harap ia akan membantu anda!
Dalam artikel sebelumnya, kami mengetahui tentang operasi video tersuai dalam Angular Pembaca yang belum mengalaminya boleh mempelajarinya terlebih dahulu.
Sekarang terdapat permintaan sedemikian, bagaimana anda akan merealisasikannya?
Dalam teg video pada halaman, apabila ketinggian tatal melebihi kedudukannya, tetapkannya supaya ia boleh diseret secara bebas di kawasan yang boleh dilihat.
Idea
bagus yang boleh dicapai dengan mudah jika anda menggunakan Angular
@angular/cdk/drag-drop
, tetapi kami tidak menggunakan alatan di sini. [Cadangan tutorial berkaitan: "tutorial sudut"]
Baiklah, mari analisa idea pelaksanaan:
bottom
video adalah kurang daripada 0 berbanding dengan nilai tetingkap visual Kita perlu menetapkan video
yang membalut tag div
untuk memudahkan pengiraan daripada set asal video
. Iaitu, elemen itu terkeluar daripada susun atur dokumen asal video
Elemen boleh diseret, kemudian kedudukannya perlu ditukar kepada fixed
video
Elemen boleh diseret secara bebas dalam kawasan visual, maka nilai top
, left
perlu dihadkan jadi kami menetapkan reka letak demo
berikut:
<div id="anchor" #anchor> <div class="video" id="video" #video> <div class="masker"></div> <video width="100%" height="100%" controls poster="assets/poster.png"> <source src="../assets/demo.mp4" type="video/mp4" /> Your browser does not support. </video> </div> </div>
mempunyai gaya yang telah ditetapkan berikut:
<!-- styles.scss --> <!-- 这部分需要放在全局样式中 --> html, body { height: 6000px; background-color: #fff; }
<!-- demo.component.scss --> #anchor { height: 360px; width: 100%; background-color: #F0F0F0; } .video { width: 640px; height: 360px; margin: 0 auto; background-color: black; <!-- video fixed 布局的样式,默认布局中是没有的 --> &.video-fixed { position: fixed; top: 10px; left: 10px; width: 320px; height: 150px; cursor: all-scroll; .masker { display: none; } &:hover { .masker { display: block; position: absolute; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); z-index: 2; } } } }
Di sini juga memperkenalkan rxjs
untuk operasi.
Elemen terkeluar daripada reka letak dokumen asal
Kami baru sahaja menganalisis pelarasan kritikal elemen video
daripada dokumen :
di luar videodiv
ialah #anchor
pandangan relatif elemen bottom < 0
. Jadi kita ada:
@ViewChild('anchor', { static: false }) public anchor!: ElementRef; @ViewChild('video', { static: false }) public video!: ElementRef; public scroll!: any; ngAfterViewInit(): void { this.scroll = fromEvent(document, 'scroll'); this.scrollFn(); } // 页面滚动 public scrollFn() { this.scroll .pipe( debounceTime(50), // 防抖 map(() => this.anchor.nativeElement.getBoundindClientRect().bottom < 0) ) .subscribe((flag: boolean) => { // 添加和移除样式 if(flag) { this.video.nativeElement.classList.add('video-fixed'); } else { this.video.nativeElement.classList.remove('video-fixed'); } }) }
Mula-mula dapatkan anchor
objek elemen dan dengar tatal objek halaman document
(kami telah menambah fungsi anti goncang pengoptimuman di sini), apabila bottom < 0
, tambah gaya yang berkaitan video-fixed
pada video
.
Menyeret elemen
Langkah seterusnya ialah melaksanakan penyeretan elemen video
. Di sini kita ingin mendengar tiga peristiwa elemen video
iaitu tetikus ke bawah mousedown
, pergerakan tetikus mousemove
dan tetikus ke atas mouseup
.
// demo.component.ts public mouseDown!: any; public mouseUp!: any; public mouseMove!: any; ngAfterViewInit(): void { this.mouseDown = fromEvent(this.video.nativeElement, 'mousedown'); // 目标元素按下,即 video this.mouseMove = fromEvent(document, 'mousemove'); // 元素在文档内移动 this.mouseUp = fromEvent(document, 'mouseup'); // 鼠标抬起 this.moveFn() } // 目标元素移动 public moveFn() { this.mouseDown .pipe( filter(() => this.video.nativeElement.classList.contains('video-fixed')), map(() => this.mouseMove.pipe( throttleTime(50), // 节流 takeUntil(this.mouseUp) )), // concatAll 顺序接受上游抛出的各个数据流作为它的数据, 若前面的数据流不能同步的完结,它会暂存后续数据流,当前数据流完成后它才会订阅后一个暂存的数据流 concatAll(), withLatestFrom(this.mouseDown, (move:any, down:any) => { return { x: this.validValue(move.clientX - down.offsetX, window.innerWidth - this.video.nativeElement.offsetWidth, 0), y: this.validValue(move.clientY - down.offsetY, window.innerHeight - this.video.nativeElement.offsetHeight, 0) } }) ) .subscribe((position: { x: number, y: number }) => { this.video.nativeElement.style.top = position.y + 'px'; this.video.nativeElement.style.left = position.x + 'px'; }) } // 校验边界值 public validValue = (value:number, max:number, min: number) => { return Math.min(Math.max(value, min), max) }
Kami mendengar elemen sasaran (fungsi penapis) ditekan oleh tetikus, dan kemudian tetikus boleh bergerak dalam julat document
(dioptimumkan di sini dengan fungsi pendikit) sehingga tetikus dinaikkan . Semasa pergerakan, jarak ke kiri dan atas tetingkap visual relatif elemen sasaran dikira dan nilai diberikan kepada left
dan top
.
Pengiraan di sini move.clientX - down.offsetX, window.innerWidth - this.video.nativeElement.offsetWidth
, anda mungkin tidak begitu jelas tentang konsep yang berkaitan, tetapi tidak mengapa, faham sahaja kandungan di atas. Perkara pengetahuan yang berkaitan akan diperkenalkan dalam artikel berikut.
Akhir sekali, kesan yang kami dapat adalah seperti berikut
[Tamat]
Untuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila layari: Video Pengaturcaraan! !
Atas ialah kandungan terperinci Analisis ringkas tentang bagaimana Angular rxjs melaksanakan fungsi drag-and-drop?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!