vue.js實作仿原生ios時間選擇元件開發經驗
前言
最近幾個月一直在看VUE,然後試著只用原生js+vue實作某些元件。
PC端時間選擇元件這是最開始實現的pc上的時間選擇,平時移動端也在做,所以就想實現一下移動端的時間選擇器,下面分享一下我實現移動端滾輪特效時間選擇器的想法與過程。整個元件是基於vue-cli來進行建構的
功能
1.時間選擇[
A.年月日选择
B.年月日小时分钟选择
C.小時分鐘選擇D.分鐘選擇]
2.滾輪效果[
A.构成一个圆环首尾相连
B.不構成首尾相連]
3.時間選擇範圍設定(所選時間超過範圍將彈窗提示),分鐘間隔設定
4. 多語言設定
5.時間格式設定滿足yyyy/MM/dd HH:mm 這一類的設定規則
6.UE上做到接近ios原生效果
7.擴充不隻隻能選擇時間,可以傳入自訂連動選擇資料
這裡主要講講無限滾輪的實作
資料準備1
這裡拿
天
來做說明
取得一個月有多少天的一個巧妙的方法。
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方法來實現,放入
yearList
monthList
dayList
hourList
minuteList
來存儲基礎數據,這裡數據準備就先告一段落。
靜態效果實現
實現滾輪靜態效果有多種方式
1.視覺3D效果[加陰影]
2.實際3D效果[ CSS3D]
我把实现效果大致分为上面2种,具体的大家可以自己搜索相关资料,这里展开涉及太多就带过好了
我自己實作是用的第二種採用了CSS3D
說明
首先我們看到原生ios的選擇效果在進入選擇範圍內和選擇範圍外的滾輪是有差別的
所以為了實現這個效果差別我選擇用2個dom結構來實現,一個dom實現滾輪,一個dom實現黑色選取效果,這樣連動的時候就有類似原生的效果差別
picker-panel
裝各種選擇dom,這裡只給了day的,
box-day
裝天資料的一個最外層盒子,
check-line
實作選取的那2條線,
day-list
最外層黑色效果資料,
day-wheel
灰色滾輪部分
<p class="picker-panel"> <!--other box--> <p class="box-day"> <p class="check-line"></p> <p class="day-checked"> <p class="day-list"> <p class="list-p" v-for="day in renderListDay"> {{day.value}} </p> </p> </p> <p class="day-wheel"> <p class="wheel-p" v-for="day in renderListDay" transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);> {{day.value}} </p> </p> </p> <!--other box--> </p>
.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-p{ 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;
滾輪背後部分自動隱藏
postition:absolute;
用來定位輪子
transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);
每個資料旋轉的角度和滾輪側檢視圓的半徑
每個資料旋轉的角度和建構原理
如上圖
是我們滾輪的效果立體圖,r 就是我們translated3d(0px,0px,2.5rem) 這條css中的2.5rem,
如果沒有這句css 那麼所有的資料將會匯聚在圓心
上圖不做旋轉(紅色代表我們看到的資料效果)
上圖做了旋轉(紅色橘色代表我們看到的資料效果)
藍色弧線表示的角度是一樣的(這個涉及角的知識),也是視覺旋轉角度,就是rotate3d這句css裡面的80deg ,我做的是每個間隔20度,這樣實際我們只用旋轉x軸就順帶旋轉了圓心角度,這樣就把整個環給鋪開了。完整一個圓可以裝下360/20 個數據,而我們肉眼正能看見正面的數據,所以過了一定角度就在背後應該不能被我們看見,而-webkit-backface-visibility: hidden;這句話就起了作用。
这里我们发现轮子装不完所有数据,而且我们要实现数据循环
類似下圖效果
所以就有了第二次資料準備
資料準備2
這裡也是用我們的dayList作為初始資料[1,2,3,4,.....,30,31]
這裡我們每次取19個資料作為渲染資料,而我們需要renderListDay初始呈現是[23 ,24,25,26,27,28,29,30,31,1,2,3,4,5,6,7,8,9,10]
因為這樣取最中間的數剛好是第一個(僅在初始化的時候)
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 },
取資料的方法小於0倒著取大於0正著取,索引大於原始資料長度都用%計算來取得正常範圍對應的索引,所以上面的spin 就是我們的取資料的叉子(初始是從-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]; } //... },
每條資料旋轉的角度(上半圓是正,下半圓是負)
<p class="wheel-p" 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}}</p>
接着需要旋转到我们需要的角度,跟我们的初始化时间对上,this.orDay-this.DayList[0] 是获取偏移量来矫正角度
this.$el.getElementsByClassName('day-wheel')[0].style.transform = 'rotate3d(1, 0, 0, ' + (this.orDay - this.dayList[0]) * 20 + 'deg)';
增加touch事件
剩下的事就很好处理了,给对应的dom绑定事件根据touchmove的距离来转换成旋转的角度 和check-list的位移这里translateY是用来记录实际移动的距离的,最后输出需要算入偏移量
<p class="box-day" v-on:touchstart="myTouch($event,'day')" v-on:touchmove="myMove($event,'day')" v-on:touchend="myEnd($event,'day')"> <p class="check-line"></p> <p class="day-checked"> <p class="day-list" data-translateY="0" style="transform: translateY(0rem)"> <p class="list-p" v-for="day in renderListDay" v-bind:data-index="day.index"> {{day.value}} </p> </p> </p> <p class="day-wheel" style=" transform: rotate3d(1, 0, 0,0deg)"> <p class="wheel-p" 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}} </p> </p> </p>
惯性滚动
这个实现我是用了一个 cubic-bezier(0.19, 1, 0.22, 1)
判断手势是不是flicker 如果是flicker通过一个瞬时速度来算出位移,和时间,然后一次性设置,然后用transition做惯性滚动,
普通拖动 设置1秒
这个实际效果还是有点不好,以后来改进。
其他功能的实现
这里不做详细说明了
总结
自适应方面用了手淘的解决方案
这次实现这个组件最困难的就是实现无限滚动,和无限滚动的渲染数据的构造,接着就是惯性滚动的实现。
已知问题
1.惯性滚动不完美
2.无限滚动实现了。非无限滚动没实现,就是渲染数据就是[1,2,3,4,5,6,7,8,9,10]
3.现在选择必须 年月日 或者年月日小时分钟 不能单独选小时或者分钟
以上是vue.js實作仿原生ios時間選擇元件開發經驗的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

