Set events on canvas pushpin of Bing Map - events

I am facing one issue while setting event on Pushpin which was created by canvas. To set the environment please goto Bing Map - Pushpin Event Example. And copy below code in Javascript tab and run the example.
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {});
var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), {
icon: createRedArrow(110),
anchor: new Microsoft.Maps.Point(12, 12)
});
map.entities.push(pushpin);
function createRedArrow(heading) {
var c = document.createElement('canvas');
c.width = 24;
c.height = 24;
var ctx = c.getContext('2d');
// Offset the canvas such that we will rotate around the center of our arrow
ctx.translate(c.width * 0.5, c.height * 0.5);
// Rotate the canvas by the desired heading
ctx.rotate(heading * Math.PI / 180);
//Return the canvas offset back to it's original position
ctx.translate(-c.width * 0.5, -c.height * 0.5);
ctx.fillStyle = '#f00';
// Draw a path in the shape of an arrow.
ctx.beginPath();
ctx.moveTo(12, 0);
ctx.lineTo(5, 20);
ctx.lineTo(12, 15);
ctx.lineTo(19, 20);
ctx.lineTo(12, 0);
ctx.closePath();
ctx.fill();
ctx.stroke();
// Generate the base64 image URL from the canvas.
return c.toDataURL();
}
// Binding the events
Microsoft.Maps.Events.addHandler(pushpin, 'click', function () { highlight('pushpinClick'); });
Microsoft.Maps.Events.addHandler(pushpin, 'dblclick', function () { highlight('pushpinDblclick'); });
Microsoft.Maps.Events.addHandler(pushpin, 'mousedown', function () { highlight('pushpinMousedown'); });
Microsoft.Maps.Events.addHandler(pushpin, 'mouseout', function () { highlight('pushpinMouseout'); });
Microsoft.Maps.Events.addHandler(pushpin, 'mouseover', function () { highlight('pushpinMouseover'); });
Microsoft.Maps.Events.addHandler(pushpin, 'mouseup', function () { highlight('pushpinMouseup'); });
// Setting up the printout panel
document.getElementById('printoutPanel').innerHTML =
'<div id="pushpinClick">click</div><div id="pushpinDblclick">dblclick</div><div id="pushpinMousedown">mousedown</div><div id="pushpinMouseout">mouseout</div><div id="pushpinMouseover">mouseover</div><div id="pushpinMouseup">mouseup</div>';
function highlight(id) {
document.getElementById(id).style.background = 'LightGreen';
setTimeout(function () { document.getElementById(id).style.background = 'white'; }, 1000);
}
You can notice that all pushpin events are working on canvas's width/height (24/24) area as shown in below image
And as per my requirement events should only work on drawn part of canvas and also canvas w/h will be like 100. So, how do I achieve that?
Also, if two or more pushpins are nearer (see below image) and if both canvas are overlap to each other then how we can identify both pushpins are different for pushpin event?
Here, I have provided my requirement with Bing Map's exisiting example. But here is actual pushpin secnario.

Unfortunately this is a limitation in how pushpins are rendered in Bing Maps. There is an option to modify the click area to be round rather than square which will help a bit here. See the roundClickableArea pushpin option: https://learn.microsoft.com/en-us/bingmaps/v8-web-control/map-control-api/pushpinoptions-object

Related

Rotate an object like OrbitControls but only the object itself

