当前位置:   article > 正文

css实现3D长方形,可旋转_长方体旋转的代码

长方体旋转的代码

先上图:

实现过程:

1、长方体六个面 

before,after, top ,buttom,left,right

2、每个面不同旋转角度

  1. before: 向前移动一半width宽度,transform: translateZ(${width/2}px)
  2. after: 向后移动一半width宽度、y轴旋转180度 transform: `translateZ(${-width/2}px) rotateY(180deg)`
  3. top: 以top为轴,x轴旋转90度,向后移动一半宽度 transform-origin: top; transform: `rotateX(90deg) translate(0, ${-width/2}px)`}
  4. bottom: 以bottom为轴,x轴旋90度,向后移动一半宽度, 放缩width/height,width: `${width}px`, height: `${height}px`,transform: `rotateX(90deg) translate(0, ${-width/2}px) scale(0,width/height)`
  5. left: 以left为轴,y轴旋转-90度,向左移动一半宽度,{transform: `rotateY(-90deg) translate(${-width/2}px, 0)`}
  6. right: 以right为轴,y轴旋转90度,向右移动一半宽度,{transform: `rotateY(90deg) translate(${width/2}px, 0)`}
3、在外圈div做旋转
4、代码:box.vue
  1. <template>
  2. <div class="box-wrap">
  3. <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">
  4. <div id="face-before" class="face face-before" :style="{transform: `translateZ(${width/2}px)`}">
  5. <slot name="before" ></slot>
  6. </div>
  7. <div id="face-after" class="face face-after" :style="{transform: `translateZ(${-width/2}px) rotateY(180deg)`}">
  8. <slot name="after"></slot>
  9. </div>
  10. <div id="face-top" class="face face-top" :style="{width: `${width}px`, height: `${width}px`, transform: `rotateX(90deg) translate(0, ${-width/2}px)`}">
  11. <slot name="top"></slot>
  12. </div>
  13. <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)`}">
  14. <slot name="buttom"></slot>
  15. </div>
  16. <div id="face-left" class="face face-left" :style="{transform: `rotateY(-90deg) translate(${-width/2}px, 0)`}" >
  17. <slot name="left"></slot>
  18. </div>
  19. <div id="face-right" class="face face-right" :style="{transform: `rotateY(90deg) translate(${width/2}px, 0)`}">
  20. <slot name="right"></slot>
  21. </div>
  22. </div>
  23. </div>
  24. </template>
  25. <script>
  26. export default {
  27. name: 'box',
  28. data() {
  29. return {
  30. canMove: false,
  31. startX: 0,
  32. startY: 0,
  33. currentDeg: 0,
  34. }
  35. },
  36. props: {
  37. width: {
  38. type: Number,
  39. default: 300,
  40. },
  41. height: {
  42. type: Number,
  43. default: 300,
  44. },
  45. },
  46. methods: {
  47. // mouseenter(ev) { // 按下鼠标
  48. // this.canMove = true;
  49. // this.startX = ev.clientX;
  50. // this.startY = ev.clientY;
  51. // },
  52. mousedown(ev) { // 按下鼠标
  53. this.canMove = true;
  54. this.startX = ev.clientX;
  55. this.startY = ev.clientY;
  56. },
  57. mousemove(ev) { // 鼠标移动
  58. if(this.canMove) {
  59. const $box = document.getElementById('box');
  60. const obj = this.getTransform();
  61. const x = this.startX - ev.clientX;
  62. const y = this.startY - ev.clientY;
  63. const newx = (obj.x - (y / this.height * 180));
  64. const newy = (obj.y - (x / this.width * 180));
  65. console.log('x / this.width * 90===', x / this.width * 180);
  66. console.log('newy===', newy);
  67. this.startX = ev.clientX;
  68. this.startY = ev.clientY;
  69. $box.style.transform = `rotateX(-5deg) rotateY(${newy}deg)`;
  70. this.currentDeg = newy;
  71. }
  72. },
  73. mouseout() { // 鼠标离开
  74. if(this.canMove) {
  75. const $box = document.getElementById('box');
  76. const value = this.currentDeg % 90;
  77. if(Math.abs(value) >= 45) {
  78. $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg + (90 - value) + 0.01}deg)`;
  79. }else {
  80. $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg - value + 0.01}deg)`;
  81. }
  82. this.canMove = false;
  83. }
  84. },
  85. showAuto() {
  86. const $box = document.getElementById('box');
  87. $box.style['transform-origin'] = 'center';
  88. $box.style.transform = `rotateX(-20deg) rotateY(20deg)`;
  89. },
  90. showTop() {
  91. const $box = document.getElementById('box');
  92. $box.style['transform-origin'] = 'center';
  93. $box.style.transform = `rotateX(-89.999deg) rotateY(0deg)`;
  94. },
  95. showLeft() {
  96. const $box = document.getElementById('box');
  97. $box.style['transform-origin'] = 'center';
  98. $box.style.transform = `rotateX(0deg) rotateY(89.999deg)`;
  99. },
  100. mouseup() { // 鼠标离开
  101. if(this.canMove) {
  102. const $box = document.getElementById('box');
  103. const value = this.currentDeg % 90;
  104. if(Math.abs(value) >= 45) {
  105. if(value < 0) {
  106. $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg - (90 - Math.abs(value)) + 0.01}deg)`;
  107. }else {
  108. $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg + (90 - Math.abs(value)) + 0.01}deg)`;
  109. }
  110. }else {
  111. if(value < 0) {
  112. $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg - value + 0.01}deg)`;
  113. }else {
  114. $box.style.transform = `rotateX(0deg) rotateY(${this.currentDeg + value + 0.01}deg)`;
  115. }
  116. }
  117. this.canMove = false;
  118. }
  119. },
  120. reset() {
  121. const $box = document.getElementById('box');
  122. $box.style.transform = `rotateX(-20deg) rotateY(20deg)`;
  123. },
  124. getTransform() {
  125. const $box = document.getElementById('box');
  126. const ts = $box.style.transform.split(' ');
  127. const xs = ts[0].indexOf('X(');
  128. const xe = ts[0].indexOf('deg');
  129. const ys = ts[1].indexOf('Y(');
  130. const ye = ts[1].indexOf('deg');
  131. const x = ts[0].substring(xs + 2, xe);
  132. const y = ts[1].substring(ys + 2, ye);
  133. return {
  134. x,
  135. y,
  136. }
  137. },
  138. },
  139. mounted() {
  140. },
  141. }
  142. </script>
  143. <style lang="scss" scoped>
  144. .box-wrap {
  145. .box {
  146. position: relative;
  147. z-index: 6;
  148. margin: auto;
  149. transform-style: preserve-3d;
  150. transform-origin: center, center;
  151. transition: transform 1s;
  152. .face {
  153. position: absolute;
  154. width: 100%;
  155. height: 100%;
  156. opacity: 0.3;
  157. font-size: 30px;
  158. }
  159. .face-before {
  160. transform: translateZ(150px);
  161. background-color: rgb(0, 255, 170);
  162. text-align: left;
  163. }
  164. .face-after {
  165. transform-origin: center;
  166. transform: translateZ(-150px) rotateX(-180deg);
  167. background-color: #0088cc;
  168. }
  169. .face-top {
  170. transform-origin: top;
  171. transform: rotateX(90deg) translate(0, -150px);
  172. background-color: rgb(255, 0, 170);
  173. }
  174. .face-bottom {
  175. transform-origin: bottom;
  176. transform: rotateX(-90deg) translate(0, 150px);
  177. background-color: rgb(0, 255, 85);
  178. }
  179. .face-left {
  180. transform-origin: left;
  181. transform: rotateY(-90deg) translate(-150px, 0);
  182. background-color: rgb(255, 208, 0);
  183. }
  184. .face-right {
  185. transform-origin: right;
  186. transform: rotateY(90deg) translate(150px, 0);
  187. background-color: rgb(255, 208, 0);
  188. }
  189. }
  190. }
  191. </style>

