K41F4r
K41F4r

Reputation: 1551

Scaling elements based on another element

I have elements positioned on top of am img in the following way:

<div style={{  display: "inline-block", position: "relative" }} >
         <img /> 
         <div style={{ position: "absolute", left: 0, right: 0, top: 0, bottom: 0, width: "100%", height: "100%" }} > 
                 <child elements I'm trying to position />
           </div>    
    </div>

The child elements use the top, left, width, height properties to position themselves on top of the image.

I'm trying to make them scale with the image (- when the image's width and height changes I want them to stay in the same place and scale to the image):

width: Math.round(((box.x2 - box.x1) / imgWidth) * 100) + "%",
height: Math.round(((box.y2 - box.y1) / imgHeight) * 100)  + "%",
left: Math.round((box.x1 / imgWidth) * 100)  + "%",
top: Math.round((box.y1 / imgHeight) * 100)  + "%"

But the results when using percentage are a little off than just using the coordinates.

Is there a better way to position the elements (boxes) so they scale with the image? Is there something wrong with the formula I'm using?

Edit: For example: enter image description here

The squares are the child elements I mentioned and when the user zooms in or out of the page or if the image's size changes I want the squares position on the image to be preserved and their scale match the image's scale

Upvotes: 2

Views: 646

Answers (1)

Halden Collier
Halden Collier

Reputation: 862

Ok, so this may not fit into your project straight off the bat but you should be able to get it working with a little bit of tweaking.

Use some JavaScript to calculate the absolute positioning of the child elements to a percentage.

var imgWrapper = document.getElementById("wrapper");
var children = document.getElementsByClassName("child");

window.onresize = function(event) {
  var imgWidth  = imgWrapper.offsetWidth;
  var imgHeight = imgWrapper.offsetHeight;

  for (var i = 0; i < children.length; i++)
  {
    // - Current child element
    var child = children.item(i);

    // - Child positions
    var currentTop = child.offsetTop;
    var currentLeft = child.offsetLeft;
    var currentBottom = imgHeight - (currentTop + child.offsetHeight);
    var currentRight = imgWidth - (currentLeft + child.offsetWidth);

    var newTop = (100 * currentTop / imgHeight);
    var newLeft = (100 * currentLeft / imgWidth);
    var newBottom = (100 * currentBottom / imgHeight);
    var newRight = (100 * currentRight / imgWidth);

    child.style.top = newTop + "%";
    child.style.left = newLeft + "%";
    child.style.bottom = newBottom + "%";
    child.style.right = newRight + "%";
  }
};

http://next.plnkr.co/edit/E8RbqFTClYklW4w7

Upvotes: 1

Related Questions