Project premise
Chinese New Year is coming soon. If you want to change your mobile phone, it will be huawei in addition to fruit. I’m a hammer fan. Unfortunately, hammer is out of business. At the bottom of huawei official website event page, there is a turntable lottery function, which is quite interesting (damn the front-end professional faults), think of the mobile phone does not buy always bring something to go, at the same time, I haven’t written a native JS for a long time, so I want to implement this thing simply (without considering packaging). This is not a case for big men.
Pictured above,
Train of thought to sort out
1. DOM structure
<div id="allParent">
<! -- Click Start/Back -->
<div class="selectBox">
<div class="parent">
<div class="start"></div>
<div class="back">
<img
src="https://res7.vmallres.com/shopdc/pic/9c9af0eb-4c3d-4053-ae33-fd5f3fe90492.png"
alt=""
/>
</div>
</div>
</div>
</div>
Copy the code
2. Flip effect 3D
Start by adding perspective properties to the outermost layer
#allParent .item .parent {
width: 100%;
height: 100%;
transform-style: preserve-3d; // Child perspectiveperspective-origin: center;
perspective: 500px; // Perspective distanceposition: relative;
}
Copy the code
Prize and click flip are two pictures together, by default, click flip to rotate first.
#allParent .item .parent .back{
position: absolute;
height: 100%;
transition: all .6s;
transform: rotateY(270deg); / / turn first270The degree ofborder-radius: 9px;
opacity: 0;
}
Copy the code
3. JS effect
The core code calculates the offset of each award relative to the center position.
Basic idea:
function initPosition() { // Calculate the position
var gapW = (allParentWidth - boxWidth * 3) / 4.// The width of the space
gapH = (allParentHeight - boxHeight * 3) / 2; // Height space distance
for (var i = 0; i < itemDoms.length; i++) {
var pos = {};
if (i < 3) {
/ / the first column
pos.y = -(gapH + boxHeight); // all Y is the height of the box + the distance of the space
pos.x = (i - 1) * (boxWidth + gapW);
} else if (i == 3 || i == 4) {
/ / the second column
if (i == 3) {
pos.x = -(boxWidth + gapW);
} else {
pos.x = boxWidth + gapW;
}
pos.y = 0;
} else {
/ / the third column
pos.y = gapH + boxHeight;
pos.x = (((i + 1) % 3) - 1) * (boxWidth + gapW);// The x offset of the third row} boxsPositions.push(pos); }}Copy the code
All the code
Can copy directly run
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#allParent {
width: 716px;
height: 508px;
margin: 0 auto;
position: relative;
background: radial-gradient(# 000000a6, # 00000026);
padding: 10px 0;
box-sizing: content-box;
}
.selectBox {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 144px;
height: 144px;
z-index: 99
}
.selectBox > div > div {
width: 144px;
height: 144px;
}
.selectBox .start {
background: url(https://res0.vmallres.com/shopdc/pic/7848e6d2-8420-410e-893d-fbd3b9ac1e78.png)
no-repeat center center/ cover;
}
.selectBox .back {
display: none;
}
.selectBox .back img {
width: 100%;
height: 100%;
border: 0 none;
vertical-align: top;
}
#allParent .item {
width: 220px;
height: 160px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -110px;
margin-top: -80px;
z-index: 10;
}
#allParent .item .parent {
width: 100%;
height: 100%;
transform-style: preserve-3d;
perspective-origin: center;
perspective: 500px;
position: relative;
}
#allParent .item .parent .face {
transition: all .6s;
width: 100%;
height: 100%;
position: absolute;
background-color: rgba(248.113.13.0.1);
transform: rotateY(0deg);
border: none;
backface-visibility: hidden;
}
#allParent .item .parent.active .face{
transform:rotateY(180deg);
opacity: 0;
}
#allParent .item .parent .back{
position: absolute;
height: 100%;
transition: all .6s;
transform: rotateY(270deg);border-radius: 9px;
opacity: 0;
}
#allParent .item .parent.active .back{
transform: rotateY(360deg);opacity: 1;
}
</style>
</head>
<body>
<div id="allParent">
<! -- Click Start/Back -->
<div class="selectBox">
<div class="parent">
<div class="start"></div>
<div class="back">
<img
src="https://res7.vmallres.com/shopdc/pic/9c9af0eb-4c3d-4053-ae33-fd5f3fe90492.png"
alt=""
/>
</div>
</div>
</div>
</div>
</body>
<script src="https://res9.vmallres.com/shopdcGray/shopdc/cdn/modules/common/pc/js/jquery-3.5.0.min.js"></script>
<script>
var data = [
{
img:
"https://res6.vmallres.com/shopdc/pic/20201231/0924a81c-feff-4686-a4ca-b90913d51d5d.png"}, {img:
"https://res5.vmallres.com/shopdc/pic/a38461b2-8317-4a66-877a-ee3d1ed8ea27.png"}, {img:
"https://res0.vmallres.com/shopdc/pic/20201231/c8214cf6-778a-4dc9-a068-bc91622f3e24.png"}, {img:
"https://res6.vmallres.com/shopdc/pic/20201231/0924a81c-feff-4686-a4ca-b90913d51d5d.png"}, {img:
"https://res5.vmallres.com/shopdc/pic/a38461b2-8317-4a66-877a-ee3d1ed8ea27.png"}, {img:
"https://res0.vmallres.com/shopdc/pic/20201231/c8214cf6-778a-4dc9-a068-bc91622f3e24.png"}, {img:
"https://res2.vmallres.com/shopdcGray/shopdc/pic/f19ce100-4afc-439e-bc90-5b92e4755c07.png"}, {img:
"https://res6.vmallres.com/shopdc/pic/20201231/0924a81c-feff-4686-a4ca-b90913d51d5d.png",},];var $allParent = $("#allParent"),
$selectBox = $(".selectBox"),
$start = $(".start"),
$back = $(".back")
var allParentWidth = $allParent.width(),
allParentHeight = $allParent.height();
var boxHeight = 160,
boxWidth = 220;
var itemDoms = [],
boxsPositions = [];
var isFirst = true;
function init() {
// Initialize the event
$selectBox.on("click".".start".function () {
if(isFirst){
itemDoms.forEach(function(dom){
dom.find(".parent").addClass("active")})setTimeout(function(){
for (var i = 0; i < boxsPositions.length; i++) {
itemDoms[i].get(0).style.transition = 0.6 s ` ` all
itemDoms[i].css({
transform: `translate3d(0px, 0px, 0px)`
});
}
setTimeout(function(){
initPricePosition()
},600)},700)}else{
itemDoms.forEach(function(dom){
dom.find(".parent").addClass("active")
})
}
$start.hide();
$back.show()
isFirst = false;
});
$selectBox.on("click".".back".function(){
itemDoms.forEach(function(dom){
dom.find(".parent").removeClass("active")
})
$start.show();
$back.hide()
})
}
function initDom() { // Initialize the DOM
for (var i = 0; i < data.length; i++) {
var html = $(`<div class="item i${i + 1}">
<div class="parent">
<div class="face" style='background: url("${ data[i].img }") center center / 100% 100% no-repeat; '> </div> <div class="back"> <img src="https://res0.vmallres.com/shopdc/pic/193f6450-5327-444e-a610-88125afb4ba7.png" style="width: 100%; height: 100%"> </div> </div> </div>`); itemDoms.push(html); $selectBox.before(html); }}function initPosition() { // Calculate the position
var gapW = (allParentWidth - boxWidth * 3) / 4.// The width of the space
gapH = (allParentHeight - boxHeight * 3) / 2; // Height space distance
for (var i = 0; i < itemDoms.length; i++) {
var pos = {};
if (i < 3) {
/ / the first column
pos.y = -(gapH + boxHeight);
pos.x = (i - 1) * (boxWidth + gapW);
} else if (i == 3 || i == 4) {
/ / the second column
if (i == 3) {
pos.x = -(boxWidth + gapW);
} else {
pos.x = boxWidth + gapW;
}
pos.y = 0;
} else {
/ / the third column
pos.y = gapH + boxHeight;
pos.x = (((i + 1) % 3) - 1) * (boxWidth + gapW);
}
boxsPositions.push(pos);
}
// re-assign itemDoms to transform
}
function initPricePosition() { // Initialize the DOM location
for (var i = 0; i < boxsPositions.length; i++) {
itemDoms[i].css({
transform: `translate3d(${boxsPositions[i].x}px, ${boxsPositions[i].y}px, 0px)`}); } } init() initDom();/ / initialization
initPosition();
initPricePosition();
</script>
</html>
Copy the code
conclusion
Small DEMO, for practice CSS3+DOM operations, suitable for just entered the front novice. Welcome friends to pay attention to a wave, we learn together! On the way to the gods.