1

What would be the best and most elegant way of moving an element by a predefined angle, just so its moved outside of its container?

As illustrated in the image below, I want to move the element so it is just outside of its container. And I only want to define a certain angle to make it happen. (ignore the degrees range here, it's just to illustrate my case)

The element should be able to move in all angles (0-359°)

Example movement of the element outside of its container

carl lindth
  • 111
  • 7
  • Welcome to SO. Please read [What topics can I ask about](http://stackoverflow.com/help/on-topic) and [How to ask a good question](http://stackoverflow.com/help/how-to-ask) and [The perfect question](http://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/). SO is **not the place to ask for a tutorial, nor the place to find free programmers**. Your question should _show_ that you've put some efford into solving your own problem (show us the code you have so far) and should be answerable without writing half a book. – icecub Mar 13 '19 at 15:47
  • Pythagorean theorem : I don't think you really need to know the degrees of the angle at all ... you know the boundaries of your box, you know the mid point of the element, you know the box's mid point ... each move can give you the two lines of a right triangle -- all you have to do is solve for the hypotenuse – Doug Mar 13 '19 at 15:52
  • 1
    As for your question: There's no where near enough information to even be able to answer it. What kind of container are we talking about here? What kind of element are we moving? Like, if this is a canvas, then you can't draw outside of the canvas container. You're also not moving, but re-drawing instead. If it's not a canvas, how are the elements positioned with CSS? Relative, fixed, absolute? All of this matters a lot to even begin to answer your question. – icecub Mar 13 '19 at 15:55
  • Thanks for the reply! But the thing is that the user will input an angle in degrees, and then I want it to move outside of the container. – carl lindth Mar 13 '19 at 15:56
  • @icecub I don't think any of that matters, I am more interested of how to move the position of the element, not how it is rendered. – carl lindth Mar 13 '19 at 15:59
  • 1
    It does matter. There are different kinds of elements. Different kinds of containers. One can be moved using CSS positions. The other must be re-drawn with Javascript. And yet another must be re-positioned with an animation keyframe or a combination of 2 or more of those. It's like you're asking how to go from A to B, but not telling us if there's a road, a railway or an ocean in between. Should you use a car, a train or a boat? – icecub Mar 13 '19 at 16:02
  • Anyway, the general idea is that you have X and Y positions relative to the container. One way or another you use those positions to recalculate the new ones and change the position. This does not visibly move the element. It just instantly changes it from A to B. To visibly move, you need animation keyframes or lots of redrawing depending on what you use. More info than that can't be given with the information provided. – icecub Mar 13 '19 at 16:11
  • So you have given two axis aligned rectangles (container + element) and one angle (direction). And you want to know the minimal distance s.t. the element moved by this distance along the given angle is just outside the container? – coproc Mar 14 '19 at 09:19
  • sorry for the vague explanation, i managed to solve it. I have added the solution down below :) – carl lindth Mar 14 '19 at 16:40

1 Answers1

0

I solved it by using the function from Find rectangle boundary point at an angle from point that is not in the middle of the rectangle.

Just modified the function a bit so the element is totally outside of the container.

function getEdgePointBasedOnAngle(position: Position, elementSize: Size, angle: number): Position {
    angle = (angle) * (Math.PI / 180);
    const canvasSize: Size = { width: 1, height: 1 };
    const dx = Math.cos(angle);
    const dy = Math.sin(angle);

    // Left border
    if (dx < 1.0e-16) {
        const y = (position.x) * dy / dx + (canvasSize.height - position.y);
        if (y >= 0 && y <= canvasSize.height) {
            return {
             x: -(elementSize.width / 2) , 
              y: canvasSize.height - y - elementSize.height * -(dy * 0.5);
            };
        }
    }

    // Right border
    if (dx > 1.0e-16) {
        const y = (canvasSize.width - position.x) * dy / dx + position.y;
        if (y >= 0 && y <= canvasSize.height) {
            return {
             x: canvasSize.width + (elementSize.width / 2),
              y: y + elementSize.height * (dy * 0.5)
            };
        }
    }

    // Top border
    if (dy < 1.0e-16) {
        const x = (position.y) * dx / dy + (canvasSize.width - position.x);
        if (x >= 0 && x <= canvasSize.width) {
            return {
             x: canvasSize.width - x - elementSize.width * -(dx * 0.5),
              y: -(elementSize.height / 2)
            };
        }
    }

    // Bottom border
    if (dy > 1.0e-16) {
        const x = (canvasSize.height - position.y) * dx / dy + position.x;
        if (x >= 0 && x <= canvasSize.width) {
            return {
             x: x + elementSize.width * (dx * 0.5), 
              y: canvasSize.height + (elementSize.height / 2)
            };
        }
    }

    return position;
}
carl lindth
  • 111
  • 7