I'm having a bit of an issue trying to rotate an image on a particular point.
I've been using http://jsfiddle.net/YKj5D/ as an example; which works perfectly when wanting to rotate an image from its center point.
However, using the example above, i wanted to rotate the image around the letter G, how could this be achieved?
Current code:
function rotateGearStick()
{
var rotation = function (){
$("#gear-stick").rotate({
angle:0,
animateTo:110,
});
}
rotation();
}
Where gear-stick is the ID of my image.
I'm attempting to create an rev counter dial.
http://jsfiddle.net/YKj5D/1988/
#image{
margin:100px;
padding-left:170px; /* <----- */
}
I find this a lot more cleaner fix.
#image{
-webkit-transform-origin:0px 0px;
-moz-transform-origin:0px 0px;
-ms-transform-origin:0px 0px;
transform-origin:0px 0px; //px or percent whichever you prefer
}
Just change the origin values to whatever suits your needs and it will rotate about that origin.
Recent version of jQueryRotate handles changing center of rotation cross-browse. Using padding-only solution will not work for a fallbacks to CANVAS/VML. Please check http://jqueryrotate.googlecode.com
The http://jqueryrotate.googlecode.com (suggested by Wilq32 in above post) documentation says adding the "center" attribute as shown below. It takes a array of length 2 of absolute pixel position or percentage. I.e. center: ["150px", "100px"] OR center: ["60%", "50%"]
var rotation = function (){
$("#image").rotate({
angle:0,
animateTo:360,
center: ["150px", "100px"],
callback: rotation
});
}
rotation();
Related
I have been struggling for a while with a Angular application that has one component with a map. To be able to rule out any other problems I have done a rewrite in pure javascript to test the functionality but I can't figure out how to solve this.
What I want to do is the same kind of functionality as in for example Google Maps, If you have the cursor over a specific city and zoom in with the mouse scroll then the map zooms in but keeps the city at the same place under the cursor.
I have this code and it's the function "zoomImage" that give me problems..
https://codepen.io/m-rten-sw-rd/pen/BMZvZX
Anyone that could guide me right on this?
function zoomImage(scale, mousePosInCointainer, mousePosInImage) {
var imgElement = document.getElementById("img");
imgElement.width = imgElement.width * scale;
imgElement.height = imgElement.height * scale;
/* TODO: Determine how I'm going to center the image over cursor */
}
I believe the following is what you need to be doing.
Determine transform origin (should be center) of the image.
Determine difference between mouse cursor and that point.
Scale that difference by your scale factor.
Translate the image by that difference.
I am changing a marker's position every 15 seconds based on the position from another device (something similar to what UBER does).
So basically I am doing this:
//this is the new position I get
const posObj = { lat: lat, lng: lng };
this.map.setCenter(posObj, true);
this.truckMarker.setPosition(posObj);
The problem is that the change looks abrupt, I mean there is no transition or animation between the two positions.
I added a css transition to the marker
transition: transform 1s linear;
and it is working better but I am still having troubles to animate the set center function.
BTW, I am using Ionic 3, Angular 5
Thanks in advance for you help!
Please check below route matching api between two locations or more than for a smooth transition.
https://developer.here.com/documentation/route-match/topics/quick-start-gps-trace-route.html
Requesting a route matching between two locations, you will get a route including many lat&lon along roads.
From the route result you can set lat&lon values.
I hope this helps.
You can use requestAnimationFrame in Angular for frame by frame animation and modify the marker in it.
private animate() {
requestAnimationFrame(() => this.animate());
}
I have a full page map, and what I would like to do is fix a polygon/rectangle over a portion of the map like such, so that the polygon will remain in the same place even if, say, the map was dragged. Then, I would like to set the center of the polygon to whatever the search query might be. Here is another image to illustrate what I mean. Unfortunately, from the documentation it seems as if you can only create polygons in another layer that remain attached, so to speak, to specific tiles on the base map. In addition to that, aside from setting its bounds, the documentation does not list any methods to set the center of a polygon.
Thus I have a couple of questions:
Is it even possible to fix a polygon/rectangle on the map, not in relation to but, independent of the positions of map tiles in the base layer?
Is it possible to set the center of a polygon/rectangle to a LatLng Object (or something similar), and then use this orientation to position the map as a whole?
P.S. If you're going to downvote my question, at least state why and give me a chance to address whatever your issue with the question might be...
I would recommend absolute positioning a div like this
<div id="mapdiv">
<div id="rect"></div>
</div>
and the css
#mapdiv {
position:relative;
width:600px;
height:400px;
background-color:#333;
}
#rect {
position:absolute;
top: 10%;
left: 10%;
width:80%;
height:80%;
background-color:#FFF;
}
as for using the co-ordinates and polys through the map. I have some experience with routes and such and would have to say it possible to get the shape but you would require a map refresh each time and for absolute positioning it. Not sure if thats possible
Sorry for that last answer...misunderstood. Have you tried this plus adding an offset of window width
function polygonCenter(poly) {
var lowx,
highx,
lowy,
highy,
lats = [],
lngs = [],
vertices = poly.getPath();
for(var i=0; i<vertices.length; i++) {
lngs.push(vertices.getAt(i).lng());
lats.push(vertices.getAt(i).lat());
}
lats.sort();
lngs.sort();
lowx = lats[0];
highx = lats[vertices.length - 1];
lowy = lngs[0];
highy = lngs[vertices.length - 1];
center_x = lowx + ((highx-lowx) / 2);
center_y = lowy + ((highy - lowy) / 2);
return (new google.maps.LatLng(center_x, center_y));
}
Again as for absolute positioning it after that I am still not quite certain
Might be a good starting point tho
Edit: found this link here on stack should actually work without knowing your setup how-do-i-get-google-maps-to-show-a-whole-polygon
This question is directed to Leaflet users (and those who use the Leaflet.draw plugin)...
I'm using Leaflet and would like to allow my user to draw 1--and only 1--single polygon over any area of the map. I would also like to limit the size of that polygon in some way (such as limiting the length of the side for a square or the area covered it covers--preferably specified in degrees so that the set size limits would translate regardless of the zoom level).
My end goal is simply to extract the coordinates of the 4 square vertices or the coordinates covered by the polygon area.
That said, I found the Leaflet.Draw plugin. It is fantastic, however, I need to limit its functionality to my requirements (only 1 polygon drawn at a time and, in particular, the size cannot be drawn too large). Is this possible to do? If so, how?
Regardless of if it is or is not possible, is there a better way to go about doing this?
Can I propose another solution to this issue?
I would limit the number of polygons to one by doing the following:
map.on('draw:created', function (e) {
var layer = e.layer;
if(drawnItems && drawnItems.getLayers().length!==0){
drawnItems.clearLayers();
}
drawnItems.addLayer(layer);
});
I am listening to the draw:created event and determine if there is already a marker. If there is, I remove that marker and place my new one in the desired location. Therefore, one less click for user as they no longer need to delete the previous and one marker rule is always enforced.
If you wanted to allow more than one marker you could do a FIFO delete of the oldest layer.
If you do not want to automatically delete a layer, you could either prompt the user or ignore the request.
That said, I found the Leaflet.Draw plugin. It is fantastic, however, I need to limit its functionality to my requirements (only 1 polygon drawn at a time and, in particular, the size cannot be drawn too large). Is this possible to do? If so, how?
I think you'll need to code it yourself.
I see two possibities:
hacking the draw plugin (writing your own code inside the plugin)
extending the L.Draw.Polygon class from the draw plugin (see the docs about OOP in Leaflet) to create a costum one
1 is faster, 2 is cleaner. You'll have to choose depending on the size of your project.
I did it without hacking the Leaflet Draw source.
After the controls are added to the map, I place a hidden div inside the controls. Then when a polygon is created I display that div. I used CSS to absolute position it over the controls so the buttons are then "disabled" and CSS to make the buttons look faded. If the polygon is deleted then I hide that div.
Not the best solution, but I works without having to edit the source.
After drawControl is added, I add the hidden div:
$('.leaflet-draw-section:first').append('<div class="leaflet-draw-inner-toolbar" title="Polygon already added"></div>');
Here's the JS to toggle them:
map.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
// keep the polygon on the map
drawnItems.addLayer(layer);
// disable the create polygon tools
$('.leaflet-draw-inner-toolbar').show();
});
map.on('draw:deleted', function(e) {
// enable the create polygon tools
$('.leaflet-draw-inner-toolbar').hide();
});
Here's the CSS:
.leaflet-draw-inner-toolbar {
background: none repeat scroll 0 0 rgba(255, 255, 255, 0.6);
bottom: 0;
display: none;
left: 0;
position: absolute;
right: 0;
top: 0;
}
I just started with fabric.js and I have a (probably beginner) error:
I am using fabric with jquery with the following code:
$(document).ready(function () {
canvas = new fabric.StaticCanvas('scroller');
canvas.add(
new fabric.Rect({ top: 0, left: 0, width: 140, height: 100, fill: '#f55' })
);
});
This code should draw a 140x100 Rectangle on the canvas.
Sadly, only a quarter of the Rectangle appears.
If I change the top and left values to higher numbers, more of the Rectangle appears on the canvas.
So it seems, that the canvas origin is not at 0/0, but at sth. higher.
Does someone know how to fix this or what I am doing wrong?
Thanks in advance,
McFarlane
Here is a jsfiddle link with some examples http://jsfiddle.net/pukster/sdQ7U/2/
My guess is that fabric.js calculates everything from the origin (middle point) since it is drawing exactly one quarter of a rectangle even with a canvas 10 times the size of the rectangle. My guess is that top and left actually refer to the origin and not the top and left sides of the imaginary bounding box. Trouble is there is very little documentation on fabricjs. Is there any reason you are using fabricjs and not easeljs
EDIT Here's the same fiddle but with squares instead of rectangles (it is more clear) http://jsfiddle.net/pukster/sdQ7U/3/
EDIT OK I am now almost absolutely certain that fabric.js uses the center as the top/left. I ripped their example off of their site and overlayed it with the transparent couterpart to those shapes had they been coded in pure canvas http://jsfiddle.net/pukster/uathZ/2/ (blue border is the limit of the canvas element).
What you see is that the boxes are exactly offset by half but the circle (I only drew a semi circle otherwise it would not have been discernable) is perfectly overlapped. This is b/c in HTML Canvas, the circle coordinates (x,y) refer to the origin and not the top left. I did not bother with the triangle b/c my trigonometry is a bit rusty. I personally think it's misleading to use the terms top and left, when x and y would have been more representative and shorter.
Yes, this is highly unexpected and even more undocumented.
Workaround:
Set
originX: "left"
originY: "top"
for each created object.
edit: or use kangax simpler solution in the comment below.
I want to comment but lack the reputation to do so. So anyway, here is what happens when I do the following:
fabric.Object.prototype.originX = "left";
fabric.Object.prototype.originY = "top";
The shape gets rendered fine but when I select it for resizing or moving, it gets offset to a different location. The best approach seems to be to set the coordinates for every object separately using the set() method.