Противоположность простой кубической функции Безье

У меня есть функция кубического Безье ease: cubic-bezier(.25,.1,.25,1) (http://cubic-bezier.com/#.25,.1,.25,1)

Я хочу противоположного этому. Вот графическое представление того, что я пытаюсь выполнить:

График слева — это то, что у меня есть, а функция для графика справа — это то, чего я пытаюсь добиться.

Image


person Noitidart    schedule 04.05.2014    source источник
comment
Что вы имеете в виду под противоположным? (это не такой глупый вопрос, как кажется: у кривых Безье есть несколько аспектов, каждый из которых может иметь «противоположность» в любой или во всех точках).   -  person Mike 'Pomax' Kamermans    schedule 04.05.2014
comment
О, я имею в виду, что я хочу создать переход css, который следует кривой в обратном направлении. Кривая должна быть точно такой же, просто время 0 теперь на другом конце.   -  person Noitidart    schedule 05.05.2014
comment
Кубические кривые Безье CSS определяются только двумя средними контрольными точками, причем первая вершина фиксируется в точке (0,0), а последняя — в точке (1,1). developer.mozilla.org/en-US/docs/Web/ CSS/функция синхронизации Согласно этому определению, вы не можете следовать кривой в обратном направлении, не так ли?   -  person hkrish    schedule 07.05.2014
comment
Я полностью понимаю, что ты имеешь в виду, чувак. Мне просто нужно сделать тот же путь от 1,1 до 0,0 противоположным тому, что было.   -  person Noitidart    schedule 07.05.2014
comment
Привет, @Mike'Pomax'Kamermans. Я обновил пост, добавив графику, показывающую, что я пытаюсь получить. Я не мог понять, моя математика отстой :(   -  person Noitidart    schedule 15.10.2014
comment
Привет, @hkrish обновил пост, добавив графику, показывающую, что я пытаюсь получить. Я не мог понять, моя математика отстой :(   -  person Noitidart    schedule 15.10.2014
comment
Ах, это прямое вращение вверх примерно (0,5,0,5). Кривые Безье инвариантны относительно линейных преобразований, поэтому вы можете буквально просто вращать все точки. Я напишу ответ с математикой для этого.   -  person Mike 'Pomax' Kamermans    schedule 15.10.2014
comment
Спасибо, сэр!! Я сильно терплю неудачу в математике :( Кстати, ваша функция разделения была такой потрясающей! Я немного модифицировал ее, чтобы она соответствовала элементарной ячейке для использования в css3 :): stackoverflow.com/a/26373980/1828637   -  person Noitidart    schedule 15.10.2014


Ответы (2)


Если вы хотите сделать поворот, как в вашем обновленном ответе, все, что нам нужно сделать, это ... ну, это. Повернуть вокруг (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/

person Mike 'Pomax' Kamermans    schedule 15.10.2014
comment
Так круто!! Мне очень нравится эта математика, хотя, когда я ее понимаю, особенно когда я нахожу для нее применение! :) Ты сделал за 10 минут то, что я не мог сделать месяцами, ха-ха :P, ты можешь просто сделать v.x-.5, потому что cos(pi) это 1, да? редактировать: о да, я вижу, вы сказали это в комментарии так здорово! спасибо мужик!! :) - person Noitidart; 15.10.2014
comment
да, на четверть, половину, три четверти и полные обороты правила cos/sin становятся различными членами 1, 0 и -1, поэтому они делают функции действительно простыми. - person Mike 'Pomax' Kamermans; 15.10.2014
comment
я обновил скрипку для моей функции облегчения, так круто выглядит! Спасибо, мужик! jsfiddle.net/mokg77fq/2 - person Noitidart; 15.10.2014
comment
обновлено здесь, так что это имеет смысл для других новичков, таких как я :) jsfiddle.net/mokg77fq/3 и удалил это console.log - person Noitidart; 15.10.2014
comment
Почему бы не просто x: 1-v.x и т. д.? Это также облегчает понимание того, что происходит ИМХО: просто переворачивая x и y, а не вращая (ненужная сложность?) - person Henrik Christensen; 08.05.2015
comment
в основном потому, что это снизит образовательную ценность этого ответа, скрывая тот факт, что мы меняем, слишком рано оптимизируя. Никто не говорил, что вы должны скопировать и вставить ответ, а затем никогда не пытаться его улучшить, замена 0.5 - (x-0.5) на 1-X является очевидной оптимизацией, но, конечно, не той, которая фактически улучшит производительность до такой степени, что упрощенная ротация использует плохой код =) - person Mike 'Pomax' Kamermans; 08.05.2015

Вот замечательный код Майка, помещенный в повторно используемую функцию:

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)

Графически мы видим его идеальное перекрытие, я немного сдвинул зеленый влево, чтобы показать его идеальное перекрытие.

Спасибо, Майк!

person Noitidart    schedule 15.10.2014