Write in the front, the annual meeting is approaching, demand is also naturally related to various lottery. Recently, I just received an urgent draw for sudoku, by the way, also record the process of lifting this simple sudoku.
This article may cover the following:
- Nine grid layout
- The nine – fold motion effect
- Lottery logic processing
- Front and rear end intermodulation
Nine grid layout
9 grid we should be quite familiar with it, is the nine grid, below to give you a look at our online 9 grid lottery ↓↓
And so on.. I don’t think there are nine boxes up here.
This layout I believe everyone is very familiar with it, especially after watching Ruan Yifeng Flex layout tutorial: examples of children’s shoes, is not feeling warm.
Yes, our layout is based on Flex, and the main idea is the separation of horizontal and horizontal elements.
- The entire nine-grid area should be of a fixed width and height
(It doesn’t really matter)The block element, which arranges each row vertically. - Each row is a row, where we place each item block space-between or space-around (depending on the business).
- Use Flex to center the contents of each item horizontally, and then restore the design as it should.
Pit point, in fact, is not pit, it is a mobile terminal adaptive problem.
The rem layout issue is involved here. For some historical reasons, our project did not use REM for mobile page development.
This makes it difficult to develop components that require high levels of adaptation. However, recently when I was writing other projects, I came up with a plan that is quite suitable for our use, but there may be some requirements for the version of browser and mobile phone system.
@function pxWithVw($n){
@return 100vw * $n / 375
}
@function pxWithVwMax($n){
@return 480px * $n / 375
}
@mixin pxVw2width($n) {
width: pxWithVw($n);
max-width: pxWithVwMax($n);
}
@mixin pxVw2height($n) {
height: pxWithVw($n);
max-height: pxWithVwMax($n);
}
Copy the code
Although we did not use REM layout, we still connected with SCSS, and we can restore various parameters of the design draft with THE help of SCSS mixin. The reason why we need to limit a Max value is mainly because our project supports viewing on PC, so we need to limit its width.
Why is there a vw in pxVw2height? In fact, it is a matter of pixel ratio. The ratio of the width in the design draft to the width of the device in the design draft is naturally the ratio of each PX to the screen.
However, there is an uncertainty in this writing, that is, under different DPR, whether this method has an impact on pixel restoration. I am not sure about this for the time being, but I will find time to test it.
Dynamic effect of nine squares & lottery logic processing
Dynamic effects and lottery logic are normally two different things, but we developed them in React, so I thought it was worth talking about them together.
Dynamic effect core
The triggering core of dynamic effect is the real-time change of activedId. Through the timer, the activedId in the parent component state can be changed in a certain time interval to achieve the effect of “kicking kicking kicking” in the nine grid.
class RowItem extends React.Component {
renderImgClass () {
switch (this.props.content.raw_name) {
...
}
}
render() {
const { content, activedId } = this.props;
return (
<div className={` ${activedId= = =content.id ? 'row__item row__item-active' : 'row__item` '}}id={`row_item_The ${content.id} `} >
<img src={content.img} alt="" className={this.renderImgClass()}/>
{content.name}
</div>)}}Copy the code
Above is the source of each small box, it is not difficult to see how to determine each small box should be displayed here
${activedId === content.id ? 'row__item row__item-active' : 'row__item'}
Copy the code
The activedId () function passed in to the props to determine which block is going to display the motion function. Although this is not called the motion function, the principle is interchangeable, so just use this component to display whatever you want.
Draw logic
In essence, we randomly (or specify) the ID of an item as the winning ID. Then we determine the number of cycles around this ID. Finally, we ensure that the winning box can stay on the item with the specified ID.
The process of clicking the button lottery is divided into two parts, one is state detection and return to zero, and the other is the trigger lottery method (in fact, it can also be written together, personal habit to separate it, it looks more comfortable).
- HandleBegin is responsible for state detection and zeroing
handleBegin() {
if (!this.state.prizePlaying) {
this.setState({
prizePlaying: true
})
axios.post(url)
.then(res= > {
if (res.data.code === 0) {... axios.get(url2) .then(res= > {
if (res.data.code === 0) {
this.setState({ ... = > {}, ()this.setState({
prizeActivedId: ' '.prizePrizeId: null.prizeTimes: 0.prizeActTimes: 0= > {}, ()this.handlePlay()
})
})
}
})
} else{... }}}})Copy the code
At the beginning of the first test whether the current state is in the lottery, if not just for the following request, request are completed, will be about the nine grid state are restored, and then proceed to the next operation. As for state restoration, I personally think it is relatively convenient and safe. Of course, it is also possible to retain the original lottery state. However, attention should be paid to the relationship between the two Times when using it.
- HandlePlay real lottery method
handlePlay() {
let prize;
switch (this.state.prizeLottery) {
prize = ...
}
this.setState({
prizePrizeId: prize,
prizeActivedId: 0
})
let times = this.state.prizeList.length * Math.floor(Math.random() * 5 + 4)
this.setState({
prizeTimes: times
})
this.begin = setInterval((a)= > {
let num;
if (this.state.prizeActivedId === this.state.prizePrizeId && this.state.prizeActTimes > this.state.prizeTimes) {
clearInterval(this.begin)
...
this.setState({
prizePlaying: false
})
return
}
if (this.state.prizeActivedId === ' ') {
num = 0
this.setState({
prizeActivedId: num
})
} else {
num = this.state.prizeActivedId
if (num === 7) {
num = 0
this.setState({
prizeActivedId: num
})
} else {
num = num + 1
this.setState({
prizeActivedId: num
})
}
}
this.setState({
prizeActTimes: this.state.prizeActTimes + 1})},100)}Copy the code
Determine the prizePrizeId, then randomly calculate a minimum number of animation cycles, and then start the timer to dynamically change the prizeActivedId. As the prizePrizeId changes, RowItem will also re-render, creating the so-called “kick kick” effect.
If the above explanation doesn’t seem detailed enough, you can find the Github portal at the end of this article, which contains the demo source code with related comments.
Front and rear end intermodulation
Here I would like to talk about my plan (or idea) for the whole project before starting the development. In line with the principle that the front end cannot be trusted, we should communicate with the back end before starting the lottery every time, and neither the number nor the final prizeId should be determined by the front end.
From the front end, we probably need two interfaces:
- (1) Tell us the number of times that an interface like init has won a prize
- (2) Similar to the active lottery interface, we tell the back end that a lottery request has been initiated. (2) The interface then returns to us what the prize is, and then we convert the front-end ID according to the return, so that a relatively perfect closed loop can be completed.
conclusion
This record is a small demand made in these two days, which is also my first attempt to do something similar. I believe that there will be a big turntable waiting for me in the near future (smile).
React (create-react-app) React (create-react-app) React (create-app) React (create-app)