We love three.js! And here is a page we built using it a few years ago.
https://www.jgprolock.com
We are in the process of revising the animations on this site.
Once the page loads, the user has the ability to drag and rotate the object. But it is really a trick. We are using orbit controls to rotate the camera around our scene, and thus our main object which is centered in the scene (positions x,y,z all equal to 0). If we did not place the object in the center, it starts to look uneven in its rotation as the camera now is rotating around a center that the object doesn't have.
In order to make it look like the object is on the left side, we ended up moving the canvas to the left and then we bring it back to the right or left as the animation continues after scrolling.
So, my question is .. does anyone have an example how to achieve this functionality just by rotating the actual object itself, instead of rotating the camera around the entire scene using the orbit controls plugin?
Or is there away to modify the orbit controls to rotate around an object and not the entire scene?
I've been searching for this for a while but right after asking this question I came across this link, which actually has an example of what we are trying to do.
https://jsfiddle.net/n6u6asza/1205/
The key to making this work as copied from the link: (although I am not 100% sure what this all means)
/* */
var isDragging = false;
var previousMousePosition = {
x: 0,
y: 0
};
$(renderer.domElement).on('mousedown', function(e) {
isDragging = true;
})
.on('mousemove', function(e) {
//console.log(e);
var deltaMove = {
x: e.offsetX-previousMousePosition.x,
y: e.offsetY-previousMousePosition.y
};
if(isDragging) {
var deltaRotationQuaternion = new three.Quaternion()
.setFromEuler(new three.Euler(
toRadians(deltaMove.y * 1),
toRadians(deltaMove.x * 1),
0,
'XYZ'
));
cube.quaternion.multiplyQuaternions(deltaRotationQuaternion, cube.quaternion);
}
previousMousePosition = {
x: e.offsetX,
y: e.offsetY
};
});
/* */
If you want an article on how to achieve this without the use of unnecessary jquery dependencies you can have a look here
This uses the eventListener to find a mousemove event whilst a mousedown event is occurring, and then passes the coordinates to a custom function.
var mouseDown = false,
mouseX = 0,
mouseY = 0;
var canvas = renderer.domElement
canvas.addEventListener('mousemove', function (evt) {
if (!mouseDown) {return}
//console.log('drag')
evt.preventDefault();
var deltaX = evt.clientX - mouseX,
deltaY = evt.clientY - mouseY;
mouseX = evt.clientX;
mouseY = evt.clientY;
// DO SOMETHING HERE WITH X and Y
object.rotation.x += deltaX
}, false);
canvas.addEventListener('mousedown', function (evt) {
evt.preventDefault();
mouseDown = true;
mouseX = evt.clientX;
mouseY = evt.clientY;
}, false);
canvas.addEventListener('mouseup', function (evt) {
evt.preventDefault();
mouseDown = false;
}, false);
}
But not that this will not work if you have OrbitControls or DragControls imported!

Three.js OrbitControls.js - invoking zoom in/out with button - controls.dollyOut() is not a function

I am using OrbitControls.js in my scene and it's working great with mouse and touch events.
I would like to add on screen buttons to zoom using controls.dollyIn(scale) and controls.dollOut(scale). When I implement this I am getting controls.dollyIn is not a function.
controls is global
I am setting up OrbitControls with
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;
controls.autoRotateSpeed = 0.03;
controls.enableDamping = true;
controls.dampingFactor = 0.1;
controls.rotateSpeed = 0.1;
controls.minDistance = 1;
controls.maxDistance = 200;
controls.maxPolarAngle = Math.PI/2 - .04;
controls.target.set(0, 5, 0);
And triggering the zoom with
$( "#navZoomIn" ).click(function() {
event.preventDefault();
controls.dollyIn(4);
});
any suggestions on how to accomplish this would be much appreciated.
Also, is there something similar to dollyIn() but for rotation, so that on screen buttons could trigger rotation left/right/up/down?
Thanks!
The Problem is in library. dollyIn is a private function of THREE.OrbitControls.
We can modify OrbitControls.js by putting two public methods in THREE.OrbitControls. There is section calls as public methods.
this.dollyIn = function () {
dollyIn( getZoomScale() );
scope.update();
};
this.dollyOut = function () {
dollyOut( getZoomScale() );
scope.update();
};
You can access these function as shown below:
$("#product-container .canv-zoom-in").on("click", function() {
controls.dollyOut();
});
$("#product-container .canv-zoom-out").on("click", function() {
controls.dollyIn();
});
If you want zoom step to increase, it can be done by
controls.zoomSpeed = 3.0;
I am surprised. I would think the error would be closer to something like cannot call dollyIn of undefined. I would make sure your scope chain is established with var in the same block as the click definition:
var controls = new THREE.OrbitControls(camera, renderer.domElement);
//... controls setup code here ...//
$( "#navZoomIn" ).click(function() {
event.preventDefault();
controls.dollyIn(4);
});
Orbit Controls has rotateUp and RotateLeft. use negative numbers to rotate down or rotate right. There's also panUp and PanLet. Personally I prefer to rotate the camera with a swing animation and when the animation is done I call controls.update(); it's a bit smoother.
If you don't have access to OrbitControls class or you don't want to manipulate/extend it, you can fire a wheel element like this:
//canvas object of my ThreeJS scene/a wrapper around it
export const canvas = document.getElementById('canvas');
/**
* Zoom in and out inside the model
*/
const evt = new Event('wheel', {bubbles: true, cancelable: true});
const zoomInBtn = document.querySelectorAll('.zoom_in');
zoomInBtn.forEach(btn => btn.addEventListener('click', () => {
console.debug('zoom in')
evt.deltaY = -240;
canvas.dispatchEvent(evt);
}));
const zoomOutBtn = document.querySelectorAll('.zoom_out');
zoomOutBtn.forEach(btn => btn.addEventListener('click', () => {
console.debug('zoom out')
evt.deltaY = +240;
canvas.dispatchEvent(evt);
}));

