Appcelerator: Touchmove to drag view gives very "jumpy" result - appcelerator

I am trying to drag a view in android environment using Appcelerator and it turns out to have a very jumpy animation. The codes are as below:
newmainwindow.addEventListener('touchstart', function(e){
xPos = e.x;
yPos = e.y;
});
newmainwindow.addEventListener('touchmove', function(e){
var conPoint = newmainwindow.convertPointToView({x:e.x, y:e.y}, mainview);
console.log("global y: " + conPoint.y);
var moveY = conPoint.y - yPos;
moveY /= 2;
console.log("global diff y: " + moveY);
newmainwindow.top = Math.abs(moveY);
});
newmainwindow.addEventListener('touchend', function(e){
console.log("end");
});
I have searched for a lot of solutions but unfortunately none of them works. Any help is greatly appreciated :)

The challenge with draggable views in Titanium is that the bridge between JS and native becomes a bottleneck because all the feedback back and forth.
Hyperloop (beta) allows you to directly use platform APIs. The example app also has samples for dragging views:
https://github.com/appcelerator/hyperloop-examples

https://github.com/pec1985/TiDraggable
I used this and it's an absolutely great solution. Works out of the box.

Related

d3 zoom behaviour is overwriten by mousemove event

I am implementing d3.js zoom behaviour on a svg, on the same svg I also need to capture mouse coordinate so I can set position of a tool tips that follow mouse cursor's position.
The problem is that my 'mousemove' event has override d3.js zoom behaviour.
With 'mousemove' event added, zoom behaviour stop working.
It is either I have 'mousemove' event or 'zoom' event, but not both. Any suggestion how to get around this? Thanks.
// bind zoom behavior
selection_svg.call(
d3.behavior.zoom()
.translate([0, 0])
.scale(1)
.scaleExtent([1, 14])
.on('zoom', ()=>{ selection_plotArea.attr('transform', 'translate('+d3.event.translate+')scale('+d3.event.scale+')'); })
);
// tool tip coordinate
const toolTipNode = selection_toolTip.node();
toolTipNode.style.position = 'absolute';
selection_svg.node().addEventListener('mousemove',function(evt){
const coord_client = {
x:evt.clientX,
y:evt.clientY,
}
toolTipNode.style.left = `${coord_client.x}px`;
toolTipNode.style.top = `${coord_client.y}px`;
}, false);
I have added the code for this problem to fiddle:
https://jsfiddle.net/apollotang/rt9t1vdj/
The problem seems to be related to tooltipNode catching mouse events. By adding some offset to coord_client your problem would be gone.
selection_svg.on('mousemove', function () {
const coord_client = {
x: d3.event.layerX + 10,
y: d3.event.layerY + 10
};
toolTipNode.style.left = `${coord_client.x}px`;
toolTipNode.style.top = `${coord_client.y}px`;
}, false);
Note: I also changed clientX and clientY to layerX and layerY since there was a bug when scrolling changed mouse position and tooltipNode would have been separated from mouse. Besides the event handling code changed to be handled by d3.
If you have a mousemove event attached to your svg, be sure you aren't calling d3.event.stopPropagation() within the mousemove event, or else you will prevent the zoom behavior.

drawWindow() broken with multiprocess Firefox (e10s)?

The Firefox drawWindow()-Function expects as first parameter a XUL content-window as provided by the low-level api tab utils.
However with the introduction of the multiprocess architecture in Firefox (codenamed electrolysis or e10s) directly accessing tabs via the low-level api is no longer possible. While there are compatibility shims available, it is explicitly stated that they do not support plattform APIs that expect DOM objects.
On the other hand drawWindow() cannot be used in a content script since it is "chrome only".
So my questions are these:
How am I supposed to use drawWindow() if I cannot use it outside of chrome and cannot get a contentWindow-object within chrome?
What are my other options to let my addon take screenshots of websites within multiprocess Firefox?
Our current approach is based on the answer to this SO question. However it will not work with multiprocess Firefox
The solution to using drawWindow() was indeed to use framescripts as Noitidart suggested in the comments. The framescript I use for the screenshots looks like this:
addMessageListener("fs/make_screenshot_from_rectangle", makeScreenshot);
function makeScreenshot(payload) {
var rectangle = payload.data;
var startX = rectangle.startX || 0;
var startY = rectangle.startY || 0;
var width = rectangle.width || content.innerWidth;
var height = rectangle.height || content.innerHeight;
// Create canvas to draw window unto
var canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.width = width;
canvas.height = height;
// Create context for drawing, draw the old window unto the canvas
var context = canvas.getContext("2d");
context.drawWindow(content, startX, startY, width, height, "rgb(255,255,255)");
// Save context as png
var image = canvas.toDataURL('image/png');
sendAsyncMessage("got-screenshot", image);
}
And it is called from a chrome-script with the following function:
function (rectangle) {
var tab = require("sdk/tabs").activeTab;
var xulTab = require("sdk/view/core").viewFor(tab);
var xulBrowser = require("sdk/tabs/utils").getBrowserForTab(xulTab);
var browserMM = xulBrowser.messageManager;
if ( /* framescript not yet attached to tab */ ) {
browserMM.loadFrameScript(require("sdk/self").data.url("content-scripts/frame-script.js"), false);
... // do something to remember that there is a framescript attached to the tab
browserMM.addMessageListener("got-screenshot", function (payload) {
... // handle the screenshot
});
}
browserMM.sendAsyncMessage('fs/make_screenshot_from_rectangle', rectangle);
}
Relevant reading:
https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Multiprocess_Firefox_and_the_SDK
https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Message_Manager/Message_manager_overview#Browser_messa

