| <!DOCTYPE html> <!-- webkit-test-runner [ SpatialPortalEnabled=true ModelElementEnabled=true ModelProcessEnabled=true allowTestOnlyIPC=true ] --> | |
| <html> | |
| <script src="../resources/testharness.js"></script> | |
| <script src="../resources/testharnessreport.js"></script> | |
| <script src="../model-element/resources/model-utils.js"></script> | |
| <script src="resources/spatial-portal-utils.js"></script> | |
| <style> | |
| .portal { spatial: portal; width: 40cm; height: 20cm; } | |
| </style> | |
| <body> | |
| <script> | |
| 'use strict'; | |
| internals.disableModelLoadDelaysForTesting(); | |
| const flatRectangle = "flat-rectangle.usdz"; | |
| const centeredCube = "2x2x2-center.usdz"; | |
| const offsetCube = "2x2x2-at-100x50x200.usdz"; | |
| const rotation = new DOMMatrixReadOnly().rotateAxisAngle(0, 1, 0, 45); | |
| promise_test(async t => { | |
| const autoTransform = await resolvedTransformForPortal(t, flatRectangle); | |
| const scaledTransform = await resolvedTransformForPortal(t, flatRectangle, "scale3d(2, 2, 2) auto"); | |
| assert_3d_matrix_approx_equals(scaledTransform, autoTransform); | |
| }, `a uniform scale before auto is cancelled out by the auto-fit`); | |
| promise_test(async t => { | |
| const smallPortal = { width: "10cm", height: "5cm" }; | |
| const autoThenRotation = await resolvedTransformForPortal(t, centeredCube, "auto rotate3d(0, 1, 0, 90deg)", smallPortal); | |
| const rotationThenAuto = await resolvedTransformForPortal(t, centeredCube, "rotate3d(0, 1, 0, 90deg) auto", smallPortal); | |
| assert_3d_matrix_approx_equals(autoThenRotation, rotationThenAuto); | |
| }, `a rotation that doesn't impact the bounding box has the same effect before or after auto`); | |
| promise_test(async t => { | |
| const autoTransform = await resolvedTransformForPortal(t, offsetCube); | |
| const scaledTransform = await resolvedTransformForPortal(t, offsetCube, "auto scale3d(2, 2, 2)"); | |
| assert_3d_matrix_approx_equals(scaledTransform, autoTransform.scale3d(2)); | |
| }, `a scale listed after auto applies to the content inside the auto-fit`); | |
| promise_test(async t => { | |
| const noneTransform = await resolvedTransformForPortal(t, offsetCube, "none"); | |
| const rotatedTransform = await resolvedTransformForPortal(t, offsetCube, "rotate3d(0, 1, 0, 45deg)"); | |
| assert_3d_matrix_approx_equals(rotatedTransform, noneTransform.multiply(rotation)); | |
| }, `a transform list without auto applies to the content inside the 1:1 unit mapping`); | |
| promise_test(async t => { | |
| const withoutTrailingList = await resolvedTransformForPortal(t, offsetCube, "scale3d(2, 2, 1) auto"); | |
| const withTrailingList = await resolvedTransformForPortal(t, offsetCube, "scale3d(2, 2, 1) auto rotate3d(0, 1, 0, 45deg)"); | |
| assert_3d_matrix_approx_equals(withTrailingList, withoutTrailingList.multiply(rotation)); | |
| }, `a list after auto does not change what the auto-fit measured`); | |
| promise_test(async t => { | |
| const autoTransform = await resolvedTransformForPortal(t, offsetCube); | |
| const portal = createPortal(t, { portalTransform: "auto translateX(50%)" }); | |
| portal.style.padding = "10px"; | |
| portal.style.border = "5px solid transparent"; | |
| const model = appendModel(portal, offsetCube); | |
| await model.ready; | |
| const translated = await waitForPortalTransform(portal, portalTransformIsResolved, "translated transform"); | |
| assert_approx_equals((translated.m41 - autoTransform.m41) / (portal.getBoundingClientRect().width / 2), 1, epsilon, "the translation is in CSS pixels"); | |
| }, `a length after auto displaces the content in CSS pixels`); | |
| promise_test(async t => { | |
| const tinyPortal = { width: "1cm", height: "1cm" }; | |
| const autoTransform = await resolvedTransformForPortal(t, offsetCube, undefined, tinyPortal); | |
| const portal = createPortal(t, { ...tinyPortal, portalTransform: "auto translateX(50%)" }); | |
| const model = appendModel(portal, offsetCube); | |
| await model.ready; | |
| const translated = await waitForPortalTransform(portal, portalTransformIsResolved, "translated transform"); | |
| assert_less_than(autoTransform.m11, 0.05, "the fit really is scaling the content down steeply"); | |
| assert_approx_equals((translated.m41 - autoTransform.m41) / (portal.getBoundingClientRect().width / 2), 1, epsilon, "the translation is significant"); | |
| }, `a length after auto is unaffected by the auto-fit scale`); | |
| promise_test(async t => { | |
| const unitMapping = await resolvedTransformForPortal(t, offsetCube, "none"); | |
| const portal = createPortal(t, { portalTransform: "translateX(50%)" }); | |
| portal.style.padding = "10px"; | |
| portal.style.border = "5px solid transparent"; | |
| const model = appendModel(portal, offsetCube); | |
| await model.ready; | |
| const before = await waitForPortalTransform(portal, portalTransformIsResolved, "transform before resizing"); | |
| const halfBorderBoxBefore = portal.getBoundingClientRect().width / 2; | |
| portal.style.width = "80cm"; | |
| const after = await waitForPortalTransform(portal, transform => transform && !portalTransformsApproxEqual(transform, before), "transform after resizing"); | |
| const halfBorderBoxAfter = portal.getBoundingClientRect().width / 2; | |
| assert_approx_equals((before.m41 - unitMapping.m41) / halfBorderBoxBefore, 1, epsilon, "the percentage resolves against the border box"); | |
| assert_approx_equals((after.m41 - unitMapping.m41) / halfBorderBoxAfter, 1, epsilon, "and is re-resolved against it when the portal is resized"); | |
| }, `a percentage in the portal-transform list resolves against the border box, and is re-resolved on resize`); | |
| promise_test(async t => { | |
| const unitMapping = await resolvedTransformForPortal(t, offsetCube, "none"); | |
| const portal = createPortal(t, { portalTransform: "translateX(calc(50% + 10px))" }); | |
| const model = appendModel(portal, offsetCube); | |
| await model.ready; | |
| const translated = await waitForPortalTransform(portal, portalTransformIsResolved, "calc() transform"); | |
| const expected = portal.getBoundingClientRect().width / 2 + 10; | |
| assert_approx_equals((translated.m41 - unitMapping.m41) / expected, 1, epsilon, "the percentage and the length are both accounted for"); | |
| }, `a calc() mixing a percentage and a length resolves against the border box`); | |
| </script> | |
| </body> | |
| </html> |