国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

vue.js實(shí)現(xiàn)仿原生ios時(shí)間選擇組件實(shí)例代碼

2019-11-19 18:22:02
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言

最近幾個(gè)月一直在看VUE,然后試著只用原生js+vue實(shí)現(xiàn)某些組件。

PC端時(shí)間選擇組件 這是最開(kāi)始實(shí)現(xiàn)的pc上的時(shí)間選擇,平時(shí)移動(dòng)端也在做,所以就想實(shí)現(xiàn)一下移動(dòng)端的時(shí)間選擇器,下面分享一下我實(shí)現(xiàn)移動(dòng)端滾輪特效時(shí)間選擇器的思路和過(guò)程。整個(gè)組件是基于vue-cli來(lái)進(jìn)行構(gòu)建的

功能

1.時(shí)間選擇[ A.年月日選擇 B.年月日小時(shí)分鐘選擇 C.小時(shí)分鐘選擇 D.分鐘選擇]

2.滾輪效果[ A.構(gòu)成一個(gè)圓環(huán)首尾相連 B.不構(gòu)成首尾相連]

3.時(shí)間選擇范圍設(shè)置(所選時(shí)間超過(guò)范圍將彈窗提示),分鐘間隔設(shè)置

4.多語(yǔ)言設(shè)置

5.時(shí)間格式設(shè)置 滿足 yyyy/MM/dd HH:mm 這一類的設(shè)置規(guī)則

6.UE上做到接近ios原生效果

7.擴(kuò)展 不僅僅只能選擇時(shí)間,可以傳入自定義聯(lián)動(dòng)選擇數(shù)據(jù)

這里主要講講無(wú)限滾輪的實(shí)現(xiàn)
數(shù)據(jù)準(zhǔn)備1

這里拿 來(lái)做說(shuō)明

獲取一個(gè)月有多少天的一個(gè)巧妙的方法。

 dayList () {       /* get currentMonthLenght */        let currentMonthLength = new Date(this.tmpYear, this.tmpMonth + 1, 0).getDate();       /* get currentMonth day */        let daylist = Array.from({length: currentMonthLength}, (value, index) => {          return index + 1        });        return daylist      },

這里我用了vue 的computed方法來(lái)實(shí)現(xiàn),放入 yearList monthList dayList hourList minuteList 來(lái)存儲(chǔ)基礎(chǔ)數(shù)據(jù),這里數(shù)據(jù)準(zhǔn)備就先告一段落。

靜態(tài)效果實(shí)現(xiàn)

實(shí)現(xiàn)滾輪靜態(tài)效果有多種方式

1.視覺(jué)3D效果[加陰影]

2.實(shí)際3D效果[CSS3D]

我把實(shí)現(xiàn)效果大致分為上面2種,具體的大家可以自己搜索相關(guān)資料,這里展開(kāi)涉及太多就帶過(guò)好了

我自己實(shí)現(xiàn)是用的第二種采用了CSS3D

說(shuō)明

首先我們看到原生ios的選擇效果在進(jìn)入選擇范圍內(nèi)和選擇范圍外的滾輪是有差別的

所以為了實(shí)現(xiàn)這個(gè)效果差別我選擇用2個(gè)dom結(jié)構(gòu)來(lái)實(shí)現(xiàn),一個(gè)dom實(shí)現(xiàn)滾輪,一個(gè)dom實(shí)現(xiàn)黑色選中效果,這樣聯(lián)動(dòng)的時(shí)候就有類似原生的效果差別

picker-panel 裝各種選擇dom,這里只給出了day的, box-day 裝天數(shù)據(jù)的一個(gè)最外層盒子, check-line 實(shí)現(xiàn)選中的那2條線, day-list 最外層黑色效果數(shù)據(jù), day-wheel 灰色滾輪部分