how to change view with swipe titanium appcelerator

hello i have a problem:
I have two views in a window and I wish with a swipe event is passed from one view to another as if it were a tabgroup.
Can anyone tell me how is it possible ?
thanks so much
You need to use ScrollableView for this.
your code will look like this:
var win = Ti.UI.createWindow();
var view1 = Ti.UI.createView({ backgroundColor:'#123' });
var view2 = Ti.UI.createView({ backgroundColor:'#246' });
var view3 = Ti.UI.createView({ backgroundColor:'#48b' });
var scrollableView = Ti.UI.createScrollableView({
views:[view1,view2,view3],
showPagingControl:true
});
win.add(scrollableView);
win.open();

Kinetic js rotate to mouse with stage click

got a problem with firing the mouse position event. The Object are moving when I drag them but not when I click on stage. What should I do? (of course I am adding a stage and layer and stuff ;) Thanks a lot in advance!
function rotateAlltoMouse(layer3) {
for(var n = 0; n < layer3.getChildren().length; n++) {
var shape = layer3.getChildren()[n];
var stage = shape.getStage();
var mousePos = stage.getMousePosition();
var xd = shape.getPosition().x - mousePos.x;
var yd = shape.getPosition().y - mousePos.y ;
var theta = Math.atan2(yd, xd);
var degree = theta / (Math.PI / 180) - 45;
shape.setRotationDeg(degree);
}
}
$('#container').bind('mousemove touchstart', function() {
rotateAlltoMouse(layer3);
});
Just a guess---could be better than a guess if you supply more code ;)
Try requesting the containing DOM element with kineticJS so that you know you're getting the proper container. KineticJS creates some supporting elements for its own use and your #container might not be getting the stage.
$(stage.getDOM()).on('mousemove', function(){ rotateAlltoMouse(layer3); });

d3+crossfilter: Date-axis renders pixelthin bars

I spent the better part of the day trying to get a nice Date-axis histogram, to the extent that I'm posting my first question on stackoverflow.
The axis and the stacking are just the way I want it, however the bars are really thin for no (to me) apparent reason. In other words, I would really appreciate some help.
Here's a minimized version (I'm using the dc.js library, however I'm pretty confident the challenges is on d3+crossfilters behalf):
var jsonstr = [{"timestamp": "2013-06-13T11:04:24.729Z"},{"timestamp": "2013-06-17T11:03:24.729Z"},{"timestamp": "2013-06-17T11:02:24.729Z"},{"timestamp": "2013-06-19T11:02:14.129Z"}];
var ndx = crossfilter(jsonstr);
var timestampD = ndx.dimension(function (d) {
return new Date(d.timestamp);
});
var timestampDG = timestampD.group(function (d) {
return d3.time.day(d);
});
var barChart = dc.barChart("#dc-bar");
barChart.width(500)
.height(250)
.dimension(timestampD)
.group(timestampDG)
.x(d3.time.scale().domain([(new Date(2013,05,12)), (new Date(2013,05,20))]).nice(d3.time.day))
.xAxis().tickFormat(function (x) {
return x.getDate() + "/" + (x.getMonth()+1);
});
dc.renderAll();
I think the problem is actually with how you're using dc.js; you don't specify what units the barchart should be in. Try this:
barChart
.width(500)
.height(250)
.dimension(timestampD)
.xUnits(d3.time.days)
.ect
For anyone else having this problem, for whom Adam's answer doesn't seem to do anything, make sure you don't have elasticX set to true as I did.

Resources