【问题标题】:Famo.us Scrollview + TouchSync - Make ScrollView/TouchSync Aware of rotateZ TransformsFamo.us Scrollview + TouchSync - 让 ScrollView/TouchSync 了解 rotateZ 变换
【发布时间】:2015-01-29 22:33:00
【问题描述】:

编辑:已解决 - 查看新代码摘录

我有一个嵌套在 ContainerSurface 中的 Famo.us 滚动视图。 ContainerSurface 在多点触控旋转手势上旋转,但一旦旋转,滚动视图的滚动方向就不会相对于旋转表面及其子项的修饰符保持不变。

【问题讨论】:

    标签: javascript touch scrollview famo.us


    【解决方案1】:

    鉴于当前的实现,这是不可能的,问题在于TouchSync

    要完成这样的事情,您需要编写一个自定义的 RotatedTouchSync 来“感知”旋转。这样,当 ScrollView 从 move 事件中接收到 delta 时,自定义的 TouchSync 已经将其转换为 ScrollView 可以理解的坐标系。

    【讨论】:

    • 此外,除了 0 或 1(垂直或水平)之外,似乎无法在滚动视图上定义“方向”。
    • 除非这是您开发的,否则 TouchSync 不知道。即使是这样,您也需要将坐标转换为标准化坐标系(旋转 x/y 轴)。正确定义方向的唯一方法是 x 或 y (0/1)。
    • 感谢@Joseph - 我已经创建了自定义 RoatableTouchSync 和自定义滚动视图的草稿。就像你说的,我需要做的就是在 TouchSync 中转换增量。
    【解决方案2】:

    我已经使用基本示例设置了 codepen,您可以在其中看到 ScrollView 将如何工作,除非您创建一个自定义 TouchSync 来为 ScrollView 提供转换后的 delta(正如@Joseph Carroll 所述)。

    我通过使用修改后的 _handleMove 方法创建 RotatableTouchSync 来完成此修复:

    function _handleMove(data) {
            var history = data.history;
    
            var currHistory = history[history.length - 1];
            var prevHistory = history[history.length - 2];
    
            var distantHistory = history[history.length - this.options.velocitySampleLength] ?
              history[history.length - this.options.velocitySampleLength] :
              history[history.length - 2];
    
            var distantTime = distantHistory.timestamp;
            var currTime = currHistory.timestamp;
    
            // Begin custom code -----------------------------------------------------------------------------
            var diffX, diffY, velDiffX, velDiffY;
    
            if (this.options.rotateAngle) {
    
                // Convert currHistory, prevHistory, distantHistory x,y points to quadrants because our formula only works when origin is 0,0
                var absCenter = [window.innerWidth/2, window.innerHeight/2];
    
                var currPrime = _calcCoordsByAngle([currHistory.x - absCenter[0], currHistory.y - absCenter[1]], this.options.rotateAngle);
    
                var prevPrime = _calcCoordsByAngle([prevHistory.x - absCenter[0], prevHistory.y - absCenter[1]], this.options.rotateAngle);
    
                var distPrime = _calcCoordsByAngle([distantHistory.x - absCenter[0], distantHistory.y - absCenter[1]], this.options.rotateAngle);
    
                // Converted coordinates back to normal points (clientX, clientY points)
                var convertedCurrX = currPrime.x + absCenter[0];
                var convertedCurrY = currPrime.y + absCenter[1];
    
                var convertedPrevX = prevPrime.x + absCenter[0];
                var convertedPrevY = prevPrime.y + absCenter[1];
    
                var convertedDistX = distPrime.x + absCenter[0];
                var convertedDistY = distPrime.y + absCenter[1];
    
    
                // Calculate diff like normal
                diffX = convertedCurrX - convertedPrevX;
                diffY = convertedCurrY - convertedPrevY;
    
    
                velDiffX = convertedCurrX - convertedDistX;
                velDiffY = convertedCurrY - convertedDistY;
    
            }
           // If the custom option for rotate angle isn't set, calculate as normal
            else {
                diffX = currHistory.x - prevHistory.x;
                diffY = currHistory.y - prevHistory.y;
    
                velDiffX = currHistory.x - distantHistory.x;
                velDiffY = currHistory.y - distantHistory.y;
            }
    

    修改后的_handleMove调用了一个名为_calcCoordsByAngle的自定义方法:

    /**
     *  Used to calculate a coordinate set
     *  at a given rotation
     *  See: http://math.stackexchange.com/questions/384186/calculate-new-positon-of-rectangle-corners-based-on-angle
     *  @method _calcCoordsByAngle
     *  @param {Array} oldCoords An [x,y] set of coordinates
     *  @param {number} phi The angle to move by
     *  @return {Array} The newly converted coordinates
     */
    function _calcCoordsByAngle(oldCoords, phi) {
        var newCoords = {};
        newCoords.x = (oldCoords[0] * Math.cos(-phi)) - (oldCoords[1] * Math.sin(-phi));
        newCoords.y = (oldCoords[1] * Math.cos(-phi)) + (oldCoords[0] * Math.sin(-phi));
    
        return newCoords;
    }
    

    从那里,可以使用此自定义 RotatableTouchSync 替代自定义 ScrollView 上的 TouchSync - 只需确保随时传入/设置 RotatableTouchSync 上的“rotateAngle”选项Z 轴旋转变化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多