Using svg-pan-zoom utility, I want to register the zoom and pan values every time is changes (using onPan() and onZoom()) and use these saved values to pan and zoom my SVG to the same position (using pan() and zoom()).
I works fine if the zoom level is not changed, however, if zoom level is changed, I have a gap between the wanted position of the svg and the real one.
You can see this problem in that fiddle: first, zoom in, then press the Pan button.
I would like my svg to keep its current location.
I have read other posts on stackoverflow about similar situations (I guess I should use data from getSizes()) but I'm still unable to make it work.
Any advice?
OK, I got the solution, which is quite obvious.
While zooming, I need to apply a zoom factor to the saved pan.
onZoom: function(zoom) {
ratio = zoom/currentZoom;
currentZoom = zoom;
currentPan = {
x: currentPan.x*ratio,
y: currentPan.y*ratio
}
}
See full code here
Related
Long story short: I want to set Edit2D polyline tool's line width to 6" based on calibration sizing and have it stay that size in the viewer no matter the camera zoom.
I'm using the edit2d library to allow drawing. I need to be able to set the line width for the polyline tool and have it stay at that width similar to how markups stay a set size when drawn. The default functionality of the edit2d polyline tool is for the line to be resized on camera changes and so it grows and shrinks depending on zoom.
I tried setting edit2DTools.polylineTool.style.isScreenSpace = false; which works, however, trying to set the specific size is difficult as it ends up being a decimal less then 1 and I can't find a correlation from the calibration, page size, etc. to allow me to dynamically set the size the same on different models.
I also found this in the Edit2D Snapper's code, but I can't figure out what's happening here to replicate it on the polyline tool. It seems to be doing what I want to do.
Any help or ideas at all would be greatly appreciated!
This code seems to be working for me:
async function setLineWidth(viewer) {
let mt = await viewer.loadExtension("Autodesk.Measure");
if (!mt.sharedMeasureConfig.calibrationFactor) {
console.log("Has not been calibrated yet");
return;
}
let edit2d = viewer.getExtension('Autodesk.Edit2D');
let pt1 = {x:0, y:0, z:0}, pt2 = {x:6, y:0, z:0};
viewer.model.pageToModel(pt1, pt2, 0 /*viewport id*/, true /*reverse*/);
let style = edit2d.defaultTools.polylineTool.style;
style.lineWidth = (pt2.x - pt1.x) / mt.calibration.scaleFactor;
}
Here is a video showing it in action: https://youtu.be/DIaKugvQdm4
As you can see first the lineWidth of the polylineTool is not what you want, but after setting what 6" should be in the drawing, I can set it to the same width and all is fine.
Here is a zip file with the html including the JavaScript code and the test PDFs I used: https://github.com/adamenagy/Container/blob/master/Edit2dTest.zip
I'd like to be able change the padding of a GMSMapView without changing the location of a map. Right now, Google Maps iOS SDK changes the map location so that the same point is in center after the padding has been applied. This is different than how the Android SDK works, which just leaves the map as it is.
I've found a slight workaround for this, but it doesn't work consistently. I can calculate what the new center location should be and update the map camera when I change the padding with the following...
UIEdgeInsets oldPadding = self.mapCtrl.map.padding;
UIEdgeInsets newPadding = UIEdgeInsetsMake(top, left, bottom, right);
float deltaX = ((newPadding.right - newPadding.left)/2 - (oldPadding.right-oldPadding.left)/2);
float deltaY = ((newPadding.top - newPadding.bottom)/2 - (oldPadding.top-oldPadding.bottom)/2);
GMSCameraUpdate *updatedCamera = [GMSCameraUpdate scrollByX:deltaX Y:deltaY];
[self.mapCtrl.map setPadding:newPadding];
[self.mapCtrl.map moveCamera:updatedCamera];
But I'd say it only works 50%. The other 50% the map moves to the new padding location and then back to where I want it to be.
I see two possible solutions for this... A) change the padding in a different way so that it doesn't move the map, or B) figure out a way to get the above code to work by somehow pausing or grouping map movements so that both calls only go through at once. But I can't figure out how to make either of those two things happen.
Make sure you have the same padding on top and bottom so everything keeps centered.
In case someone needs it in the future:
mapView.padding = newPadding
mapView.layer.removeAllAnimations()
That messes with the internals of GMSMapView though and the padding isn't applied to the map itself correctly, just to the UI.
I use the following code to re-apply the padding again after my animation so that the map behaves correctly again.
let newCenter = mapView.projection.coordinate(for: mapView.bounds.inset(by: newMapViewPadding).center)
mapView.padding = newMapViewPadding + UIEdgeInsets(all: 1)
mapView.padding = newMapViewPadding
mapView.moveCamera(GMSCameraUpdate.setTarget(newCenter))
It's correct that we need to set a padding with top AND bottom to keep things appearing correctly, but it's also important to do it AFTER attaching the view to it's parent.
I was doing it before and it did not work properly.
I am overlaying some clickable hotspots on top of a proprietary panorama viewer application in flash (as3), and I need to make sure that the hotspots scale according to the changing field of view as the user zooms in / zooms out, but I'm not sure what formula to use.
I set a maximum and minimum field of view of 90 and 25, respectively. I've been given some suggestions of how to calculate the scale of the icons:
from the maker of the panorama software:
Scale => 1/tan(FoV)
This doesn't seem to work for me. And:
scalar += (ZOOM_SCALE_UPPER - ZOOM_SCALE_LOWER) * ( ZOOM_LIMIT_OUT - tempFOV )/( ZOOM_LIMIT_OUT-ZOOM_LIMIT_IN) ;
hotspot.scaleX = hotspot.scaleY = scalar;
Gets me close, but at some point the hotspot stops scaling even though the panorama continues to scale. I thought I could just do something like:
diffFOV = previousFOV - currentFOV.
hotspot.scale = currentScale*(1-diffFov)
But that's not quite right either. Everything gets way too big or too small.
Any ideas?
You may be over thinking it.
//assume we change the scale
var NEW_SCALE:Number = currentScale*(1-(previousFOV-currentFOV));
//1. change the scale of the parent containing both the view and the hotspots
viewSprite.scale = NEW_SCALE;
//this way the hotspot and the panorama will scale together
//2. if they are not in the same parent... then set them both to the same view
hotspot.scale = panorama.scale;
Only thing you may have to do after is reposition if they are not registered on their center point.
First of all, I would like to say that I'm a newbie in Java3D. Please bear with my ignorance.
I have made an application with Java3D and I have the following problems with zooming.
It seems the MouseWheelZoom behaviour of Java3D moves the object along Z-axis. On the scene my Z-axis is not out of plane so by using MouseWheelZoom , the object doesn't get closer but it get out of screen. Is there a way to set the zoom direction to an arbitrary direction?
I have got around the problem by using MouseWheelListener and changing the viewing platform based on zoom steps. But there is another problem now. As the object gets closer than a certain distance, some parts of the object ( usually the corners) start disappearing so I can't zoom as much as I desire.
Could you please help ?
Regards,
Hassan
Question:
I guess you use an OrbitBehavior for MouseControl like:
orbit = new OrbitBehavior(canvas3d, OrbitBehavior.REVERSE_ALL);
If that is the case then try
orbit.setZoomFactor(-1d);
To reverse the zoom direction (the default zoom factor is +1d).
To your 2. Question:
You have to set a BoundingLeaf on your PlatformGeometry to encapsulate your "viewing area".
Try something like this
defaultBounds = new BoundingSphere(new Point3d(radiusGameMap, 0.0, radiusGameMap),
radiusGameMap * 6.0d);
BoundingLeaf boundingLeaf = new BoundingLeaf(defaultBounds);
PlatformGeometry platformGeom = new PlatformGeometry();
platformGeom.addChild(boundingLeaf);
where radiusGameMap is a double defining the radius of your whole map.
I'm using a flip mechanism to navigate through my site (flip file & demo). The problem is, once it's flipped the content been displayed good just like I want it, but there's some offset from the flipped (right) parts en the solid left part (visible when you look closely). Also the right part is now a little blurred (which is the disturbing part of my issue). This all caused by the flip (I think the rotationY is causing the problem).
When I click a button I do the following:
flip=new Flip(currentPage,nextPage,richting);
content.addChild(flip);
currentPage=nextPage;
nextPage = new MovieClip();
there is a fix for it, consider the following:
// store original matrix
var origMatrix:Matrix = box.transform.matrix;
// set initial position
box.rotationY = -180;
// start animation
TweenLite.to(box, 1, {rotationY:0, onComplete:cleanBlur})
// execute after animation complete
function cleanBlur():void {
box.transform.matrix = origMatrix;
}
maybe you can find better results using other 3d library.
EDIT: sorry the "box" object, I was testing in flash, but box would be any of your pages to flip. Just apply the same logic.
Matteo at Flash & Math has an excellent solution for this. He actually found that when you bring an object into native 3D space it expands the object by one pixel in both the width and height. This can be counteracted by scaling your object back and then setting it's z to 0 which will scale it back up. Now the object is ready to play with without the blur.
http://www.flashandmath.com/flashcs4/blursol/index.html
adding: This fixes the scale issue, but not the blurriness. You will still need to use the matrix transformation fix posted above.