Reputation: 3954
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)
Upvotes: 2
Views: 1253
Reputation: 3498
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>
Upvotes: 2