Nativescript-google-maps-sdk: mapView.zoom not changing zoom - nativescript

I am trying to change the zoom level after clicking on a marker. I've tried to redefine the zoom inside the onMarkerEvent() :
onMarkerEvent(args) {
if (args.eventName === 'markerInfoWindowTapped') {
this.routerExtenstions.navigate([`../item/${args.marker.userData.id}`], { relativeTo: this.activatedRoute });
} else if (args.eventName === 'markerSelect') {
this.zoom = 17;
this.mapView.zoom = this.zoom;
}
}
However, the zoom is not changing.
On map.component.tns.html I have:
<MapView #mapView [latitude]="latitude" [longitude]="longitude"
[zoom]="zoom" [minZoom]="minZoom" [maxZoom]="maxZoom" [bearing]="bearing"
[tilt]="tilt" i-padding="50,50,50,50" [padding]="padding" (mapReady)="onMapReady($event)"
(markerSelect)="onMarkerEvent($event)" (markerInfoWindowTapped)="onMarkerEvent($event)"
(coordinateTapped)="onCoordinateTapped($event)"
(cameraChanged)="onCameraChanged($event)" (mapAnimationsEnabled)="true"
(cameraMove)="onCameraMove($event)">
</MapView>
Any ideas on how to fix this? I feel that maybe be something basic I am forgetting.
Thanks!

To adjust the zoom you might have better luck by changing the mapView properties directly, you can do so by accessing the MapView through the args inside of the onMarkerEvent function.
Doing args.object.zoom = 17; should do the trick.

Related

vis.js timeline auto scroll function

I have gotten into a small issue I can't seam to wrap my head around, and I hope for some guidesnes from you folks.
I have a timeline with a bunch of groups and subgroups, and the height of the timeline is now bigger than the height of the monitor showing it.
And that is fine it can be scrolled using the scroll wheel on the mouse, however as it is ment to be just a timeline on a wall mounted screen it would be cool if I could make an autoscroll function, that scroll the timeline up and down in a given timeframe.
Unfortunatly I can't figure out where to implement it to make it work.
I have the following code to make a div scroll ( and have tried diffrent ways to make it do it in the vis.js code, but so far no luck )
if anyone knows of a way to make it scroll up and down in a given timeframe i would really appreciate the help.
<script language="javascript">
ScrollRate = 1;
function scrollDiv_init() {
//this can be a class also.
DivElmnt = document.getElementById('MyDivName');
ReachedMaxScroll = false;
DivElmnt.scrollTop = 0;
PreviousScrollTop = 0;
ScrollInterval = setInterval('scrollDiv()', ScrollRate);
}
function scrollDiv() {
if (!ReachedMaxScroll) {
DivElmnt.scrollTop = PreviousScrollTop;
PreviousScrollTop++;
ReachedMaxScroll = DivElmnt.scrollTop >= (DivElmnt.scrollHeight - DivElmnt.offsetHeight);
}
else {
ReachedMaxScroll = (DivElmnt.scrollTop == 0) ? false : true;
DivElmnt.scrollTop = PreviousScrollTop;
PreviousScrollTop--;
}
}
function pauseDiv() {
clearInterval(ScrollInterval);
}
function resumeDiv() {
PreviousScrollTop = DivElmnt.scrollTop;
ScrollInterval = setInterval('scrollDiv()', ScrollRate);
}
</script>
Well, the only tricky part I can see about scrolling timeline at http://visjs.org/examples/timeline/other/verticalScroll.html is that you have to scroll certain element, not the container of the timeline. If you use inspector to find the element with the scrollbar, you'll probably be surprised to see this:
Indeed, if I apply scrolling to that element
var scrollerElement = document.querySelector('#mytimeline1 div.vis-panel.vis-left.vis-vertical-scroll');
scrollerElement.scrollTop = 100;
the timeline gets scrolled vertically. By the way, the vis-vertical-scroll class suggests that we are on the right way. Actually, you should probably use a shorter selector instead:
var scrollerElement = document.querySelector('#mytimeline1 .vis-vertical-scroll');
You can try this via browser console on that page. I think this should be enough for you to implement the desired autoscrolling.

