项目前提
快过年了嘛,想换个手机,感觉除了水果就是华为了。我锤粉,可惜锤子倒闭了。在华为官网活动页面的最下面有一个转盘抽奖功能,觉得蛮有趣的(该死的前端职业毛病),想想手机没买总要带点什么走,同时很久都没有写一下原生JS了,于是乎就想着把这个东西简单的实现一下(没有考虑封装哈)。本案例不适合大佬。
上图
思路整理
1、DOM结构
<div id="allParent">
<!--点击开始/返回-->
<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"
/>
</div>
</div>
</div>
</div>
2、翻转效果3D
首先要给最外层添加透视属性
#allParent .item .parent {
width: 100%;
height: 100%;
transform-style: preserve-3d; //子节点透视
perspective-origin: center;
perspective: 500px; //透视距离
position: relative;
}
奖品和点击翻盘是两个并在一起的图片,默认先把点击翻盘进行旋转。
#allParent .item .parent .back{
position: absolute;
height: 100%;
transition: all .6s;
transform: rotateY(270deg) ; //先转270度
border-radius: 9px;
opacity: 0;
}
3、JS效果
核心代码是计算每个奖项相对于中心位置的偏移量。
基本思路:
function initPosition() { //计算位置
var gapW = (allParentWidth - boxWidth * 3) / 4, //宽度空格的距离
gapH = (allParentHeight - boxHeight * 3) / 2; //高度空格的距离
for (var i = 0; i < itemDoms.length; i++) {
var pos = {};
if (i < 3) {
//第一列
pos.y = -(gapH + boxHeight); //所有的Y都为盒子的高度+空格的距离
pos.x = (i - 1) * (boxWidth + gapW);
} else if (i == 3 || i == 4) {
//第二列
if (i == 3) {
pos.x = -(boxWidth + gapW);
} else {
pos.x = boxWidth + gapW;
}
pos.y = 0;
} else {
//第三列
pos.y = gapH + boxHeight;
pos.x = (((i + 1) % 3) - 1) * (boxWidth + gapW);//第三排的x偏移量
}
boxsPositions.push(pos);
}
}
全部代码
可以直接拷贝运行
<!DOCTYPE html>
<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">
<!--点击开始/返回-->
<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"
/>
</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() {
//初始化事件
$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 = `all 0.6s`
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() { //初始化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() { //计算位置
var gapW = (allParentWidth - boxWidth * 3) / 4, //宽度空格的距离
gapH = (allParentHeight - boxHeight * 3) / 2; //高度空格的距离
for (var i = 0; i < itemDoms.length; i++) {
var pos = {};
if (i < 3) {
//第一列
pos.y = -(gapH + boxHeight);
pos.x = (i - 1) * (boxWidth + gapW);
} else if (i == 3 || i == 4) {
//第二列
if (i == 3) {
pos.x = -(boxWidth + gapW);
} else {
pos.x = boxWidth + gapW;
}
pos.y = 0;
} else {
//第三列
pos.y = gapH + boxHeight;
pos.x = (((i + 1) % 3) - 1) * (boxWidth + gapW);
}
boxsPositions.push(pos);
}
//重新给itemDoms赋值 transform
}
function initPricePosition() { //初始化DOM位置
for (var i = 0; i < boxsPositions.length; i++) {
itemDoms[i].css({
transform: `translate3d(${boxsPositions[i].x}px, ${boxsPositions[i].y}px, 0px)`,
});
}
}
init()
initDom(); //初始化
initPosition();
initPricePosition();
</script>
</html>
总结
小小DEMO,用于练习CSS3+DOM操作,适合刚入行的前端新手。欢迎小伙伴们关注一波,大家一起学习!早日迈向大神之路。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!