赞
踩
先上图:
实现过程:
1、长方体六个面
before,after, top ,buttom,left,right
2、每个面不同旋转角度
- before: 向前移动一半width宽度,transform: translateZ(${width/2}px)
- after: 向后移动一半width宽度、y轴旋转180度 transform: `translateZ(${-width/2}px) rotateY(180deg)`
- top: 以top为轴,x轴旋转90度,向后移动一半宽度 transform-origin: top; transform: `rotateX(90deg) translate(0, ${-width/2}px)`}
- bottom: 以bottom为轴,x轴旋90度,向后移动一半宽度, 放缩width/height,width: `${width}px`, height: `${height}px`,transform: `rotateX(90deg) translate(0, ${-width/2}px) scale(0,width/height)`
- left: 以left为轴,y轴旋转-90度,向左移动一半宽度,{transform: `rotateY(-90deg) translate(${-width/2}px, 0)`}
- right: 以right为轴,y轴旋转90度,向右移动一半宽度,{transform: `rotateY(90deg) translate(${width/2}px, 0)`}
3、在外圈div做旋转
4、代码:box.vue
- <template>
- <div class="box-wrap">
- <div class="box" id="box" style="transform: rotateX(0deg) rotateY(0deg);" :style="{width: `${width}px`, height: `${height}px`}" @mousedown="mousedown" @mousemove="mousemove" @mouseup="mouseup" @mouseout="mouseup">
- <div id="face-before" class="face face-before" :style="{transform: `translateZ(${width/2}px)`}">
- <slot name="before" ></slot>
- </div>
- <div id="face-after" class="face face-after" :style="{transform: `translateZ(${-width/2}px) rotateY(180deg)`}">
- <slot name="after"></slot>
- </div>
- <div id="face-top" class="face face-top" :style="{width: `${width}px`, height: `${width}px`, transform: `rotateX(90deg) translate(0, ${-width/2}px)`}">
- <slot name="top"></slot>
- </div>
- <div id="face-bottom" class="face face-bottom" :style="{width: `${width}px`, height: `${height}px`,transform: `rotateX(90deg) translate(0, ${width/2}px) scale(0,width/height)`}">
- <slot name="buttom"></slot>
- </div>
- <div id="face-left" class="face face-left" :style="{transform: `rotateY(-90deg) translate(${-width/2}px, 0)`}" >
- <slot name="left"></slot>
- </div>
- <div id="face-right" class="face face-right" :style="{transform: `rotateY(90deg) translate(${width/2}px, 0)`}">
- <slot name="right"></slot>
- </div>
- </div>
- </div>
- </template>
-
- <script>
- export default {
- name: 'box',
- data() {
- return {
- canMove: false,
- startX: 0,
- startY: 0,
- currentDeg: 0,
- }
- },
- props: {
- width: {
- type: Number,
- default: 300,
- },
- height: {
- type: Number,
- default: 300,
- },
- },
- methods: {
- // mouseenter(ev) { // 按下鼠标
- // this.canMove = true;
- // this.startX = ev.clientX;
- // this.startY = ev.clientY;
- // },
- mousedown(ev) { // 按下鼠标
- this.canMove = true;
- this.startX = ev.clientX;
- this.startY = ev.clientY;
- },
- mousemove(ev) { // 鼠标移动
- if(this.canMove) {
- const $box = document.getElementById('box');
- const obj = this.getTransform();
- const x = this.startX - ev.clientX;
- const y = this.startY - ev.clientY;
- const newx = (obj.x - (y / this.height * 180));
- const newy = (obj.y - (x / this.width * 180));
- console.log('x / this.width * 90===', x / this.width * 180);
- console.log('newy===', newy);
- this.startX = ev.clientX;
- this.startY = ev.clientY;
- $box.style.transform = `rotateX(-5deg) rotateY(${newy}deg)`;
- this.currentDeg = newy;
- }
- },
- mouseout() { // 鼠标离开
- if(this.canMove) {
- const $box = document.getElementById('box');
- const value = this.currentDeg % 90;
- if(Math.abs(value) >= 45) {
- $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg + (90 - value) + 0.01}deg)`;
- }else {
- $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg - value + 0.01}deg)`;
- }
-
- this.canMove = false;
- }
- },
- showAuto() {
- const $box = document.getElementById('box');
- $box.style['transform-origin'] = 'center';
- $box.style.transform = `rotateX(-20deg) rotateY(20deg)`;
- },
- showTop() {
- const $box = document.getElementById('box');
- $box.style['transform-origin'] = 'center';
- $box.style.transform = `rotateX(-89.999deg) rotateY(0deg)`;
- },
- showLeft() {
- const $box = document.getElementById('box');
- $box.style['transform-origin'] = 'center';
- $box.style.transform = `rotateX(0deg) rotateY(89.999deg)`;
- },
- mouseup() { // 鼠标离开
- if(this.canMove) {
- const $box = document.getElementById('box');
- const value = this.currentDeg % 90;
- if(Math.abs(value) >= 45) {
- if(value < 0) {
- $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg - (90 - Math.abs(value)) + 0.01}deg)`;
- }else {
- $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg + (90 - Math.abs(value)) + 0.01}deg)`;
- }
-
- }else {
- if(value < 0) {
- $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg - value + 0.01}deg)`;
- }else {
- $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg + value + 0.01}deg)`;
- }
-
- }
-
- this.canMove = false;
- }
- },
- reset() {
- const $box = document.getElementById('box');
- $box.style.transform = `rotateX(-20deg) rotateY(20deg)`;
- },
- getTransform() {
- const $box = document.getElementById('box');
- const ts = $box.style.transform.split(' ');
-
- const xs = ts[0].indexOf('X(');
- const xe = ts[0].indexOf('deg');
-
- const ys = ts[1].indexOf('Y(');
- const ye = ts[1].indexOf('deg');
-
- const x = ts[0].substring(xs + 2, xe);
- const y = ts[1].substring(ys + 2, ye);
- return {
- x,
- y,
- }
- },
- },
- mounted() {
-
- },
- }
- </script>
- <style lang="scss" scoped>
- .box-wrap {
- .box {
- position: relative;
- z-index: 6;
- margin: auto;
- transform-style: preserve-3d;
- transform-origin: center, center;
- transition: transform 1s;
- .face {
- position: absolute;
- width: 100%;
- height: 100%;
- opacity: 0.3;
- font-size: 30px;
-
- }
- .face-before {
- transform: translateZ(150px);
- background-color: rgb(0, 255, 170);
- text-align: left;
-
- }
- .face-after {
- transform-origin: center;
- transform: translateZ(-150px) rotateX(-180deg);
- background-color: #0088cc;
- }
- .face-top {
- transform-origin: top;
- transform: rotateX(90deg) translate(0, -150px);
- background-color: rgb(255, 0, 170);
- }
- .face-bottom {
- transform-origin: bottom;
- transform: rotateX(-90deg) translate(0, 150px);
- background-color: rgb(0, 255, 85);
- }
- .face-left {
- transform-origin: left;
- transform: rotateY(-90deg) translate(-150px, 0);
- background-color: rgb(255, 208, 0);
- }
- .face-right {
- transform-origin: right;
- transform: rotateY(90deg) translate(150px, 0);
- background-color: rgb(255, 208, 0);
- }
- }
- }
- </style>
-
-
5、使用:
- <template>
- <div class="app-home">
- <header class="header">
- <div class="content">
- <div class="header-left">
- <span class="title">凡夫俗子</span>
- <span class="desc">我们追寻梦想, 因为那最令人开心</span>
- </div>
- <div class="header-right">
-
- </div>
- </div>
- </header>
- <box :height="300" :width="600" ref="box">
- <template slot="before">
- <div>before</div>
- </template>
- <template slot="after">
- <div>after</div>
- </template>
- <template slot="left">
- <div>left</div>
- </template>
- <template slot="right">
- <div>right</div>
- </template>
- <template slot="top">
- <div>top</div>
- </template>
- <template slot="bottom">
- <div>bottom</div>
- </template>
- </box>
- </div>
- </template>
-
- <script>
- import box from '@/web/components/box3.vue'
- export default {
- name: 'HelloWorld',
- data () {
- return {
- boxWidth: 1152,
- boxHeight: 600,
- }
- },
- components: {
- box
- },
- methods: {
- goTopClick() {
- this.$refs.box.showTop();
- },
- goLeftClick() {
- this.$refs.box.showLeft();
- },
- showAuto() {
- this.$refs.box.showAuto();
- }
- },
- mounted() {
- this.boxHeight = document.documentElement.clientHeight - 15;
- window.onresize = () => {
- this.boxHeight = document.documentElement.clientHeight - 15;
- };
- }
- }
- </script>
-
- <!-- Add "scoped" attribute to limit CSS to this component only -->
- <style lang="scss">
- .app-home {
- background-color: #f5f5f5;
- .header {
- width: 100%;
- height: 60px;
- margin-bottom: 15px;
- background-color: rgba(255,255,255,.5);
- .content {
- width: 1200px;
- min-width: 1200px;
- margin: auto;
- overflow: auto;
- padding-left: 24px;
- padding-right: 24px;
-
- color: #00bbd3;
- .header-left {
- .title {
- display: inline-block;
- vertical-align: middle;
- margin-right: 24px;
- line-height: 60px;
- font-size: 25px;
- letter-spacing: 0.2em;
- }
- .desc {
- display: inline-block;
- vertical-align: middle;
- line-height: 60px;
- font-size: 14px;
- }
- }
- .header-right {
- font-size: 12px;
- }
- }
- }
-
- }
- </style>
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。