1

Im using snap.svg an snap.svg.zpd libraries. Same issue I have if I use snap.svg and jQuery panzoom library combination.

Code sample you can find here.

var mySvg = $("#plan")[0];
var snap = Snap("#plan");
//create an image
var imagePlan = snap.image("http://upload.wikimedia.org/wikipedia/commons/4/42/Cathedral_schematic_plan_fr_vectorial.svg", 10, 10, 900, 500);

var group = snap.group(imagePlan);

snap.zpd();

var pt = mySvg.createSVGPoint(); // create the point;

imagePlan.click(function(evt)
        {
    console.log(evt);
            pt.x = evt.x;
            pt.y = evt.y;

            console.log(mySvg.getScreenCTM().inverse());
            //When click, create a rect
            var transformed =   pt.matrixTransform(mySvg.getScreenCTM().inverse());
            var rect1 = snap.rect(transformed.x, transformed.y, 40, 40);

            group.add(rect1);

        });

Problem is...if you click on initial svg it will add rectangle to the mouse position. If you pan/zoom image and then add rectangle it will be shiffted.

It looks like problem is in method mySvg.getScreenCTM().inverse(). Matrix returned is always same one, panning and zooming does not change it. It always use matrix from initialy rendered svg. However, if I inspect svg element, I can see that pann/zoom change transform matrix directly on element (image below).

enter image description here

Does anybody know how to fix this. My requirement is to be able to drag and drop elements outside svg into svg on any zoom scale or pan context, so I need transformation from mouse click point to svg offset coordinates. If you know any other approach or any other library combination that could done this, it would be ok for me.

Thanks in advance.

Ian
  • 13,724
  • 4
  • 52
  • 75
Minja
  • 1,222
  • 1
  • 19
  • 28

1 Answers1

3

Problem is, the transform isn't in mySvg. Its on the 'g' group element thats inside the svg. Zpd will create a group to operate on as far as I know, so you want to look at that.

To hightlight this, take a look at

console.log(mySvg.firstElementChild.getScreenCTM().inverse());

In this case its the g element (there's more direct ways of accessing it, depending on whether you want to just work in js, or snap, or svg.js).

jsfiddle

Its not quite clear from your description where you want the rect (within the svg, separate or whatt) to go and at what scale etc though, and if you want it to be part of the zoom/panning, or static or whatever. So I'm not sure whether you need this or not.

I'm guessing you want something like this

var tpt = pt.matrixTransform( mySvg.firstElementChild.getScreenCTM().inverse()  )

var rect1 = snap.rect(tpt.x, tpt.y, 40, 40);
Ian
  • 13,724
  • 4
  • 52
  • 75
  • This is exactly what I wanted. New created point to become part of the group and to follow group transformation when zooming and panning. Thanks – Minja Nov 25 '15 at 15:21
  • 1
    No problem, well done for getting that far actually, sometimes the matrix stuff is a bit hairy to understand. – Ian Nov 25 '15 at 15:30
  • Actually, my friend succeed to fix pan like this http://jsfiddle.net/L2kpd6yt/64/. We missed property you mentioned on svg object. – Minja Nov 25 '15 at 15:39
  • it is a bit late but it works even now. you saved my day bro. You are fucking great) thank you) – Begmuhammet Kakabayev Mar 20 '18 at 12:06