mac

# HTML5 陀螺仪

# 简介

陀螺仪又称角速度传感器,是不同于加速度计(G-sensor)的,它的测量物理量是偏转、倾斜时的转动角速度。在手机上,仅用加速度计没办法测量或重构出完整的 3D 动作,测不到转动的动作的。G-sensor 只能检测轴向的线性动作,这样就可以精确分析判断出使用者的实际动作。而后根据动作,可以对手机做相应的操作。

# 基础知识

  • deviceoriention (opens new window) 提供设备的物理方向信息,表示为一系列本地坐标系的旋角。

  • devicemotion 提供设备的加速信息。

  • compassneedscalibration 用于通知 web 站点使用罗盘信息校准上述事件。

# 相关文章

# 获取旋转角度

window.addEventListener(
  "deviceoriention",
  function(event) {
    // 处理 event.alpha、event.beta 以及 event.gamma
  },
  true
);
1
2
3
4
5
6
7
  • z 轴为轴,alpha 的作用域为 (0, 360)。

  • x 轴为轴,beta 的作用域为 (-180, 180)。

  • y 轴为轴,gamma 的作用域为 (-90, 90)。

mac

# 获取罗盘校准

window.addEventListener(
  "compassneedscalibration",
  function(event) {
    alert("您的罗盘需要校准");
    event.preventDefault();
  },
  true
);
1
2
3
4
5
6
7
8

# 获取重力加速度

window.addEventListener(
  "devicemotion",
  function(event) {
    // event.accleration
    // x(y, z):设备在 x(y, z) 方向上的移动加速度值
    // event.acclerationIncludingGravity
    // 考虑了重力加速度后,设备在 x(y, z) 方向上的移动加速度值
    // event.rotationRate
    // alpha, beta, gamma:设备绕 x, y, z 轴旋转的角度
  },
  true
);
1
2
3
4
5
6
7
8
9
10
11
12

# 摇一摇

var speed = 30;
var x = (y = z = lastX = lastY = lastZ = 0);