<div class="picker-panel"><!--other box--><div class="box-day">  <div class="check-line"></div>  <div class="day-checked">    <div class="day-list">      <div class="list-div" v-for="day in renderListDay">       {{day.value}}      </div>    </div>  </div>  <div class="day-wheel">    <div class="wheel-div" v-for="day in renderListDay" transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);>    {{day.value}}    </div>  </div></div><!--other box--></div>
.day-wheel{    position: absolute;    overflow: visible;    height: px2rem(68px);    font-size: px2rem(36px);    top:px2rem(180px);    left: 0;    right: 0;    color:$unchecked-date;    -webkit-transform-style: preserve-3d;    transform-style: preserve-3d;    .wheel-div{     height: px2rem(68px);     line-height: px2rem(68px);     position: absolute;     top:0;     width: 100%;     text-align: center;     -webkit-backface-visibility: hidden;     backface-visibility: hidden;     white-space: nowrap;     overflow: hidden;     text-overflow: ellipsis;    }   }

主要涉及的css屬性

transform-style: preserve-3d;

展示3D效果,

-webkit-backface-visibility: hidden;

滾輪背后部分自動(dòng)隱藏

postition:absolute;

用來(lái)定位輪子

transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);

每個(gè)數(shù)據(jù)旋轉(zhuǎn)的角度 和滾輪側(cè)視圖圓的半徑

每個(gè)數(shù)據(jù)旋轉(zhuǎn)的角度和構(gòu)造原理

如上圖

是我們滾輪的效果立體圖,r 就是我們 translated3d(0px,0px,2.5rem) 這條css中的2.5rem,

如果沒(méi)有這句css 那么所有的數(shù)據(jù)將匯聚在圓心

 

上圖 不做旋轉(zhuǎn)(紅色代表我們看到的數(shù)據(jù)效果)

 

上圖 做了旋轉(zhuǎn)(紅色 橙色代表我們看到的數(shù)據(jù)效果)

藍(lán)色弧線表示的角度是一樣的(這個(gè)涉及角的知識(shí)),也是視覺(jué)旋轉(zhuǎn)角度,就是rotate3d這句css里面的80deg ,我做的是每個(gè)間隔20度,這樣實(shí)際我們只用旋轉(zhuǎn)x軸就順帶旋轉(zhuǎn)了圓心角度,這樣就把整個(gè)環(huán)給鋪開(kāi)了。完整一個(gè)圓可以裝下360/20 個(gè)數(shù)據(jù),而我們?nèi)庋壅芸匆?jiàn)正面的數(shù)據(jù),所以過(guò)了一定角度就在背后應(yīng)該不能被我們看見(jiàn),而-webkit-backface-visibility: hidden;這句話就起了作用。

這里我們發(fā)現(xiàn)輪子裝不完所有數(shù)據(jù),而且我們要實(shí)現(xiàn)數(shù)據(jù)循環(huán)

類似下圖效果

所以就有了第二次數(shù)據(jù)準(zhǔn)備

數(shù)據(jù)準(zhǔn)備2

這里也是用我們的dayList作為初始數(shù)據(jù)[1,2,3,4,.....,30,31]

這里我們每次取19個(gè)數(shù)據(jù)來(lái)作為渲染數(shù)據(jù),而我們需要renderListDay初始呈現(xiàn)是[23,24,25,26,27,28,29,30,31,1,2,3,4,5,6,7,8,9,10]

因?yàn)檫@樣取最中間的數(shù)剛好是第一個(gè)(僅在初始化的時(shí)候)

renderListDay(){        let list = [];        for (let k = this.spin.day.head; k <= this.spin.day.last; k++) {          let obj = {            value: this.getData(k, 'day'),            index: k,          };          list.push(obj)        }        return list      },

取數(shù)據(jù)的方法 小于0倒著取 大于0正著取,索引大于原始數(shù)據(jù)長(zhǎng)度都用%計(jì)算來(lái)獲得正常范圍對(duì)應(yīng)的索引,所以上面的spin 就是我們的取數(shù)據(jù)的叉子(初始是從-9到9)

