Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[motion] Inconsistency in offset-path contain #22

Closed
ewilligers opened this issue Aug 15, 2016 · 5 comments · Fixed by #205
Closed

[motion] Inconsistency in offset-path contain #22

ewilligers opened this issue Aug 15, 2016 · 5 comments · Fixed by #205
Assignees
Labels

Comments

@ewilligers
Copy link
Contributor

https://drafts.fxtf.org/motion-1/#offset-path-property

"The path ends at the edge of the containing block."

Note that this implies that, when no size is specified in offset-distance, the path length is not constant as the angle changes, and we only have a polar coordinate system if offset-distance is a length, not a percentage.

The text for 'contain' is not consistent with Example 2.

"When the value of offset-distance would select a point on the path which is outside the edge of the containing element, the value is instead clipped so that the selected point lies on the edge of the element."

"offset-path: 45deg; offset-distance: 100%" gives the point at the top right corner of the containing element.

Figure 2 displays the top-right element incorrectly.

"offset-path: 180deg; offset-distance: 100%" gives a point on the bottom edge of the containing element.

Figure 2 correctly displays the bottom element.

In each case, 'contain' would not cause any change. Figure 3 displays both elements incorrectly.

It is possible the intent for 'contain' is that the entire element stays inside the containing block. If so, we need to specify what happens when the element is larger than the container.

Perhaps have an example with
"offset-path: 60deg contain; offset-distance: 150%"

Then clamping causes the selected point to lie on the right edge of the element.

It would be helpful to describe what happens to the vertical positioning of this element.
Does the element continue to lie on the path, making this equivalent to "offset-path: 60deg; offset-distance: 100%" ?
Or is the vertical positioning the same as it would have been without contain?
(I suspect the former is intended but the wording allows either.)

(In all the above, I assume a square containing element.)

@jihyerish jihyerish self-assigned this Aug 18, 2016
@jihyerish
Copy link

jihyerish commented Sep 13, 2016

Sorry for the late reply.

The description of 'contain' is bit wrong. The intent of the contain is guaranteeing the entire element stays inside the path, not the containing block.

The < size > was added to 'offset-path' with < angle >, and it decides the end point of the path.
Its default is 'closet-side' and that makes the length of the path constant with the changes in < angle > of the path.
Therefore, when "offset-path: 45deg", the end point of the path isn't on the edge of the containing block as Fig2.
'closet-side' makes the distance between the initial point and the end point of the path as same when the end point is on the closet side edge of the containing block.
After the path is defined, contain makes the whole content area of the element are positioned on the path.

It would be helpful to describe what happens to the vertical positioning of this element.
Does the element continue to lie on the path, making this equivalent to "offset-path: 60deg; offset-distance: 100%" ?
Or is the vertical positioning the same as it would have been without contain?

I couldn't get your intention for the vertical positioning.
Could you tell me what the vertical positioning means?

@ewilligers
Copy link
Contributor Author

I couldn't get your intention for the vertical positioning.
Could you tell me what the vertical positioning means?

y-coordinate of the placed item.

If we have an example with the following:
container size: 200px 200px;
item size: 0px 0px;
offset-position: center; /* 100px 100px */
offset-path: angle(60deg);
offset-distance: 150%; /* 150 px */
then the element would be placed at 230px 25px.

When we change this to
offset-path: angle(60deg contain);
then my question can be reworded: Where is the element now placed?

If the horizontal position changes from 230px to 200px, and the vertical position remains unchanged, the element would be placed at 200px 25px.

If the horizontal position changes from 230px to 200px, but the element must remain on the path, the element would be placed at 200px 42px.

If we say that the "entire element stays inside the path, not the containing block" and that the element must remain on the path, then any offset-distance exceeding 100% is equivalent to offset-distance: 100%, and the element would be placed at 187px 50px

Assume 187px 50px is required.

