成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Angular+rxjs如何實(shí)現(xiàn)拖拽功能

這篇文章主要介紹“Angular+rxjs如何實(shí)現(xiàn)拖拽功能”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Angular+rxjs如何實(shí)現(xiàn)拖拽功能”文章能幫助大家解決問(wèn)題。

成都創(chuàng)新互聯(lián)公司是一家朝氣蓬勃的網(wǎng)站建設(shè)公司。公司專(zhuān)注于為企業(yè)提供信息化建設(shè)解決方案。從事網(wǎng)站開(kāi)發(fā),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),網(wǎng)站模板,微信公眾號(hào)開(kāi)發(fā),軟件開(kāi)發(fā),微信小程序,10年建站對(duì)成都服務(wù)器租用等多個(gè)方面,擁有豐富的網(wǎng)站維護(hù)經(jīng)驗(yàn)。

Angular+rxjs如何實(shí)現(xiàn)拖拽功能

頁(yè)面中 video 標(biāo)簽,當(dāng)滾動(dòng)高度超過(guò)其位置之后,將其設(shè)置為可在可視區(qū)域自由拖拽。

一個(gè)不錯(cuò)的 Idea,如果你使用 Angular@angular/cdk/drag-drop 可以輕松實(shí)現(xiàn),但是我們這里不使用工具。

好吧,我們來(lái)分析下實(shí)現(xiàn)的思路:

  • 頁(yè)面滾動(dòng)高度大于視頻所在的位置:那么就是視頻的 bottom 值相對(duì)可視窗口的值要小于0,我們需要設(shè)定一個(gè)包裹 video 標(biāo)簽的 div 方便計(jì)算,其高度是原設(shè)定 video 的高度。即元素脫離原文檔布局

  • video 元素可以拖拽,那么其定位需要被改變?yōu)?fixed

  • video 元素在可視區(qū)內(nèi)自由拖動(dòng),那么需要對(duì)其 top, left 值進(jìn)行限定

所以我們?cè)O(shè)定下面的 demo 布局:

<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>

有下面這些預(yù)定的樣式:

<!-- 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 布局的樣式,默認(rèn)布局中是沒(méi)有的 -->
  &.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;
      }
    }
  }
}

這里還引入了 rxjs 來(lái)操作。

元素脫離原文檔布局

剛才已經(jīng)分析了 video 元素脫離文檔的臨界調(diào)節(jié)了:

video的外 div,即 #anchor 元素的相對(duì)視圖的 bottom < 0。所以我們有:

@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();
}

// 頁(yè)面滾動(dòng)
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');
      }
    })
}

先獲取 anchor 元素對(duì)象,監(jiān)聽(tīng)頁(yè)面對(duì)象 document 滾動(dòng)(我們這里加入了防抖函數(shù)優(yōu)化),當(dāng) bottom < 0 的時(shí)候,將相關(guān)的樣式 video-fixed 添加給 video

元素拖拽

接下來(lái)就是實(shí)現(xiàn) video 元素的拖拽。這里我們要監(jiān)聽(tīng) video 元素的三個(gè)事件,分別是鼠標(biāo)按下 mousedown,鼠標(biāo)移動(dòng) mousemove 和鼠標(biāo)抬起 mouseup。

// demo.component.ts

public mouseDown!: any;
public mouseUp!: any;
public mouseMove!: any;

ngAfterViewInit(): void {
  this.mouseDown = fromEvent(this.video.nativeElement, 'mousedown'); // 目標(biāo)元素按下,即 video
  this.mouseMove = fromEvent(document, 'mousemove'); // 元素在文檔內(nèi)移動(dòng)
  this.mouseUp = fromEvent(document, 'mouseup'); // 鼠標(biāo)抬起
  
  this.moveFn()
}

// 目標(biāo)元素移動(dòng)
public moveFn() {
  this.mouseDown
    .pipe(
      filter(() => this.video.nativeElement.classList.contains('video-fixed')),
      map(() => this.mouseMove.pipe(
        throttleTime(50), // 節(jié)流
        takeUntil(this.mouseUp)
      )),
      // concatAll 順序接受上游拋出的各個(gè)數(shù)據(jù)流作為它的數(shù)據(jù), 若前面的數(shù)據(jù)流不能同步的完結(jié),它會(huì)暫存后續(xù)數(shù)據(jù)流,當(dāng)前數(shù)據(jù)流完成后它才會(huì)訂閱后一個(gè)暫存的數(shù)據(jù)流
      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';
    })
}

// 校驗(yàn)邊界值
public validValue = (value:number, max:number, min: number) => {
  return Math.min(Math.max(value, min), max)
}

我們監(jiān)聽(tīng)目標(biāo)元素(filter 函數(shù))被鼠標(biāo)按下,然后鼠標(biāo)可以在 document 范圍內(nèi)移動(dòng)(這里用節(jié)流函數(shù)優(yōu)化了下),直到監(jiān)聽(tīng)到鼠標(biāo)抬起。在移動(dòng)的過(guò)程中,計(jì)算目標(biāo)元素的相對(duì)可視窗口左側(cè)和頂部的距離,將值賦予到 lefttop

這里的計(jì)算 move.clientX - down.offsetX, window.innerWidth - this.video.nativeElement.offsetWidth,相關(guān)的概念也許你不是很清楚,不過(guò)沒(méi)關(guān)系,上面的內(nèi)容,理解思路即可。

關(guān)于“Angular+rxjs如何實(shí)現(xiàn)拖拽功能”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

當(dāng)前題目:Angular+rxjs如何實(shí)現(xiàn)拖拽功能
當(dāng)前鏈接:http://jinyejixie.com/article0/jjgcoo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、品牌網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、網(wǎng)站內(nèi)鏈、網(wǎng)站設(shè)計(jì)公司、關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
凌源市| 绥中县| 江北区| 招远市| 鸡泽县| 岳普湖县| 古浪县| 东港市| 成武县| 邵阳县| 宜城市| 合阳县| 临西县| 文安县| 报价| 浪卡子县| 万山特区| 金沙县| 景德镇市| 响水县| 贵定县| 龙南县| 财经| 汝阳县| 彩票| 黑水县| 来安县| 清河县| 台安县| 沁阳市| 江口县| 丰宁| 武强县| 乐昌市| 丰原市| 克山县| 赤壁市| 毕节市| 郁南县| 潮安县| 确山县|