¿Cómo hago que el último fotograma clave gire mi rectángulo a un ángulo de 35 grados usando popmotion pure?

enter image description here https://codepen.io/matthewharwood/pen/XWmRPaK?editors=1111

Html:

<div class="flex h-screen w-screen justify-center items-center">
  <div class="portal-b">
    <h1 class="left"></h1>
  </div>
</div>
<button class="trigger fixed z-10 left-0 top-0">
  B replace A
</button>

Css:

.portal-b {
  background: blue;
  width: 1px;
  height: 100px;
}

Js

const { easing, keyframes, styler } = window.popmotion;
const trigger = document.querySelector('.trigger');
const [_, portalB] = [document.querySelector('.portal-a'), document.querySelector('.portal-b')];
trigger.addEventListener('click', () => {
  const portalS = styler(portalB);
  keyframes({
  values: [
    { translateX: 0, scaleX: 0, rotateZ: 0, transformOrigin: 'left center' },
    { translateX: 200, scaleX: 400, rotateZ: 0, transformOrigin: 'left center' },
    { translateX: 200, scaleX: 400,  rotateZ: 90,  transformOrigin: 'left center' },
  ],
  duration: 3000,
  easings: easing.easeInOut,
}).start(portalS.set)
})
4
Matthew Harwood 28 abr. 2020 a las 07:46

2 respuestas

Aquí hay una solución que usa Popmotion Pure, usando las opciones de transformación incorporadas en lugar de una cadena de transformación: https://codepen.io/JeremyRoundill/pen/xxwYpdJ

Tienes razón en que el problema está basado en las matemáticas. Debe establecer las dimensiones de su rectángulo en su CSS para que sea lo que desea al final de la animación.

El problema es que Popmotion Pure aplicará rotateZ, antes de que aplique scaleX.

La solución:

El CSS utiliza el ancho para establecer las dimensiones deseadas al final de la animación, y se transforma para establecer las dimensiones deseadas al principio. Si configura width: 1px, su rotateZ se aplica antes de scaleX, lo que lo deja con un rombo (es decir, un rectángulo sesgado) en lugar de un rectángulo girado, según lo desee.

.portal-b {
  background: blue; 
  width: 300px; /* set the width to what you want at the end */
  height: 100px;
  transform: scaleX(0.001); /* transform the width to what you want at the start */
}

El Javascript solo tiene que desarmar nuestro transform: scaleX(0.001) de arriba. El segundo fotograma clave animará el rectángulo de ancho = 0.3px a ancho = 300px. Luego, el fotograma clave final gira esto a -35 grados alrededor del eje Z.

  values: [
  { translateX: 0, scaleX: 0.001, rotateZ: 0, transformOrigin: 'left center' },
    { translateX: 200, scaleX: 1, rotateZ: 0, transformOrigin: 'left center' },
    { translateX: 200, rotateZ: -35,  transformOrigin: 'center' },
  ],
2
Joundill 6 may. 2020 a las 21:54

Para este tipo de problema, recomiendo recorrer los valores en CSS simple en su navegador. Descubrí que la siguiente regla CSS proporcionaba el estado final que deseabas

.portal-b {
  background: blue;
  width: 1px;
  height: 100px;
  transform: translateX(200px) rotate(-35deg) scaleX(400);
}

Entonces todo lo que necesita es que sus fotogramas clave avancen allí, indicando explícitamente los valores que esperan así

  values: [
    { transform: "translateX(0px) rotate(0deg) scaleX(1)" },
    { transform: "translateX(200px) rotate(0deg) scaleX(400)" },
    { transform: "translateX(200px) rotate(-35deg) scaleX(400)"},
  ],

Aquí está tu pluma con mis cambios: https://codepen.io/kcerb/pen/wvKyWLv?editors=1111

5
KCE 6 may. 2020 a las 13:23