【问题标题】:Opposite of ease cubic-bezier function与简单三次贝塞尔函数相反
【发布时间】:2014-05-04 07:25:59
【问题描述】:

我有easecubic-bezier 函数:cubic-bezier(.25,.1,.25,1) (http://cubic-bezier.com/#.25,.1,.25,1)

我想要相反的。这是我要完成的工作的图形表示:

左边的图表是我所拥有的,右边图表的功能是我想要实现的。

【问题讨论】:

  • “对面”是什么意思? (这并不像听起来那么愚蠢的问题:贝塞尔曲线有几个方面,所有这些方面都可能在任何或所有点上都有一个“相反”)。
  • 哦,我的意思是,我想创建一个反向跟随曲线的 CSS 过渡。曲线应该是完全一样的,只是 0 现在在另一端。
  • CSS 三次贝塞尔曲线仅由两个中间控制点定义,第一个顶点固定在 (0,0),最后一个顶点固定在 (1,1)。 developer.mozilla.org/en-US/docs/Web/CSS/timing-function 按照这个定义,你不能逆着这条曲线走,对吗?
  • 我完全明白你的意思。我只需要使从 1,1 到 0,0 的相同路径与原来的路径相反。
  • 啊,这是一个关于 (0.5,0.5) 的直线向上旋转。贝塞尔曲线在线性变换下是不变的,因此您可以直接旋转所有点。我会用数学写一个答案。

标签: javascript css-transitions bezier cubic


【解决方案1】:

如果您想按照更新后的答案进行轮换,我们所要做的就是……嗯,就是这样。围绕 (0.5,0.5) 旋转 180 度或 π 弧度角。假设我们有一个编码为数组c 的曲线,其中包含四个点对象{ x:..., y... },那么我们可以实现这种旋转:

c = [ {x:...,y:...}, ..., ..., ...];

function halfUnitTurn(v) {
  // Note: it's actually 0.5 + ((v.x-0.5)*cos(pi) - (v.x-0.5)*sin(pi)),
  // (and x*sin + y*cos for the y:... part) but: cos(pi) is just -1, and
  // sin(pi) is 0, so things REALLY simplify!
  return {
    x: 0.5 - (v.x-0.5),
    y: 0.5 - (v.y-0.5)
  };
}

var rotated = c.map(function(p) { return halfUnitTurn(p); });

作为演示代码:http://jsfiddle.net/mokg77fq/

【讨论】:

  • 太棒了!!我真的很喜欢那种数学,但一旦我理解了,尤其是当我找到它的应用程序时! :) 你在不到 10 分钟内完成了我几个月内无法完成的事情哈哈:P 你可以做 v.x-.5 因为 cos(pi)1 嗯?编辑:哦,是的,我看到你在评论中说太酷了!谢谢你! :)
  • 是的,在四分之一、一半、四分之三和完整的旋转中,cos/sin 规则变为各种项 1、0 和 -1,因此它们使函数真正变得简单.
  • 我为我的轻松功能更新了小提琴,看起来很酷!谢谢你,兄弟! jsfiddle.net/mokg77fq/2
  • 在这里更新了,所以对像我这样的其他菜鸟来说很有意义:) jsfiddle.net/mokg77fq/3 并删除了 console.log
  • 为什么不只是x: 1-v.x 等?恕我直言,它还可以更轻松地查看发生了什么:只需翻转 x 和 y 而不是旋转(不必要的复杂性?)
【解决方案2】:

这是 Mike 的很棒的代码放入可重用函数中:

function reverseCssCubicBezier(cubicBezier) {
    var maxX = Math.max(cubicBezier[0].x, cubicBezier[1].x, cubicBezier[2].x, cubicBezier[3].x);
    var maxY = Math.max(cubicBezier[0].y, cubicBezier[1].y, cubicBezier[2].y, cubicBezier[3].y);
    var halfUnitTurn = function(v) {
        var tx = maxX/2, ty = maxY/2;
        return { x: tx - (v.x-tx), y: ty - (v.y-ty) };
    };
    var revd = cubicBezier.map(halfUnitTurn);
    return revd.reverse();
}

这是如何使用它:

var ease = [{x:0,y:0}, {x:.25,y:.1}, {x:.25,y:1}, {x:1,y:1}]; //cubic-bezier(.25, .1, .25, 1)
var ease_reversed = reverseCssCubicBezier(ease);
var ease_css_string = 'cubic_bezier(' + [ease[1].x, ease[1].y, ease[2].x, ease[2].y].join(', ') + ')';
var ease_reversed_css_string = 'cubic_bezier(' + [ease_reversed[1].x, ease_reversed[1].y, ease_reversed[2].x, ease_reversed[2].y].join(', ') + ')';

这会返回:

ease: [{x:0, y:0}, {x:0.25, y:0.1}, {x:0.25, y:1}, {x:1, y:1}]
ease-reversed: [{x:0, y:0}, {x:0.75, y:0}, {x:0.75, y:0.9}, {x:1, y:1}]

ease: cubic_bezier(0.25, 0.1, 0.25, 1)
ease-reversed: cubic_bezier(0.75, 0, 0.75, 0.9)

从图形上我们看到它的完美重叠,我将绿色的向左移动一点以显示它的完美重叠。

谢谢迈克!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-30
    • 2014-05-03
    • 1970-01-01
    • 2012-07-27
    • 2011-03-10
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多