How can I reposition the map center to fit the infobubble? - here-api

I can easily get the marker to be centered. However, it does not count in the size of the infobubble.
I'd like to reposition the map when clicking a marker such that the info bubble fits. This can be as simple as aligning center horizontally and bottom vertically.
I tried manipulating the position for centering the marker. However, that surprisingly moves the marker to the new location also.

Can you please try to add below JS snippet, as it allows marker movement ,but restrict its movement when the map is dragged.
I hope this will help you to achieve the desired outcome.
<script>
function addDraggableMarker(map, behavior){
var marker = new H.map.Marker({lat:42.35805, lng:-71.0636});
// Ensure that the marker can receive drag events
marker.draggable = true;
map.addObject(marker);
// disable the default draggability of the underlying map
// when starting to drag a marker object:
map.addEventListener('dragstart', function(ev) {
var target = ev.target;
if (target instanceof H.map.Marker) {
behavior.disable();
}},false);
// re-enable the default draggability of the underlying map
// when dragging has completed
map.addEventListener('dragend', function(ev) {
var target = ev.target;
if (target instanceof mapsjs.map.Marker) {
behavior.enable();
}
}, false);
// Listen to the drag event and move the position of the marker
// as necessary
map.addEventListener('drag', function(ev) {
var target = ev.target,
pointer = ev.currentPointer;
if (target instanceof mapsjs.map.Marker) {
target.setPosition(map.screenToGeo(pointer.viewportX, pointer.viewportY));
}
}, false);
}
</script>

Related

HOWTO: Manipulate Back Arrow Icon and Button on Navigation Bar (Xamarin Forms / Android)

I am attempting to change the size of the back arrow in the navigation bar.
Using information from this article, I have added the following code:
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
var result = base.OnPushAsync(view, animated);
var activity = (Activity) Context;
var toolbar = activity.FindViewById<Toolbar>(Resource.Id.toolbar);
if (toolbar != null)
{
if (toolbar.NavigationIcon != null)
{
if (toolbar.NavigationIcon is DrawerArrowDrawable navigationIcon)
{
// Code goes here?
}
}
}
return result;
}
If this is indeed the correct path, what code goes in the area marked by the comment "Code goes here?"?
* UPDATE *
I realized that what I am trying to figure out was not exactly described in my original question.
More specifically, when I mentioned that I am trying to resize the navigation bar back arrow, what I am really trying to do is to resize the button that the icon appears on.
For example, if I shrink the height of the navigation bar using code like the following:
On<Android>().SetBarHeight(100);
The button that the icon appears on will be clipped.
Ultimately, what I am trying to accomplish is resizing the icon AND the button that the icon appears on. I have already figured out how to do the former.
I am attempting to change the size of the back arrow in the navigation bar.
If you want to change size of the back button in the navigation bar, you can get new icon from Drawable in resource for toolbar.NavigationIcon.
public class NavigationPageRenderer : Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer
{
public AppCompToolbar toolbar;
public Activity context;
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
var retVal = base.OnPushAsync(view, animated);
context = (Activity)Forms.Context;
toolbar = context.FindViewById<AppCompToolbar>(Droid.Resource.Id.toolbar);
if (toolbar != null)
{
if (toolbar.NavigationIcon != null)
{
if (toolbar.NavigationIcon is DrawerArrowDrawable navigationIcon)
{
// Code goes here?
toolbar.NavigationIcon = Android.Support.V7.Content.Res.AppCompatResources.GetDrawable(context, Resource.Drawable.back);
toolbar.Title = "Back";
}
}
}
return retVal;
}
}
Here is the sample you can take a look:
https://github.com/hachi1030-Allen/XamarinCustomNavBar
<NavigationPage.TitleView> will help you out there. This is a XAML approach.
Example:
<NavigationPage.TitleView>
<StackLayout>
....
</StackLayout>
</NavigationPage.TitleView>
Using this approach you will be able to set HeightRequest and WidthRequest of whatever element you place inside the StackLayout and whatever else you want to amend.
Also, note that if you are having icon size problems it may be worth looking into whether or not your drawable/ icons are the right size for the right resolution.

