Reference juejin. Cn/post / 696131…
Other activities achieved:
Collection of energy: vue.js to achieve the receipt of energy red envelope rain: vue.js to achieve red envelope rain vue.js to achieve rotation lottery: vue.js to achieve rotation lottery
For a quick copy of the results, look at heading 2
1. Understand transition and transform.Transition requires an event to be triggered
The 1transform is a transition from state A to state B, so it has to be triggered by an event. It can’t happen automatically when the page loads. 2Transform is a transform that changes the appearance of the element. For example, displacement, scaling, rotation, etc., and the displacement function name is translate, so translate is part of transform. Transform is not animated, you change its value, the element changes immediately
When I wanted to see the 360 degree rotation effect, I found the browser and showed it directly
<div id="test"></div>
#test {
width: 100px;
height: 100px;
background-color: red;
transition: transform 5s ease-in-out 0s;
transform: rotate(360deg);
}
Copy the code
The display effect is:
So we should change it to:
<div id="test"></div>
<div onclick="test()">Click on the</div>
<style>
#test {
width: 100px;
height: 100px;
background-color: red;
}
.test {
transition: transform 5s ease-in-out 0s;
transform: rotate(360deg);
}
</style>
</head>
<body>
<script>
function test() {
document.getElementById('test').className = 'test'
}
</script>
Copy the code
2. Realize the lottery of static rotary table
data() {
return {
rotateAngle: 0.// Rotate the Angle
config: {
duration: 3000.// Total rotation time ms level
circle: 7.// The number of turns
mode: 'ease-in-out'.// The inertia effect from fast to slow is reduced
},
drawIndex: 0.// Lottery index dial picture sort pointer right hand start 0-... 0 to 5
juneInfoStatusObj: {
residueCount: 0.// The number of remaining lucky draws
},
run: false.// If it is rotating
rewardMaskVisible: false.// The winning frame
rewardList: [].}},async mounted() {
this.$loading.show()
try {
await this.getActivity21StJuneInfo()
} finally {
this.$loading.hide()
}
},
methods: {
// Basic information
async getActivity21StJuneInfo() {
const data = awaitXXXXXXX interface (this.token)
const { residueCount = 0 } = data
this.juneInfoStatusObj = { residueCount } // First get the number of lucky draw, the code has been deleted, if you only need to draw once can be removed
},
// Click the wheel to get the specified item
async getActivity21StJuneLottery() {
const { reward } = awaitThe interface XXXX of what prize should be won (this.token)
this.rewardList = [ reward ] // The backend returns what prize did the user win
this.drawIndex = reward.id // The backend directly returns the user which prize to win
},
// Start to rotate
async startPlay() {
if (!this.checkToken()) return // If you do not need to log in, you can delete it
if (+this.rotateAngle > 0) {
this.$toast('Please do not double click while drawing')
return
}
if (+this.juneInfoStatusObj.residueCount === 0) {
this.$toast('Operation reached upper limit')
return
}
await this.getActivity21StJuneLottery()
this.run = true
this.rotateAngle = this.config.circle * 360 - (30 + this.drawIndex * 60)}},Copy the code
this.rotateAngle = this.config.circle * 360 – (30 + this.drawIndex * 60) The most important thing to understand is to make sure that the pointer of the lottery is pointing straight at the middle line and not biased towards any module, so if there are 6 areas, each area will be 360/6=60 degrees. If you look clockwise, the first area will be index = 0. The second field corresponds to index = 1….. The sixth field is index= 5, and if the back end returns index=4, it points to the fifth field. The number of turns in the config object can be discussed with the product, and the number of turns *360 is the number of turns
Index =5, index=4,index… Index =0 through the pointer in order, if the index=0 returned by the back end, i.e., in the middle of the rotation close to 360 degrees,360-30, this.config.circle * 360- (30 + this.drawindex * 60), Remember, if the hands are not moving and the dial is moving, what is the regional rotation path of the dial
The above can complete the operation of the turntable from turn to stop, if you need to turn after, and the number of rotation, you can add the following code
// Close the dialog box
setData(dialogName, handle) {
this.run = false
this.rotateAngle = 0
this.rewardMaskVisible = false
},
// Wait n seconds to play again
sleep(time){
return new Promise(function(resolve){
setTimeout(resolve, time)
})
},
// When the rotation is complete, pop up the frame
async finishRotate() {
await this.sleep(1000)
this.rewardDetailVisible = true
},
Copy the code
FinishRotate actually has a transitionEnd listening event when the rotation is complete
<img
:style="` ${! run ? '' : rotateStyle}`"
class="turntable-img"
src="@/assets/image/juneTurntable/turntable-center.png"
@transitionend="finishRotate"
>
Copy the code
3. First move, click and then draw, and then move the way of drawing
Previously, our lucky draw button was static, so it might not be able to attract users to remove it visually. Therefore, we changed the clicking of the lucky draw button into a dynamic one, and let the rotary wheel slowly turn in
I have considered two methods. The first one is to use animation: Rotate 15s Linear Infinite to do perpetual motion first, and then rotate with 0 when clicked, which will have a reset effect on the page. Therefore, the second one is to use timer to do perpetual motion
this.rotateAngle = 0
await this.sleep(0)
this.rotateAngle = this.config.circle * 360 - (30 + this.drawIndex * 60)
Copy the code
Code (add or modify above)
<img
:style="`${normalRotateStyle} ${! run ? '' : rotateStyle}`"
:class="['turntable-img', {'normal': normalTranstion}]"
src="@/assets/image/juneTurntable/turntable-center.png"
@transitionend="finishRotate"
>
.turntable-img {
width: 524px;
height: 524px;
&.normal{
transition: transform 1slinear; }}Copy the code
data() {
return {
normalRotateAngle: 0.normalTranstion: true,}},computed: {
rotateStyle () {
const config = this.config
console.log(this.rotateAngle, 78979)
return `
-webkit-transition: transform ${config.duration}ms ${config.mode};
transition: transform ${config.duration}ms ${config.mode};
-webkit-transform: rotate(The ${this.rotateAngle}deg);
transform: rotate(The ${this.rotateAngle}deg); `
},
normalRotateStyle () {
return `transform: rotate(The ${this.normalRotateAngle}deg); `}},async mounted() {
this.$loading.show()
try {
await this.getActivity21StJuneInfo()
} finally {
this.$loading.hide()
}
this.initNormalRotate()
},
methods: {
initNormalRotate () {
this.t = setInterval(() = > {
this.normalRotateAngle += 10
this.normalTranstion = true
}, 500)},// Start to rotate
async startPlay() {
if (!this.checkToken()) return // If you do not need to log in, you can delete it
if (+this.rotateAngle > 0) {
this.$toast('Please do not double click while drawing')
return
}
if (+this.juneInfoStatusObj.residueCount === 0) {
this.$toast('Operation reached upper limit')
return
}
await this.getActivity21StJuneLottery()
clearInterval(this.t)
this.normalTranstion = false
this.run = true
this.rotateAngle = this.config.circle * 360 - (30 + this.drawIndex * 60)},// Modify the data function in general
setData(dialogName, handle) {
this.run = false
this.rotateAngle = 0
this.rewardMaskVisible = false
this.initNormalRotate()
this.getActivity21StJuneInfo()
},
// When the rotation is complete, pop up the frame
async finishRotate() {
if (!this.run) {
return
}
await this.sleep(1000)
this.rewardDetailVisible = true
this.run = false
this.normalRotateAngle = 0
this.rotateAngle = 0}},Copy the code