Kendo Grid: Removing dirty cell indicators

I have been looking at a way to save off my client side edited grid data automatically when the user changes to another row (just like in access, sql management studio etc). It really seems to be a bit of a challenge to do.
One scheme was to use the data source sync, but this ha the problem of loosing our cell position (it always jumped to cell 0, 0).
I have been shown some clever work arounds (go back to the cell after the case, which by the way is hugely appreciated thanks),
but it after some lengthy testing (by myself and others) seemed to be a little "glitchy" (perhaps I just need to work on this more)
At any rate, I wanted to explore perhaps not using this datasource sync and perhaps just do the server side calls "manually" (which is a bit is a pity, but if that's what we need to do, so be it). If I do this, I would want to reset the cell little red cell "dirty" indicators.
I thought I could use something similar to this scheme (except rather than resetting the flag, I want to unset).
So, as in the above link, I have the following..
var pendingChanges = [];
function gridEdit(e) {
var cellHeader = $("#gridID").find("th[data-field='" + e.field + "']");
if (cellHeader[0] != undefined) {
var pendingChange = new Object();
pendingChange.PropertyName = e.field;
pendingChange.ColumnIndex = cellHeader[0].cellIndex;
pendingChange.uid = e.items[0].uid;
pendingChanges.push(pendingChange);
}
}
where we call gridEdit from the datasource change..
var dataSrc = new kendo.data.DataSource({
change: function (e) {
gridEdit(e);
},
Now assuming we have a callback that detects the row change, I thought I could do the following...
// clear cell property (red indicator)
for (var i = 0; i < pendingChanges.length; i++) {
var row = grid.tbody.find("tr[data-uid='" + pendingChanges[i].uid + "']");
var cell = row.find("td:eq(" + pendingChanges[i].ColumnIndex + ")");
if (cell.hasClass("k-dirty-cell")) {
cell.removeClass("k-dirty-cell");
console.log("removed dirty class");
}
}
pendingChanges.length = 0;
// No good, we loose current cell again! (sigh..)
//grid.refresh();
When this didn't work, I also tried resetting the data source dirty flag..
// clear dirty flag from the database
var dirtyRows = $.grep(vm.gridData.view(),
function (item) {
return item.dirty == true;
})
if (dirtyRows && dirtyRows.length > 0) {
dirtyRows[0].dirty = false;
}
demo here
After none of the above worked, I tried the grid.refresh(), but this has the same problem as the datasource sync (we loose our current cell)
Would anyone have any idea how I can clear this cell indicator, without refreshing the whole grid that seems to totally loose our editing context?
Thanks in advance for any help!
Css :
.k-dirty-clear {
border-width:0;
}
Grid edit event :
edit: function(e) {
$("#grid .k-dirty").addClass("k-dirty-clear"); //Clear indicators
$("#grid .k-dirty").removeClass("k-dirty-clear"); //Show indicators
}
http://jsbin.com/celajewuwe/2/edit
Simple solution for resolve that problem is to override the color of the "flag" to transparent.
just override the ".k-dirty" class (border-color)
just adding the above lines to your css
CSS:
//k-dirty is the class that kendo grid use for mark edited cells that not saved yet.
//we override that class cause we do not want the red flag
.k-dirty {
border-color:transparent transparent transparent transparent;
}
This can also be done by applying the below style,
<style>
.k-dirty{
display: none;
}
</style>

Hammer.js breaks vertical scroll when horizontal pan

I'm using Hammer.js to look for horizontal pan gestures, I've devised a simple function to clicks a button when panned left or right. It works okay, except the vertical scroll doesn't do anything on a touch device, or it's really glitchy and weird.
Here's the function:
var panelSliderPan = function() {
// Pan options
myOptions = {
// possible option
};
var myElement = document.querySelector('.scroll__inner'),
mc = new Hammer.Manager(myElement);
mc.add(new Hammer.Pan(myOptions));
// Pan control
var panIt = function(e) {
// I'm checking the direction here, my common sense says it shouldn't
// affect the vertical gestures, but it blocks them somehow
// 2 means it's left pan
if (e.direction === 2) {
$('.controls__btn--next').click();
// 4 == right
} else if (e.direction === 4) {
$('.controls__btn--prev').click();
}
};
// Call it
mc.on("panstart", function(e) {
panIt(e);
});
};
I've tried to add a horizontal direction to the recognizer but it didn't really help (not sure if I did it even right):
mc = new Hammer.Manager(myElement, {
recognizers: [
[Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL }],
]
});
Thanks!
Try setting the touch-action property to auto.
mc = new Hammer.Manager(myElement, {
touchAction: 'auto',
recognizers: [
[Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL }],
]
});
From the hammer.js docs:
When you set the touchAction to auto it doesnt prevent any defaults, and Hammer would probably break. You have to call preventDefault manually to fix this. You should only use this if you know what you're doing.
User patforna is correct. You need to adjust the touch-action property. This will fix scrolling not working when you have hammer bound on a big element in mobile.
You create a Hammer instance like so
var h = new Hammer(options.contentEl, {
touchAction : 'auto'
});
I was working on a pull to refresh feature, so I need the pan event.
Add the recognizers.
h.get( 'pan' ).set({
direction : Hammer.DIRECTION_VERTICAL,
});
h.on('panstart pandown panup panend', eventHandler);
Inside the eventhandler, you'd look at the event that was triggered and manually call on event.preventDefault() when you require it. This is applicable for hammer 2.0.6.
For anyone who's looking the pull to refresh code was taken from - https://github.com/apeatling/web-pull-to-refresh
My problem was that vertical scroll was toggling a sidebar that was supposed to show/hide on horizontal pan/swipe. After looking at the event details, I realized that Hammer probably triggers panleft and panright event based on X delta and doesn't consider Y delta, so my quick solution was to check the pan direction in my handler:
this.$data.$hammer.on('panleft', (e) => {
if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
return;
}
this.isVisible = true;
});
I was stuck on this for several days. Hope this will fix your problem.
mc = new Hammer(myElement, {
inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput,
touchAction: 'auto',
});
When the relevant gesture is triggered, we applied a css class to the element, that would set the touch-action to none.
mc.on('panmove panstart', event => {
mc.addClass('is-dragging');
}
);
.is-dragging {
touch-action: none !important;
}
Hammer 2.x does not support vertical swipe/pan. Documentation says:
Notes:
When calling Hammer() to create a simple instance, the pan and swipe recognizers are configured to only detect horizontal gestures
You can however use older 1.1.x version, which supports vertical gestures
——
Clarification: this refers to a ‘simple instance’ which is when you don’t pass in any recognizer configuration as the second parameter. In other words these are the defaults but can (and usually should) be overridden.