5、使用:

  1. <template>
  2. <div class="app-home">
  3. <header class="header">
  4. <div class="content">
  5. <div class="header-left">
  6. <span class="title">凡夫俗子</span>
  7. <span class="desc">我们追寻梦想, 因为那最令人开心</span>
  8. </div>
  9. <div class="header-right">
  10. </div>
  11. </div>
  12. </header>
  13. <box :height="300" :width="600" ref="box">
  14. <template slot="before">
  15. <div>before</div>
  16. </template>
  17. <template slot="after">
  18. <div>after</div>
  19. </template>
  20. <template slot="left">
  21. <div>left</div>
  22. </template>
  23. <template slot="right">
  24. <div>right</div>
  25. </template>
  26. <template slot="top">
  27. <div>top</div>
  28. </template>
  29. <template slot="bottom">
  30. <div>bottom</div>
  31. </template>
  32. </box>
  33. </div>
  34. </template>
  35. <script>
  36. import box from '@/web/components/box3.vue'
  37. export default {
  38. name: 'HelloWorld',
  39. data () {
  40. return {
  41. boxWidth: 1152,
  42. boxHeight: 600,
  43. }
  44. },
  45. components: {
  46. box
  47. },
  48. methods: {
  49. goTopClick() {
  50. this.$refs.box.showTop();
  51. },
  52. goLeftClick() {
  53. this.$refs.box.showLeft();
  54. },
  55. showAuto() {
  56. this.$refs.box.showAuto();
  57. }
  58. },
  59. mounted() {
  60. this.boxHeight = document.documentElement.clientHeight - 15;
  61. window.onresize = () => {
  62. this.boxHeight = document.documentElement.clientHeight - 15;
  63. };
  64. }
  65. }
  66. </script>
  67. <!-- Add "scoped" attribute to limit CSS to this component only -->
  68. <style lang="scss">
  69. .app-home {
  70. background-color: #f5f5f5;
  71. .header {
  72. width: 100%;
  73. height: 60px;
  74. margin-bottom: 15px;
  75. background-color: rgba(255,255,255,.5);
  76. .content {
  77. width: 1200px;
  78. min-width: 1200px;
  79. margin: auto;
  80. overflow: auto;
  81. padding-left: 24px;
  82. padding-right: 24px;
  83. color: #00bbd3;
  84. .header-left {
  85. .title {
  86. display: inline-block;
  87. vertical-align: middle;
  88. margin-right: 24px;
  89. line-height: 60px;
  90. font-size: 25px;
  91. letter-spacing: 0.2em;
  92. }
  93. .desc {
  94. display: inline-block;
  95. vertical-align: middle;
  96. line-height: 60px;
  97. font-size: 14px;
  98. }
  99. }
  100. .header-right {
  101. font-size: 12px;
  102. }
  103. }
  104. }
  105. }
  106. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/96994
推荐阅读
相关标签
  

闽ICP备14008679号