一年一度的WWDC已經結束,iOS18無疑是大家關注的一大焦點。目前有許多iPhone用戶都搶先升級到了iOS18,但各種系統Bug讓人難受。有部落客表示,升級iOS18要謹慎,因為「Bug多到飛起」。部落客表示,如果你的iPhone是主力機,建議不要升級iOS18,因為第一版的Bug非常多。他也彙整了幾個目前遇到的系統Bug:1、切換圖示樣式卡頓,導致圖示不顯示2、手電筒示寬動畫經常遺失3、抖音App上傳不了影片4、微信訊息延遲10s左右推送5 、電話偶爾打不出去,顯示黑屏6、發熱嚴

感谢网友吉茵珂絲、xxx_x、番茄炒西红柿、Terrence、香辣鸡腿堡的线索投递!7月27日消息,苹果公司今天面向开发者,重新发布了iOS/iPadOS18Beta4更新,内部版本号从22A5316j升级到22A5316k,目前尚不清楚两个Beta4版本更新之间的区别。已经注册的开发者可以打开“设置”应用程序,进入“软件更新”部分,点击“测试版更新”选项,然后切换iOS18/iPadOS18开发者测试版设置来选择测试版。下载并安装测试版需要与开发者账户关联的AppleID。7月24日报道,iO

7月31日消息,蘋果昨天(7月30日)發布新聞稿,宣布推出新的開源Swift包(swift-homomorphic-encryption),用於在Swift程式語言中啟用同態加密。註:同態加密(HomomorphicEncryption,HE)是指滿足密文同態運算性質的加密演算法,即資料經過同態加密之後,對密文進行特定的計算,得到的密文計算結果在進行對應的同態解密後的明文等同於明文資料直接進行相同的計算,實現資料的「可算不可見」。同態加密技術可以計算加密數據,而且不會向操作過程洩漏底層的未加

更新:Saunders Tech 已將教學上傳到他的 YouTube 頻道(下面嵌入影片),解釋如何在歐盟境外的 iPad 上安裝 Fortnite 和 Epic Games Store。然而,該過程不僅需要特定的 iO 測試版

感謝網友辣雞腿堡、軟媒新友2092483、手寫的從前、DingHao、小星_14、窩窩頭吃大口、非影Q、軟媒新友2168428、Slades、Aaron212、快樂小刺蝟、小伯爵、吃魚的小奶貓的線索投遞! 【點此直達升級教學】7月24日訊息,蘋果今日向iPhone和iPad用戶推送了iOS/iPadOS18開發者預覽版Beta4更新(內部版本號:22A5316j),這次更新距離上次發布隔了15天。 Carplay壁紙蘋果為CarPlay添加了壁紙,涵蓋淺色和深色兩種模式,其壁紙風格類似於iPhon

在剛結束的歐洲盃決賽中,你是否為自己支持的球隊瘋狂打call?在馬上到來的巴黎奧運中,你是否也期待能完美捕捉到各賽事的高光時刻?這其中,擁有一台優質的觀賽設備至關重要。哈趣K2投影機以其高性價比和出色的性能,當之無愧地成為觀賽良選。它不僅具備高亮度、清晰的畫質,還能提供沉浸式的觀影體驗,讓每一場比賽的精彩時刻都彷彿近在咫尺。這樣的設備,你是否已經心動了呢?它定能讓你在家中也能享受到奧運賽事的熱情與夢想。哈趣K2貼心最大的亮點就是它210°的超大角度調節,無論是天花板還是牆壁,都可以方便觀影。

感謝網友末6_、嗯嗯嗯哼哼、吃貓的鹹魚、瑤池青蓮、辣雞腿堡、思燕、蒂姆Apple的線索投遞! 7月30日消息,蘋果今日針對iPhone和iPad用戶推出了iOS18和iPadOS18公測版Beta2版本更新,距離上個公測版本過了兩週時間。該公測版的更新內容類似開發者預覽版Beta4,新增CarPlay壁紙、梳理設定選項、增強相機控制、深色/淺色模式圖示等,具體可以看先前詳細報道內容。 ##如何升級iOS/iPadOS/watchOS/macOS開發版和公測版? iOS/iPadOS升級iOS/iPa

蘋果公司最新發布的iOS18、iPadOS18以及macOSSequoia系統為Photos應用程式增添了一項重要功能,旨在幫助用戶輕鬆恢復因各種原因遺失或損壞的照片和影片。這項新功能在Photos應用的"工具"部分引入了一個名為"已恢復"的相冊,當用戶設備中存在未納入其照片庫的圖片或影片時,該相冊將自動顯示。 "已恢復"相簿的出現為因資料庫損壞、相機應用未正確保存至照片庫或第三方應用管理照片庫時照片和視頻丟失提供了解決方案。使用者只需簡單幾步
