Vue. js implements native ios-like Time Selection Component instance code, vue. jsios

Source: Internet
Author: User

Vue. js implements native ios-like Time Selection Component instance code, vue. jsios

Preface

I have been watching VUE for the past few months, and then I tried to use native js + vue to implement some components.

PC-side Time Selection Component this is the time selection on the pc that was initially implemented. It is also done on the mobile end at ordinary times, so I want to implement the time selector on the Mobile End, next, I will share with you the idea and process of implementing the time selector for the special effect on the mobile scroll wheel. The entire component is built based on vue-cli.

Function

1. Select time [A. Select year, month, and dayB. Select year, month, day, hour, and minuteC. Select D. minute in the hour]

2. scroll wheel effect [A. forming A ring connected at the beginning and endB. does not constitute a connection between the beginning and end]

3. Set the time selection range (a window is displayed when the selected time exceeds the range), and set the minute interval.

4. Multilingual settings

5. The time format settings meet the rules of yyyy/MM/dd HH: mm.

6. The native Effect of ios is similar to that of UE.

7. The extension can not only select time, but also pass in custom association to select data.

Here we will talk about the implementation of the infinite scroll wheel.
Data Preparation 1

HereDaysInstructions

A clever way to get how many days a month has.

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

Here I use the computed method of vue to implement, putyearList monthList DayListhourList minuteList To store basic data. The data preparation is coming to an end.

Static effect implementation

There are multiple ways to achieve the roller static Effect

1. 3D visual effects [add shadow]

2. Actual 3D effects [CSS3D]

I have roughly divided the implementation effect into the above two types. You can search for the relevant information by yourself. If there is too much involved here, it will be better.

My own implementation is the second method using CSS3D.

Description

First, we can see that the selection effect of native ios is different between the selection range and the selection range.

So in order to achieve this difference, I chose to implement it using two dom structures, one dom implementation scroll wheel and one dom implementation black selection effect. In this way, there will be effects similar to native differences in association.

picker-panel Install various options dom. here only the day is given,box-day An outermost box containing day data,check-line Implement the selected two lines,day-list Black effect data on the outermost layer,day-wheel Grey wheel Section

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

transform-style: preserve-3d;

Demonstrate 3D effects,

-webkit-backface-visibility: hidden;

Hide part of scroll wheel automatically

postition:absolute;

Used to locate the wheel

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

The Rotation Angle of each data and the radius of the scroll wheel side view circle

Angle and construction principle of each data Rotation

For example

Is the effect stereoscopy of our scroll wheel, and r is the 2.5rem In the css of our translated3d (0px, 0px, 2.5rem,

Without this css statement, all the data will be aggregated at the center of the circle.

 

Do not rotate (red indicates the data effect we see)

 

Rotate (red and orange represent the data we see)

The angle indicated by the Blue arc is the same (this involves the angle knowledge). It is also the visual rotation angle, that is, 80deg In the css of rotate3d. What I do is 20 degrees at each interval, in this way, we only use the X axis to rotate the center angle along with the belt, so that the entire ring is paved. A complete circle can hold up to 360/20 pieces of data, while we can see the front data with the naked eye, so after a certain angle, we should not be able to see the data behind the scenes, and-webkit-backface-visibility: this sentence plays a role.

Here we find that the wheel cannot complete all the data, and we need to implement a data loop.

Similar Effect

So there is a second data preparation.

Data Preparation 2

Here we also use our dayList as the initial data [1, 2, 3, 4,..., 30, 31]

Here we take 19 pieces of data each time as the rendering data, and we need the initial rendering of the renderListDay is [,].

This is because the number in the middle is the first (only during initialization)

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

The data retrieval method is less than 0. If the index is greater than the original data length, % is used to obtain the index corresponding to the normal range, therefore, the spin above is the data-collecting fork (initially from-9 to 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];        }         //...      },

The Rotation Angle of each data record (the upper half circle is positive, and the lower half circle is negative)

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

Next we need to rotate to the angle we need, and to our initialization time, this. orDay-this.DayList [0] is to get the offset to correct the angle

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

Add touch events

The rest is well handled. The corresponding dom binding event is converted to the Rotation Angle Based on the touchmove distance and the check-list displacement. Here the translateY is used to record the actual movement distance, the final output must be included in the offset.

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

Inertial Rolling

In this implementation, I used a cubic-bezr (0.19, 1, 0.22, 1)

Determine if the gesture is a QR code. If the gesture is a QR code, the instantaneous speed is used to calculate the displacement and time, and then the time is set at one time. Then, the transition is used for inertial rolling,
Set normal drag to 1 second

The actual effect is still a little poor and will be improved later.

Implementation of other functions

I will not describe it in detail here

Summary

The mobile Taobao solution is used for self-adaptation.

The most difficult thing to implement this component this time is to implement the infinite rolling and the construction of the infinite rolling rendering data, followed by the implementation of inertial rolling.

Known issues

1. Imperfect inertial Rolling

2. Implement unlimited scrolling. Non-infinite scrolling is not implemented, that is, rendering data is [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].

3. Now you must select the year, month, day, year, month, hour, and minute. You cannot select the hour or minute separately.

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.