properties-cpp  0.0.1
A very simple convenience library for handling properties and signals in C++11.
svgpan.js
Go to the documentation of this file.
1 
34 var root = document.documentElement;
35 var state = 'none';
37 var stateTf = root.createSVGMatrix();
38 var cursorGrab = ' url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRFAAAA////////c3ilYwAAAAN0Uk5T//8A18oNQQAAAD1JREFUeNp0zlEKACAIA9Bt9z90bZBZkQj29qFBEuBOzQHSnWTTyckEfqUuZgFvslH4ch3qLCO/Kr8cAgwATw4Ax6XRCcoAAAAASUVORK5CYII="), move';
39 var zoomSteps = 10;
44 var svgDoc;
45 var minZoom;
46 var maxZoom;
47 if (!window) window=this;
48 
52 function show()
53 {
54  if (window.innerHeight) // Firefox
55  {
56  windowWidth = window.innerWidth;
57  windowHeight = window.innerHeight;
58  }
59  else if (document.documentElement.clientWidth) // Chrome/Safari
60  {
61  windowWidth = document.documentElement.clientWidth
62  windowHeight = document.documentElement.clientHeight
63  }
64  if (!windowWidth || !windowHeight) // failsafe
65  {
66  windowWidth = 800;
67  windowHeight = 600;
68  }
69  minZoom = Math.min(Math.min(viewHeight,windowHeight)/viewHeight,Math.min(viewWidth,windowWidth)/viewWidth);
70  maxZoom = minZoom+1.5;
71  zoomInFactor = Math.pow(maxZoom/minZoom,1.0/zoomSteps);
72  zoomOutFactor = 1.0/zoomInFactor;
73 
74  var g = svgDoc.getElementById('viewport');
75  try
76  {
77  var bb = g.getBBox(); // this can throw an exception if css { display: none }
78  var tx = (windowWidth-viewWidth*minZoom+8)/(2*minZoom);
79  var ty = viewHeight+(windowHeight-viewHeight*minZoom)/(2*minZoom);
80  var a = 'scale('+minZoom+') rotate(0) translate('+tx+' '+ty+')';
81  g.setAttribute('transform',a);
82  }
83  catch(e) {}
84 }
85 
89 function init(evt)
90 {
91  svgDoc = evt.target.ownerDocument;
92  if (top.window && top.window.registerShow) // register show function in html doc for dynamic sections
93  {
94  top.window.registerShow(sectionId,show);
95  }
96  show();
97 
98  setAttributes(root, {
99  "onmousedown" : "handleMouseDown(evt)",
100  "onmousemove" : "handleMouseMove(evt)",
101  "onmouseup" : "handleMouseUp(evt)"
102  });
103 
104  if (window.addEventListener)
105  {
106  if (navigator.userAgent.toLowerCase().indexOf('webkit') >= 0 ||
107  navigator.userAgent.toLowerCase().indexOf("opera") >= 0 ||
108  navigator.appVersion.indexOf("MSIE") != -1)
109  {
110  window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari/IE9
111  }
112  else
113  {
114  window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
115  }
116  }
117 }
118 
119 window.onresize=function()
120 {
121  if (svgDoc) { show(); }
122 }
123 
127 function getEventPoint(evt)
128 {
129  var p = root.createSVGPoint();
130  p.x = evt.clientX;
131  p.y = evt.clientY;
132  return p;
133 }
134 
138 function setCTM(element, matrix)
139 {
140  var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
141  element.setAttribute("transform", s);
142 }
143 
147 function setAttributes(element, attributes)
148 {
149  for (i in attributes)
150  element.setAttributeNS(null, i, attributes[i]);
151 }
152 
153 function doZoom(g,point,zoomFactor)
154 {
155  var p = point.matrixTransform(g.getCTM().inverse());
156  var k = root.createSVGMatrix().translate(p.x, p.y).scale(zoomFactor).translate(-p.x, -p.y);
157  var n = g.getCTM().multiply(k);
158  var s = Math.max(n.a,n.d);
159  if (s>maxZoom) n=n.translate(p.x,p.y).scale(maxZoom/s).translate(-p.x,-p.y);
160  else if (s<minZoom) n=n.translate(p.x,p.y).scale(minZoom/s).translate(-p.x,-p.y);
161  setCTM(g, n);
162  stateTf = stateTf.multiply(n.inverse());
163 }
164 
168 function handleMouseWheel(evt)
169 {
170  if (!evt) evt = window.evt;
171  if (!evt.shiftKey) return; // only zoom when shift is pressed
172  if (evt.preventDefault) evt.preventDefault();
173  evt.returnValue = false;
174 
175  if (state!='pan')
176  {
177  var delta;
178  if (evt.wheelDelta)
179  {
180  delta = evt.wheelDelta / 7200; // Opera/Chrome/IE9/Safari
181  }
182  else
183  {
184  delta = evt.detail / -180; // Mozilla
185  }
186  var svgDoc = evt.target.ownerDocument;
187  var g = svgDoc.getElementById("viewport");
188  var p = getEventPoint(evt);
189  doZoom(g,p,1+delta);
190  }
191 }
192 
196 function handleMouseMove(evt)
197 {
198  if(evt.preventDefault)
199  evt.preventDefault();
200 
201  evt.returnValue = false;
202 
203  var g = svgDoc.getElementById("viewport");
204 
205  if (state == 'pan')
206  {
207  // Pan mode
208  var p = getEventPoint(evt).matrixTransform(stateTf);
209  setCTM(g,stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
210  }
211 }
212 
216 function handleMouseDown(evt)
217 {
218  if(evt.preventDefault)
219  evt.preventDefault();
220  evt.returnValue = false;
221  var g = svgDoc.getElementById("viewport");
222  state = 'pan';
223  stateTf = g.getCTM().inverse();
224  stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
225  g.style.cursor = cursorGrab;
226 }
227 
231 function handleMouseUp(evt)
232 {
233  if (evt.preventDefault) evt.preventDefault();
234  evt.returnValue = false;
235  var g = svgDoc.getElementById("viewport");
236  g.style.cursor = "default";
237  // Quit pan mode
238  state = '';
239 }
240 
244 function dumpMatrix(matrix)
245 {
246  var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n 0, 0, 1 ]";
247  return s;
248 }
249 
253 function handlePan(x,y)
254 {
255  var g = svgDoc.getElementById("viewport");
256  setCTM(g,g.getCTM().translate(x*20/minZoom,y*20/minZoom));
257 }
258 
262 function handleReset()
263 {
264  show();
265 }
266 
270 function handleZoom(evt,direction)
271 {
272  var g = svgDoc.getElementById("viewport");
273  var factor = direction=='in' ? zoomInFactor : zoomOutFactor;
274  var m = g.getCTM();
275  var p = root.createSVGPoint();
276  p.x = windowWidth/2;
277  p.y = windowHeight/2;
278  doZoom(g,p,factor);
279 }
280 
281 function serializeXmlNode(xmlNode)
282 {
283  if (typeof window.XMLSerializer != "undefined") {
284  return (new window.XMLSerializer()).serializeToString(xmlNode);
285  } else if (typeof xmlNode.xml != "undefined") {
286  return xmlNode.xml;
287  }
288  return "";
289 }
290 
294 function handlePrint(evt)
295 {
296  evt.returnValue = false;
297  var g = svgDoc.getElementById("graph");
298  var xs = serializeXmlNode(g);
299  try {
300  var w = window.open('about:blank','_blank','width='+windowWidth+',height='+windowHeight+
301  ',toolbar=0,status=0,menubar=0,scrollbars=0,resizable=0,location=0,directories=0');
302  var d = w.document;
303  d.write('<html xmlns="http://www.w3.org/1999/xhtml" '+
304  'xmlns:svg="http://www.w3.org/2000/svg" '+
305  'xmlns:xlink="http://www.w3.org/1999/xlink">');
306  d.write('<head><title>Print SVG</title></head>');
307  d.write('<body style="margin: 0px; padding: 0px;" onload="window.print();">');
308  d.write('<div id="svg" style="width:'+windowWidth+'px; height:'+windowHeight+'px;">'+xs+'</div>');
309  d.write('</body>');
310  d.write('</html>');
311  d.close();
312  } catch(e) {
313  alert('Failed to open popup window needed for printing!\n'+e.message);
314  }
315 }
316 
317 
318 
319 
var zoomInFactor
Definition: svgpan.js:40
var zoomOutFactor
Definition: svgpan.js:41
function p(by, bw, bv)
Definition: jquery.js:23
var stateTf
Definition: svgpan.js:37
var zoomSteps
Definition: svgpan.js:39
function init(evt)
Definition: svgpan.js:89
function show()
Definition: svgpan.js:52
var svgDoc
Definition: svgpan.js:44
var state
Definition: svgpan.js:35
var maxZoom
Definition: svgpan.js:46
var cursorGrab
Definition: svgpan.js:38
var windowHeight
Definition: svgpan.js:43
var minZoom
Definition: svgpan.js:45
var root
Definition: svgpan.js:34
var windowWidth
Definition: svgpan.js:42
function bb
Definition: jquery.js:16
var k
Definition: jquery.js:23
var stateOrigin
Definition: svgpan.js:36