There is a requirement for the front-end time that the whole web subsystem of rotary table lottery should be embedded in the client’s two-terminal APP. Specifically, it should be able to control the number of big rotary table lottery prizes and the number of free lottery times for users in the background. When the free lottery is used, users can watch advertisements for lottery or use points for lottery. Just recently free, out of this tutorial, analysis of the turntable lottery implementation process.
I am responsible for the overall development of this subsystem, including the front-end technology: H5+CSS3+JS; Back-end technology: YII2+Redis.
Click to view the rotary table demo video effect
Here are two parts to introduce the rotary table lottery:
First, front-end style and lottery operation development
The Transform property is used for the display of the front end. The Transform property is used for the display of the front end. The Transform property is used for the display of the front end and the Transform property is used for the display of the front end. Specify Angle in parameters), skewX (define 2D skew conversion along the X axis)
Take our code as an example: in prize-list, we first make the background picture of the whole turntable, and prize-reward displays the information of each prize. When entering the page for the first time, the interface is called to obtain the information of the rotary table prize, such as: After assembly, the number of prizes is calculated based on the returned prize information. Rotate and skewX of the Transform property are set. Since the background color is displayed at intervals, the number of prizes displayed is even and the maximum number of prizes displayed is 12. At that time, I did not find the rule of each assignment, so I tried to work out the scene values of 2-12. By now, the whole style has been shown. The video shows the effect of 6 prize items, and this page shows different effects due to the different number of prize items returned by the interface.
This is the layout of the turntable:
<div class="wheelSurf">
<div class="wheel">
<div class="wheel-icon">
<img src=".. /images/wheel/wheel_back.png" alt="">
</div>
<div class="prize-box">
<div class="prize-content">
<! -- Turntable background box, JS filling prize background -->
<div class="prize-list" id="prize-list"></div>
<! -- Turntable prize box, JS filled prize -->
<div class="prize-reward" id="prize-reward"></div>
</div>
<! -- Click the lucky draw button -->
<div class="prize-button" id="prize-button">
<img src=".. /images/wheel/start_button.png" alt="">
</div>
</div>
<div class="score">
<div class="spend_score">
<span class="consume-score">0</span>Integral/time</div>
<div class="my_score">My integral:<span id="my-score">0</span>
</div>
</div>
</div>
<div class="activity_rule">
<div class="rule_title">Activity rules</div>
<div class="rule_list" id="activity-rule"></div>
</div>
</div>
Copy the code
This part is the code of the turntable prize display:
/** * Large turntable fills awards, initializes display turntable background *@param data* /
function prize(data) {
let list = ' ';
let reward = ' ';
let count = data.length;
let rotate = 360 / count;
prizeCount = count;
prizeDeg = 360 / count;
let itemRotate = 360 / 2 / count;
let liRotate = 0;
// Set the rotation Angle values of 4, 6, 8, 10, 12 prizes
let width;
switch (count) {
case 2:
liRotate = 0;
width = 4;
break;
case 4:
liRotate = 0;
width = 3;
break;
case 6:
liRotate = 30;
width = 2;
break;
case 8:
liRotate = 45;
width = 1.5;
break;
case 10:
liRotate = 54;
width = 1.3;
break;
case 12:
liRotate = 60;
width = 1;
break;
default:
liRotate = 0;
width = 1;
}
// Assemble the background and prize labels, and set the rotation Angle of the prize
for(let i=0; i < count; i++) {
list += "<div class=\"prize-li\"></div>";
reward += "<div class=\"prize-item\" data-id=\"" + data[i]['id'] + "\" style=\"transform: rotate(" + (rotate*(i+1) - itemRotate) + "deg) translateX(-50%); width: " + width + "rem; \">\n" +
"
\n"
+
data[i]['title'] +
" \n" +
"
+
" + data[i]['icon'] + "\">\n" +
" \n" +
" "
}
// Fill in the content
$('#prize-list').html(list);
$('#prize-reward').html(reward);
// Get all the background labels, loop to set the background color and rotation Angle value and tilt conversion value
[].slice.call(document.querySelectorAll('.prize-li'), 0).forEach(function (item, i) {
if(count == 2) {
return false;
}
item.style.backgroundColor = '#ffffff';
if(i%2= =0) {
item.style.backgroundColor = '#FCE9C1';
}
item.style.transform = 'rotate(' + (360 / count * i + liRotate) + 'deg) skewX(' + liRotate +'deg)';
});
// If there are only two prizes, deal with the styles separately
if(count == 2) {$('#prize-list').find('.prize-li').css('width'.'2.49 rem');
$('#prize-list').find('.prize-li').css('height'.'4.98 rem');
$('#prize-list').find('.prize-li').css('top'.'0rem');
$('#prize-list').find('.prize-li').css('left'.'0rem');
$('#prize-list').find('.prize-li').eq(0).css('background'.'#FCE9C1');
$('#prize-list').find('.prize-li').eq(1).css('left'.'2.49 rem'); }}Copy the code
Then there is the front draw the implementation of the operation, the user click on the draw button of lottery, the first front-end lock set a lottery, with a click on the draw button you will lock the lock, in the drawing process is completed, open the lock, users click on the draw, request draw interface, and then draw logical interface, and will eventually prize information back to the front end, That is, the ID of the prize, and then the front end gets the label subscript of the prize according to the ID. The front end uses transition to render and load the disk. Finally, the pointer stops at the prize returned by the interface in the rotary table, and the user sees the winning information and proceeds to the next operation. In this case, the whole front-end lottery process is complete
This part is part of the turntable lottery code
/** * lottery operation *@param type* /
function lottery(type) {
// Request the backend interface to get the winning information
$.ajax({
url: wheel_lottery,
type: 'get'.headers: {
"token": token,
"Accept": "application/json"."appid": appId
},
data: {
type: type // User lottery type
},
success:function (res) {
if(! res.data) { flag =true;
return false;
}
var type = res.data.type;
var title = res.data.title;
var img = res.data.img;
var rid = res.data.record_id;
myScore = res.data.my_score;
pid = res.data.prize_id;
// Update the number of points and lucky draw
count--;
$('#prize-count').html(count);
// Get the subscript of the current prize tag, used to calculate the rotation Angle value of the rotary table
var code = $("#prize-reward").find(".prize-item[data-id=" + pid + "]").index();
if(code == -1) { // No label was found
flag = true;
return false;
}
// Set the rotation Angle of the rotary table
var e = 3600 - (code * prizeDeg) - prizeDeg / 2;
$('.prize-content').css({'transition': 'transform 6s Cubic - Bezier (0.25, 0.1, 0.01, 1)'.'transform': "rotate(" + e + "deg)"});
setTimeout(function () { // Message prompt
$('#mask').css('display'.'block');
$('#my-score').html(myScore);
if (type == 1) {$('#prize-score').css('display'.'block');
$('#result-img').attr('src', img);
$('#result-score').html(title);
} else if(type == 2) {$('#prize-result').css('display'.'block');
$('#result-icon').attr('src', img);
$('#result-reward').html(title);
$('#go-write').attr('data-id', rid)
} else{$('#prize-no').css('display'.'block');
}
// The turntable is reset
$('.prize-content').css({'transition': ' '.'transform': "rotate(0deg)"});
// Open the lottery lock
flag = true;
}, 6000);
},
error:function(res) {}})}Copy the code
Second, the development of back-end interface lottery logic
Actually about setting data show the number of article awards, winning awards these interfaces do not have what to say, is usually to add and delete operations, which it should be emphasized, the general drawing system is the ability to control the odds of each award, we here by setting the weight [weight] field values to control the odds, The higher the weight, the higher the chance of winning.
Confirm the winning prize code:
/** * return the id of the winning item **@return mixed
*/
private function _getLotteryPrize()
{
// Weights and ids for all prizes
$prize = WheelAwardPrize::select('id'.'weight')
->orderBy('created_at'.'desc')
->limit(Tenancy::setting('wheel.prize_num'))
->get();
$data = []; // Final raffle prize array
$totalWeight = 0; // Initialize the total weight
foreach ($prize as $item) {
$weight = $item['weight']; // Current prize weight value
if (!$weight) { // No weight value skipped
continue;
}
for ($i = 1; $i< =$weight; $i{+ +)// loop into the final array
$data[] = $item;
}
$totalWeight+ =$weight; // Increase the total weight
}
// Randomly get the winning prize subscript
$index = rand(0.$totalWeight - 1);
// Return the prize ID
return $data[$index] ['id'];
}
Copy the code
The following is mainly about the realization of the lottery logic: first of all, like the front end, set the lottery lock, complete the lottery remember to release the lock, the same user to complete a lottery process, to allow the next lottery. Then check for all prize ids and weights from the library. Then loop weight, place the ID and weight of the current weight in a two-dimensional array, so that we can get a value that does not store weight 0. And the length is the total weight of the prize array, and then randomly select a range of values according to the length of the array, so that we get the current index value, and then get the winning prize ID. Finally, according to the winning prize ID, generate the user’s winning information, if it is virtual currency, directly to the user recharge, physical reward, the front end will prompt the user to fill in the receiving information, in the prize ID and user winning record ID through the interface back to the front end.
Drawing process code:
/** * return the prize ID **@return array
*/
public function lottery(Request $request)
{
/ / lock
$lockKey = RedisKey::getApiLockKey('wheel/lottery'['member_id' => auth()->user()->member_id]);
if (Cache::has($lockKey)) { / / a lock
throw new BusinessException('Your operation is too frequent, please try again later');
}
// Get the winning prize ID
$pid = $this->_getLotteryPrize();
if (!$pid) {
throw new BusinessException('Prize is in preparation, please try again later');
}
// Add a reward record
$records = new WheelAwardRecord();
$records->member_id = auth()->user()->member_id;
$records->wheel_id = $pid;
$records->type = $request->type;
$records->date = date('Ymd');
$asset = Asset::where('member_id', auth()->user()->member_id)->first();
if ($request->type == 2) { // Draw points
$config = Tenancy::setting('wheel');
if (!$asset| | -$asset->score < $config['consume_score'])) {
Cache::forget($lockKey);
throw new BusinessException('Insufficient integral');
}
// Deduct user credits
$this->user->changeScore(-$config['consume_score'], ScoreReason::REASON_WHEEL, Task::TASK_WHEEL);
}
// Give rewards
$prizes = WheelAwardPrize::where('id'.$pid)->first();
if ($prizes->type == 1) { // Reward virtual currency
$records->status = 3;
// Add user credits
$this->user->changeScore($config['consume_score'], ScoreReason::REASON_WHEEL, Task::TASK_WHEEL);
} else if($prizes->type == 2) { // Reward in kind
$records->status = 1; // The default state is to be provisioned
} else { / / not winning
$records->status = 3; // The default state is to be provisioned
}
$records->save();
/ / remove the lock
Cache::forget($lockKey);
return [
'prize_id'= >$pid.'type'= >$prizes->type,
'title'= >$prizes->title,
'img'= >$prizes->icon,
'record_id'= >$records->id,
'my_score'= >600
];
}
Copy the code
I have been in Beijing for one and a half years. I will finish my life in Beijing tomorrow and prepare to go back to my hometown for a rest. Then I will go to Shanghai to find a job around 10th.
Because I now do is to the development of novel reading, so during the rest of the time a novel blog reader, is about the article, take you to master the H5 novel reader development, imitation beginning readers “reading, parsing the novel reader development process, the development of words is to prepare to simulate beginning reader reading development, build a novel reader from 0 to 1.