Erase method for raphael object

is there a way to implement a erase method for raphael objects. in this erase method I want to remove specific parts of a particular raphael object. It means that the erase method should work like a real eraser. In the raphael documentation there is a method call Paper.clear(). But we only can delete entire paper.
Any kind of help is appreciated.
The normal way to be to use the remove() method.
http://raphaeljs.com/reference.html#Element.remove
element.remove();
You could eventually create a function that draws shapes with the same color than your paper background-color, on click. Something like this code (jsfiddle at the end of the post). It would cover your content and not erase it, but it would look like it.
var timeoutId = 0;
var cursorX;
var cursorY;
var mouseStillDown = false;
paper = Raphael("paper1","100%","100%");
paper.rect(10,10,100,100).attr({
fill : "black"
});
$("#paper1").mousemove(function(event){
cursorY=event.pageY;
cursorX=event.pageX;
});
function erase() {
if (!mouseStillDown) { return; }
paper.rect(cursorX-25,cursorY-25,50,50).attr({
fill :"white",
stroke : "white"
});
if (mouseStillDown) { setInterval("erase", 100); }
}
$("#paper1").mousedown(function(event) {
mouseStillDown = true;
erase(event.pageX,event.pageY);
});
$("#paper1").mouseup(function(event) {
mouseStillDown = false;
});
Here, each time you click, it creates a white rectangle at your cursor position.
Here's a fiddle of the code : http://jsfiddle.net/c6Xs6/
With a few modifications you could create a menu allowing the user to choose the size and shape of the form you use to "erase".
Something more or less like this : http://jsfiddle.net/8ABe9/
You could also use a div following your cursor to show exactly where the "eraser" would be drawn.
Hope that helped you :)

