Как пропорционально увеличить перспективу?
Есть такой замечательный способ выставления перспективы - 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
Но вот где именно, не понимаю. Если ли способ вычислить их? Заранее благодарен!