Swift 3 iOS -Override HitTest not letting SubView Receive Touches Outside it's SuperView's Bounds

I have a collectionView cell that has an imageView from StoryBoard and a deleteButton (the red X) added programmatically that extends beyond the cell's bounds x:-12, y:-18. I tried to override the hitTest to receive touches outside the cell's bounds but it doesn't work. However I am able to trigger events on the button when it (or any part of it) is within the cell's bounds. On the imageView in storyboard's I have isUserIneractionEnabled checked and inside the cell class I have it enabled on the deleteButton and cell itself. I also have clipsToBounds = false on the cell and imageView.
I did notice that as I printed out my subviews the only view that gets printed is the imageView. Maybe that's the problem?
Here's the code:
class MyCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
var deleteButton: UIButton!
var deleteButtonImg: UIImage!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
deleteButton = UIButton(frame: CGRect(x: -12, y: -18, width: frame.size.width/4, height: frame.size.width/4))
deleteButtonImg = UIImage(named: "red-x")!
deleteButton.setImage(deleteButtonImg, for: .normal)
self.isUserInteractionEnabled = true
deleteButton.isUserInteractionEnabled = true
contentView.addSubview(deleteButton)
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if (!self.clipsToBounds && !self.isHidden && self.alpha > 0.0) {
for view in self.subviews.reversed() {
print(".......\(subviews.description)")
let subPoint = view.convert(point, from: self)
let result = view.hitTest(subPoint, with: event)
if (result != nil){
return result
}
}
}
return nil;
}
Why cannot I not receive touches event though I'm overriding the hitTest?

Rotate CSS 3D generated cube on drag

I have a 3D generated Cube made with CSS and it rotates perfectly when hovered on.
What I need is to add the draggable function to make it rotate with the mouse.
So far I have this:
JSFIDDLE
In order to make the hover work you need to uncomment the following CSS:
/*.box-scene:hover .box {
-webkit-transform: rotateY(-90deg);
}*/
I use draggable function from JQueryUI to try to make it work but somehow it is not working.
PS: I only need it to rotate on Y Axis.
Any help will be appresiated.
Ok so I got it working finally.
Apparently the error was that JSFiddle doesn't load external resources if they are requested without SSL.
The code that was loaded initially is actually correct.
The final working fiddle is:
JSFiddle
Final Javascript:
var offset = 0, startX;
var elem = document.getElementById("box");
$('#box-scene').on('mousedown', function (e) {
startX = e.pageX - offset;
})
.on('mouseup', function() {
startX = null;
})
.on('mousemove', function (e) {
if(startX) {
offset = e.pageX - startX;
elem.style['-webkit-transform'] = 'rotateY(-' + offset + 'deg)';
}
});
Thank you #Andrew and #Armand Maree for your help.
Hope this works for future reference.
I don't think draggable is what you want; that widget allows you to move objects around on the page. It looks like you want to be able to click the mouse and move it, and then see the cube rotate proportionally to how far you've moved the mouse. I don't know of a way to do that in pure CSS, I would suggest javascript similar to the following:
var dragging = false;
var originalX;
cube.mouseDown(function(e){
originalX = e.pageX;
dragging = true;
});
cube.mouseUp(function(e){
dragging = false;
});
cube.mouseMove(function(e){
if (dragging){
var DeltaX = e.pageX - originalX;
var rotation = CalculateRotationDegrees(DeltaX);
cube.css('transform',rotation);
}
});
In this example, the method CalculateRotationDegrees would take the distance the user has moved the mouse and figure out how far the cube should rotate based on that distance.
An idea would be to have a boolean variable that indicates whether the mouse button is pressed down. And then adjust the rotation when the mouse moves.
var mouseDown = false;
var mouseButtonDown = function () {
mouseDown = true;
}
var mouseButtonUp = function () {
mouseDown = false;
}
var mouseMove = function (event) {
if(mouseDown) {
// get mouse coordinates and do rotation in jquery
}
}
The HTML:
<div onmousedown="mouseButtonDown" onmouseup="mouseButtonUp" onmousemove="mouseMove"></div>

