【问题标题】:Rotate element based on touch event根据触摸事件旋转元素
【发布时间】:2012-12-01 14:04:35
【问题描述】:

我正在寻找一些指导和/或示例来创建一种触摸对象并旋转它的方法。假设我们有一个圆圈的图像,我希望能够触摸一个点,围绕该圆圈拖动并在我的手指移动时操纵它旋转。

我找到了很多关于旋转的教程:

我只需要将触摸部分合并。

以前有人做过,或者可以解释一下吗?

【问题讨论】:

    标签: javascript html canvas rotation


    【解决方案1】:

    您可以简单地将触摸的旋转映射到元素的transform: rotate(Ndeg) CSS。

    并非所有支持触摸的浏览器都在event 对象上提供rotate 属性,因此您可以通过数学计算得出值。

    document
    .getElementById("some-element")
    .addEventListener("touchmove", function(event) {
        var rotation = event.rotation;
    
        // This isn't a fun browser!
        if ( ! rotation) {
             rotation = Math.arctan2(event.touches[0].pageY - event.touches[1].pageY,
                   event.touches[0].pageX - event.touches[1].pageX) * 180 / Math.PI;
        }
    
        // Take into account vendor prefixes, which I haven't done.
        this.style.transform = "rotate(" + rotation + "deg)":
    });
    

    如果您希望用户能够多次旋转它,您还需要存储之前的旋转值并根据它调整这个值。 :)

    【讨论】:

    • 我在触摸事件中找不到任何旋转属性。如何访问它?
    【解决方案2】:

    鼠标/触摸拖动时旋转元素

    这是一个关于如何拖动-旋转元素的完整示例:

    存储起始角度,即坐标处的相对角度减去当前角度。
    按鼠标移动 XY 坐标角度的差值(增量)旋转从中心减去起始角度。

    const rotate = (EL) => {
      
      let ang = 0; // All angles are expressed in radians
      let angStart = 0;
      let isStart = false;
    
      const angXY = (ev) => {
        const bcr = EL.getBoundingClientRect();
        const radius = bcr.width / 2;
        const { clientX, clientY } = ev.touches ? ev.touches[0] : ev;
        const y = clientY - bcr.top - radius;  // y from center
        const x = clientX - bcr.left - radius; // x from center
        return Math.atan2(y, x);
      };
    
      const mousedown = (ev) => {
        isStart = true;
        angStart = angXY(ev) - ang;
      };
    
      const mousemove = (ev) => {
        if (!isStart) return;
        ev.preventDefault();
        ang = angXY(ev) - angStart;
        EL.style.transform = `rotateZ(${ang}rad)`;
      };
    
      const mouseup = () => {
        isStart = false; 
      };
    
      EL.addEventListener("mousedown", mousedown);
      document.addEventListener("mousemove", mousemove);
      document.addEventListener("mouseup", mouseup);
    };
    
    document.querySelectorAll(".rotate").forEach(rotate);
    .rotate {
      border-radius: 50%;
      width: 180px;
      cursor: ns-resize;
    }
    <img class="rotate" src="https://www.gravatar.com/avatar/1771ce957b38fbb7f9bb01f58b89fd3f?s=328&d=identicon&r=PG" alt="Wheel image">
    <img class="rotate" src="https://i.stack.imgur.com/qCWYU.jpg?s=328&g=1" alt="Wheel image">

    【讨论】:

      【解决方案3】:

      您需要考虑在您的canvas 上实现MouseDownMouseUpMouseMove 事件侦听器,因为与触摸屏的“触摸”交互只不过是一种花哨的鼠标移动。

      MouseDownMouseUp 可用于查找用户是否在canvas 上拖动。 MouseMove 是您需要放置旋转处理逻辑的位置。剩下的就是实现了:

      /* Borrowed from http://www.marceloduende.com/blog/?p=25 */ function addCrossBrowseEventListener(myElement, myEvent, myFunction) { if(myElement.addEventListener){ myElement.addEventListener(myEvent, myFunction, false); return true; } else { myElement.attachEvent('on'+myEvent, myFunction); return true; }

      myElement 是画布的 DOM 元素,myEvent 是要为其添加侦听器的事件的名称,myFunction 是负责处理事件逻辑的函数的名称。

      或者,您可以使用 jQuery 来完成大部分工作,因为它有许多更简洁的事件处理方法。

      【讨论】:

      • 谢谢贾斯汀——一切都说得通,不幸的是我没有足够的经验来独自完成这一切。你知道我可以逆向工程的任何例子吗?谢谢
      • 我不确定 OP 是否需要移动事件,他们说的是“触摸”而不是“点击”,所以我倾向于认为这是针对触摸屏设备上的某些东西。在这种情况下,事件将是“touchstart”和“touchmove”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 2013-12-26
      • 2012-07-15
      相关资源
      最近更新 更多