developing for Gear s2 web app (Tizen),
how is it possible to scroll a page which has only text, using the bezel?
Thanks.
First you have to listen to the "rotarydetent" events, e.g. like following:
document.addEventListener('rotarydetent', onRotarydetent);
function onRotarydetent(ev) {
var direction = ev.detail.direction;
if(direction === "CW"){ // CW = clockwise; CCW = counterclockwise
... scroll down ...
} else {
... scrull up ...
}
}
So now to scroll the page content it depends on how build your web app. If you use the SDK Wizard and have a project including tau.js it will be simple if you know that tau adds a scroller container around each page. Now you just need to find the scroller and scroll it. Using jQuery it could look like following:
function onRotarydetent(ev) {
var direction = ev.detail.direction,
uiScroller = $('#pageid').find('.ui-scroller'),
scrollPos = $(uiScroller).scrollTop();
console.debug("onRotarydetent: " + direction);
if(direction === "CW"){
$(uiScroller).scrollTop(scrollPos + 100); // scroll down 100px
} else {
$(uiScroller).scrollTop(scrollPos - 100); // scroll up 100px
}
}
Have a look at the UIComponents sample app available within the Tizen Wearable SDK.
You need to use the TAU library to achieve Text scrolling using Beezel.
Create a new project using the UI Components app and Install it on Gear s2 emulator or original hardware. Then Run the app and click on the first option 'Header' which contains your use case i.e. plain text scrollable by beezel.
Related
I’m migrating a CKEditor v4 to v5.
I need to be able to scroll to the bottom (or the top) of the editor content.
The solution here is not working for me.
This is what I tried:
function ckScroll(editor, position){
editor.model.change( writer => {
var root = editor.model.document.getRoot();
var pos = writer.createPositionAt( root, position);
writer.setSelection(pos);
}
);
}
ckScroll is called (with position ‘end’ or ‘before’) from a button.
Nothing happens...
Adding writer.setSelectionFocus(pos); doesn’t help.
Any help is welcome !
I need to add back navigation on swipe. I can do that fairly easily by just adding a swipe listener to the page view and calling goBack. But I really would like the animation that goes with it (in Instagram or FB) where as soon as you start dragging your thumb, the page translates to the right and the previous page starts to translate into view. And then once you get to a certain point it actually performs the navigation.
I tried animating the page, as well as the frame to the right figuring since the view isn't being destroyed it might work. But it doesn't display the page Im navigating back to.
Looking for help on how to accomplish this!
I guess you might have come across the other SO thread answering this question natively.
All you have to do is modify the default gesture recogniser on iOS frame.
export function onNavigatedFrom(args: EventData) {
console.log("Adding gesture...");
const frame = (<Page>args.object).frame;
if (frame.ios && !(<any>frame)._gestureRecognizer) {
const controller = frame.ios.controller;
const popGestureRecognizer = controller.interactivePopGestureRecognizer;
const targets = popGestureRecognizer.valueForKey("targets");
if (targets) {
let gestureRecognizer = UIPanGestureRecognizer.alloc().init();
gestureRecognizer.setValueForKey(targets, "targets");
frame.nativeView.addGestureRecognizer(gestureRecognizer);
(<any>frame)._gestureRecognizer = gestureRecognizer;
}
}
}
export function onNavigatedTo(args: EventData) {
console.log("Back to root page, removing gesture...");
const frame = (<Page>args.object).frame;
if (frame.ios && (<any>frame)._gestureRecognizer) {
frame.nativeView.removeGestureRecognizer((<any>frame)._gestureRecognizer);
(<any>frame)._gestureRecognizer = null;
}
}
Playground Sample
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.
I need to capture tap (click) events on a WebView (to display a picture in a SVG file), so that I can show another Nativescript page (or show another SVG) based on where the image is clicked..
Is there a way to capture a tap event with x,y coordinates for WebView?
Another thing. I found WebView can capture hyperlinks within the html loaded... Is there a way to make a link within the html so it open another local file within the nativescript app? For example: < a href="~/stuff/foo2.html">here< /a >, but didn't work (where stuff is under my "app" folder) but I am getting a 404.
Here's a possible solution.
Add some front end Javascript code to the page displaying in your WebView. Use that Javascript to detect taps on the page and when tapped redirect the WebView to a new (fake) page. On the NativeScript side, listen to the loadStartedEvent of the WebView (firing when the WebView navigates) and do something when the WebView tries to navigate to that new fake page.
I'd look something like this:
In the browser/WebView code. We add an event listener for click events (you probably want to change this to tap events). When clicked navigate the user to nativescript://{X coordinate}/{Y coordinate}.
window.addEventListener('click', function(event){
window.location.href='nativescript://' + event.screenX + '/' + event.screenY;
})
Then on the NativeScript side, set up an event listener listening for when the WebView is navigating and if it's navigating to a URL starting with 'nativescript://' then stop the loading event and extract the coordinates from the URL.
var wv = new webViewModule.WebView();
wv.on(webViewModule.WebView.loadStartedEvent, function(event) {
// Check if the WebView is trying to navigate to 'nativescript://...'
if (event.url.indexOf('nativescript://') === 0 ) {
// Stop the loading event
if (ios) {
event.object.ios.stopLoading();
} else if (android) {
event.object.android.stopLoading();
}
// Do something depending on the coordinates in the URL
var coords = event.url.split('/');
coords.splice(0, 2);
console.log(coords[0] + ' - ' + coords[1])
}
});
As for loading local file, you just need to create a file:// path to the local file. E.g.
var linkPath = fs.path.join(fs.knownFolders.currentApp().path, 'localHTMLFiles') + '/myFile.html';
var link = '<a href="file://" + linkPath + ">"'
You can extend WebView to WebViewExt https://market.nativescript.org/plugins/#nota%2Fnativescript-webview-ext and grab links with
webview.on(WebViewExt.shouldOverrideUrlLoadingEvent, (_args: ShouldOverrideUrlLoadEventData) => {
let blocked_url = _args.url;
// Disable loading native app
_args.cancel = true;
// Do some stuff and load another url..
});
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.