CreateJS click target is wrong on Samsung Internet browser - javascript

I develop a html5 canvas browser game with createjs (Adobe Animate) and after the last update of Samsung Internet browser when the user clicks somewhere, it fires the click event for totally different button. It looks like the createjs native method _getObjectsUnderPoint() gives the wrong target of the click. Even when I click on empty space on the stage, where there is not buttons, a click handler is fired. This strange behavior is not present in Google Chrome or Opera for mobile, only in Samsung Internet.
In rare cases, even though the click target is correct, the handler is not called. More specifically, the problem must be in the createjs functions _testMask() or _testHit(). They use the canvas context and matrix transformations.
Does anyone has idea what should be fixed in the CreateJs library for Samsung Internet browser.

I solved the problem like this:
Check if the user agent contains SamsungBrowser
var userAgent = navigator.userAgent;
userAgent = userAgent.toLowerCase();
var isSamsungBrowser = userAgent.indexOf("samsungbrowser") != -1;
In CreateJs in _getObjectsUnderPoint() I added this near the end of the
for loop:
if(isSamsungBrowser) {
var bounds = child.getBounds();
if(bounds) {
var p = child.globalToLocal(x, y);
var hit = p.x >= bounds.x &&
p.x <= bounds.x + bounds.width &&
p.y >= bounds.y &&
p.y <= bounds.y + bounds.height;
if(! hit) {
continue;
}
}
else {
console.error('NO BOUNDS FOR', child);
continue;
}
}
The only drawback is that every Shape must have bounds. So you can convert the shapes to bitmaps in Adobe Animate or use setBounds().

Related

Canvas element + Javascript working in Chrome and Firefox, not in Internet Explorer

