Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 规范化SVG以便于存储_Javascript_Html_Canvas_Svg_Adobe Illustrator - Fatal编程技术网

Javascript 规范化SVG以便于存储

Javascript 规范化SVG以便于存储,javascript,html,canvas,svg,adobe-illustrator,Javascript,Html,Canvas,Svg,Adobe Illustrator,我有一个SVG文件要存储在数据库中。将所有对象存储为多边形并存储坐标将非常有用。但是,我使用的文件是从Ilustrator导出的。它确实包含多边形,但也包含变换的矩形和其他形式。元素不必以绝对精度渲染,因此舍入误差不是问题 如何转换转换后的矩形 这没关系: <polygon points="2694.423,2972.209 2685.76,2982.961 2702.282,2996.274 2710.938,2985.526 "/ canvas与svg之间是否存在性能问题?。我有

我有一个SVG文件要存储在数据库中。将所有对象存储为多边形并存储坐标将非常有用。但是,我使用的文件是从Ilustrator导出的。它确实包含多边形,但也包含变换的矩形和其他形式。元素不必以绝对精度渲染,因此舍入误差不是问题

如何转换转换后的矩形

这没关系:

<polygon points="2694.423,2972.209 2685.76,2982.961 2702.282,2996.274
2710.938,2985.526   "/

canvas与svg之间是否存在性能问题?。我有大约3000个可单击的对象要渲染。

应用变换normaliser步骤可以通过使用来实现


至于第二步,您可能需要为此添加自己的代码。

在许多情况下,在转换后将某些svg元素(直线、矩形、圆、椭圆、多边形、多段线和路径)返回到其屏幕x、y值是有意义的。这是通过使用getCTMmatrixTransform 注意:对于带有笔划(*在IE中不可用)的元素,使用vector effect=“非缩放笔划”。 以下是返回各种转换svg元素的屏幕点的代码:

//----build a generic document SVG root to hold svg point---
function screenLine(line,svg)
{
    var sCTM = line.getCTM()
    var x1=parseFloat(line.getAttribute("x1"))
    var y1=parseFloat(line.getAttribute("y1"))
    var x2=parseFloat(line.getAttribute("x2"))
    var y2=parseFloat(line.getAttribute("y2"))

    var mySVGPoint1 = svg.createSVGPoint();
    mySVGPoint1.x = x1
    mySVGPoint1.y = y1
    mySVGPointTrans1 = mySVGPoint1.matrixTransform(sCTM)
    line.setAttribute("x1",mySVGPointTrans1.x)
    line.setAttribute("y1",mySVGPointTrans1.y)

    var mySVGPoint2 = svg.createSVGPoint();
    mySVGPoint2.x = x2
    mySVGPoint2.y = y2
    mySVGPointTrans2= mySVGPoint2.matrixTransform(sCTM)
    line.setAttribute("x2",mySVGPointTrans2.x)
    line.setAttribute("y2",mySVGPointTrans2.y)
    //---force removal of transform--
    line.setAttribute("transform","")
    line.removeAttribute("transform")
}
function screenCircle(circle,svg)
{
    var sCTM = circle.getCTM()
    var scaleX  = sCTM.a;

    var cx=parseFloat(circle.getAttribute("cx"))
    var cy=parseFloat(circle.getAttribute("cy"))

    var r=parseFloat(circle.getAttribute("r"))

    var mySVGPointC = svg.createSVGPoint();
    mySVGPointC.x = cx
    mySVGPointC.y = cy
    mySVGPointTransC = mySVGPointC.matrixTransform(sCTM)
    circle.setAttribute("cx",mySVGPointTransC.x)
    circle.setAttribute("cy",mySVGPointTransC.y)

    circle.setAttribute("r",r*scaleX)
    //---force removal of transform--
    circle.setAttribute("transform","")
    circle.removeAttribute("transform")
}
function screenEllipse(ellipse,svg)
{
    var sCTM = ellipse.getCTM()
    var scaleX  = sCTM.a;
    var scaleY  = sCTM.d;

    var cx=parseFloat(ellipse.getAttribute("cx"))
    var cy=parseFloat(ellipse.getAttribute("cy"))

    var rx=parseFloat(ellipse.getAttribute("rx"))
    var ry=parseFloat(ellipse.getAttribute("ry"))

    var mySVGPointC = svg.createSVGPoint();
    mySVGPointC.x = cx
    mySVGPointC.y = cy
    mySVGPointTransC = mySVGPointC.matrixTransform(sCTM)
    ellipse.setAttribute("cx",mySVGPointTransC.x)
    ellipse.setAttribute("cy",mySVGPointTransC.y)

    ellipse.setAttribute("rx",rx*scaleX)
    ellipse.setAttribute("ry",ry*scaleY)

    //---force removal of transform--
    ellipse.setAttribute("transform","")
    ellipse.removeAttribute("transform")
}
function screenRect(rect,svg)
{
    var sCTM = rect.getCTM()
    var scaleX  = sCTM.a;
    var scaleY  = sCTM.d;

    var x=parseFloat(rect.getAttribute("x"))
    var y=parseFloat(rect.getAttribute("y"))

    var width=parseFloat(rect.getAttribute("width"))
    var height=parseFloat(rect.getAttribute("height"))

    var mySVGPoint = svg.createSVGPoint();
    mySVGPoint.x = x
    mySVGPoint.y = y
    mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
    rect.setAttribute("x",mySVGPointTrans.x)
    rect.setAttribute("y",mySVGPointTrans.y)

    rect.setAttribute("width",width*scaleX)
    rect.setAttribute("height",height*scaleY)

    //---force removal of transform--
    rect.setAttribute("transform","")
    rect.removeAttribute("transform")
}
function screenPolyline(myPoly,svg)
{
    var sCTM = myPoly.getCTM()
    var pointsList = myPoly.points;
    var n = pointsList.numberOfItems;
    for(var m=0;m<n;m++)
    {
        var mySVGPoint = mySVG.createSVGPoint();
        mySVGPoint.x = pointsList.getItem(m).x
        mySVGPoint.y = pointsList.getItem(m).y
        mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
        pointsList.getItem(m).x=mySVGPointTrans.x
        pointsList.getItem(m).y=mySVGPointTrans.y
    }
    //---force removal of transform--
    myPoly.setAttribute("transform","")
    myPoly.removeAttribute("transform")
}

function screenPath(path,svg)
{
    var sCTM = path.getCTM()
    var scaleX  = sCTM.a;
    var scaleY  = sCTM.d;

    var segList=path.pathSegList
    var segs=segList.numberOfItems
    //---change segObj values
    for(var k=0;k<segs;k++)
    {
        var segObj=segList.getItem(k)

        if(segObj.x && segObj.y )
        {
            var mySVGPoint = svg.createSVGPoint();
            mySVGPoint.x = segObj.x
            mySVGPoint.y = segObj.y
            mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
            segObj.x=mySVGPointTrans.x
            segObj.y=mySVGPointTrans.y
        }

        if(segObj.x1 && segObj.y1)
        {
            var mySVGPoint1 = svg.createSVGPoint();
            mySVGPoint1.x = segObj.x1
            mySVGPoint1.y = segObj.y1
            mySVGPointTrans1 = mySVGPoint1.matrixTransform(sCTM)
            segObj.x1=mySVGPointTrans1.x
            segObj.y1=mySVGPointTrans1.y
        }
        if(segObj.x2 && segObj.y2)
        {
            var mySVGPoint2 = svg.createSVGPoint();
            mySVGPoint2.x = segObj.x2
            mySVGPoint2.y = segObj.y2
            mySVGPointTrans2 = mySVGPoint2.matrixTransform(sCTM)
            segObj.x2=mySVGPointTrans2.x
            segObj.y2=mySVGPointTrans2.y
        }

        if(segObj.r1)segObj.r1=segObj.r1*scaleX
        if(segObj.r2)segObj.r2=segObj.r2*scaleX
    }
    //---force removal of transform--
    path.setAttribute("transform","")
    path.removeAttribute("transform")
}

//---changes all transformed points to screen points---
function screenPolygon(myPoly,mySVG)
{
    var sCTM = myPoly.getCTM()
    var pointsList = myPoly.points;
    var n = pointsList.numberOfItems;
    for(var m=0;m<n;m++)
    {
        var mySVGPoint = mySVG.createSVGPoint();
        mySVGPoint.x = pointsList.getItem(m).x
        mySVGPoint.y = pointsList.getItem(m).y
        mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
        pointsList.getItem(m).x=mySVGPointTrans.x
        pointsList.getItem(m).y=mySVGPointTrans.y
    }
    //---force removal of transform--
    myPoly.setAttribute("transform","")
    myPoly.removeAttribute("transform")
}
/----构建一个通用文档SVG根以保存SVG点---
功能屏幕行(行,svg)
{
var sCTM=line.getCTM()
var x1=parseFloat(line.getAttribute(“x1”))
var y1=parseFloat(line.getAttribute(“y1”))
var x2=parseFloat(line.getAttribute(“x2”))
var y2=parseFloat(line.getAttribute(“y2”))
var mySVGPoint1=svg.createSVGPoint();
mySVGPoint1.x=x1
mySVGPoint1.y=y1
mySVGPointTrans1=mySVGPoint1.matrixTransform(sCTM)
line.setAttribute(“x1”,mySVGPointTrans1.x)
line.setAttribute(“y1”,mySVGPointTrans1.y)
var mySVGPoint2=svg.createSVGPoint();
mySVGPoint2.x=x2
mySVGPoint2.y=y2
mySVGPointTrans2=mySVGPoint2.matrixTransform(sCTM)
line.setAttribute(“x2”,mySVGPointTrans2.x)
line.setAttribute(“y2”,mySVGPointTrans2.y)
//---变换的强制消除--
line.setAttribute(“转换”,“转换”)
行。删除属性(“转换”)
}
功能屏幕圆圈(圆圈、svg)
{
var sCTM=circle.getCTM()
var scaleX=sCTM.a;
var cx=parseFloat(circle.getAttribute(“cx”))
var cy=parseFloat(circle.getAttribute(“cy”))
var r=parseFloat(circle.getAttribute(“r”))
var mySVGPointC=svg.createSVGPoint();
mySVGPointC.x=cx
mysvgpoint c.y=cy
mySVGPointTransC=mySVGPointC.matrixTransform(sCTM)
circle.setAttribute(“cx”,mySVGPointTransC.x)
circle.setAttribute(“cy”,mySVGPointTransC.y)
circle.setAttribute(“r”,r*scaleX)
//---变换的强制消除--
circle.setAttribute(“transform”、“”)
圈。删除属性(“转换”)
}
函数屏幕椭圆(椭圆,svg)
{
var sCTM=eliple.getCTM()
var scaleX=sCTM.a;
var scaleY=sCTM.d;
var cx=parseFloat(ellipse.getAttribute(“cx”))
var cy=parseFloat(ellipse.getAttribute(“cy”))
var rx=parseFloat(ellipse.getAttribute(“rx”))
var ry=parseFloat(ellipse.getAttribute(“ry”))
var mySVGPointC=svg.createSVGPoint();
mySVGPointC.x=cx
mysvgpoint c.y=cy
mySVGPointTransC=mySVGPointC.matrixTransform(sCTM)
setAttribute(“cx”,mySVGPointTransC.x)
setAttribute(“cy”,mySVGPointTransC.y)
ellipse.setAttribute(“rx”,rx*scaleX)
ellipse.setAttribute(“ry”,ry*scaleY)
//---变换的强制消除--
setAttribute(“transform”、“”)
ellipse.removeAttribute(“变换”)
}
函数screenRect(rect,svg)
{
var sCTM=rect.getCTM()
var scaleX=sCTM.a;
var scaleY=sCTM.d;
var x=parseFloat(rect.getAttribute(“x”))
var y=parseFloat(rect.getAttribute(“y”))
var width=parseFloat(rect.getAttribute(“宽度”))
var height=parseFloat(rect.getAttribute(“height”))
var mySVGPoint=svg.createSVGPoint();
mySVGPoint.x=x
mySVGPoint.y=y
mySVGPointTrans=mySVGPoint.matrixTransform(sCTM)
rect.setAttribute(“x”,mySVGPointTrans.x)
rect.setAttribute(“y”,mySVGPointTrans.y)
rect.setAttribute(“宽度”,宽度*scaleX)
rect.setAttribute(“高度”,高度*scaleY)
//---变换的强制消除--
rect.setAttribute(“transform”,“”)
rect.removeAttribute(“转换”)
}
函数屏幕多段线(myPoly、svg)
{
var sCTM=myPoly.getCTM()
var pointsList=myPoly.points;
var n=pointsList.numberOfItems;

对于(var m=0;m给定:

function simplifyTransform(point,matrix){
    simpleX = point.x * matrix[0] + point.y * matrix[2] + matrix[4];
    simpleY = point.x * matrix[1] + point.y * matrix[3] + matrix[5];
    return({x:simpleX,y:simpleY});
}
  • 您未转换的SVG点

  • 以及您的SVG转换矩阵

可以从数学上将变换应用于这些点

结果点是变换后的XY——“标准化”XY

生成的点将在与转换的SVG点相同的位置绘制到画布

生成的点不需要在正确的位置绘制SVG转换

下面是应用转换矩阵“规范化”点的代码:

function simplifyTransform(point,matrix){
    simpleX = point.x * matrix[0] + point.y * matrix[2] + matrix[4];
    simpleY = point.x * matrix[1] + point.y * matrix[3] + matrix[5];
    return({x:simpleX,y:simpleY});
}
下面是一个例子:

下面是代码和演示:


正文{背景色:象牙;}
#画布{边框:1px纯红;}
$(函数(){
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var x=50;
变量y=50;
var h=30;
var w=50;
var矩阵=[1.25,75,75,1.25,20,20];
ctx.save();
变换(矩阵[0],矩阵[1],矩阵[2],矩阵[3],矩阵[4],矩阵[5],矩阵[6]);
ctx.fillStyle=“红色”;
ctx.fillRect(x,y,w,h);
ctx.restore();
//将矩形的4个角做成一个数组
var点=[];
push({x:x,y:y});
push({x:x+w,y:y});
push({x:x+w,y:y+h});
push({x:x,y:y+h});
//获取未转换空间中已转换矩形的角点
var rect=简化多边形(点、矩阵);
//笔划未转换的矩形
ctx.save();
ctx.strokeStyle=“绿色”;
ctx.线宽=2;
移动到(rect[0].x,rect[0].y);
对于(var i=1;
function simplifyTransform(point,matrix){
    simpleX = point.x * matrix[0] + point.y * matrix[2] + matrix[4];
    simpleY = point.x * matrix[1] + point.y * matrix[3] + matrix[5];
    return({x:simpleX,y:simpleY});
}
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var x=50;
    var y=50;
    var h=30;
    var w=50;
    var matrix=[1.25,.75,.75,1.25,20,20];

    ctx.save();
    ctx.transform(matrix[0],matrix[1],matrix[2],matrix[3],matrix[4],matrix[5],matrix[6]);
    ctx.fillStyle="red";
    ctx.fillRect(x,y,w,h);
    ctx.restore();


    // make an array of the 4 corners of the rectangle
    var points=[];
    points.push({x:x,y:y});
    points.push({x:x+w,y:y});
    points.push({x:x+w,y:y+h});
    points.push({x:x,y:y+h});

    // get the transformed rectangle's corners in untransformed space
    var rect=simplifyPoly(points,matrix);

    // stroke the untransformed rectangle
    ctx.save();
    ctx.strokeStyle="green";
    ctx.lineWidth=2;
    ctx.moveTo(rect[0].x,rect[0].y);
    for(var i=1;i<rect.length;i++){
        ctx.lineTo(rect[i].x,rect[i].y);
    }
    ctx.closePath();
    ctx.stroke();
    ctx.restore();

    function simplifyTransform(point,matrix){
        simpleX = point.x * matrix[0] + point.y * matrix[2] + matrix[4];
        simpleY = point.x * matrix[1] + point.y * matrix[3] + matrix[5];
        return({x:simpleX,y:simpleY});
    }

    function simplifyPoly(points,matrix){
        var simplePoints=[];
        for(var i=0;i<points.length;i++){
            simplePoints.push(simplifyTransform(points[i],matrix));
        }
        return(simplePoints);
    }

}); // end $(function(){});
</script>

</head>

<body>
    <h4>The red fill is drawn using untransformed points plus a transform<br>The green stroke is drawn using the "simplified" points--no transform involved.</h4>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>