Search code examples
javascriptcssmathformulascale

Recalculate transform origin on a scaled element


I have an element which has to be scaled from 100px from the left while already having a scale of 0.5. When transforming the origin it is on 50px on the left side and scaling from the wrong side of the line.

When scaling the element I want it to scale from the purple line. Without using the left CSS property.

I tried to use this formula but it was slightly off:

x + (x * scale)

enter image description here

* {
  margin: 0;
  padding: 0;
}

.box {
  position: relative;
  width: 100px;
  height: 100px;
  margin-top: -10px;
}

.example-initial {
  background: blue;
  transform: scale(0.2);
  transform-origin: 100px 0px;
}

.example-wrong {
  background: green;
  transform: scale(0.5);
  transform-origin: 100px 0px;
}

.example-right {
  background: red;
  transform: scale(0.5);
  transform-origin: 200px 0px;
}

.transform-origin-line-example {
  position: absolute;
  left: 100px;
  width: 1px;
  height: 200px;
  background: purple;
  top: 0;
}
<div class="example-initial box"></div>

<div class="example-wrong box"></div>

<div class="example-right box"></div>

<div class="transform-origin-line-example"></div>


Solution

  • The formula you're looking for is:

    (x * (1 / (1 - 0.1));

    x is the left position.
    1 is the full scale.
    0.1 is the used scale.

    * {
      margin: 0;
      padding: 0;
    }
    
    .box {
      position: relative;
      background: red;
      width: 100px;
      height: 100px;
      transform: scale(0.1);
      transform-origin: calc(100px * (1 / 0.9)) 0px;
    } 
    
    .example-box {
      position: relative;
      background: blue;
      width: 100px;
      height: 100px;
      transform: scale(0.5);
      transform-origin: calc(100px * (1 / 0.5))  0px;
    }
    
    .transform-origin-line-example {
      position: absolute;
      left: 100px;
      width: 1px;
      height: 200px;
      background: green;
      top: 0;
    }
    <div class="box"></div>
    
    <div class="example-box"></div>
    
    <div class="transform-origin-line-example"></div>