Now suppose we change the size:
item size: 20% 20%; /* 40px 40px */
offset-path: angle(60deg contain);
offset-anchor: 20px 20px /* center */
One way for the element to be fully contained within the containing block, would be for the element to be moved left 7px to 180px 50px, with the vertical position not changing.

If the element must be contained within the fully containing block, and the anchor must remain on the path, the element moves to 180px 54px.

If the "entire element stays inside the path", and the anchor must remain on the path, the element moves to 163px 64px. The top right corner of the element becomes 183px 44px, which is 100px from offset-position.

I suspect this is the placement we require. I've implemented code that achieves this, and can

  • formalize the algorithm
  • put the implementation online so people can see how it responds to various interesting test cases (such as when the element is larger than the containing element.)

@ewilligers ewilligers changed the title Inconsistency in offset-path contain [motion] Inconsistency in offset-path contain Nov 14, 2016
@jihyerish
Copy link

When we change this to
offset-path: angle(60deg contain);
then my question can be reworded: Where is the element now placed?

If we have an example with the following:

container size: 200px 200px;
element size: 0px 0px;
offset-position: center; /* 100px 100px */
offset-path: angle(60deg contain);
offset-distance: 150%; /* 150 px */

Then the element would be placed at 187px 50px. (Assuming 50*sqrt(3) is 17)
image

When calculating the position with contain and considering the size of the element, there could be 2 ways:

  • Case A:
    Until one of the edges of the element meets the end point of the path, move the element towards offset-position with letting the anchor always be on the path.
  • Case B:
    Until the entire element stays inside the path, move the element towards offset-position with letting the anchor always be on the path.

For example, if the size of the element in the example above changes 0px 0px to 40px 40px (20% 20%),
the element would:
(let 20 / SQRT(3) = 12, 20 * SQRT(2) = 28, 14 * SQRT(3) = 24)

  • Case A: move left 20px and bottom 12px to 167px 62px.
    image

  • Case B: move left 24px and bottom 14px to 163px 64px.
    image

If the "entire element stays inside the path", and the anchor must remain on the path, the element moves to 163px 64px. The top right corner of the element becomes 183px 44px, which is 100px from offset-position.

You calculated the position by Case B, and I also agree with that -
Case B is more suitable than Case A, because the result of Case B is the best possible outcome when the clipping problem is solved.

I think I need to update the spec with:

  • Describing that contain adjusts the total length of the path not the offset-distance of the element
  • Algorithm (Case B) for calculating the position when using contain

such as when the element is larger than the containing element.

In this case, no matter how the element moves, it can't avoid being clipped.
So the element could be positioned along the path with having the smallest clipped area by moving the shortest distance.

For example, the element like below would be placed at 120px 89px.

container size: 200px 200px;
element size: 240px 240px;
offset-position: center; /* 100px 100px */
offset-path: angle(60deg contain);
offset-distance: 150%; /* 150 px */

(let 110/SQRT(3) = 64)

image

@jihyerish
Copy link

jihyerish commented Jun 2, 2017

such as when the element is larger than the containing element.

I think this case, the result would be:
https://jihyerish.github.io/motion-path-testsuits/offset-path-ray-contain-001-ref.html

@ericwilligers Do you have another opinion?

ewilligers pushed a commit to ewilligers/fxtf-drafts that referenced this issue Jun 28, 2017
'smallest clipped area' gave no guidance when the path and the box
had zero area in common regarless of the value of offset-distance.

For example, this can occur when the path size is 0, or when
offset-anchor is substantially outside the box.

We now define the meaning of 'contain' by specifying that the path
size is minimally increased so that the box can be contained.

resolves w3c#22
@ewilligers
Copy link
Contributor Author

such as when the element is larger than the containing element.

In this case, no matter how the element moves, it can't avoid being clipped.
So the element could be positioned along the path with having the smallest clipped area by moving the shortest distance.

Suppose the path size is 0px and/or offset-anchor is very large in magnitude. In such cases, the clipped area can be always 100% regardless of offset-distance.

Minimally increasing the path size is a good solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants