如何使用 svg 矩阵变换来缩放而不是翻译(隐式)? [英] how to use a svg matrix transform to scale only not to translate (implicite)?

查看:39
本文介绍了如何使用 svg 矩阵变换来缩放而不是翻译(隐式)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与 svg 矩阵作斗争

我想要的是缩放对象的大小,而不是它的原点(在绘图中),即.让它变小(或变大)但不要移动它

我有一个盒子 x=y=w=h=4 和另一个

X---####----####----####----####----####----####----####----####

我想要 x=4=y=4 w=h=2

X---##------##------------------##------##--------------

我所尝试的(没有无用的东西)

h=y=w=h=2(即缩小一半)

X-##--##--##--##

注意,我不知道缩放"到一半大小的线的原点

我的数学不是那么糟糕,但我的向量数学很小而且很久以前

小提琴(哦,来晚了)

小提琴

解决方案

通常,缩放是一个 4 步过程:

步骤 1 - 通过其边界框获取元素的中心

第 2 步 - 平移元素,使中心位于原点 (0,0)

第 3 步 - 缩放

第 4 步 - 将元素平移回其原始位置

在处理 SVG 矩阵和转换时,最好使用矩阵变换请求对象并将要变换的元素附加到变换列表对象.最初这可能不像使用转换字符串那样直观.即translate(-100,-200)scale(2,2)translate(100,200)"

但是,从长远来看,它会对您有好处.

以下是对象驱动转换的示例

<html xmlns="http://www.w3.org/1999/xhtml"><头><meta http-equiv="content-type" content="text/html; charset=UTF-8"><body style='font-family:arial'><中心>(此示例在:IE11/CH31/FF23 中测试)<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:8px;'>围绕元素中的固定中心点"顺序变换元素.对于此示例,使用其边界框的初始中心.

<div id="svgDiv" style='background-color:lightblue;width:400px;height:400px;'><svg id="mySVG" width="400" height="400"><rect id="myBox" fill="red" x=100 y=100 width=100 height=100/><圆id=centerPoint r=10 填充=石灰/></svg>

<button onClick=rotate()>rotate</button><button onClick=scaleXY()>scaleXY</button><button onClick=skewX()>skewX</button><button onClick=skewY()>skewY</button><button onClick=startOver()>重新开始</button><br/>SVG 来源:<br/><textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></textarea></中心><脚本>document.addEventListener("onload",init(),false)函数初始化(){initTransform()svgSourceValue.value=svgDiv.innerHTML}var Cx,Cyvar TransformRequestObjvar 变换列表//- -负载 - -函数 initTransform(){var bb=myBox.getBBox()var bbx=bb.xvar bby=bb.yvar bbw=bb.widthvar bbh=bb.heightCx=bbx+.5*bbwCy=bby+.5*bbhcenterPoint.setAttribute("cx",Cx)centerPoint.setAttribute("cy",Cy)SVGPnt=mySVG.createSVGPoint()TransformRequestObj=mySVG.createSVGTransform()var animTransformList=myBox.transformTransformList=animTransformList.baseVal}//- 按钮 -函数旋转(){可变角度=30TransformRequestObj.setRotate(10,Cx,Cy)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()svgSourceValue.value=svgDiv.innerHTML}//- -按钮 - -函数 scaleXY(){var scaleX=1.05var scaleY=1.05TransformRequestObj.setTranslate(Cx,Cy)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()TransformRequestObj.setScale(scaleX,scaleY)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()TransformRequestObj.setTranslate(-Cx,-Cy)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()svgSourceValue.value=svgDiv.innerHTML}//- -按钮 - -函数 skewX(){var skwX=5//---弧度TransformRequestObj.setTranslate(Cx,Cy)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()TransformRequestObj.setSkewX(skwX)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()TransformRequestObj.setTranslate(-Cx,-Cy)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()svgSourceValue.value=svgDiv.innerHTML}//- -按钮 - -函数 skewY(){var skwY=10//---度TransformRequestObj.setTranslate(Cx,Cy)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()TransformRequestObj.setSkewY(skwY)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()TransformRequestObj.setTranslate(-Cx,-Cy)TransformList.appendItem(TransformRequestObj)TransformList.consolidate()svgSourceValue.value=svgDiv.innerHTML}//- -按钮 - -函数 startOver(){myBox.removeAttribute("转换")TransformRequestObj=mySVG.createSVGTransform()var animTransformList=myBox.transformTransformList=animTransformList.baseVal}</html>

