本文小编为大家详细介绍“vue旋转木马组件demo怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue旋转木马组件demo怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
实现步骤
1.确定组件类型
确定组件类型,如上图设计,标准的旋转木马组件
2.选择实现方式
1.1 使用swpier等现有的组件,进行css样式覆盖
优点:利用现有的组件进行样式覆盖,开发速度快
缺点:需覆盖样式较多,编写混乱,css基础不足,导致徒劳无功 1.2 自己编写一个旋转木马公用组件(选用)
优点:锻炼下自己插拔编程思想,方便后期复用,送人玫瑰,手留余香
3.功能需求分析
本次我们主要讲述自己实现组件,分析后,需要满足以下功能点:
3.1 构建空间,满足3d外观要求,并配有旋转动画、激活后的抖动(抖动暂未实现,有需要的可以自己追加css动画接口)
3.2 可拖拽组件中子元素,拖拽结束后,激活选中的子元素
3.3 任意点击子元素,激活点击的子元素
4.话不多说,上代码
复制下方的代码,粘贴到vue文件中,即可使用。
<template>
<div class="wapper">
<main id="main">
<div class="Trojan"
:style="{
'transform':'rotateX('+TrojanOptions.rotateX+'deg) rotateY('+(-TrojanOptions.activeChildSort*singleAngle)+'deg)'
}">
<div v-for="(item,index) in TrojanOptions.data"
:key="index"
class="TrojanChild"
:class="TrojanOptions.activeChildSort===item.sort?'activeChild TrojanChild':'TrojanChild'"
:style=" {
'--index': index+1,
'transform':'rotateY('+(singleAngle*index)+'deg) translateZ(320px)'
} "
@mousedown="handleDrapDown($event,item)"> <img :src="item.src">
{{item.sort}}
</div>
</div>
</main>
</div>
</template>
<script>
export default {
name: 'demo',
components: {},
data () {
return {
// 旋转木马配置
TrojanOptions: {
//默认激活的子元素坐标
activeChildSort: 0,
//是否允许进行拖拽
isDrop: false,
//旋转角度
rotate: 0,
// 向内倾斜角度
rotateX: -12,
// 旋转木马子元素
data: [
{
sort: 0,
src: require("@/assets/logo.png"),
},
{
sort: 1,
src: require("@/assets/logo.png"),
},
{
sort: 2,
src: require("@/assets/logo.png"),
},
{
sort: 3,
src: require("@/assets/logo.png"),
},
{
sort: 4,
src: require("@/assets/logo.png"),
},
{
sort: 5,
src: require("@/assets/logo.png"),
},
],
},
}
},
watch: {
},
created () {
},
computed: {
//单个元素占用的角度
singleAngle () {
return parseInt(360 / this.TrojanOptions.data.length)
},
},
mounted () {
},
destroyed () {
},
methods: {
//复位
resetPosition () {
if (this.TrojanOptions.activeChildSort >= this.TrojanOptions.data.length) {
this.TrojanOptions.activeChildSort = 0
}
if (this.TrojanOptions.activeChildSort < 0) {
this.TrojanOptions.activeChildSort = this.TrojanOptions.data.length-1
}
},
//旋转方法
startTurn (addflag, item) {
let Trojan = document.querySelector(".Trojan");
if (addflag === 0) {
this.TrojanOptions.activeChildSort -= 1
this.resetPosition()
}
else if (addflag === 1) {
this.TrojanOptions.activeChildSort += 1
this.resetPosition()
}
else {
this.TrojanOptions.activeChildSort = item.sort
}
Trojan.style.cssText = ` transform: rotateX(` + this.TrojanOptions.rotateX + `deg) rotateY(${this.TrojanOptions.rotate}deg); `;
},
//旋转的触发方法
//也是入口
handleDrapDown (de, item) {
const th = this
let stratPoint = de.clientX || de.touches[0].clientX
let endPoint = de.clientX || de.touches[0].clientX
this.TrojanOptions.isDrop = true;
// 此处可以扩展鼠标的移动,旋转延续跟着移动的动画效果
document.onmousemove = (e) => {
if (!this.TrojanOptions.isDrop) return false;
e.preventDefault();
}
document.onmouseup = (e) => {
if (!this.TrojanOptions.isDrop) return;
endPoint = e.clientX || e.touches[0].clientX;
this.TrojanOptions.isDrop = false;
if (stratPoint < endPoint) {
th.startTurn(0, item)
}
else if (stratPoint > endPoint) {
th.startTurn(1, item)
}
else {
th.startTurn(3, item)
}
}
}
}
}
</script>
<style lang="scss">
.wapper {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #000;
}
main {
user-select: none;
position: relative;
width: 220px;
height: 130px;
// 官方解释:指定了观察者与z=0平面的距离,使具有三维位置变换的元素产生透视效果
// 具体可以操作该值进行效果观测
perspective: 800px;
}
.Trojan {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: all 1s;
}
.TrojanChild {
position: absolute;
width: 100%;
height: 100%;
border: 1px solid yellow;
color: #fff;
&.activeChild {
border: 1px solid red !important;
}
& img {
width: 100%;
height: 100%;
}
:hover {
cursor: grab;
}
:active {
cursor: grabbing;
}
}
</style>
版权声明:除特别声明外,本站所有文章皆是本站原创,转载请以超链接形式注明出处!