我是靠谱客的博主 高大便当,最近开发中收集的这篇文章主要介绍react down下来如何启动_如何实现一个 3D 效果的魔方,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

b7c857a9ef312e585483b299b161f779.gif

合抱之木,生于毫末;九层之台,起于累土.

当我们遇到一个较难问题的时候,把它逐步分解,转化为我们熟悉的内容,问题就很容易得到解决。

我们现在的目标是做一个 3D 效果的魔方,我们找到它的本质,对它解构?那就先写一个立方块!

刚毕业时写了一个魔方,最近看到掘金的这个技术专题,总结一下思路及基本的知识

  • 魔方项目:https://github.com/shfshanyue/react-rubic
  • 魔方演示地址: https://shfshanyue.github.io/react-rubic/

3D 相关 CSS 属性及函数

在 3D 空间中转换最重要几个形态的是平移,旋转与缩放,接下来将会介绍与制作一个 3D 效果立方体相关的 CSS 属性及函数。

  • transform-style
  • perspective
  • backface-visibility

3D 空间

一个立方体,必然存在于一个 3D 空间,首先需要使用 CSS 指明该立方体处于 3D 空间中。

.cube {
  transform-style: preserve-3d;
}

通过 CSS 的属性值 transform-style: preserve-3d 可以设置该元素的所有子元素都处于 3D 空间。

在科幻小说三体中,云天明讲了三个故事,其中讲到有一个深水王子,无论你在远处看还是近处看,他都一般高,不会受距离增减的影响,不符合我们现实中「近大远小」的透视规律。

正是有了透视距离,现实世界的事物才会有层次感,而在 CSS 的 3D 世界里,也有一个属性代表透视距离。

.cube {
  perspective: 800px;
  // 观察者眼睛位于上边看的全面
  perspective-origin: 150% -150%;
}

与二维平面不同,在 3D 空间中多了一个 Z 轴,而与 Z 轴 垂直的平面构成了 Z 平面,即我们在 2D 方向上能够看到的这个平面。

perspective 定义了观察者眼睛与 Z=0 平面(即投影面)的距离,来制造一种空间感。

0dc2706ae64bb564e5fe0beb07c6e2c0.png

perspective 最小可设置为 1px,当它值越小时,物体在投影面上越大。如下图所示

ce484f98f4f4076207a772be6e6ef848.png

perspective-origin 代表观察者眼睛的位置,默认居中

cc1fdbbbc1ac21c07b337c78000e22c1.png

平移与坐标系: translate3d()

.cube {
  transform: translate3d(x, y, z);
}

translate3d(x, y, z) 定义了元素在 3D 空间沿坐标系的平移,而如果只在单轴上平移,则可以使用独立的 API。

  • translateX(x): translate3d(x, 0, 0)
  • translateY(y): translate3d(0, y, 0)
  • translateZ(z): translate3d(0, 0, z)

当作 Z 轴方向平移时,正值代表离用户越来越近,即在视觉效果上它会越来越大。负值则相反。具体视觉效果可参考 MDN 文档。

一种他们在三维坐标系下的正方向如下所示:

cfc6b74f176c370bdd3ef7f52415dcf7.png

translateZ | MDN[1]

旋转与原点: rotate3d() 与 transform-origin

.cube {
  transform: rotate3d(x, y, z, a);
}

rotate3d 定义了元素在 3D 空间的旋转,旋转相比平移来说,它要多一个指标:「旋转轴,它根据从原点出发的向量 [x, y, z] 来确定旋转轴。」

[x, y, z] 坐标自然由 rotate3d(x, y, z, a) 来指定,那如何确定原点呢?

原点坐标由属性 transform-origin 来指定,如果只有前两个值代表在 2D 平面,如果有三个值代表在 3D 空间。

你可以通过围绕各个坐标轴旋转 180 度,来确定原点坐标

.cube {
  transform-origin: 100px 100px 100px;
}

可以通过对一个立方体的旋转对 rotate3d 有直观的了解

正常放置

在正常状态下,各面数字如下

8fdcdb14d25e1cffec65ed887fa315ac.png

rotateX(180deg)

沿 X 轴旋转 180 度后,位面 2 面对用户

7ec67eeaa603d3921b7241670648f6a1.png

rotateZ(180deg)

沿 Z 轴旋转 180 度后,位面 1 面对用户,但是翻转了过来

0bc22e1af5a0cbfbcfba0718469d24f3.png

通过 MDN 文档也可以对各个转换有更直观的了解

  • rotateX | MDN[2]
  • rotateY | MDN[3]
  • rotateZ | MDN[4]
  • transform-origin | MDN[5]

一个立方体

对 CSS 3D 方面的属性及值进行熟悉之后,就能够很容易地画出一个立方体。

一个立方体由六个面组成,分别使用 UpDownLeftRightFrontBack 的首字母进行表示。使用 html 描述它的结构如下

