RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1231684
Accepted
DiD
DiD
Asked:2022-01-15 15:38:13 +0000 UTC2022-01-15 15:38:13 +0000 UTC 2022-01-15 15:38:13 +0000 UTC

使用 CSS 旋转对象。目前尚不清楚旋转方向如何工作

  • 772

如果我们查看图片,我们会看到立方体在其初始位置(带有一个点)跟随光标。当光标向左或向右移动时,立方体沿轴旋转Y。实际上,这就是我试图从多维数据集实现的目标。

旋转方向

但是当正方体以五个点翻转到一边时,左右移动时,正方体沿轴旋转Z。然后,将立方体旋转三个点,首先它向正确的方向旋转,在 gif 结束时它向相反的方向旋转。

如何使旋转方向可预测?例如,使立方体始终像在其原始位置一样旋转。

      let [action,angleX,angleY,map,touchX,touchY] = ["idle",0,0,new WeakMap,0,0];
      const dice = [first, second, third, fourth, fifth, sixth];
      
      dice.forEach(el => 
         map.set(el, [...document.styleSheets[0].rules]
          .find(rule=>`#${el.id}`==rule.selectorText).style.transform
         ));
const ontouchstart=e => {
  if(e.touches.length==1){
 [touchX,touchY]=[e.touches[0].pageX,e.touches[0].pageY];}
  else {
  [touchX,touchY]=[0,0];
}
};
const ontouchend =()=>[touchX,touchY]=[0,0];
const ontouchmove=e=>{
if(touchX&&touchY){
  [angleX,angleY]=[
  angleX-e.touches[0].pageY+touchY,
  angleY+e.touches[0].pageX-touchX]
  .map((a) => (a > 360 ? a - 360 : a < 0 ? a + 360 : a));
          dice.map(el => el.style.transform = 
            `rotateX(${angleX}deg) rotateY(${angleY}deg) ` + map.get(el));
        
  [touchX,touchY]=[e.touches[0].pageX,e.touches[0].pageY];
}
}
      const onmousedown = () => action = "rotate"; 
      const onmouseup = () => action = "idle";
    
      const onmousemove = e => {
        if (action == "rotate") {
          [angleX, angleY] = [ angleX - e.movementY, angleY + e.movementX ]
            .map((a) => (a > 360 ? a - 360 : a < 0 ? a + 360 : a));
          dice.map(el => el.style.transform = 
            `rotateX(${angleX}deg) rotateY(${angleY}deg) ` + map.get(el));
        }
      };
      
      Object.assign(document.body, {onmousedown, onmousemove,ontouchstart,ontouchmove});
      Object.assign(window, {onmouseup,ontouchend});
      * {
        box-sizing: border-box;
      }

      body,
      div {
        margin: 0;
        padding: 0;
      }

      body {
        width: 100vw;
        height: 100vh;
        perspective: 100vh;
        transform-style: preserve-3d;
        background-color: #333;
        display: flex;
        flex-direction: row;
        justify-content: space-between;
      }

      .face {
        background-color: #cccc;
        border-radius: 0;
        border: 3px solid #000;
        padding: 3vh;
        margin: 3px;
        display: flex;
        width: 25vh;
        height: 25vh;
        position: fixed;
        left: calc(50vw - 12.5vh);
        top: calc(50vh - 12.5vh);
        pointer-events: none;
        /* backdrop-filter: blur(2px); */
      }

      .column {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
      }

      .pip {
        background-color: #000;
        width: 4vh;
        height: 4vh;
        display: inline-block;
        border-radius: 4rem;
      }

      #first {
        justify-content: center;
        align-items: center;
        transform: translateZ(12.5vh);
      }

      #second {
        justify-content: space-between;
        transform: rotateX(90deg) translateZ(-12.5vh);
      }

      #second .pip:nth-of-type(2) {
        align-self: flex-end;
      }

      #third {
        justify-content: space-between;
        align-items: center;
        transform: rotateY(90deg) translateZ(-12.5vh);
      }

      #third .pip:nth-of-type(1) {
        align-self: flex-start;
      }

      #third .pip:nth-of-type(3) {
        align-self: flex-end;
      }

      #fourth {
        justify-content: space-between;
        transform: rotateY(180deg) translateZ(12.5vh);
      }

      #fifth {
        justify-content: space-between;
        justify-content: space-between;
        transform: rotateX(90deg) translateZ(12.5vh);
      }

      #fifth .column:nth-of-type(2) {
        align-self: center;
      }

      #sixth {
        justify-content: space-between;
        transform: rotateY(90deg) translateZ(12.5vh);
      }
    <div id="first" class="face"><span class="pip"></span></div>
    <div id="second" class="face">
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
    <div id="third" class="face">
      <span class="pip"></span>
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
    <div id="fourth" class="face">
      <div class="column">
        <span class="pip"></span> <span class="pip"></span>
      </div>
      <div class="column">
        <span class="pip"></span> <span class="pip"></span>
      </div>
    </div>
    <div id="fifth" class="face">
      <div class="column">
        <span class="pip"></span> <span class="pip"></span>
      </div>
      <div class="column"><span class="pip"></span></div>
      <div class="column">
        <span class="pip"></span> <span class="pip"></span>
      </div>
    </div>

    <div id="sixth" class="face">
      <div class="column">
        <span class="pip"></span> <span class="pip"></span>
        <span class="pip"></span>
      </div>
      <div class="column">
        <span class="pip"></span> <span class="pip"></span>
        <span class="pip"></span>
      </div>
    </div>