Animate point with paper.js

I’d like to rebuild this animation http://imgur.com/l5Vhswe in paper.js.
I already tried SVG animations (http://codepen.io/magglomag/pen/jrVwzy) but despite from the fact that they’ll be deprecated soon I was not able to move the two points asynchronously.
What I have so far is the shape and I know that I can animate with the onFrame event handler. But I have no clue how to say that the point should animate between the coordinates [43,168.7] and [43,35.3].
http://codepen.io/magglomag/pen/yaVXrr
var firstSegment = new Segment({
point: [109,3.7]
});
var secondSegment = new Segment({
point: [43,168.7]
});
var thirdSegment = new Segment({
point: [109,202.2]
});
var path = new Path({
segments: [firstSegment, secondSegment, thirdSegment],
fillColor: '#2dfd9a',
closed: true
});
secondSegment.onFrame = function(event) {
this.point = [43,35.3]
}
The error you are making is that you are trying to bind an handler to segment.onFrame event.
But only item.onFrame and view.onFrame are available.
In PaperScript context, you can even use a global onframe named function as a convenient way to animate things.
Here is a simple example demonstrating how a path segment can be animated.
// create a triangle
var triangle = new Path.RegularPolygon({
center: view.center,
sides: 3,
radius: 50,
fillColor: 'orange'
});
// store initial first point position
var initialPoint = triangle.firstSegment.point.clone();
// on frame
function onFrame(event) {
// use sine function as a convenient way to demonstrate animation
var newPoint = initialPoint + Math.sin(event.count * 0.05) * 30;
// update first point
triangle.firstSegment.point = newPoint;
}

zooming based on the position of cursor in mousewheel

I am currently working on a THREE.js project.While using trackball control zooming it is zooming relative to the center of the model.But i want to zoom according to the position of cursor with mouse wheel.Any one who is familiar please help me over this.
Thank you in advance.
In mousewheel add this code which helps you in zooming based on the cursor position and not relative to the model.
If you are using trackball controls,you could use that for panning and rotating.
So set trackball controls enabled to false in mousewheel.
renderer.domElement.addEventListener('mousewheel',
function (e) {
mousewheel(e);
},
false);
function mousewheel(event) {
trackBallControls.noZoom = true;
event.preventDefault();
var factor = 50;
var mX = (event.clientX / jQuery(container).width()) * 2 - 1;
var mY = -(event.clientY / jQuery(container).height()) * 2 + 1;
var vector = new THREE.Vector3(mX, mY, 0.5);
//console.log(vector);
vector.unproject(camera);
vector.sub(camera.position);
if (event.deltaY < 0) {
camera.position.addVectors(camera.position,
vector.setLength(factor));
trackBallControls.target.addVectors(trackBallControls.target,
vector.setLength(factor));
camera.updateProjectionMatrix();
} else {
camera.position.subVectors(camera.position,
vector.setLength(factor));
trackBallControls.target.subVectors(trackBallControls.target,
vector.setLength(factor));
camera.updateProjectionMatrix();
}
}

Raphael JS : how to remove events?

I use the Raphael .mouseover() and .mouseout() events to highlight some elements in my SVG.
This works fine, but after I click on an element, I want it to stop highlighting.
In the Raphael documentation I found :
To unbind events use the same method names with “un” prefix, i.e. element.unclick(f);
but I can't get this to work and I also don't understand the 'f' parameter.
This doesn't work , but what does??
obj.click( function() {
this.unmouseover();
});
Ok, what you have to do is pass the handler function to the unmouseover request:
// Creates canvas 320 × 200 at 10, 50
var paper = Raphael(10, 50, 320, 200);
// Creates circle at x = 50, y = 40, with radius 10
var circle = paper.circle(50, 40, 10);
// Sets the fill attribute of the circle to red (#f00)
circle.attr("fill", "#f00");
// Sets the stroke attribute of the circle to white
circle.attr("stroke", "#fff");
var mouseover = function (event) {
this.attr({fill: "yellow"});
}
var mouseout = function (event) {
this.attr({fill: "red"});
}
circle.hover(mouseover, mouseout);
circle.click(function (event) {
this.attr({fill: "blue"});
this.unmouseover(mouseover);
this.unmouseout(mouseout);
});
http://jsfiddle.net/GexHj/1/
That's what f is about. You can also use unhover():
circle.click(function (event) {
this.attr({fill: "blue"});
this.unhover(mouseover, mouseout);
});
http://jsfiddle.net/GexHj/2/

Resources