I am using a modified version of the Leaflet FullCanvas Plugin to draw lines on a map. These lines work perfectly find on Firefox and Chrome, but on Internet Explorer (version 11, I'm using Windows 8.1) these lines never get reset when moving/zooming the map. I made a Fiddle to illustrate the problem:
http://jsfiddle.net/tee99z65/
Try dragging and zooming while on Chrome or Firefox, and then Internet Explorer (11). What is going on in this code? The method that gets called every time the lines need to be redrawn is drawCanvas() :
drawCanvas: function () {
var canvas = this.getCanvas();
var ctx = canvas.getContext('2d');
var me = this;
ctx.clearRect(0, 0, canvas.width, canvas.height);
var bounds = this._myMap.getBounds();
if (!this.options.filterPointsInBounds) bounds = new L.LatLngBounds([-90, -180], [90, 180]);
var points = this._myQuad.retrieveInBounds(this.boundsToQuery(bounds));
points.forEach(function (point) {
var d = point.data;
if (d.draw && !d.draw(d)) return; // allows dynamic filtering of curves
var spoint = me._myMap.latLngToContainerPoint(new L.LatLng(d.slat, d.slon));
if (d.tlat && d.tlon) {
var tpoint = me._myMap.latLngToContainerPoint(new L.LatLng(d.tlat, d.tlon));
me.drawCurve(point, spoint, tpoint, d.style ? d.style(d) : null);
}
});
},
Does anyone have any idea what's going on here? A fix would be nice, but I'm already happy if anyone can point out why this is happening so I can attempt a fix myself.
Why?
Because mousewheel events are not yet standardized. (Note to browser makers: Seriously!???, why have you not standardized the mousewheel event yet. Scrolling mice have been around for years! -- end of rant/ ).
Fix:
You will have to listen for the mousewheel event on IE instead of the DOMMouseScroll event that most other browsers listen for. I don't work with leavlet, but that appears to be where you need to add the fix.
Problem solved:
http://jsfiddle.net/tee99z65/3/
The function that draws the curve, drawCurve(), has been edited from:
ctx.moveTo(startPoint.x, startPoint.y);
ctx.quadraticCurveTo(px, py, endPoint.x, endPoint.y);
ctx.stroke();
To:
ctx.beginPath();
ctx.moveTo(startPoint.x, startPoint.y);
ctx.quadraticCurveTo(px, py, endPoint.x, endPoint.y);
ctx.stroke();
ctx.closePath();
Lesson learned: never forget about beginPath() and closePath().

Why cocos2d-js + chipmunk, only works with web build

I've implemented simple example based on this
My example uses chipmunk along with cocos2d-js.
The problem is that physic only works with web builds. With the other builds (native ones - ios, mac, win32) all object are shown but they just hang - no animation.
My update method is called with specified intervals, where I execute "step" method on space object.
All my sprites are loaded using PhysicSprite class.
PS: I'm using cocos2d-js v3.0alpha
Use this tutorial:
http://www.cocos2d-x.org/docs/tutorial/framework/html5/parkour-game-with-javascript-v3.0/chapter6/en
I tried it both in the browser and in the iphone simulator and it worked just fine.
you should apply impulse on your physics body, they will move surely but if you would try to move the body with schedular by changing its coordinate on every call they will work on web but not on native ones like iOS or mac .
for example:-
var mass = 1;
var width = 1, height = 1;
playerBody = new cp.Body(mass , cp.momentForBox(mass, width, height));
playerBody.applyImpulse(cp.v(200, 300), cp.v(0, 0));// now you can move your playerBody
it will work well on all the platform but if you try my alternate solution
ie:-
init: function{
var mass = 1;
var width = 1, height = 1;
this.playerBody = new cp.Body(mass , cp.momentForBox(mass, width, height));
this.schedule(this.move);
},
move: function(dt){
this.playerBody.getPos().x += 2 * dt;
this.playerBody.getPos().y += 2 * dt;
}
this will work on web but on native platform like iOS or mac it will not move the playerBody at all. i don't know the reason yet if i got one i will let you know

Touch event doesnt works in IOS7 Iphone

I am working for html5 games and everything was working well in chrome, firefox, safari, Ipad IO6, android, but it does not work well in IOS7 and Iphone4. The touch event does not work well. even the simply 'e.preventdefault' cant handle the double touch issue, its keeping zoom in and out. not like another device.
anyone had same issue ??
its part of my code.. sorry cant write too much.. I had some NDA
var ua = navigator.userAgent.toLowerCase();
var checks = Boolean(ua.match(/android/))||
Boolean(ua.match(/ipod/))||
Boolean(ua.match(/ipad/))||
Boolean(ua.match(/tablet/))||
Boolean(ua.match(/tablet pc/))
var touchable = checks && (typeof (document.ontouchstart) != 'undefined');
if(touchable){
canvas.addEventListener('touchstart',mouseDown,false);
canvas.addEventListener('touchmove',mouseMove,false);
document.addEventListener('touchend',mouseUp,false);
}else{
canvas.addEventListener('mousedown',mouseDown,false);
canvas.addEventListener('mousemove',mouseMove,false);
document.addEventListener('mouseup',mouseUp,false);
}
function getMousePos(evt)
{
if(touchable && evt.touches.length>1)return;
if(touchable)evt = evt.changedTouches[0];
var rect = canvas.getBoundingClientRect();
return {
x: (evt.clientX - rect.left) / game.scale.x,
y: (evt.clientY - rect.top) / game.scale.y
};
}
function mouseDown(e)
{
var mousePos = getMousePos(e);
alert(mousePos.x + "," + mousePos.y);
e.preventDefault();
}
I definitely faced this issue while testing phonegap apps on an iPhone4 running iOS7. I removed the 300ms delay with fastclick.js, set all transitions to 0, removed the hover-delay, and there was still significant lag when scrolling. Unfortunately, the issue seems to be directly related to the iPhone4 hardware attempting to run iOS7. Technically while iOS7 is available on the iPhone4, iOS7 was not designed with the iPhone4 in mind.

Asynchronous canvas drawing with Web Workers

So, I'm making a relatively trivial HTML5 Canvas drawing web app. Basically, you can select your color, and then draw on a 500x500 canvas. It's going to be themed as a "graffiti" wall, so I am attempting to create a graffiti effect to the drawing, much like the Spray tool in MS Paint of yore.
Feel free to take a look at it here.
In order to facilitate this effect, I'm making use of web workers to callback on mouse events and asynchronously draw to the canvas. The naive implementation I have now is that on any mouse event, 5 pixels are randomly drawn around the coords of the event.
What I would like to do though, is to have those pixels drawn continuously from the mousedown event until the mouseup event, while updating the coords on mousemove events. From my limited knowledge of JavaScript, I imagine that this could involve a setTimeout(), but I'm not sure how to manipulate this to achieve what I want.
DISCLAIMER: This is part of a school project, and as such I am trying to avoid JQuery, Ajax, and other such frameworks; my goal here is to make an as-pure-as-possible JavaScript/HTML5 web app.
Thanks in advance.
Using a timer (no worker required):
var mouseX = 0,
mouseY = 0,
mouseDown = false;
function ev_canvas( ev ) {
if (ev.offsetX || ev.offsetX == 0) { //opera
mouseX = ev.offsetX;
mouxeY = ev.offsetY;
} else if (ev.layerX || ev.layerX == 0) { //firefox
var canvasOffset = document.getElementById("graffiti_wall").getBoundingClientRect();
mouseX = ev.layerX - canvasOffset.left;
mouseY = ev.layerY - canvasOffset.top;
}
if ( ev.type == 'mousedown' ) {
mouseDown = true;
}
else if ( ev.type == 'mouseup' ) {
mouseDown = false;
}
}
function draw_spray() {
if( !mouseDown ) {
//Don't do anything since the mouse is not pressed down
return;
}
//Draw something at the last known location
context.strokeRect( mouseX, mouseY, 1, 1 );
}
//Call draw_spray function continuously every 16 milliseconds
window.setInterval( draw_spray, 16 );
If you want to use a WebWorker (for example for more complex drawing algorithms), I could think of the following setup:
onmousedown, spawn a new worker and register a handler on it that paints objects on the canvas
onmouseup (and -leave etc), terminate the worker
onmousemove, if a worker exists determine mouse coordinates and send them into the worker
In the worker
listen to new mouse coordinates
start an timeout interval which constantly fires draw-events (depending on current coordinates and a clever algorithm)
Yet I think that a Worker is too much overhead for a simple graffiti tool. Use the simple solution without a Worker like #Esailija demonstrated.
If you had a more complex application which could make good use of Workers, you wouldn't really spawn them onmousedown and terminate them. Instead, you maybe instantiated single Workers for single kinds of tools, and fired start-processing and end-processing events to them.

Multitouch Pinch, Pan, Zoom in HTML 5 Canvas

I have most of a module written to handle multitouch pinch, pan and zoom on an HTML 5 canvas element. I will share it below. I've been developing in JavaScript for some time now, and this one continues to boggle me. If anybody has any insights, I will post the final version up on stack for everybody to share once it is confirmed working on my iPad.
Here is what I am doing:
touchmove events trigger the changing of variables. I use these variables to change the way in which my image is painted onto the canvas. I have eight variables, each corresponding to the options that can be put into the drawImage() function. These eight variables get updated through functions that increment/decrement their values and keep them within a certain range. The variables are closure variables, so they are global throughout my module. To prevent over-processing, I make a call to this drawImage() function once every 40ms while the user has their finger pressed to the screen using a setInterval().
Here is the problem:
touchmove events seem to be causing a race condition where my variables get updated by many different instances of that same event. I can somewhat confirm this through my console output, that tracks one variable that is bounded to never reach below 20. When I swipe in one direction quickly, that variable dips down far below 20. Then when I release my finger, swipe slowly, it returns to 20. Another thing that points me in this direction, when I look at these variables while stepping through my program, they differ from what my console.log() pumps out.
Note: The code successfully draws the image the first time, but not anytime thereafter. A basic rendition of my code is below... The full version is on GitHub inside the Scripts folder. It is a Sencha Touch v1.1 app at heart
function PinchPanZoomFile(config)
{
/*
* Closure variable declaration here...
* Canvas Declaration here...
*/
function handleTouchStart(e) {
whatDown.oneDown = (e.originalEvent.targetTouches.length == 1) ? true : false;
whatDown.twoDown = (e.originalEvent.targetTouches.length >= 2) ? true : false;
drawInterval = setInterval(draw, 100);
}
function handleTouchEnd(e) {
whatDown.oneDown = (e.originalEvent.targetTouches.length == 1) ? true : false;
whatDown.twoDown = (e.originalEvent.targetTouches.length >= 2) ? true : false;
clearInterval(drawInterval);
}
function handleTouchMove(e) {
if(whatDown.twoDown) {
/*
* Do Panning & Zooming
*/
changeWindowXBy(deltaDistance); //deltaDistance
changeWindowYBy(deltaDistance); //deltaDistance
changeCanvasXBy(deltaX); //Pan
changeCanvasYBy(deltaY); //Pan
changeWindowDimsBy(deltaDistance*-1,deltaDistance*-1); //(deltaDistance)*-1 -- get smaller when zooming in.
changeCanvasWindowDimsBy(deltaDistance,deltaDistance); //deltaDistance -- get bigger when zooming in
} else if(whatDown.oneDown) {
/*
* Do Panning
*/
changeWindowXBy(0);
changeWindowYBy(0);
changeCanvasXBy(deltaX);
changeCanvasYBy(deltaY);
changeWindowDimsBy(0,0);
changeCanvasWindowDimsBy(0,0);
}
}
function draw() {
//Draw Image Off Screen
var offScreenCtx = offScreenCanvas[0].getContext('2d');
offScreenCtx.save();
offScreenCtx.clearRect(0, 0, canvasWidth, canvasHeight);
offScreenCtx.restore();
offScreenCtx.drawImage(base64Image,
parseInt(windowX),
parseInt(windowY),
parseInt(windowWidth),
parseInt(windowHeight),
parseInt(canvasX),
parseInt(canvasY),
parseInt(canvasWindowWidth),
parseInt(canvasWindowHeight)
);
//Draw Image On Screen
var offScreenImageData = offScreenCtx.getImageData(0, 0, canvasWidth, canvasHeight);
var onScreenCtx = canvas[0].getContext('2d');
onScreenCtx.putImageData(offScreenImageData, 0, 0);
}
}
I strongly recommend using Sencha Touch 2.0.1, as it supports a lot of the touch events you need. See http://dev.sencha.com/deploy/touch/examples/production/kitchensink/#demo/touchevents for examples.

Categories