本文小编为大家详细介绍“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>