Handling fixed position in relation to touch devices

The menu is fixed and will follow on scroll. This does not work well with touch devices.
I want to call the script, using Modernizr, when it detect no-touch devises. But I'm unsure how to do this.
Also, is there elements from the Modernizr download-page that I need to accomplish this?
Here is my script:
$(document).ready(function() {
$(window).scroll(function() {
var header = $('#fixed-bar').outerHeight(true);
console.log(header);
var scrollTopVal = $(this).scrollTop();
if ( scrollTopVal > header ) {
$('nav').css({'position':'fixed','top' :'0px', 'border-bottom':'4px solid #ff5454'});
} else {
$('nav').css({'position':'absolute','top':'90px', 'border-bottom':'none'});
}
});
});
But I'm unsure how to do this.
You don't want to just use javascript, you want to use mostly css, and just toggle classes with javascript. Its more performant (which is super important with something like scroll loops).
#fixed-bar {
position: fixed;
top: 0px;
border-bottom:4px solid #ff5454;
}
.touch #fixed-bar, #fixed-bar.at-top {
top: 90px;
border-bottom: none
}
also, you don't want to directly attach to window.scroll. Instead, you want to use requestAnimationFrame (shimming where needed) to get the most buttery smooth animations possible. Here is a coffeescript example for jQUery.With that, you would be looking to do something like this
$(document).ready(function() {
// the height doesn't change, so we don't need to look it up on scroll.
var headerHeight = $('#fixed-bar').outerHeight(true);
$.request_scroll(function() {
var scrollTopVal = $(this).scrollTop();
if ( scrollTopVal > headerHeight ) {
$('nav').addClass('at-top');
}
else {
$('nav').removeClass('at-top');
}
});
Also, is there elements from the Modernizr download-page that I need to accomplish this?
just the Modernizr.touch test.
Be warned, this doesn't detect touch screens, just devices that support touchevents. That means new windows 8 laptops will be detected as .touch, and windows phones will not (they use pointer-events, not touch events).
I now have a fiddle with help from Patricks answers, but as you can see, the bar does still not go to the top, when you scroll as it should, like on my website.
Is there a solution for this? Tablets and phones don't like effects, which have $(window).scroll(function().
Currently I have this javascript on my website (the id's are different):
$(document).ready(function() {
$(window).scroll(function() {
var header = $('#fixed-bar').outerHeight(true);
console.log(header);
//this will calculate header's full height, with borders, margins, paddings
var scrollTopVal = $(this).scrollTop();
if ( scrollTopVal > header ) {
$('nav').css({'position':'fixed','top' :'0px', 'border-bottom':'4px solid #ff5454'});
} else {
$('nav').css({'position':'absolute','top':'90px', 'border-bottom':'none'});
}
});
});
While most tablets have problems with $(window).scroll(function(), it works on desktop pc. Not much consolation though.
Is there an alternate way of getting this to work? Using touch- and pointer events, maybe someone has a working fiddle og example?

Resources