Vorwort
Ich habe mir in den letzten Monaten VUE angesehen und dann versucht, einige Komponenten nur mit nativem js+vue . PC-Zeitauswahlkomponente Dies ist die erste Implementierung der Zeitauswahl auf dem PC. Sie erfolgt auch auf der mobilen Seite, daher möchte ich die
Zeitauswahl auf der mobilen Seite implementieren Ich habe es auf Mobilgeräten implementiert. Die Idee und der Prozess des Zeitselektors für Spezialeffekte am Ende des Scrollrads. Die gesamte Komponente basiert auf vue-cli
Funktion1. Zeitauswahl [
A.年月日选择
B.年月日小时分钟选择
2. Scrollrad-Effekt [
A.构成一个圆环首尾相连
3 erscheint, wenn die ausgewählte Zeit den Bereich überschreitet), Minutenintervalleinstellung
4.
MehrsprachigkeitEinstellung5. Die Zeitformateinstellung entspricht den Einstellungsregeln von JJJJ/MM/TT HH:mm
6. UE kommt dem nativen iOS-Effekt nahe
7. Die Erweiterung kann nicht nur die Zeit auswählen, sondern auch benutzerdefinierte Verknüpfungsauswahldaten übergeben
Hier geht es hauptsächlich um die Implementierung des unendlichen Scrollrads
Datenvorbereitung 1Hier verwenden wir
天
eine clevere Möglichkeit zu veranschaulichen, die Anzahl der Tage in einem Monat zu ermitteln.
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 },
yearList
monthList
hourList
minuteList
StatischEffektrealisierungEs gibt viele Möglichkeiten, den statischen Effekt des Scrollrads zu realisierenVisueller 3D-Effekt [Schatten hinzufügen]
2 . Tatsächlicher 3D-Effekt[ CSS3D]
我把实现效果大致分为上面2种,具体的大家可以自己搜索相关资料,这里展开涉及太多就带过好了
Erklärung
Zuerst sehen wir den nativen iOS-Auswahleffekt, wenn Eingabe Es gibt einen Unterschied zwischen dem Scrollrad innerhalb des Auswahlbereichs und außerhalb des Auswahlbereichs
Um diesen Effektunterschied zu erzielen, habe ich mich für die Verwendung von 2 Dom-Strukturen entschieden Wenn Sie es implementieren, implementiert ein Dom das Scrollrad und ein Dom implementiert den Schwarzauswahleffekt, sodass bei der Verknüpfung ein ähnlicher Unterschied zum ursprünglichen Effekt entsteht
picker-panel
box-day
check-line
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; } }
transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
postition:absolute;
transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);
Der Radius des KreisesDer Winkel und das Konstruktionsprinzip von jede Datenrotation
Wie oben gezeigt ist der Effekt unserer Scrollrad-Stereoansicht, r ist das 2.5rem in unserem übersetzten 3d(0px,0px,2.5rem) CSS,
Wenn es kein solches CSS gibt, werden alle Daten in der Mitte des Kreises gesammelt
Das obige Bild ist keine Rotation (rot stellt den Dateneffekt dar, den wir sehen)
Das obige Bild ist gedreht (Rot und Orange stellen den Dateneffekt dar, den wir sehen)
Blauer Bogen Der dargestellte Winkel ist derselbe (dazu gehört die Kenntnis der Winkel) und es ist auch der Der visuelle Rotationswinkel beträgt 80 Grad im CSS „rotate3d“. Ich mache also einen Abstand von 20 Grad, sodass wir tatsächlich nur die x-Achse drehen und den gesamten Ring ausbreiten. Ein vollständiger Kreis kann 360/20 Daten enthalten, und wir können die vorderen Daten mit bloßem Auge sehen, sodass sie ab einem bestimmten Winkel für uns nicht mehr sichtbar sein sollten, und -webkit-backface-visibility: versteckt bedeutet es hat funktioniert.
这里我们发现轮子装不完所有数据,而且我们要实现数据循环
Es gibt also eine zweite Datenaufbereitung
Datenaufbereitung 2
Hier verwenden wir auch unsere Tagesliste als Anfangsdaten [1, 2, 3, 4,..., 30, 31] Hier nehmen wir jedes Mal 19 Daten als Rendering-Daten und wir benötigen renderListDay, das anfängliche Rendering ist [ 23,24,25,26,27,28,29,30,31,1,2,3,4,5,6,7,8,9,10]
Weil es genau richtig ist, die mittlere Zahl zu nehmen Es ist das erste (nur während der Initialisierung)
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 },
größer als die ursprüngliche Datenlänge, um den Index zu erhalten, der dem normalen Bereich entspricht. Der obige Spin ist also unsere Abzweigung zum Abrufen von Daten (zunächst von -9 bis 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.现在选择必须 年月日 或者年月日小时分钟 不能单独选小时或者分钟
Das obige ist der detaillierte Inhalt vonvue.js implementiert Entwicklungserfahrung zur Nachahmung der nativen iOS-Zeitauswahlkomponente. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!