溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

基于uni-app開(kāi)發(fā)刻度尺組件的示例分析

發(fā)布時(shí)間:2022-03-29 09:11:12 來(lái)源:億速云 閱讀:283 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)基于uni-app開(kāi)發(fā)刻度尺組件的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

一、前言

小編最近接到一個(gè)任務(wù),就是在輸入數(shù)值的時(shí)候不再使用傳統(tǒng)的鍵盤(pán)了,而是用拖拉尺子的形式選擇數(shù)值,大概長(zhǎng)這樣:

基于uni-app開(kāi)發(fā)刻度尺組件的示例分析

其實(shí)這需求不是第一次提出來(lái)了,在我們的應(yīng)用第一版的時(shí)候產(chǎn)品就想這樣做。
當(dāng)然小編我當(dāng)時(shí)剛接到這個(gè)任務(wù)的時(shí)候是拒絕的,你不能讓我做,我就馬上去做,第一我要調(diào)研一下,因?yàn)槲也幌牖敲炊鄷r(shí)間成本開(kāi)發(fā)出這個(gè)組件再加一些特技上去,

滑動(dòng)超過(guò)邊緣還能duang一下彈回來(lái),但是其實(shí)用起來(lái)還沒(méi)直接鍵盤(pán)輸入數(shù)字來(lái)得方便,這樣領(lǐng)導(dǎo)出來(lái)一定會(huì)罵我;后面經(jīng)過(guò)一番調(diào)研和時(shí)間評(píng)估,最終選擇了另一套方案:

基于uni-app開(kāi)發(fā)刻度尺組件的示例分析

自己寫(xiě)了一套數(shù)字鍵盤(pán),比刻度尺簡(jiǎn)單很多,也不怎么耗性能,用起來(lái)還挺方便。

為什么不用系統(tǒng)自帶鍵盤(pán)呢?這個(gè)不用說(shuō),大家都知道手機(jī)瀏覽器調(diào)用系統(tǒng)自帶鍵盤(pán)有多惡心。
然而,該應(yīng)用迎來(lái)了第二個(gè)版本,產(chǎn)品又把刻度尺拿了出來(lái)并揚(yáng)言:“要砍需求先砍我!”。

不過(guò)確實(shí),第二版有了更加復(fù)雜的場(chǎng)景,選擇的數(shù)值需要限制范圍,而且范圍大小會(huì)隨著一些條件不斷變化,要想用戶能直觀并快速地輸入正確的數(shù)值,只能是刻度尺了。

然后經(jīng)過(guò)小編兩分鐘的深思熟慮,最終把任務(wù)接了下來(lái)。

二、開(kāi)發(fā)

首先我們來(lái)看看刻度尺有哪些特點(diǎn)。

  • 可以滑動(dòng);

  • 根據(jù)滑動(dòng)距離輸出數(shù)值;

  • 滑過(guò)頭了會(huì)自動(dòng)回彈;

看起來(lái),我們可以基于uni-app提供的scroll-view組件來(lái)開(kāi)發(fā),該組件有提供以下屬性正好適合我們的刻度尺特性:

屬性名類型默認(rèn)值說(shuō)明
scroll-xBooleanfalse允許橫向滾動(dòng)
scroll-leftNumber/String 設(shè)置橫向滾動(dòng)條位置
scroll-with-animationBooleanfalse在設(shè)置滾動(dòng)條位置時(shí)使用動(dòng)畫(huà)過(guò)渡
@scrollEventHandle 滾動(dòng)時(shí)觸發(fā),event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}

然后第二步,需要計(jì)算刻度。
小編先設(shè)置好了默認(rèn)每個(gè)刻度占10像素;

const GUTTER = 10;

然后就開(kāi)始計(jì)算我們一共需要多少個(gè)刻度,其實(shí)很簡(jiǎn)單,就是你需要多少刻度,就傳進(jìn)來(lái)一個(gè)最大最小值,然后用最大值減去最小值,就是刻度的數(shù)量了;

