Как добавить слушателя событий в анимированное вращение преобразования? - PullRequest
0 голосов
/ 03 сентября 2018

, поэтому у меня 2-х сторонняя карта, и каждый раз, когда карта поворачивается на 180 градусов, она меняет ценность лица.

Одна вещь, о которой я подумал, это добавить прослушиватель событий в поворот преобразования анимации, но кажется, что это невозможно?

Вот скрипка: https://jsfiddle.net/4qovckd7/

То, чего я пытаюсь добиться, - это изменять значение лицевой карты (текст FRONT и BACK) каждые 180 градусов. Уже пытались использовать jquery animate step и progress, но я не могу получить правильное значение прогресса (возвращает только 0 или 1, что является началом и концом анимации)

$('.card').on('swipeleft swiperight', function (event) {
  var spinValue = 5 * 180;

  if (event.handleObj.type == 'swipeleft')
    spinValue = spinValue * -1;

  $(this).animate({
    borderSpacing: spinValue
  }, {
    step: function (now, fx) {
      $(this).css('transform', 'rotateY(' + now + 'deg)');
    },
    progress: function (animation, progress, msRemaining) {
      //supposedly to get the progress value here
    }
  });
})

Любые идеи будут оценены. Спасибо!

1 Ответ

0 голосов
/ 05 сентября 2018

Ваш удар и анимация сломаны. Если вы проведете пальцем влево несколько раз, вы увидите, что переход не может следить за текущим состоянием поворота градусов - с новым входом.

Решение

  • Используйте переменную для хранения текущего Исходного поворота градусов (-N° … 0° … N°) - это означает, что независимо от того, сколько раз вы проведете пальцем, число будет увеличиваться (или уменьшаться) ) к текущей организации. градусов.
  • Нормализация Ваш Исходный спад до Относительное вращение градусов с использованием этой формулы:
deg = orgDeg % 360          // This still has negatives: -360° … 0° … 360°
if ( deg < 0 ) deg += 360   // Always 0° … 360°. Now you can rotateY( deg )
  • Получить текущее лицо в двоичном виде 0, 1.
    Как вы могли заметить, лицо (скажем, передняя сторона) не начинается с 0 градусов!
    Он начинает отображаться в -90° (теперь нормализован до 270). То же самое касается задней поверхности. Начинается «Я видна!» Путешествие на +90°. Если вы не последуете, представьте, что вы хотите менять лицо на случайное изображение каждый ход, было бы глупо делать это, когда поверхность полностью обращена вперед.
    Итак, ход начинается, когда края самолета обращены вперед! Вот математика:
face = round( ((deg + 90) % 360) / 360 )    // 0, 1, 0, 1, 0…

Сделайте вещи немного более реалистичными

Перспектива

Добавление perspective: 1000px; к родителю, помогает визуализировать преобразования карт в 2D3D .

Анимация

Ослабление swing или linear (по умолчанию jQuery .animate() замедления) не подходят как хороший easeOutCubic, который лучше всего описывает импульс роста к естественной остановке .
Если вы не хотите включать всю библиотеку пользовательского интерфейса jQuery, вы можете расширить $.easing

// https://github.com/gdsmith/jquery.easing
jQuery.extend(jQuery.easing, {
    easeOutCubic :function(x){return 1-Math.pow(1-x,3)}
});

Скорость

Улучшите UX, добавив скорость прокрутки к вращению карты . Вот функция:

function swipeSpeed(e) {
    var st = e.swipestart,
        sp = e.swipestop,
        time = sp.time - st.time,
        a = st.coords[0] - st.coords[1],
        b = sp.coords[0] - sp.coords[1],
        dist = Math.sqrt( a*a + b*b );
    return dist / time;
}

Очистить очередь анимации

Для воспроизведения проведите пальцем вперед и назад , вам нужно очистить очередь анимации, используя .stop():

.stop().animate({ 

Достаточно говорить

// https://github.com/gdsmith/jquery.easing
jQuery.extend(jQuery.easing, {
  easeOutCubic: function(x) {
    return 1 - Math.pow(1 - x, 3)
  }
});


function swipeSpeed(e) {
  var st = e.swipestart,
    sp = e.swipestop,
    time = sp.time - st.time,
    a = st.coords[0] - st.coords[1],
    b = sp.coords[0] - sp.coords[1],
    dist = Math.sqrt(a * a + b * b);
  return dist / time;
}


var cats = [ // cause we luw catz
  "https://i.stack.imgur.com/bBGtG.jpg",
  "https://i.stack.imgur.com/UzdQz.jpg",
  "https://i.stack.imgur.com/MJl4g.jpg",
  "https://i.stack.imgur.com/7QAyw.jpg",
  "https://i.stack.imgur.com/updEN.jpg",
];

var $info = $("#info");
$(".card-wrapper").each(function() {

  var $card = $(this).find(".card");
  var $back = $(this).find(".card-back");
  var _d = 0;

  $(this).on({
    'swipeleft swiperight': function(e) {

      var isLeft = e.type === 'swipeleft';
      var sw = Math.min(swipeSpeed(e), 10); // Math.min to prevent excessive momentum
      var s = 180 * sw;
      var spinDegs = _d + (isLeft ? -s : s);
      spinDegs -= spinDegs % 180; // (optional) end rotation as full-face

      $card.stop().animate({
        sD: spinDegs
      }, {
        duration: 700 * sw,
        easing: "easeOutCubic",
        step: function(d) {
          _d = d; // store now for later use
          var deg = (d %= 360) < 0 ? d + 360 : d; // Degrees Normalization
          $(this).css('transform', 'rotateY(' + deg + 'deg)'); // Rotate

          // Extra fun!
          var face = Math.round(((deg + 90) % 360) / 360);
          var idx = Math.abs(Math.round(((_d + 90) / 360)) % cats.length);
          $back.css({
            backgroundImage: `url('${cats[idx]}')`
          });
          // Show info
          $info.html(`
            Face: ${ face }<br> 
            Org Degrees: ${ _d }<br>
            Degrees: ${ deg }<br>
            Cat image: ${ idx }
          `);

        }
      });
    }
  });
});
/* Flipping cards */

.card-wrapper {
  width: 200px;
  height: 200px;
  margin: 0 auto;
  perspective: 1000px;
}

.card {
  position: relative;
  width: 200px;
  height: 200px;
  transform-style: preserve-3d;
}

.card * {
  pointer-events: none;
}

.card .card-front,
.card .card-back {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  top: 50%;
  left: 50%;
  backface-visibility: hidden;
  font-size: 25px;
  color: white;
  background: 50% 50%/cover transparent none no-repeat;
}

.card .card-front {
  transform: translate(-50%, -50%);
  background-color: blue;
}

.card .card-back {
  transform: translate(-50%, -50%) rotateY(180deg);
  background-color: red;
}

#info {
  position: absolute;
  pointer-events: none;
  top: 0;
  left: 0;
}


/* Should all go to top but yeah I'll keep it below-the-fold for this demo*/


/* QuickReset */

* {
  margin: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  font: 14px/1.4 sans-serif;
}


/* jQueryMobile resets */

[data-role="page"] {
  outline: none;
}

.ui-loader {
  display: none !important;
}
<div class="card-wrapper">
  <div class="card">
    <div class="card-front"><span class="card-content">SWIPE</span></div>
    <div class="card-back"><span class="card-content">:)</span></div>
  </div>
</div>

<div id="info"></div>


<script src="//code.jquery.com/jquery-1.11.3.js"></script>
<script src="//code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.js"></script>
...