Как пропорционально увеличить перспективу?

Есть такой замечательный способ выставления перспективы - https://bl.ocks.org/mbostock/10571478

Тут контрольные точки и они же точки по которым считается перспектива, расположены по углам квадрата, т.е по границе вращаемого изображения, а мне нужно чтобы изображение могло выходить за границы контрольных точек. Моя идея в том чтобы по расположению контрольных точек в перспективе отрисовывались еще 4 точки, которые будут больше контольного квадрата скажем в 1.5 раза. И по ним уже считалась перспектива. Т.е как бы масштабировать перспективу контрольных точек.

Вот примерно так:

введите сюда описание изображения

Т.е дергая черные точки - красные должны отрисовываться и формировать пропорционально увеличенный черный четырехугольник как бы в перспективе.

Понимая что эти красные точки должны быть на линиях пересечения A1-A3 и A2-A4 дошел пока до этого (спасибо Stranger in the Q):

let x, y, cur;

document.querySelectorAll('circle').forEach(c => c.onmousedown = e => {
  cur = c;
  x = +c.getAttribute('cx') - e.x;
  y = +c.getAttribute('cy') - e.y;
});

addEventListener('mouseup', e => cur = null);

addEventListener('mousemove', e => {
  if (!cur) return;
  cur.setAttribute('cx', x + e.x)
  cur.setAttribute('cy', y + e.y)
  move();
});

move();

function move() {
  let el = document.getElementById("svg"),
      svg = el.getBoundingClientRect(),
      
      x1 = +p1.getAttribute('cx'),    
      y1 = +p1.getAttribute('cy'), 

      x2 = +p2.getAttribute('cx'),    
      y2 = +p2.getAttribute('cy'),      

      x3 = +p3.getAttribute('cx'),    
      y3 = +p3.getAttribute('cy'),

      x4 = +p4.getAttribute('cx'),    
      y4 = +p4.getAttribute('cy'),

      w = +svg.width, 
      h = +svg.height,

      k1 = (y3 - y1) / (x3 - x1),
      fX1 = x => y1 + (x - x1) * k1,
      fY1 = y => x1 + (y - y1) / k1;

      k2 = (y4 - y2) / (x4 - x2),
      fX2 = x => y2 + (x - x2) * k2,
      fY2 = y => x2 + (y - y2) / k2;
      
  let pt1 = check([0, fX1(0)], fY1);
  let pt2 = check([w, fX1(w)], fY1);  
  let pt3 = check([0, fX2(0)],fY2);
  let pt4 = check([w, fX2(w)], fY2);  

  path.setAttribute('d', `M ${x1} ${y1} ${x2} ${y2} ${x3} ${y3} ${x4} ${y4} Z`);
  
  l1.setAttribute('points', `${pt1[0]} ${pt1[1]} ${pt2[0]} ${pt2[1]}`);
  l2.setAttribute('points', `${pt3[0]} ${pt3[1]} ${pt4[0]} ${pt4[1]}`);

  function check(p, f) {
    if (p[1] < 0) 
      return [f(0), 0];
    if (p[1] > h) 
      return [f(h), h];
    return p;
  }
}
.wrap {
  position: relative;
  width: 1000px;
  height: 500px;
  margin: 0 auto;
}

#path {
    stroke: black;
    stroke-width: 2px;
    stroke-linecap: square;
    fill: none;
}
<div class="wrap">

<svg id="svg" width="100%" height="100%" style="border:solid">
    <polyline id="l1" stroke="red" stroke-width="2" stroke-dasharray="8 8"></polyline>
    <polyline id="l2" stroke="red" stroke-width="2" stroke-dasharray="8 8"></polyline>
    <path id="path" stroke="red" stroke-width="2"></path>
    <circle id="p1" cx="200" cy="100" r="10"></circle>
    <circle id="p2" cx="400" cy="100" r="10"></circle>
    <circle id="p3" cx="400" cy="200" r="10"></circle>
    <circle id="p4" cx="200" cy="200" r="10"></circle>
</svg>

</div>

https://codepen.io/kushnir22/pen/zYoJEjN

Но вот где именно, не понимаю. Если ли способ вычислить их? Заранее благодарен!


Ответы (0 шт):