将一个svg元素集中在另一个svg元素时的比例关系

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将一个svg元素集中在另一个svg元素时的比例关系相关的知识,希望对你有一定的参考价值。

我已经编写了这些函数来将一个svg元素集中在另一个中:

import { Matrix, translate } from 'transformation-matrix';

export const getElementCenter = (element: SVGGraphicsElement) => {
  const bBox = element.getBBox();

  return { x: bBox.x + bBox.width / 2, y: bBox.y + bBox.height / 2 };
};

export const centerElementInOther = (
  element: SVGGraphicsElement,
  other: SVGGraphicsElement,
  scaleFactor: number = 1
): Matrix => {
  const elementCentre = getElementCenter(element);
  const otherCentre = getElementCenter(other);

  const x = elementCentre.x - otherCentre.x;
  const y = elementCentre.y - otherCentre.y;

  // how can I work out the scaleFactor?  If it the actual scale is 0.5 then I need to divide by 2 but if it is 1 then I need to divide by 1

  return translate(-x / scaleFactor, -y / scaleFactor);
};

一切都有效,除非元素缩放然后我需要应用一些数学,但我不理解配给。

一切正常,直到我将元素的比例改为0.5然后我必须将中心x和中心y除以2。

答案

实际上你需要将xyscaleFactor相乘,因为scaleFactorDecimal Fraction

return translate(-x * scaleFactor, -y * scaleFactor);

如果它的实际比例是0.5,那么我需要除以2,但如果它是1,那么我需要除以1

这意味着什么:

x / 2 <=> x * 0.5
x / 1 <=> x * 1

所以x * scaleFactory * scaleFactor将适用于scaleFactor小数部分的所有值。

以下是一些测试x, y值的示例:

const centerElementInOtherDiv = (x, y, scaleFactor = 1) => {
  return {
    x: -x / scaleFactor,
    y: -y / scaleFactor
  };
};

const centerElementInOtherMul = (x, y, scaleFactor = 1) => {
  return {
    x: -x * scaleFactor,
    y: -y * scaleFactor
  };
};


const svgCoords = [
  { x: 100, y: 100 },
  { x: 200, y: 200 },
  { x: 100, y: 300 }
];

for(svgCoord of svgCoords) {
  let mulXY = centerElementInOtherMul(svgCoord.x, svgCoord.y);
  let divXY = centerElementInOtherDiv(svgCoord.x, svgCoord.y);
  console.log(`scaleFactor = 1   -> mul(x: ${mulXY.x}, y: ${mulXY.y}), div(x: ${divXY.x}, y: ${divXY.y})`)

  mulXY = centerElementInOtherMul(svgCoord.x, svgCoord.y, 0.5);
  divXY = centerElementInOtherDiv(svgCoord.x, svgCoord.y, 0.5);
  console.log(`scaleFactor = 0.5 -> mul(x: ${mulXY.x}, y: ${mulXY.y}), div(x: ${divXY.x}, y: ${divXY.y})`)
}
另一答案

我很想看到SVG代码。

将svg元素置于另一个转换元素中的一种方法是将两个元素包装在<g>中,并将转换应用于组,如下所示:

const bBox1 = theRect1.getBBox();

c1.setAttributeNS(null,"cx",bBox1.x + bBox1.width / 2)
c1.setAttributeNS(null,"cy",bBox1.y + bBox1.height / 2);
svg{border:1px solid;}
<svg viewBox="0 0 200 100">
  <g transform="scale(.5,.5) translate(150,50) rotate(30,30,10)">
  <rect id="theRect1" x="30" y="10" width="80" height="40" />
  <circle id="c1" r="2" fill="red" />
  </g>
</svg>

以上是关于将一个svg元素集中在另一个svg元素时的比例关系的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 viewbox 属性的情况下制作 SVG 比例?

简单实现svg的拖拽和缩放

在 ie9 中不遵守 img 元素比例中的 SVG

按比例禁用 SVG 自动缩放

svg 到 png 不工作,怀疑 svg 元素差异

将全尺寸图像的大小和比例与 SVG 视图框匹配