transform.mjs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. function buildProjectionTransform(delta, treeScale, latestTransform) {
  2. let transform = "";
  3. /**
  4. * The translations we use to calculate are always relative to the viewport coordinate space.
  5. * But when we apply scales, we also scale the coordinate space of an element and its children.
  6. * For instance if we have a treeScale (the culmination of all parent scales) of 0.5 and we need
  7. * to move an element 100 pixels, we actually need to move it 200 in within that scaled space.
  8. */
  9. const xTranslate = delta.x.translate / treeScale.x;
  10. const yTranslate = delta.y.translate / treeScale.y;
  11. const zTranslate = latestTransform?.z || 0;
  12. if (xTranslate || yTranslate || zTranslate) {
  13. transform = `translate3d(${xTranslate}px, ${yTranslate}px, ${zTranslate}px) `;
  14. }
  15. /**
  16. * Apply scale correction for the tree transform.
  17. * This will apply scale to the screen-orientated axes.
  18. */
  19. if (treeScale.x !== 1 || treeScale.y !== 1) {
  20. transform += `scale(${1 / treeScale.x}, ${1 / treeScale.y}) `;
  21. }
  22. if (latestTransform) {
  23. const { transformPerspective, rotate, rotateX, rotateY, skewX, skewY } = latestTransform;
  24. if (transformPerspective)
  25. transform = `perspective(${transformPerspective}px) ${transform}`;
  26. if (rotate)
  27. transform += `rotate(${rotate}deg) `;
  28. if (rotateX)
  29. transform += `rotateX(${rotateX}deg) `;
  30. if (rotateY)
  31. transform += `rotateY(${rotateY}deg) `;
  32. if (skewX)
  33. transform += `skewX(${skewX}deg) `;
  34. if (skewY)
  35. transform += `skewY(${skewY}deg) `;
  36. }
  37. /**
  38. * Apply scale to match the size of the element to the size we want it.
  39. * This will apply scale to the element-orientated axes.
  40. */
  41. const elementScaleX = delta.x.scale * treeScale.x;
  42. const elementScaleY = delta.y.scale * treeScale.y;
  43. if (elementScaleX !== 1 || elementScaleY !== 1) {
  44. transform += `scale(${elementScaleX}, ${elementScaleY})`;
  45. }
  46. return transform || "none";
  47. }
  48. export { buildProjectionTransform };