css3
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    DiD
    2022-01-16T03:51:23Z2022-01-16T03:51:23Z

    该解决方案并不完美,但似乎有效。基于旋转矩阵的保存。

    let [action,touchX,touchY] = [0,0,0];
      const {sign, hypot} = Math;
    
      const [onmousedown, onmouseup, ontouchstart] = [() => action = 1, () => [action,touchX,touchY] = [0,0,0],
        (e) => [action,touchX,touchY] = e.touches.length == 1 ? [1,e.touches[0].pageX,e.touches[0].pageY] : [0,0,0] ];
      const rotate = (x,y) => {
        const t = getComputedStyle(surface).transform;
        surface.style.transform = `rotate3d(${sign(-y)},${sign(x)},0,${hypot(x,y)}deg) `+('none'==t?'':t);
      }
      const onmousemove = e => {
        if (action) rotate(e.movementX,e.movementY);
      };
      const ontouchmove = e => {
        if(action){ 
          rotate(e.touches[0].pageX-touchX,e.touches[0].pageY-touchY);
          [touchX,touchY]=[e.touches[0].pageX,e.touches[0].pageY];
        }
      }
      Object.assign(window, {onmousedown, onmousemove, onmouseup, ontouchstart,
         ontouchend: onmouseup, ontouchcancel: onmouseup, ontouchmove});
    * { box-sizing: border-box; }
    body, div, p, i { margin: 0; padding: 0; }
    body{ background-color: #333; }
    
    body, #surface { width: 100vw; height: 100vh; perspective: 50vh;  transform-style: preserve-3d; }
    #surface{ perspective: 1000vh;  }
    .face {
      background-color: #cccc; border: 3px solid #000;
      padding: 3vh; margin: 3px; width: 25vh; height: 25vh;
      left: calc(50vw - 12.5vh); top: calc(50vh - 12.5vh);
      display: flex; position: fixed;
    }
    
    #surface, .face, p, i { pointer-events: none; }
    
    p { display: flex; flex-direction: column; justify-content: space-between; }
    i { background-color: #000; width: 4vh; height: 4vh; display: inline-block; border-radius: 4rem; }
    #first { justify-content: center; align-items: center; transform: translateZ(12.5vh);}
    #second { justify-content: space-between; transform: rotateX(90deg) translateZ(-12.5vh); }
    #second i:nth-of-type(2) { align-self: flex-end;}
    #third { justify-content: space-between; align-items: center; transform: rotateY(90deg) translateZ(-12.5vh); }
    #third i:nth-of-type(1) { align-self: flex-start;}
    #third i:nth-of-type(3) { align-self: flex-end;}
    #fourth { justify-content: space-between; transform: rotateY(180deg) translateZ(12.5vh); }
    #fifth { justify-content: space-between; transform: rotateX(90deg) translateZ(12.5vh);}
    #fifth p:nth-of-type(2) { align-self: center; }
    #sixth { justify-content: space-between; transform: rotateY(90deg) translateZ(12.5vh); }
    <div id="surface">
      <div id="first" class="face"><i></i></div>
      <div id="second" class="face"><i></i><i></i></div>
      <div id="third" class="face"><i></i><i></i><i></i></div>
      <div id="fourth" class="face"><p><i></i><i></i></p><p><i></i><i></i></p></div>
      <div id="fifth" class="face"><p><i></i><i></i></p><p><i></i></p><p><i></i><i></i></p></div>
      <div id="sixth" class="face"><p><i></i><i></i><i></i></p><p><i></i><i></i><i></i></p></div>
    </div>

    • 2

相关问题

  • 如何用线条绘制立体图并进行动画处理?

  • 如何将心形图像添加到按钮?

  • 如何布置菜单

  • 如何将转换应用于按钮内的文本?

  • 如何在网格中制作滚动项目?

  • 图片与文本重叠的矩形

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5