function deviceMotionHandler(eventData) {
  var acceleration = event.acclerationIncludingGravity,
    x = acceleration.x,
    y = acceleration.y,
    z = acceleration.z;
  if (
    Math.abs(x - lastX) > speed ||
    Math.abs(y - lastY) > speed ||
    Math.abs(z - lastZ) > speed
  ) {
    // 简单的摇一摇触发代码
    alert(1);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# CSS3 3D 模型

# 球面投影

在三维空间,每个 3D 模型都等同于一个多面体(即 3D 模型只能由不弯曲的平面组成)。你只能以一个正多边形表示圆:边越多,圆就越“完美”。

mac

mac

mac

# 触摸事件

# CSS 3D 库

var s = new C3D.Stage();
s.size(window.innerWidth, window.innerHeight)
  .material({
    color: "#cccccc",
  })
  .update();
document.getElementById("main").appendChild(s.el);

//创建1个立方体放入场景
var c = new C3D.Skybox();
c.size(1024)
  .position(0, 0, 0)
  .material({
    front: { image: "images/cube_FR.jpg" },
    back: { image: "images/cube_BK.jpg" },
    left: { image: "images/cube_LF.jpg" },
    right: { image: "images/cube_RT.jpg" },
    up: { image: "images/cube_UP.jpg" },
    down: { image: "images/cube_DN.jpg" },
  })
  .update();
s.addChild(c);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# JS 3D 库

这个库主要用来做一些视差效果。

<div id="scene">
  <div data-depth="0.2">My first Layer!</div>
  <div data-depth="0.6">My second Layer!</div>
</div>
1
2
3
4
var scene = document.getElementById("scene");
var parallaxInstance = new Parallax(scene);
1
2

# CSS 3D 魔方

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <style type="text/css">
            #box div
            {
                position: absolute;
                height: 160px;
                width: 160px;
                border: 3px solid #000;
                background: rgba(255,200,100,0.8);
                text-align: center;
                font-size: 130px;
            }

            #box
            {
                -webkit-animation-name: animation;
                -webkit-animation-timing-function: ease-in-out;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-duration: 8s;
                margin:80;
                -webkit-transform-style: preserve-3d;
                -webkit-transform-origin: 80px 80px 0;
            }

            #box .one
            {
                -webkit-transform: translateZ(80px);
            }
            #box .two
            {
                -webkit-transform: rotateX(-90deg) translateZ(80px);
            }
            #box .three
            {
                -webkit-transform: rotateY(90deg) rotateX(90deg) translateZ(80px);
            }
            #box .four
            {
                -webkit-transform: rotateY(180deg) rotateZ(90deg) translateZ(80px);
            }
            #box .five
            {
                -webkit-transform: rotateY(-90deg) rotateZ(90deg) translateZ(80px);
            }
            #box .six
            {
                -webkit-transform: rotateY(90deg) translateZ(80px);
            }

            @-webkit-keyframes animation
            {
                from,to{}
                16% { -webkit-transform: rotateY(-90deg);}
                33% { -webkit-transform: rotateY(-90deg) rotateZ(135deg);}
                50% { -webkit-transform: rotateY(225deg) rotateZ(135deg);}
                66% { -webkit-transform: rotateY(135deg) rotateX(135deg);}
                83% { -webkit-transform: rotateX(135deg);}
            }
        </style>

        <script type="text/javascript">
            function init()
            {
                document.addEventListener("touchstart", function(event){event.preventDefault();}, false);
            }
            window.onLoad = init();
        </script>

    </head>
    <body>
        <h2 align=center>CSS 3D基础</h1>
        <div id="view" style="width:160px; height:160px; margin:80px auto 0 auto;">
            <div id="box">
                <div class="one">A</div>
                <div class="two">B</div>
                <div class="three">C</div>
                <div class="four">D</div>
                <div class="five">E</div>
                <div class="six">F</div>
            </div>
        </div>
    </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

效果如下:

mac

# CSS 3D 球体

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="index.css" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <script type="text/javascript" src="index.js"></script>
  </head>
  <body>
    <div class="circle">
      <div class="box"></div>
    </div>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.circle {
  position: relative;
  margin: 20px auto;
  width: 200px;
  height: 200px;
}
.circle .box {
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}
.circle span {
  position: absolute;
  top: 85px;
  left: 85px;
  width: 30px;
  height: 30px;
}
.circle span:nth-child(2n + 1) {
  background: rgba(53, 226, 80, 0.8);
}
.circle span:nth-child(2n) {
  background: rgba(0, 160, 233, 0.8);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
半径:200px;
小元素:10px;
40排
**/

window.onload = function() {
  var letCircleMove = {
    ele: {
      circle: document.getElementsByClassName("circle")[0],
      box: document
        .getElementsByClassName("circle")[0]
        .getElementsByClassName("box")[0],
    },
    buildCircle: function() {
      // var circle = document.getElementsByClassName('circle')[0];
      // var box = circle.getElementsByClassName('box')[0];
      var num = 20;
      var r = 100;
      var arr = [];
      var l = -1;
      var str = "";
      var theta, phi; //theta 球半径与y的夹角,phi 小圆半径x的夹角
      for (var i = 0; i <= num; i++) {
        if (i > num / 2) {
          l = l - 2;
        } else {
          l = l + 2;
        }
        arr.push(l);
      }
      l = arr.length;
      theta = Math.PI / (l - 1);
      for (var i = 0; i < l; i++) {
        phi = (Math.PI * 2) / arr[i];
        for (var j = 0; j < arr[i]; j++) {
          var x = r * Math.sin(i * theta) * Math.sin(j * phi);
          var y = -r * Math.cos(i * theta);
          var z = r * Math.sin(i * theta) * Math.cos(j * phi);
          var transform = "translate3D(" + x + "px," + y + "px," + z + "px)";
          var rotate =
            "rotateY(" +
            j * phi +
            "rad)" +
            "rotateX(" +
            (Math.PI / 2 - i * theta) +
            "rad)";
          var style = 'style="transform:' + transform + " " + rotate + '"';
          span = "<span " + style + "></span>";
          str += span;
        }
      }
      this.ele.box.innerHTML = str;
    },
    addRock: function() {
      var d = 0;
      var alpha = (lastAlpha = gamma = 0),
        lastGamma = 5;
      var _this = this;
      function deviceMotionHandler(event) {
        gamma = event.gamma;
        alpha = event.alpha;
        // z = event.alpha;
        if (Math.abs(lastGamma - gamma) > d) {
          //||Math.abs(lastAlpha-alpha)>d
          // alert((gamma-lastGamma));
          _this.ele.box.style.transform =
            "translate3d(0, 0, 0) rotateY( " + gamma * 3 + "deg)";
          // alert(gamma);
          // _this.ele.box.style.transform = 'translate3d(0, 0, 0) rotateY( ' + (gamma-lastGamma)*5+ 'deg)';
        }

        lastGamma = gamma;
        lastAlpha = alpha;
      }
      window.addEventListener("deviceorientation", deviceMotionHandler, false);
    },
    move: function() {
      var startX = 0,
        startY = 0,
        endX = 0,
        endY = 0,
        x = 0,
        y = 0,
        _this = this;
      this.ele.box.addEventListener("touchstart", function(event) {
        event.preventDefault();
        var touch = event.targetTouches[0];
        startX = touch.pageX - x;
        startY = touch.pageY - y;
      });
      this.ele.box.addEventListener("touchmove", function(event) {
        event.preventDefault();

        var touch = event.targetTouches[0];
        endX = touch.pageX;
        endY = touch.pageY;
        y = endY - startY;
        x = endX - startX;
        _this.ele.box.style.transform =
          "translate3d(0, 0, 0) rotateX( " + y + "deg) rotateY( " + x + "deg)";
      });
      this.ele.box.addEventListener("touchend", function(event) {
        event.preventDefault();
        console.log(endY - startY, endX - startX);
        console.log(y, x);
      });
    },
    init: function() {
      var _this = this;
      this.buildCircle();
      this.move();
      this.addRock();
      var angleX = 0;
      // setInterval(function() {
      //     angleX++;
      //  _this.ele.box.style.transform = 'translate3d(0, 0, 0) rotateX(' + angleX + 'deg) rotateY(' + angleX + 'deg)';
      // }, 1);
    },
  };
  letCircleMove.init();
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

效果如下:

支持手机旋转感应、拖拽旋转。

mac

上次更新时间: 2023年11月30日 00:46:03