這時(shí)候會(huì)出現(xiàn)一個(gè)交互問(wèn)題,因?yàn)榭潭瘸叩倪x擇標(biāo)是放在屏幕中間的,所以刻度尺的邊界是需要顯示多余的刻度用來(lái)充滿屏幕,于是小編就決定生成相當(dāng)于兩倍于屏幕寬度的多余刻度;

// 多余的刻度數(shù)量
const extraGridCount = Math.ceil(window.innerWidth / GUTTER);
// 生成刻度數(shù)組
this.gridList = Array.from(Array(this.gridMax - this.gridMin + extraGridCount * 2)).map((_, i) => {
      const num = i + this.gridMin - extraGridCount;
      const displayNum = this.decimal === 1 ? num / 10 : num;
      return {
        num,
        displayNum,
        isLongGrid: num % GUTTER === 0,
        showText: num % GUTTER === 0 && num >= this.gridMin && num <= this.gridMax
      }
});

刻度數(shù)組內(nèi)每個(gè)元素就是一個(gè)刻度對(duì)象,包含了以下屬性:

  • 刻度數(shù)值

  • 刻度顯示的數(shù)值(顯示的數(shù)值可能會(huì)與實(shí)際數(shù)值不一致,是為了擴(kuò)展小數(shù)用的)

  • 是否是長(zhǎng)刻度(因?yàn)榭潭瘸呙扛?0個(gè)就會(huì)出現(xiàn)一條長(zhǎng)刻度)

  • 是否顯示刻度的數(shù)值(只有長(zhǎng)刻度和有效刻度才會(huì)顯示數(shù)值)

數(shù)組生成好,就可以根據(jù)數(shù)組來(lái)渲染整個(gè)刻度尺了;

 <u-row v-if="show" class="grid-wrapper" align="top">
    <view
        class="grid-item"
        :class="{'long': item.isLongGrid}"
        v-for="(item, i) in gridList"
        :key="i"
        :
    >
      <text
          class="grid-num"
          v-if="item.showText"
      >{{item.displayNum}}</text>
    </view>
  </u-row>

渲染完畢之后,就可以通過(guò)一些算法計(jì)算刻度尺的初始位置了。然后通過(guò)scroll事件,在刻度尺滑動(dòng)過(guò)程中計(jì)算數(shù)值;

scroll(e){
  const scrollLeft = e.detail.scrollLeft;
  let value = Math.floor((scrollLeft - this.offsetScroll + this.gridMin * GUTTER) / GUTTER);
  if(value < this.gridMin){
    value = this.gridMin;
  }else if(value > this.gridMax){
    value = this.gridMax;
  }}

其中offsetScroll 就是多余的那部分刻度,需要減掉的,還要判斷一下是否小于最小值或者是否大于最大值; 接下來(lái)就是刻度尺的回彈了,當(dāng)滑動(dòng)超過(guò)最大值或最小值時(shí),需要往回彈,在視覺(jué)上與計(jì)算好的數(shù)值保持一致; 其實(shí)也只是在滑動(dòng)結(jié)束時(shí)算一下刻度尺是否應(yīng)該回到邊界就好了,動(dòng)畫(huà)上scroll-view已經(jīng)幫我們解決好了;

adjustScrollPosition(){
    /** 滾動(dòng)結(jié)束后調(diào)節(jié)滾動(dòng)位置 */
    if(this.actualScrollLeft < this.offsetScroll){
        this.scrollLeft = this.offsetScroll + (Math.random() / 100);
    } else if(this.actualScrollLeft > (this.gridMax - this.gridMin) * GUTTER + this.offsetScroll){
        this.scrollLeft = (this.gridMax - this.gridMin) * GUTTER + 
        this.offsetScroll + (Math.random() / 100);
    } else if(Math.floor(this.actualScrollLeft - this.offsetScroll) % GUTTER !== 0){
        const dryScrollLeft = this.actualScrollLeft - this.offsetScroll;
        this.scrollLeft = dryScrollLeft - dryScrollLeft % GUTTER + this.offsetScroll;
    }
}

關(guān)于“基于uni-app開(kāi)發(fā)刻度尺組件的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI