У меня есть элемент SVG, и мне нужно нарисовать точки трансформации вокруг. Я использую svg. js и часть его плагина изменения размера .
. Он работает для перемещения и вращения не преобразованного элемента, но не для элемента с преобразованием matrix.
Короче говоря, мне нужно получить преобразование от элемента и применить его к группе. Мне удается это сделать, но только до тех пор, пока я не изменю x, y, ширину или высоту элемента.
Следующий фрагмент иллюстрирует, что я имею в виду. Кнопки с пометкой «Steps1..3» показывают шаги, а кнопка «Переключить функцию преобразования» изменяет функцию преобразования.
// transform function
const makeTransformTR = (bbox, el, nested) => {
const elTransfrom = el.transform();
let cx = bbox.width / 2;
let cy = bbox.height / 2;
let tx = bbox.x;
let ty = bbox.y;
let transfromAttr = `translate(${tx}, ${ty})`;
let rotate = elTransfrom.rotate;
if (rotate) {
transfromAttr += `, rotate(${rotate}, ${cx}, ${cy} )`;
}
nested.attr('transform', transfromAttr);
};
const makeTransformRT = (bbox, el, nested) => {
const elTransfrom = el.transform();
let cx = bbox.cx;
let cy = bbox.cy;
let tx = bbox.x;
let ty = bbox.y;
let transfromAttr = ``;
let rotate = elTransfrom.rotate;
if (rotate) {
transfromAttr += ` rotate(${rotate}, ${cx}, ${cy} )`;
}
transfromAttr += (transfromAttr ? ',' : '') + ` translate(${tx}, ${ty})`;
nested.attr('transform', transfromAttr);
};
const makeTransformByMatrix = (bbox, el, nested) => {
const matrix = new SVG.Matrix(el);
const zeroMatrix = {
a: 1,
b: 0,
c: 0,
d: 1,
e: 0,
f: 0,
originX: 0,
originY: 0,
rotate: 0,
scaleX: 1,
scaleY: 1,
shear: 0,
translateX: 0,
translateY: 0
};
const elTransfrom = el.transform();
let a = elTransfrom.rotate * Math.PI / 180 || 0;
let cosA = Math.cos(a);
let sinA = Math.sin(a);
let cx = 1 * bbox.cx;
let cy = 1 * bbox.cy;
let tx = -1 * cx * cosA + cy * sinA + cx;
let ty = -1 * cx * sinA - cy * cosA + cy;
let newMatrix = new SVG.Matrix({
a: cosA,
b: sinA,
c: -1 * sinA,
d: cosA,
e: tx,
f: ty
});
nested.matrix(newMatrix);
nested.translate(bbox.x, bbox.y);
};
const transformFuncs = {
'makeTransformRT' : makeTransformRT,
'makeTransformTR' : makeTransformTR,
'makeTransformByMatrix' : makeTransformByMatrix
}
const getRect = () => {
return SVG(document.getElementById('rect1'));
};
const getGroup = () => {
return SVG(document.getElementById('g1'));
};
const reset = () => {
const rect = getRect();
const g = getGroup();
rect.attr('transform', '');
rect.width("108");
g.attr('transform', '')
};
const funcs=Object.keys(transformFuncs);
let fIndex = 0;
// rotate the rect and get the transform from the group
const step1 = () => {
const rect = getRect();
rect.attr('transform', 'matrix(0.5906056676199253,0.806960312143802,-0.806960312143802,0.5906056676199253,140.68774443238965,-45.31069334044855)')
}
const step2 = () => {
transformFunction(getRect().bbox(), getRect(), getGroup());
}
// This might cause my issue
const step3 = () => {
const rect = getRect();
rect.width(2); // changing width
transformFunction(rect.bbox(), rect, getGroup());
}
const log = (text) => {
let t = document.getElementById('log').value;
t+='\n'+text;
document.getElementById('log').value = t;
}
const setTransformFunc=()=>{
transformFunction = transformFuncs[ funcs[fIndex] ];
log('new func: ' + funcs[fIndex]);
}
const switchToAlernative=() => {
reset();
if(fIndex>=funcs.length){
fIndex = 0;
}
setTransformFunc();
fIndex++;
}
switchToAlernative();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/3.0.16/svg.js"></script>
<body>
<section style="display: flex">
<svg width="300" height="300" style="display: block;" xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="61" y="62" width="108" height="108" fill="none" stroke="#000" stroke-width="2"
id="rect1"
></rect>
<g id="g1" >
<rect width="108" height="108"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="101" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="101" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="47" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="101" y="47"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="47" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="47"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="47" y="-27"></rect>
</g>
</svg>
<div >
<button onclick="step1()">Step1</button>
<button onclick="step2()">Step2</button>
<button onclick="step3()">Step3</button>
<br><br>
<div><button onclick="reset()">Reset</button><button onclick="switchToAlernative()">Switch transform function</button></div>
<div><textarea cols="40" rows="30" id="log"></textarea> </div>
</div>
</section>
<section >
<svg width="300" height="300" style="display: block;" xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="61" y="62" width="108" height="108" fill="none" stroke="#000" stroke-width="2"
id="rect2"
transform="matrix(0.5906056676199253,0.806960312143802,-0.806960312143802,0.5906056676199253,140.68774443238965,-45.31069334044855)"></rect>
<g id="g2" transform=" rotate(53.80000000000001, 115, 116 ), translate(61, 62)">
<rect width="108" height="108" class="svg_select_boundingRect"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="101" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="101" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="47" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="101" y="47"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="47" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="47"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="47" y="-27"></rect>
</g>
</svg>
</section>
<section >
<svg width="300" height="300" style="display: block;" xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="61" y="62" width="2" height="108" fill="none" stroke="#000" stroke-width="2"
id="rect3"
transform="matrix(0.5906056676199253,0.806960312143802,-0.806960312143802,0.5906056676199253,140.68774443238965,-45.31069334044855)"></rect>
<g id="g3" transform=" rotate(53.80000000000001, 62, 116 ), translate(61, 62)">
<rect width="2" height="108" class="svg_select_boundingRect"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-5" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-5" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-6" y="-7"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-5" y="47"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-6" y="101"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-7" y="47"></rect>
<rect width="14" height="14" stroke-width="3" stroke="#5ab3e4" fill="#ffffff" rx="3" ry="3" x="-6" y="-27"></rect>
</g>
</svg>
</section>
</body>
</html>
Я думаю, что функция "makeTransformTR" работает, как и ожидалось для шагов 1-2; «makeTransformRT» не должен работать для шагов 1-2; "makeTransformByMatrix" не работает, но перспективен.
Итак, у вас есть идея, как исправить функцию преобразования, чтобы правильно выполнить все шаги? Пожалуйста, помогите!