Easeljs: Object added to stage on click has no X value - drag-and-drop

Trying to following the example at http://www.createjs.com/tutorials/Mouse%20Interaction/ , which shows how to drag and drop a shape. Something is going wrong for me. I add a circle when the stage is clicked, then I try to get it's x location... my alert shows a 0, but the circle appears in the right place. Then I try to drag, and the circle moves around, but at a distance from the mouse pointer.
var stage = new createjs.Stage("demoCanvas")
stage.on("stagemousedown", function(evt) {
var corn = new createjs.Shape()
corn.graphics.beginFill('white').drawCircle(evt.stageX, evt.stageY, 20).endFill()
stage.addChild(corn)
stage.update()
alert(corn.x)
corn.on("pressmove", function(dragEvent) {
dragEvent.target.x = dragEvent.stageX;
dragEvent.target.y = dragEvent.stageY;
stage.update()
});
})

You are mistaking the shape x/y position with the graphics coordinates. The shape is at [0,0], since you have not changed its x or y position.
Instead, draw the circle at [0,0], and move it to the mouse position.
var corn = new createjs.Shape()
.set({x:evt.stageX, y:evt.stageY});
corn.graphics.beginFill('green').drawCircle(0,0,20).endFill();
Here is a quick fiddle: http://jsfiddle.net/xnn803sx/

Related

How to get the edge of a polygon drawn on map within Leaflet