I am fighting with svg matrix

what i want is to scale the size of an object, not its origin (in the drawing), ie. make it smaller (or bigger) but dont move it

i have a box x=y=w=h=4 and an other

X---####----####
----####----####
----####----####
----####----####

i want x=4=y=4 w=h=2

X---##------##
--------------
----##------##
--------------

what ever I try i get (without useless things)

h=y=w=h=2 (ie. scale a half)

X-##--##
--##--##

notice, that i dont know the origin at the line of "scale" to half size

my math isnt that bad but my vector-math was small and is long ago

edit: fiddle (oh, to late)

fiddle

解决方案

Typically, scaling is a 4-step process:

step 1 - get element's center via its bounding box

step 2 - translate the element so the center is at the origin(0,0)

step 3 - scale it

step 4 - translate the element back to its original position

When dealing with SVG matrices and transforms it is a good idea to use a Matrix Transform Request Object and attach the element to be transformed to a Transform List Object. Initially this may not be as intuitive as using transform strings. i.e. "translate(-100,-200)scale(2,2)translate(100,200)"

However, in the long run it will serve you well.

Below is an example of the Object driven transforms

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='font-family:arial'>
<center>
(This example tested in: IE11/CH31/FF23)
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:8px;'>
Sequentially Transform an element about a fixed 'center point' in the element.
For this example, use the initial center of its bounding box.
</div>
<div id="svgDiv" style='background-color:lightblue;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400">
<rect id="myBox" fill="red" x=100 y=100 width=100 height=100 />
<circle id=centerPoint r=10 fill=lime />
</svg>
</div>
<button onClick=rotate()>rotate</button>
<button onClick=scaleXY()>scaleXY</button>
<button onClick=skewX()>skewX</button>
<button onClick=skewY()>skewY</button>
<button onClick=startOver()>start over</button>
 <br />SVG Source:<br />
<textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></textarea>
</center>
</body>
<script>
document.addEventListener("onload",init(),false)
function init()
{
    initTransform()
    svgSourceValue.value=svgDiv.innerHTML
}

var Cx,Cy
var TransformRequestObj
var TransformList
//---onload---
function initTransform()
{
    var bb=myBox.getBBox()
    var bbx=bb.x
    var bby=bb.y
    var bbw=bb.width
    var bbh=bb.height
    Cx=bbx+.5*bbw
    Cy=bby+.5*bbh
    centerPoint.setAttribute("cx",Cx)
    centerPoint.setAttribute("cy",Cy)
    SVGPnt=mySVG.createSVGPoint()

    TransformRequestObj=mySVG.createSVGTransform()
    var animTransformList=myBox.transform
    TransformList=animTransformList.baseVal
}
//--button--
function rotate()
{
    var angle=30

    TransformRequestObj.setRotate(10,Cx,Cy)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()

    svgSourceValue.value=svgDiv.innerHTML
}
//---button---
function scaleXY()
{
    var scaleX=1.05
    var scaleY=1.05

    TransformRequestObj.setTranslate(Cx,Cy)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()
    TransformRequestObj.setScale(scaleX,scaleY)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()
    TransformRequestObj.setTranslate(-Cx,-Cy)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()

    svgSourceValue.value=svgDiv.innerHTML

}
//---button---
function skewX()
{
    var skwX=5 //---radians

    TransformRequestObj.setTranslate(Cx,Cy)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()

    TransformRequestObj.setSkewX(skwX)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()

    TransformRequestObj.setTranslate(-Cx,-Cy)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()

   svgSourceValue.value=svgDiv.innerHTML
}
//---button---
function skewY()
{
    var skwY=10 //---deg
    TransformRequestObj.setTranslate(Cx,Cy)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()

    TransformRequestObj.setSkewY(skwY)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()

    TransformRequestObj.setTranslate(-Cx,-Cy)
    TransformList.appendItem(TransformRequestObj)
    TransformList.consolidate()

    svgSourceValue.value=svgDiv.innerHTML
}
//---button---
function startOver()
{
    myBox.removeAttribute("transform")
    TransformRequestObj=mySVG.createSVGTransform()
    var animTransformList=myBox.transform
    TransformList=animTransformList.baseVal
}

</script>
</html>

这篇关于如何使用 svg 矩阵变换来缩放而不是翻译(隐式)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