Specific .js files for stage, rectangle and other shapes to be used in Canvas

I want to currently work on Canvas in HTML5. I am new to canvas and want to start working on it. I am using easeljs for implementing canvas. But can anybody specify any particular .js file to implement Canvas. As when I am using this .js I am getting error : "0x800a1391 - Microsoft JScript runtime error: 'Stage' is undefined If there is a handler for this exception, the program may be safely continued."
Here my piece of code where we getting the above specified error. I have copied this code from internet only:
<script>
//EaselJS Stage instance that wraps the Canvas element
var stage;
//EaselJS Shape instance that we will animate
var circle;
//radius of the circle Graphics that we will draw.
var CIRCLE_RADIUS = 10;
//x position that we will reset Shape to when it goes off
//screen
var circleXReset;
//EaselJS Rectangle instance we will use to store the bounds
//of the Canvas
var bounds;
//initialize function, called when page loads.
function init() {
//check and see if the canvas element is supported in
//the current browser
////http://diveintohtml5.org/detect.html#canvas
if (!(!!document.createElement('canvas').getContext)) {
var wrapper = document.getElementById("canvasWrapper");
wrapper.innerHTML = "Your browser does not appear to support " +
"the HTML5 Canvas element";
return;
}
//get a reference to the canvas element
var canvas = document.getElementById("stageCanvas");
//copy the canvas bounds to the bounds instance.
//Note, if we resize the canvas, we need to reset
//these bounds.
//bounds = new Rectangle();
//bounds.width = canvas.width;
//bounds.height = canvas.height;
//pass the canvas element to the EaselJS Stage instance
//The Stage class abstracts away the Canvas element and
//is the root level display container for display elements.
stage = new Stage(canvas);
//Create an EaselJS Graphics element to create the
//commands to draw a circle
var g = new Graphics();
//stroke of 1 px
g.setStrokeStyle(1);
//Set the stroke color, using the EaselJS
//Graphics.getRGB static method.
//This creates a white color, with an alpha
//of .7
g.beginStroke(Graphics.getRGB(255, 255, 255, .7));
//draw the circle
g.drawCircle(0, 0, CIRCLE_RADIUS);
//note that the circle has not been drawn yet.
//the Graphics instance just has the commands to
//draw the circle.
//It will be drawn when the stage needs to render it
//which is usually when we call stage.tick()
//create a new Shape instance. This is a DisplayObject
//which can be added directly to the stage (and rendered).
//Pass in the Graphics instance that we created, and that
//we want the Shape to draw.
circle = new Shape(g);
//set the initial x position, and the reset position
circle.x = circleXReset = -CIRCLE_RADIUS;
//set the y position
circle.y = canvas.height / 2;
//add the circle to the stage.
stage.addChild(circle);
//tell the stage to render to the canvas
stage.update();
Ticker.setFPS(24);
//Subscribe to the Tick class. This will call the tick
//method at a set interval (similar to ENTER_FRAME with
//the Flash Player)
Ticker.addListener(this);
}
//function called by the Tick instance at a set interval
function tick() {
//check and see if the Shape has gone of the right
//of the stage.
if (circle.x > bounds.width) {
//if it has, reset it.
circle.x = circleXReset;
}
//move the circle over 10 pixels
circle.x += 8;
//re-render the stage
stage.update();
}
</script>
The only thing in the above code is just to add "createjs" before every even.
<script>
//EaselJS Stage instance that wraps the Canvas element
var stage;
//EaselJS Shape instance that we will animate
var circle;
//radius of the circle Graphics that we will draw.
var CIRCLE_RADIUS = 10;
//x position that we will reset Shape to when it goes off
//screen
var circleXReset;
//EaselJS Rectangle instance we will use to store the bounds
//of the Canvas
var bounds;
//initialize function, called when page loads.
function init() {
//check and see if the canvas element is supported in
//the current browser
////http://diveintohtml5.org/detect.html#canvas
if (!(!!document.createElement('canvas').getContext)) {
var wrapper = document.getElementById("canvasWrapper");
wrapper.innerHTML = "Your browser does not appear to support " +
"the HTML5 Canvas element";
return;
}
//get a reference to the canvas element
var canvas = document.getElementById("stageCanvas");
//copy the canvas bounds to the bounds instance.
//Note, if we resize the canvas, we need to reset
//these bounds.
//var s = new Shape();
//s.graphics.setStrokeStyle(1).beginStroke("#f00").drawRect(0, 0, canvas.width, canvas.height);
//stage.addChild(s);
bounds = new **createjs**.Rectangle();
bounds.width = canvas.width;
bounds.height = canvas.height;
//pass the canvas element to the EaselJS Stage instance
//The Stage class abstracts away the Canvas element and
//is the root level display container for display elements.
stage = new createjs.Stage(canvas);
//Create an EaselJS Graphics element to create the
//commands to draw a circle
var g = new **createjs**.Graphics();
//stroke of 1 px
g.setStrokeStyle(1);
//Set the stroke color, using the EaselJS
//Graphics.getRGB static method.
//This creates a white color, with an alpha
//of .7
g.beginStroke(createjs.Graphics.getRGB(255, 255, 255, .7));
//draw the circle
g.drawCircle(0, 0, CIRCLE_RADIUS);
//note that the circle has not been drawn yet.
//the Graphics instance just has the commands to
//draw the circle.
//It will be drawn when the stage needs to render it
//which is usually when we call stage.tick()
//create a new Shape instance. This is a DisplayObject
//which can be added directly to the stage (and rendered).
//Pass in the Graphics instance that we created, and that
//we want the Shape to draw.
circle = new createjs.Shape(g);
//set the initial x position, and the reset position
circle.x = circleXReset = -CIRCLE_RADIUS;
//set the y position
circle.y = canvas.height / 2;
//add the circle to the stage.
stage.addChild(circle);
//tell the stage to render to the canvas
stage.update();
createjs.Ticker.setFPS(24);
//Subscribe to the Tick class. This will call the tick
//method at a set interval (similar to ENTER_FRAME with
//the Flash Player)
createjs.Ticker.addListener(this);
}
//function called by the Tick instance at a set interval
function tick() {
//check and see if the Shape has gone of the right
//of the stage.
if (circle.x > bounds.width) {
//if it has, reset it.
circle.x = circleXReset;
}
//move the circle over 10 pixels
circle.x += 8;
//re-render the stage
stage.update();
}
</script>
I have marked as bold what we have to add before every function or event.