I am working with Leaflet and Leaflet-Draw in Angular to draw some polygons on the Google Map. How can I implement a listener when the user clicks exactly on the edge of the drawn polygons and get the lat and lng of that edge. I know a similar situation can be implemented with Google Map API like the code below, but I can not find any source to help me implement the same thing in Leaflet.
google.maps.event.addListener(polygon, 'click', function (event) { console.log(event.edge) }
Google Map Documentation: https://developers.google.com/maps/documentation/javascript/reference/polygon#PolyMouseEvent
For those who come across this question: I found a solution myself!
I didn't find anything directly from Leaflet draw library that I could use, so I defined the problem for myself as a trigonometry problem and solve it that way.
I defined a function in which on polygon click, it converts the event.latlng and loops over polygon.getLatLngs()[0] taking a pair of A and B points. A is the first coordinates, B is the next and if it reaches to the end of array, B will be the first point. Then using Collinear Function of 3 points with x, y, I checked if the clicked x, y has a same slope as point A and B.(has to be rounded it up), if so, I would save that A and B point pair with their latLng information and further used it in my project.
Although this method works, I would appreciate if anybody would know a better solution or library built-in function that can be used instead. Thanks!
When the user clicks on the polygon you can loop through all corners and check if he clicked in the near of the corner.
poly.on('click', function(e){
var latlng = e.latlng;
var corners = poly.getLatLngs();
if(!L.LineUtil.isFlat(corners)){ //Convert to a flat array
corners = corners[0];
}
//Convert the point to pixels
var point = mymap.latLngToContainerPoint(latlng);
//Loop through each corner
corners.forEach(function(ll){
//Convert the point to pixels
var point1 = mymap.latLngToContainerPoint(ll);
var distance = Math.sqrt(Math.pow(point1.x - point.x, 2) + Math.pow(point.y - point1.y, 2));
//Check if distance between pixels is smaller then 10
if(distance < 10){
console.log('corner clicked');
}
});
});
This is plain JS you have to convert it self to angular.
A alternativ is to place on each corner a DivMarker or a CircleMarker and fire a event if the marker is clicked.
Looks like: https://geoman.io/leaflet-geoman

Leap Motion - Angle of proximal bone to metacarpal (side to side movement)

I am trying to get the angle between the bones, such as the metacarpal bone and the proximal bone (angle of moving the finger side to side, for example the angle when your index finger is as close to your thumb as you can move it and then the angle when your index finger is as close to your middle finger as you can move it).
I have tried using Vector3.Angle with the direction of the bones but that doesn't work as it includes the bending of the finger, so if the hand is in a fist it gives a completely different value to an open hand.
What i really want is a way i can "normalize" (i know normalizing isn't the correct term but it's the best i could think of) the direction of the bones so that even if the finger is bent, the direction vector would still point out forwards and not down, but would be in the direction of the finger (side to side).
I have added a diagram below to try and illustrate what i mean.
In the second diagram, the blue represents what i currently get if i use the bone's directions, the green is the metacarpal direction and the red is what i want (from the side view). The first diagram shows what i am looking for from a top-down view. The blue line is the metacarpal bone direction and in this example the red line is the proximal bone direction, with the green smudge representing the angle i am looking for.
To get this value, you need to "uncurl" the finger direction based on the current metacarpal direction. It's a little involved in the end; you have to construct some basis vectors in order to uncurl the hand along juuust the right axis. Hopefully the comments in this example script will explain everything.
using Leap;
using Leap.Unity;
using UnityEngine;
public class MeasureIndexSplay : MonoBehaviour {
// Update is called once per frame
void Update () {
var hand = Hands.Get(Chirality.Right);
if (hand != null) {
Debug.Log(GetIndexSplayAngle(hand));
}
}
// Some member variables for drawing gizmos.
private Ray _metacarpalRay;
private Ray _proximalRay;
private Ray _uncurledRay;
/// <summary>
/// This method returns the angle of the proximal bone of the index finger relative to
/// its metacarpal, when ignoring any angle due to the curling of the finger.
///
/// In other words, this method measures the "side-to-side" angle of the finger.
/// </summary>
public float GetIndexSplayAngle(Hand h) {
var index = h.GetIndex();
// These are the directions we care about.
var metacarpalDir = index.bones[0].Direction.ToVector3();
var proximalDir = index.bones[1].Direction.ToVector3();
// Let's start with the palm basis vectors.
var distalAxis = h.DistalAxis(); // finger axis
var radialAxis = h.RadialAxis(); // thumb axis
var palmarAxis = h.PalmarAxis(); // palm axis
// We need a basis whose forward direction is aligned to the metacarpal, so we can
// uncurl the finger with the proper uncurling axis. The hand's palm basis is close,
// but not aligned with any particular finger, so let's fix that.
//
// We construct a rotation from the palm "finger axis" to align it to the metacarpal
// direction. Then we apply that same rotation to the other two basis vectors so
// that we still have a set of orthogonal basis vectors.
var metacarpalRotation = Quaternion.FromToRotation(distalAxis, metacarpalDir);
distalAxis = metacarpalRotation * distalAxis;
radialAxis = metacarpalRotation * radialAxis;
palmarAxis = metacarpalRotation * palmarAxis;
// Note: At this point, we don't actually need the distal axis anymore, and we
// don't need to use the palmar axis, either. They're included above to clarify that
// we're able to apply the aligning rotation to each axis to maintain a set of
// orthogonal basis vectors, in case we wanted a complete "metacarpal-aligned basis"
// for performing other calculations.
// The radial axis, which has now been rotated a bit to be orthogonal to our
// metacarpal, is the axis pointing generally towards the thumb. This is our curl
// axis.
// If you're unfamiliar with using directions as rotation axes, check out the images
// here: https://en.wikipedia.org/wiki/Right-hand_rule
var curlAxis = radialAxis;
// We want to "uncurl" the proximal bone so that it is in line with the metacarpal,
// when considered only on the radial plane -- this is the plane defined by the
// direction approximately towards the thumb, and after the above step, it's also
// orthogonal to the direction our metacarpal is facing.
var proximalOnRadialPlane = Vector3.ProjectOnPlane(proximalDir, radialAxis);
var curlAngle = Vector3.SignedAngle(metacarpalDir, proximalOnRadialPlane,
curlAxis);
// Construct the uncurling rotation from the axis and angle and apply it to the
// *original* bone direction. We determined the angle of positive curl, so our
// rotation flips its sign to rotate the other direction -- to _un_curl.
var uncurlingRotation = Quaternion.AngleAxis(-curlAngle, curlAxis);
var uncurledProximal = uncurlingRotation * proximalDir;
// Upload some data for gizmo drawing (optional).
_metacarpalRay = new Ray(index.bones[0].PrevJoint.ToVector3(),
index.bones[0].Direction.ToVector3());
_proximalRay = new Ray(index.bones[1].PrevJoint.ToVector3(),
index.bones[1].Direction.ToVector3());
_uncurledRay = new Ray(index.bones[1].PrevJoint.ToVector3(),
uncurledProximal);
// This final direction is now uncurled and can be compared against the direction
// of the metacarpal under the assumption it was constructed from an open hand.
return Vector3.Angle(metacarpalDir, uncurledProximal);
}
// Draw some gizmos for debugging purposes.
public void OnDrawGizmos() {
Gizmos.color = Color.white;
Gizmos.DrawRay(_metacarpalRay.origin, _metacarpalRay.direction);
Gizmos.color = Color.blue;
Gizmos.DrawRay(_proximalRay.origin, _proximalRay.direction);
Gizmos.color = Color.red;
Gizmos.DrawRay(_uncurledRay.origin, _uncurledRay.direction);
}
}
For what it's worth, while the index finger is curled, tracked Leap hands don't have a whole lot of flexibility on this axis.

Mapbox Icons/Markers "BearingSnap" or Snap to Position

Is there a way to move icons/markers to a certain location where it will then "snap" to the location?
For example, chess games on the computer where when you move a chess piece to the correct square, it will snap to that position when you let go of the piece near/around the square.
So what I want is to move a marker or an icon to a certain location, let's say the capital of California, and the marker will "snap" to the location that I want when I move it and let go of the marker near the location. But I also want to still be able to move the marker if I want to.
I know Mapbox gl has bearingSnap which snaps the map back to north after the user rotates the map but I can't find anything for just icons/markers and I don't believe I can use bearingSnap for it.
Thanks.
You can use Turfs distance function: turf.distance(pt1, pt2) to measure distances between 2 points. If then the calculated distance is under a certain threshold, you can set the location of your dragging point to the location of your snap point.
I have you a working example in a jsfiddle:
https://jsfiddle.net/andi_lo/nmc4kprn/
function onMove(e) {
if (!isDragging) return;
var coords = e.lngLat;
// Set a UI indicator for dragging.
canvas.style.cursor = 'grabbing';
// Update the Point feature in `geojson` coordinates
// and call setData to the source layer `point` on it.
geojson.features[0].geometry.coordinates = [coords.lng, coords.lat];
map.getSource('point').setData(geojson);
let snapTo = map.getSource('snap')._data;
turf.featureEach(snapTo, (feature) => {
let dist = turf.distance(feature, turf.point([coords.lng, coords.lat]));
console.log(dist);
// if the distance of the dragging point is under a certain threshold
if (dist < 500) {
// set the location of the dragging point to the location of the snapping point
geojson.features[0].geometry.coordinates = feature.geometry.coordinates;
map.getSource('point').setData(geojson);
}
});
}
This is a feature you can and should implement upstream of GL JS. When you construct the coordinate of the marker or GeoJSON feature, snap it to the desired grid.

How do I add a units label to a ILNumerics Colorbar

I would like to display the units in text for the values displayed on the colorbar. I have a colorbar added to my ILSurface and I'd like to show my units in text on the color bar along with the range.
Edit: I want to display text at the bottom of the color bar below the bottom tick just the one label.
I was able to get this to work this way
new ILColorbar()
{
Children = { new ILLabel("nm") {Position = new Vector3(.2f,.98f,0) } }
}
I have to say the Position coordinates are not very intuitive. I had to basically adjust the numbers by trial and error until it fit. I knew that the values range 0..1 so the X value was 1 at the bottom but I wanted it up from the border. And the Y value would need to be indented in some but I wasn't sure what was a good value but .2 works.
You can access the axis of ILColorbar and configure it in the usual way. Use the LabelTransformFunc on the ticks to set your own label text. You can use the default transform func and add your unit string.
Example:
var cb = scene.First<ILColorbar>();
cb.Axis.Ticks.LabelTransformFunc = (ind, val) =>
{
return ILTickCollection.DefaultLabelTransformFunc(ind, val) + "nm";
};
You can read more about the axis configuration here:
Axis Configuration
LabelTransformFunc in ApiDoc
Edit:
If only one label is needed, then add a new ILLabel object in ILColorbar group as follows:
new ILColorbar() {
new ILLabel("z(nm)") {
Position = new Vector3(0.5,1,0),
Anchor = new PointF(0.5f,0)
}
}
The ILColorbar area have the relative coordinates 0..1 over the width and the height of the color bar. So we set position x in the middle of the ILColorbar, and position y at the bottom.
The Anchor position is used as relative position in relation to the Position point.
ILLabel Documentation

Circle not showing in OpenLayers

Extremely new to OpenLayers and trying to draw a circle on a map around a clicked origin. I have this code -
circleLayer = new OpenLayers.Layer.Vector "Circle Search"
circle = new OpenLayers.Geometry.Polygon.createRegularPolygon(
new OpenLayers.Geometry.Point(lat,lon),
100,
30
)
console.log(circle)
feature = new OpenLayers.Feature.Vector(circle)
circleLayer.addFeatures(feature)
mapApp.map.openLayersMap.addLayer circleLayer
But the circle is not showing up, and I'm not sure why. Can anyone tell me?
Are you converting your lat lon to the projection used by your map?
Test:
Try using 0,0 for lon,lat with a bigger circle and see if it appears off the coast of east-central Africa.
If that's the problem then here's how you do the transform:
add at the top:
projLatLon = new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
projMap = new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator Projection
then the third line of your example code becomes:
new OpenLayers.Geometry.Point(lat,lon).transform(projLatLon,projMap),