如何正确计算 viewpoint("0 0 1200 800")
的center 值
我想在我的JS中分配
translate(${translateXValue}px, -300px) rotateY(180deg) scale(1.5)
;*中的值。
我希望点击时该框位于 viewpoint(blue background)
的
center中。我的 Y 值是静态的
-300px
因为我不确定如何动态计算 x 和 y
const foreignObjects = [{
x: 0,
y: 0,
width: "100%",
height: "100%",
content: '<div xmlns="http://www.w3.org/1999/xhtml"></div>',
style: {
backgroundColor: "blue"
}
},
{
x: 100,
y: 0,
width: 1000,
height: 750,
content: '<div class="container"></div>',
style: {}
}
];
const boxes = [{
y: -50,
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ddd"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ddd"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ddd"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
];
function applyStyles(element, styles) {
for (const [key, value] of Object.entries(styles)) {
element.style[key] = value;
}
}
function renderBoxes(container) {
boxes.forEach(box => {
const div = document.createElement('div');
div.className = box.class;
applyStyles(div, box.style);
let clicked = false;
div.addEventListener('click', () => {
if (clicked) {
// Reset the transformation
div.style.transform = 'none';
clicked = false;
} else {
// Calculate the translation needed to move the element to the top and center of the viewport
const translateXValue = (600 / 2);
// Apply the transformation
div.style.transform = `translate(${translateXValue}px, -300px) rotateY(180deg) scale(1.5)`;
clicked = true;
}
});
container.appendChild(div);
});
}
function renderForeignObjects() {
const svg = document.getElementById('mySvg');
foreignObjects.forEach(obj => {
const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
foreignObject.setAttribute('x', obj.x);
foreignObject.setAttribute('y', obj.y);
foreignObject.setAttribute('width', obj.width);
foreignObject.setAttribute('height', obj.height);
const div = document.createElement('div');
div.innerHTML = obj.content;
applyStyles(div.firstChild, obj.style);
if (div.firstChild && div.firstChild.classList.contains('container')) {
renderBoxes(div.firstChild);
}
foreignObject.appendChild(div);
svg.appendChild(foreignObject);
});
}
// Call the function to render foreign objects
renderForeignObjects();
.a {
height: 100vh;
width: 100%;
}
div {
width: 100%;
height: 100%;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.container {
display: flex;
align-items: flex-end;
justify-content: center;
position: relative;
}
<svg id="mySvg" xmlns="http://www.w3.org/2000/svg" class="a p" viewBox="0 0 1200 800">
</svg>
看起来你只需将 x 值更改为 50% 并将 div css 位置设置为“absolute”即可。清除变换时还会恢复位置类型。
查看并运行代码片段以查看更改。
const foreignObjects = [{
x: 0,
y: 0,
width: "100%",
height: "100%",
content: '<div xmlns="http://www.w3.org/1999/xhtml"></div>',
style: {
backgroundColor: "blue"
}
},
{
//Whole page
x: 100,
y: 0,
width: 1000,
height: 750,
content: '<div class="container"></div>',
style: {}
}
];
const boxes = [{
y: -50,
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ddd"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ddd"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ddd"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
];
function applyStyles(element, styles) {
for (const [key, value] of Object.entries(styles)) {
element.style[key] = value;
}
}
function renderBoxes(container) {
boxes.forEach(box => {
const div = document.createElement('div');
div.className = box.class;
applyStyles(div, box.style);
let clicked = false;
div.addEventListener('click', () => {
if (clicked) {
// Reset the transformation
div.style.transform = 'none';
// NOTE Change css position back to what it was
div.style.position="revert";
clicked = false;
} else {
// Calculate the translation needed to move the element to the top and center of the viewport
const translateXValue = (600 / 2);
// Apply the transformation
// div.style.transform = `translate(${translateXValue}px, -300px) rotateY(180deg) scale(1.5)`;
// NOTE Use 50% for the x
div.style.transform = `translate(50%, -300px) rotateY(180deg) scale(1.5)`;
// NOTE Change css position to "absolute"
div.style.position="absolute";
clicked = true;
}
});
container.appendChild(div);
});
}
function renderForeignObjects() {
const svg = document.getElementById('mySvg');
foreignObjects.forEach(obj => {
const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
foreignObject.setAttribute('x', obj.x);
foreignObject.setAttribute('y', obj.y);
foreignObject.setAttribute('width', obj.width);
foreignObject.setAttribute('height', obj.height);
const div = document.createElement('div');
div.innerHTML = obj.content;
applyStyles(div.firstChild, obj.style);
if (div.firstChild && div.firstChild.classList.contains('container')) {
renderBoxes(div.firstChild);
}
foreignObject.appendChild(div);
svg.appendChild(foreignObject);
});
}
// Call the function to render foreign objects
renderForeignObjects();
.a {
height: 100vh;
width: 100%;
}
div {
width: 100%;
height: 100%;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.container {
display: flex;
align-items: flex-end;
justify-content: center;
position: relative;
}
<svg id="mySvg" xmlns="http://www.w3.org/2000/svg" class="a p" viewBox="0 0 1200 800">
</svg>