How to prevent a component from being dragged out of the stage in Flex 3

I think there is a simple solution to this question, just not simple enough for me to find it.
Question:
How do you constrain a TitleWindow in Flex 3 from being dragged off the screen/stage? Is there a way to restrict the TitleWindow to the viewing area?
Example: Let's say I have an application that take 100% of the screen. Next, I create a TitleWindow via the PopUpManager. I can then proceed to click and hold (drag) that window off the screen, then release the mouse button. That window is now lost off-screen somewhere. Is there a way to keep the window from being dragged beyond the viewing area?
Thanks for the help in advance.
this is a very old post, but here's another way of doing it:
Whether you are extending the component or not, in the TitleWindow definition add the following line: move:"doMove(event)"
Import the Application library (import mx.core.Application;)
and add the doMove function:
private function doMove(event:Event):void
{//keeps TW inside layout
var appW:Number=Application.application.width;
var appH:Number=Application.application.height;
if(this.x+this.width>appW)
{
this.x=appW-this.width;
}
if(this.x<0)
{
this.x=0;
}
if(this.y+this.height>appH)
{
this.y=appH-this.height;
}
if(this.y<0)
{
this.y=0;
}
}
For flex 4 the answer is here: http://blog.flexexamples.com/2010/01/20/constraining-the-movement-on-a-spark-titlewindow-container-in-flex-4/
You can set its isPopUp property to false to prevent it from being dragged in the first place.
var popupWin:TitleWindow = PopUpManager.createPopUp(this, TitleWindow);
PopUpManager.centerPopUp(popupWin);
popupWin.isPopUp = false;
I don't know if the DragManager class in flex supports bounds checking, but if you really want to allow dragging but limit its bounds, you can still set isPopUp to false and implement the dragging code yourself so that the component never goes outside the limits specified by you. Check startDrag() method for an example. Bounds rectangle is the key.
Flex 4
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
windowMoving="windowMovingHandler(event)">
.
.
.
protected function windowMovingHandler(event:TitleWindowBoundsEvent):void
{
var appBounds:Rectangle = parentApplication.getBounds(DisplayObject(parentApplication));
if(!appBounds.containsRect(event.afterBounds)){
event.preventDefault();
}
}
// for better precision, corect appBounds manualy, or, instead of "parentApplication.getBounds..." create new rectangle of your application size
Subclass the TitleWindow and add a canvas over the title bar as a drag proxy. Then you can explicity call startDrag with a boundary rectangle.
This is pretty skeletal, but should put you on the path...
The reason for the proxy is you may get some weird behavior when you click the titleBar label if you don't have the canvas over it.
public class MyTitleWindow extends TitleWindow
{
public var titleBarOverlay:Canvas;
override protected function createChildren():void
{
super.createChildren();
if(!titleBarOverlay)
{
titleBarOverlay = new Canvas();
titleBarOverlay.width = this.width;
titleBarOverlay.height = this.titleBar.height;
titleBarOverlay.alpha = 0;
titleBarOverlay.setStyle("backgroundColor", 0x000000);
rawChildren.addChild(titleBarOverlay);
}
addListeners();
}
override protected function updateDisplayList(w:Number, h:Number):void
{
super.updateDisplayList(w, h);
titleBarOverlay.width = this.width;
titleBarOverlay.height = this.titleBar.height;
}
private function addListeners():void
{
titleBarOverlay.addEventListener(MouseEvent.MOUSE_DOWN, onTitleBarPress, false, 0, true);
titleBarOverlay.addEventListener(MouseEvent.MOUSE_UP, onTitleBarRelease, false, 0, true);
}
private function onTitleBarPress(event:MouseEvent):void
{
// Here you can set the boundary using owner, parent, parentApplication, etc.
this.startDrag(false, new Rectangle(0, 0, parent.width - this.width, parent.height - this.height));
}
private function onTitleBarRelease(event:Event):void
{
this.stopDrag();
}
}
You could simply override the move function and prevent "illegal" movement (it is called internally by the Panel drag management).
I think that you also should listen on stage resize, because reducing it (e.g. if the user resize the browser window) could send your popup out of stage even without actually moving it.
public class MyTitleWindow extends TitleWindow {
public function MyTitleWindow() {
// use a weak listener, or remember to remove it
stage.addEventListener(Event.RESIZE, onStageResize,
false, EventPriority.DEFAULT, true);
}
private function onStageResize(event:Event):void {
restoreOutOfStage();
}
override public function move(x:Number, y:Number):void {
super.move(x, y);
restoreOutOfStage();
}
private function restoreOutOfStage():void {
// avoid the popup from being positioned completely out of stage
// (use the actual width/height of the popup instead of 50 if you
// want to keep your *entire* popup on stage)
var topContainer:DisplayObjectContainer =
Application.application.parentDocument;
var minX:int = 50 - width;
var maxX:int = topContainer.width - 50;
var minY:int = 0;
var maxY:int = topContainer.height - 50;
if (x > maxX)
x = maxX
else if (x < minX)
x = minX;
if (y > maxY)
y = maxY
else if (y < minY)
y = minY;
}
}
In your TitleWindow's creationComplete handler add the following:
this.moveArea.visible=false;
This will do the job.
On the other hand, if you have a custom skin, you can remove the "moveArea" part. This should work, too.

Resources