<div class="cube-container">
  <div class="cube">
    <div class="face face-up">Udiv>
    <div class="face face-down">Ddiv>
    <div class="face face-left">Ldiv>
    <div class="face face-right">Rdiv>
    <div class="face face-front">Fdiv>
    <div class="face face-back">Bdiv>
  div>
div>

  • .cube-container: 为立方体提供布局,使之处于屏幕中心位置
  • .cube: 表示该立方体容器
  • .face: 表示该立方体的六个面

.cube 选择器中声明一个 3D 空间,指定 perspectivetransform-style 属性

.cube {
  perspective: 1500px;
  transform-style: preserve-3d;
}

为了立方体的美观,优雅及调试方便,对立方体加入一些 3D 无关的样式: 关于布局,显示及色彩

为立方体提供一个 100px/100px 大小的容器,并处于屏幕正中,并且立方体每一面的字也垂直居中

$ width: 100px;

.cube-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 500px;
}

.cube {
  width: $width;
  height: $width;
  margin: $width;
}

.face {
  background: #f60;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 2em;
  color: #fff;
}

接下来对六个面做绝对定位,并且根据目标位置做适当的平移与旋转即可组成立方体。

$width: 100px;

.face {
width: $width;
height: $width;
position: absolute;

&.face-up {
transform: rotateX(90deg) translateZ($width / 2);
}

&.face-down {
transform: rotateX(-90deg) translateZ($width / 2);
}

&.face-left {
transform: rotateY(-90deg) translateZ($width / 2);
}

&.face-right {
transform: rotateY(90deg) translateZ($width / 2);
}

&.face-front {
transform: translateZ($width / 2);
}

&.face-back {
transform: rotateX(180deg) translateZ($width / 2);
}
}

效果图如下

e574951c0f6a54e1507af02f208eaf8b.png

全部代码如下

codepen[6]

让立方体动起来

此时 3D 空间的立方体已经成形,为了更加形象,我决定给它一个动画。

下列 CSS 动画使它绕着向量 [1, 1, 0] 永无停歇地旋转。

@keyframes rotate {
  0% {
    transform: rotate3d(0, 0, 0, 0);
  }
  100% {
    transform: rotate3d(1, 1, 0, 360deg);
  }
}

.cube {
  animation: rotate 2s linear reverse infinite;
}

效果图如下所示

11a55d9378baa83defe608fcc68b33a8.gif

来画一个魔方

魔方由 27 个小块组成,通过 translate3d 对 27 个小立方块进行位移,即可得到一个魔方,代码如下所示

mixin coordinate() {
@for $x from 1 through 3 {
@for $y from 1 through 3 {
@for $z from 1 through 3 {
.cube-#{$x}-#{$y}-#{$z} {
transform: translate3d(($x - 2) * $width, ($y - 2) * $width, ($z - 2) * $width);
}
}
}
}
}

@include coordinate();
b7c857a9ef312e585483b299b161f779.gif

最后成型的代码及演示如下所示:

  • 魔方项目:https://github.com/shfshanyue/react-rubic
  • 魔方演示地址: https://shfshanyue.github.io/react-rubic/

Reference

[1]

translateZ | MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/translateZ

[2]

rotateX | MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotateX

[3]

rotateY | MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotateY

[4]

rotateZ | MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotateZ

[5]

transform-origin | MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin

[6]

codepen: https://codepen.io/shanyue/pen/QWNqqwm

ef65863bc59377e82700ad3d1393a95a.png

 相关推荐

用Js实现人脸识别功能

JavaScript 启动性能瓶颈分析与解决方案

从零看清Node源码createServer和负载均衡整个过程

【项目实战】sass使用进阶篇(下)

【项目实战】sass使用基础篇(上)

最详细的从零开始配置 TypeScript 项目的教程

5 款非常好用的开源 Docker 工具

WebSocket 全面知识补全

7个处理JavaScript值为undefined的技巧

immutablejs 是如何优化我们的代码的?

Chrome 新功能尝鲜!— CSS Overview

又一个布局利器, CSS 伪类 :placeholder-shown

封装一个vue视频播放器组件

对于组件的可重用性,大佬给出来6个建议

学习 TS 不要错过的八个工具

Node 中的全链路式日志标记及处理

使用 Node 开发服务器项目时如何高效地打日志?

用TypeScript学设计模式(享元模式)

用TypeScript学设计模式(模板方法模式)

TypeScript 设计模式之适配器模式

用TypeScript学设计模式(观察者模式)

用TypeScript学设计模式(单例模式)

d93d471cb0aa502b97f3a9372a9d2015.png

81f91606985140ccb71f7181f8f4f9fc.png点在看的人特别帅/美 ee80f00b2bd0edcbb0cb79e16d61632c.gif

最后

以上就是高大便当为你收集整理的react down下来如何启动_如何实现一个 3D 效果的魔方的全部内容,希望文章能够帮你解决react down下来如何启动_如何实现一个 3D 效果的魔方所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(75)

评论列表共有 0 条评论

立即
投稿
返回
顶部