When developing the official website of mobile terminal, the designer wanted to achieve the effect of labels moving along the track (as follows). When clicking labels, they move along the track, and the clicked labels are arranged in sequence to position 1, accompanied by rotation. The label styles of each position are different.
The design idea is as follows:
First, label or track motion?
- Label movement: set width and height and positioning properties for different class names. Click to change the class name assigned by the label. Make a distinction between label order and position order
In this case, the label position is [0,1,2,3,4,5].
When the tag movesThe order of label positions is [5,0,1,2,3,4] (label 0 is in position 5).
That is, we need to get the order value of the current click on the label, this label to position 1, the other order in order for example, click on the label 4, the label order changes to [2,3,4,5,0,1], click on the label 5, the label order changes to [1,2,3,4,5,0]
Vue + SCSS as an example
<ul class="label_ul">
<li
class="label_li"
:class="`label${indexList[index]}`"
:data-order="indexList[index]"
ref="labelLi"
@click="handleLabelChange($event, index)"
v-for="(item, index) in labelList"
:key="index"
>
<div>{{ item.name }}</div>
</li>
</ul>
Copy the code
Data stores the current location information. IndexList stores an array of locations, starting with [0,1,2,3,4,5] and then clicking on the action to change the array
CSS:
.label_ul {
.label_li {
position: absolute;
transition: all 300ms ease-in-out 0s;
}
.label0 {
width: 108px;
height: 56px;
top: 128px;
left: calc(50% - 53px);
z-index: 5;
font-size: 18px;
box-shadow: 0px 2px 0px 0px #2d63fb inset;
}
.label1{···}
.label2{...}}Copy the code
Js:
method:{
handleLabelChange(e, index) {
this.order = e.currentTarget.dataset.order;// Get the current label position
this.currentIndex = index;// Get the index of the current TAB}},watch: {currentIndex(n){
if (n == 0) {
this.indexList = [0.1.2.3.4.5];
} else if (n == 1) {
this.indexList = [5.0.1.2.3.4];
} else if (n == 2) {
this.indexList = [4.5.0.1.2.3];
} else if (n == 3) {
this.indexList = [3.4.5.0.1.2];
} else if (n == 4) {
this.indexList = [2.3.4.5.0.1];
} else if (n == 5) {
this.indexList = [1.2.3.4.5.0];
}IndexList [n]=0; indexList[n]=0;}}Copy the code
Optimization 1: If you click 2/4, it will go directly to position 0. Desired effect: first to position 1/5, then to 0
Solution: If position 2 is determined, move to position 1, i.e. delete the last bit of the indexList and move to the first; If position 4 is determined, move to position 5, that is, delete the first digit of the indexList and move to the last digit.
watch:{
currentIndex(n){
if (this.order == 2) {
let num = this.indexList.pop();
this.indexList.unshift(num);
} else if (this.order == 4) {
let num = this.indexList.shift();
this.indexList.push(num);
}
if (n == 0) {
this.indexList = [0.1.2.3.4.5];
} else if (n == 1) {
this.indexList = [5.0.1.2.3.4];
} else if (n == 2) {
this.indexList = [4.5.0.1.2.3];
} else if (n == 3) {
this.indexList = [3.4.5.0.1.2];
} else if (n == 4) {
this.indexList = [2.3.4.5.0.1];
} else if (n == 5) {
this.indexList = [1.2.3.4.5.0];
}IndexList [n]=0; indexList[n]=0;}}Copy the code
Optimization 2: In order to prevent the continuous click position confusion, can add a shaking function;
- Track motion: a label is integral to the track. The movement of the label along the track is actually the rotation of the track
1, layout track and label
<div class="track">
<div class="label">
</div>
</div>
Copy the code
2. Rotate, compress and turn the orbit into an ellipse
.track{
width: 315px;
height:315px;
transform: scaleY(0.5) rotateZ(180deg);
border-radius: 50%;
}
.label{
width: 108px;
height: 56px;
position: absolute;
top: -28px;
left: calc(50% - 54px);
box-shadow: 0px 2px 0px 0px #2d63fb inset;
transform: rotateZ(-180deg) scaleY(2); // Rotate first, the Angle is opposite to the orbit, then change to double}Copy the code
Track transform scaleY() first, then rotate, label and track in order not to be affected
3. At this time, the rotation of the label is the overall movement of the track, and only the rotation Angle needs to be changed
Both the track and the label are animated, but in reverse order
4, overlap multiple label tracks, track border can be hidden
Second, linkage with round seeding
Then click the label event to obtain the index value of the current click label, and then use the rotation event to slide to the corresponding module, where swiper is used for rotation.