getData(idx, type){       //...        else if (type == 'day') {          return this.dayList[idx % this.dayList.length >= 0 ? idx % this.dayList.length : idx % this.dayList.length + this.dayList.length];        }         //...      },

每條數(shù)據(jù)旋轉(zhuǎn)的角度(上半圓是正,下半圓是負(fù))

<div class="wheel-div" v-for="day in renderListDay" v-bind:data-index="day.index" v-bind:style="{transform: 'rotate3d(1, 0, 0, '+ (-day.index)*20%360+'deg) translate3d(0px, 0px, 2.5rem)'}">{{day.value}}{{day.value}}</div>

接著需要旋轉(zhuǎn)到我們需要的角度,跟我們的初始化時(shí)間對(duì)上,this.orDay-this.DayList[0] 是獲取偏移量來(lái)矯正角度

this.$el.getElementsByClassName('day-wheel')[0].style.transform = 'rotate3d(1, 0, 0, ' + (this.orDay - this.dayList[0]) * 20 + 'deg)';

增加touch事件

剩下的事就很好處理了,給對(duì)應(yīng)的dom綁定事件根據(jù)touchmove的距離來(lái)轉(zhuǎn)換成旋轉(zhuǎn)的角度 和check-list的位移這里translateY是用來(lái)記錄實(shí)際移動(dòng)的距離的,最后輸出需要算入偏移量

<div class="box-day" v-on:touchstart="myTouch($event,'day')" v-on:touchmove="myMove($event,'day')" v-on:touchend="myEnd($event,'day')">  <div class="check-line"></div>  <div class="day-checked">    <div class="day-list" data-translateY="0" style="transform: translateY(0rem)">      <div class="list-div" v-for="day in renderListDay" v-bind:data-index="day.index">        {{day.value}}      </div>    </div>  </div>  <div class="day-wheel" style=" transform: rotate3d(1, 0, 0,0deg)">    <div class="wheel-div" v-for="day in renderListDay" v-bind:data-index="day.index" v-bind:style="{transform: 'rotate3d(1, 0, 0, '+ (-day.index)*20%360+'deg) translate3d(0px, 0px, 2.5rem)'}">     {{day.value}}    </div>  </div></div>

慣性滾動(dòng)

這個(gè)實(shí)現(xiàn)我是用了一個(gè) cubic-bezier(0.19, 1, 0.22, 1)

判斷手勢(shì)是不是flicker 如果是flicker通過(guò)一個(gè)瞬時(shí)速度來(lái)算出位移,和時(shí)間,然后一次性設(shè)置,然后用transition做慣性滾動(dòng),
普通拖動(dòng) 設(shè)置1秒

這個(gè)實(shí)際效果還是有點(diǎn)不好,以后來(lái)改進(jìn)。

其他功能的實(shí)現(xiàn)

這里不做詳細(xì)說(shuō)明了

總結(jié)

自適應(yīng)方面用了手淘的解決方案

這次實(shí)現(xiàn)這個(gè)組件最困難的就是實(shí)現(xiàn)無(wú)限滾動(dòng),和無(wú)限滾動(dòng)的渲染數(shù)據(jù)的構(gòu)造,接著就是慣性滾動(dòng)的實(shí)現(xiàn)。

已知問(wèn)題

1.慣性滾動(dòng)不完美

2.無(wú)限滾動(dòng)實(shí)現(xiàn)了。非無(wú)限滾動(dòng)沒(méi)實(shí)現(xiàn),就是渲染數(shù)據(jù)就是[1,2,3,4,5,6,7,8,9,10]

3.現(xiàn)在選擇必須 年月日 或者年月日小時(shí)分鐘 不能單獨(dú)選小時(shí)或者分鐘

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 广元市| 茶陵县| 南乐县| 洛川县| 玉树县| 贵南县| 遂平县| 苍南县| 蓬溪县| 青神县| 共和县| 平果县| 同仁县| 江陵县| 即墨市| 蒙自县| 营山县| 肇东市| 萝北县| 兴国县| 花莲市| 瑞金市| 桂阳县| 泰兴市| 清水县| 乡宁县| 嵊州市| 田阳县| 内丘县| 康乐县| 贵南县| 苍梧县| 弥勒县| 田林县| 景德镇市| 木兰县| 鹤岗市| 客服| 黄浦区| 鹤岗市| 司法|