I have a problem in mobile browsers.
I maked a canvas chart without any js library or frameworks, but its animations is very very slow in mobile
I use this function for requestAnimationFrame:
(function () {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function () {
callback(currTime + timeToCall);
},
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
}());
requestAnimationFrame(myFunc);
function myFunc(){
//any code
.
.
requestAnimationFrame(myFunc);
})
What should I do?
First off, you didn't post the relevant code. How you are drawing to the canvas is almost certainly your problem. There are a few tips for making that better:
Draw to an offscreen canvas and copy the image data over all at once.
Combine the above with multiple canvases, only draw layers that have changed e.g. your graph layer may have changed but not the labels/legend.
Draw to a smaller canvas and scale it up.
To be honest though, mobile browsers are way, way slower than their desktop counterparts for a variety of reasons (heat and power consumption being two rather large ones). If you want smooth animations you will have to either write some high-performance rendering code (likely in WebGL) or use someone elses (e.g. pixi.js).
Related
Here's the site in question: https://marks-groovy-project-2fa056.webflow.io/
I want to rotate each letter by 90 degrees on their Y axis while scroll is active, and return them back to their original position as soon as scrolling stops.
Visualization: in top view, a letter should rotate 90deg counter-clockwise when scroll is activated, which will render the letter invisible in front view ( the viewport) while scrolling, and then turn back 90 degrees clockwise when scrolling ends, so that each letter is visible again.
Method: used skew.js and slightly modified it:
skew.js is applied to an entire section. I want to apply it to every instance of a span with id="letter-animation". I've appropriately renamed the constant and referenced the #.
const speed is a remnant from skew.js. I haven't yet figured out how to rewrite it. It expresses the amount of skew as a function of the difference in newPixel/oldPixel. Which I don't want. My rotation needs to be 90deg every time. Once in, once out.
letter.style.transform = "rotateY(45deg)" used to be "rotateY(" + speed + "deg)" in the old script. (technically it was "skewY", not "rotateY" but you get my point). const speed would then be replaced with whatever new constant is appropriate as mentioned in point 2.
I've set up this codepen to isolate the script in question. https://codepen.io/mhedinger/pen/yLJaLmp
const letter = document.querySelector("#letter-animation")
let currentPixel = window.pageYOffset
const looper = function(){
const newPixel = window.pageYOffset
const diff = newPixel - currentPixel
const speed = diff * 11
letter.style.transform = "rotateY(45deg)"
currentPixel = newPixel
requestAnimationFrame(looper)
}
looper()
Here's the tutorial that explains how skew.js works: https://www.superhi.com/video/skew-on-scroll-effect
And here's an example of it working, according to the video tutorial above: https://codepen.io/emgiust/pen/rdOJwQ
const section = document.querySelector("section");
let currentPixel = window.pageYOffset
//looper keeps running and keeps track of where the new pixel is
const looper = function () {
const newPixel = window.pageYOffset;
const diff = newPixel - currentPixel
const speed = diff * 0.35;
section.style.transform = "skewY(" + speed + "deg)"
currentPixel = newPixel;
requestAnimationFrame(looper)
}
looper();
Can anybody help me get this working? So far, the main issue seems to be that they're spans and not sections, but it could also just be my complete absence of understanding of javascript.
I'm hoping to control the transition speed, curve, and delay via css, but if it has to be controlled in JS, i'd also appreciate some advice on how to do this.
Thank you everyone in advance for trying to help.
Cheers,
Mark
NOTE: there is another script running (fullpage.js) which simulates a swiping experience during scroll. deactivate it temporarily to get a better view of what’s happening during scroll while you’re checking things out/setting things up. End-product, a letter animation that synchronously rotates each letter by 90 degrees (rendering the words invisible) for the duration of the swipe/scroll, and returning them to normal once the section snaps into place.
In case anybody is still interested in this, I have figured it out in the meantime.
const letter = document.getElementsByTagName("SPAN");
var timer = null;
window.addEventListener('scroll', function() {
if(timer !== null) {clearTimeout(timer)}
timer = setTimeout(function() {
var i;
for (i = 0; i < letter.length; i++) {
letter[i].style.transform = "rotateY(0deg)";
};
}, 150);
var i;
for (i = 0; i < letter.length; i++) {
letter[i].style.transform = "rotateY(90deg)";
};
}, false);
https://codepen.io/mhedinger/pen/yLJaLmp
EDIT:
I have improved this script for best-practice purposes. This makes it more stable and versatile because it can now be used together with plugins like fullpage.js. Additionally, if desired, the transforms can now also be called manually by referencing the appropriate function.
let letter = document.getElementsByTagName("SPAN");
var timer = null;
var rotateLetter = function() {
Array.from(letter).forEach(function(letter) {
letter.style.transform = "rotateY(90deg)";
});
};
var resetLetter = function() {
Array.from(letter).forEach(function(letter) {
letter.style.transform = "rotateY(0deg)";
});
};
window.addEventListener('scroll', function() {
if(timer !== null) {clearTimeout(timer)}
timer = setTimeout(function() {resetLetter()}, 125);
rotateLetter()
}, false);
https://codepen.io/mhedinger/pen/dypmKZd
StackOverflow is loaded with questions about how to check if an element is really visible in the viewport, but they all seek for a boolean answer. I'm interested in getting the element's actual areas that are visible.
function getVisibleAreas(e) {
...
return rectangleSet;
}
Putting it more formally - the visible areas of elements is the set of (preferably non-overlapping) rectangles in CSS coordinates for which elementFromPoint(x, y) will return the element if the point (x, y) is contained in (at least) one of the rectangles in the set.
The outcome of calling this function on all DOM elements (including iframes) should be a set of non-overlapping area sets which union is the entire viewport area.
My goal is to create some kind of a viewport "dump" data structure, which can efficiently return a single element for a given point in the viewport, and vice versa - for a given element in the dump, it will return the set of visible areas.
(The data structure will be passed to a remote client application, so I will not necessarily have access to the actual document when I need to query the viewport structure).
Implementation requirements:
Obviously, the implementation should consider element's hidden state, z-index, header & footer etc.
I am looking for an implementation that works in all common used browsers, especially mobile - Android's Chrome and iOS's Safari.
Preferably doesn't use external libraries.
Of course, I could be naïve and call elementFromPoint for every discrete point in the viewport, But performance is crucial since I iterate over all of the elements, and will do it quite often.
Please direct me as to how I can achieve this goal.
Disclaimer: I'm pretty noob to web programming concepts, so I might have used wrong technical terms.
Progress:
I came up with an implementation. The algorithm is pretty simple:
Iterate over all elements, and add their vertical / horizontal lines to a coordinates map (if the coordinate is within the viewport).
Call `document.elementFromPoint` for each "rectangle" center position. A rectangle is an area between two consecutive vertical and two consecutive horizontal coordinates in the map from step 1.
This produces a set of areas / rectangles, each pointing to a single element.
The problems with my implementation are:
It is inefficient for complicated pages (can take up to 2-4 minutes for a really big screen and gmail inbox).
It produces a large amount of rectangles per a single element, which makes it inefficient to stringify and send over a network, and also inconvenient to work with (I would want to end up with a set with as few rectangles as possible per element).
As much as I can tell, the elementFromPoint call is the one that takes a lot of time and causes my algorithm to be relatively useless...
Can anyone suggest a better approach?
Here is my implementation:
function AreaPortion(l, t, r, b, currentDoc) {
if (!currentDoc) currentDoc = document;
this._x = l;
this._y = t;
this._r = r;
this._b = b;
this._w = r - l;
this._h = b - t;
center = this.getCenter();
this._elem = currentDoc.elementFromPoint(center[0], center[1]);
}
AreaPortion.prototype = {
getName: function() {
return "[x:" + this._x + ",y:" + this._y + ",w:" + this._w + ",h:" + this._h + "]";
},
getCenter: function() {
return [this._x + (this._w / 2), this._y + (this._h / 2)];
}
}
function getViewport() {
var viewPortWidth;
var viewPortHeight;
// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
if (
typeof document.documentElement != 'undefined' &&
typeof document.documentElement.clientWidth != 'undefined' &&
document.documentElement.clientWidth != 0) {
viewPortWidth = document.documentElement.clientWidth,
viewPortHeight = document.documentElement.clientHeight
}
// the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
else if (typeof window.innerWidth != 'undefined') {
viewPortWidth = window.innerWidth,
viewPortHeight = window.innerHeight
}
// older versions of IE
else {
viewPortWidth = document.getElementsByTagName('body')[0].clientWidth,
viewPortHeight = document.getElementsByTagName('body')[0].clientHeight
}
return [viewPortWidth, viewPortHeight];
}
function getLines() {
var onScreen = [];
var viewPort = getViewport();
// TODO: header & footer
var all = document.getElementsByTagName("*");
var vert = {};
var horz = {};
vert["0"] = 0;
vert["" + viewPort[1]] = viewPort[1];
horz["0"] = 0;
horz["" + viewPort[0]] = viewPort[0];
for (i = 0 ; i < all.length ; i++) {
var e = all[i];
// TODO: Get all client rectangles
var rect = e.getBoundingClientRect();
if (rect.width < 1 && rect.height < 1) continue;
var left = Math.floor(rect.left);
var top = Math.floor(rect.top);
var right = Math.floor(rect.right);
var bottom = Math.floor(rect.bottom);
if (top > 0 && top < viewPort[1]) {
vert["" + top] = top;
}
if (bottom > 0 && bottom < viewPort[1]) {
vert["" + bottom] = bottom;
}
if (right > 0 && right < viewPort[0]) {
horz["" + right] = right;
}
if (left > 0 && left < viewPort[0]) {
horz["" + left] = left;
}
}
hCoords = [];
vCoords = [];
//TODO:
for (var v in vert) {
vCoords.push(vert[v]);
}
for (var h in horz) {
hCoords.push(horz[h]);
}
return [hCoords, vCoords];
}
function getAreaPortions() {
var portions = {}
var lines = getLines();
var hCoords = lines[0];
var vCoords = lines[1];
for (i = 1 ; i < hCoords.length ; i++) {
for (j = 1 ; j < vCoords.length ; j++) {
var portion = new AreaPortion(hCoords[i - 1], vCoords[j - 1], hCoords[i], vCoords[j]);
portions[portion.getName()] = portion;
}
}
return portions;
}
Try
var res = [];
$("body *").each(function (i, el) {
if ((el.getBoundingClientRect().bottom <= window.innerHeight
|| el.getBoundingClientRect().top <= window.innerHeight)
&& el.getBoundingClientRect().right <= window.innerWidth) {
res.push([el.tagName.toLowerCase(), el.getBoundingClientRect()]);
};
});
jsfiddle http://jsfiddle.net/guest271314/ueum30g5/
See Element.getBoundingClientRect()
$.each(new Array(180), function () {
$("body").append(
$("<img>"))
});
$.each(new Array(180), function () {
$("body").append(
$("<img>"))
});
var res = [];
$("body *").each(function (i, el) {
if ((el.getBoundingClientRect().bottom <= window.innerHeight || el.getBoundingClientRect().top <= window.innerHeight)
&& el.getBoundingClientRect().right <= window.innerWidth) {
res.push(
[el.tagName.toLowerCase(),
el.getBoundingClientRect()]);
$(el).css(
"outline", "0.15em solid red");
$("body").append(JSON.stringify(res, null, 4));
console.log(res)
};
});
body {
width : 1000px;
height : 1000px;
}
img {
width : 50px;
height : 50px;
background : navy;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I don't know if the performance will be sufficient (especially on a mobile device), and the result is not quite a rectangle-set as you requested, but did you consider using a bitmap to store the result?
Note some elements may have 3d css transform (eg. skew, rotate), some elements may have border radius, and some elements may have invisible background - if you want to include these features as well for your "element from pixel" function then a rectangle set can't help you - but the bitmap can accommodate all of the visual features.
The solution to generate the bitmap is rather simple (I imagine... not tested):
Create a Canvas the size of the visible screen.
iterate over all the elements recursively, sorted by z-order, ignore hidden
for each element draw a rectangle in the canvas, the color of the of the rectangle is an identifier of the element (eg. could be incremental counter). If you want you can modify the rectangle based on the visual features of the element (skew, rotate, border radius, etc...)
save the canvas as lossless format, eg png not jpg
send the bitmap as the meta data of elements on screen
To query which element is at point (x,y) you could check the color of the bitmap at pixel (x,y) and the color will tell you what is the element.
If you can jettison IE, here's a simple one:
function getElementVisibleRect(el) {
return new Promise((resolve, reject) => {
el.style.overflow = "hidden";
requestAnimationFrame((timeStamp) => {
var br = el.getBoundingClientRect();
el.style.overflow = "";
resolve(br);
});
});
}
Even then, Promises are easily polyfillable and requestAnimationFrame() works as far back as IE 8. And by 2016, the only thing you should bother to give any poor souls on older IE is a legible experience.
I’m fairly new to web development and I’ve only ever used jQuery to write my scripts. Today however, I’d like to improve my skills and build a little game that could be used on a smartphone as a web app in vanilla JS.
The game’s pretty straightforward:
You hold your phone in portrait mode and control a character that stays at the bottom of the screen and has to dodge objects that are falling on him. The character can only move left or right and thus always stays on the same x-axis. In order to control him, your finger has to stay on the screen. Once you take it off, you lose. Also, the move isn’t triggered by tapping the screen, but by moving your finger left or right.
For now, I’ve only been experimenting to get the hang of touchevents and was able to make the character move when swiping:
document.addEventListener('touchmove',function(e){
e.preventDefault(); //disable scroll
var board = document.getElementById(‘board);
var character = document.getElementById(‘character’);
if (e.targetTouches.length === 1) {
var touch = e.targetTouches[0];
board.classList.add(‘moving’);
character.style.left = touch.pageX + 'px';
}
}, false);
(The ‘moving’ class is used to move the background-position of the board and animate the character’s sprite in plain CSS.)
Separately, I made a little script that puts objects with random classes in a container with a set interval. These objects are then animated in css and fall from the top to the bottom of the screen.
Now, here comes the tricky part: the collision detection.
As I said, I’m new to development and vanilla JS, so I searched a bit to figure out how to detect when two objects collide, and it seems that most tutorials do this using canvases. The thing is, I’ve never used them and they scare me quite a bit. What’s more, I think it would render what I’ve done so far useless.
I’m okay with trying the canvas way, but before I do, I’d like to know if there’s any other way to detect if two moving objects collide?
Also, if there turns out to be no real way to do this without canvas, I plan on using this tutorial to learn how to build the app. However, this game wasn’t built for touchscreen devices, and the spaceship’s position changes on certain keystrokes (left & right) :
function update() {
if (keydown.left) {
player.x -= 5;
}
if (keydown.right) {
player.x += 5;
}
player.x = player.x.clamp(0, CANVAS_WIDTH - player.width);
}
My question is: how should I do to update the position using touchmove instead of keystrokes?
Thank you all in advance.
1) the idea : 'if you stop touching, you loose', is just a bad idea, drop it.
2) most convenient way to control is to handle any touch event (touch start/move/end/cancel), and to have the character align on the x coordinate of this event.
3) the intersection test is just a basic boundig box intersection check.
I made a very basic demo here, that uses touch, but also mouse to ease testing :
http://jsbin.com/depo/1/edit?js,output
a lot of optimisations are possible here, but you will see that touches adjust the ship's position, and that collisions are detected, so it will hopefully lead you to your own solution
Edit : i added default to 0 for left, top, in case they were not set.
boilerplate code :
var collisionDisplay = document.getElementById('collisionDisplay');
// hero ship
var ship = document.getElementById('ship');
ship.onload = launchWhenReady ;
// bad ship
var shipBad = document.getElementById('shipBad');
shipBad.onload = launchWhenReady ;
// image loader
imagesCount = 2 ;
function launchWhenReady() {
imagesCount --;
if (imagesCount) return;
setInterval(animate, 20);
}
var shipBadY = 0;
touch events :
// listen any touch event
document.addEventListener('touchstart', handleTouchEvent, true);
document.addEventListener('touchmove', handleTouchEvent, true);
document.addEventListener('touchend', handleTouchEvent, true);
document.addEventListener('touchcancel', handleTouchEvent, true);
// will adjust ship's x to latest touch
function handleTouchEvent(e) {
if (e.touches.length === 0 ) return;
e.preventDefault();
e.stopPropagation();
var touch = e.touches[0];
ship.style.left = (touch.pageX - ship.width / 2) + 'px';
}
animation :
// animation loop
function animate() {
// move ship
shipBadY += 1;
shipBad.style.top = Math.ceil(shipBadY) + 'px';
// test collision
var isColliding = testCollide(shipBad);
collisionDisplay.style.display = isColliding ? 'block' : 'none';
}
collision :
// collision test when the enemy and the ship are images
function testCollide(enemi) {
var shipPosX = parseInt(ship.style.left) || 0 ;
var shipPosY = parseInt(ship.style.top) || 0 ;
var shipWidth = ship.width ;
var shipHeight = ship.height;
var badX = parseInt(enemi.style.left) || 0 ;
var badY = parseInt(enemi.style.top) || 0 ;
var badWidth = enemi.width;
var badHeight = enemi.height;
return bBoxIntersect(shipPosX, shipPosY, shipWidth, shipHeight,
badX, badY, badWidth, badHeight);
}
EDIT : in case you're not using images :
// collision test when the enemy and the ship are ** NOT ** images
function testCollide(o) {
var characterPosX = parseInt(character.style.left);
var characterPosY = parseInt(character.style.top);
var characterWidth = parseInt(character.style.width);
var characterHeight = parseInt(character.style.height);
var obstacleX = parseInt(o.style.left) || 0 ;
var obstacleY = parseInt(o.style.top) || 0 ;
var obstacleWidth = parseInt(o.style.width);
var obstacleHeight = parseInt(o.style.height);
return boundingBoxIntersect(characterPosX, characterPosY, characterWidth, characterHeight, obstacleX, obstacleY, obstacleWidth, obstacleHeight);
}
function bBoxIntersect(x1, y1, w1, h1, x2, y2, w2, h2) {
return !(x1 + w1 < x2 || x1 > x2 + w2 || y1 + h1 < y2 || y1 > y2 + w2);
}
mouse events :
// -----------------------------------------------------
// Handle mouse event for easy testing on Browser
document.addEventListener('mousemove', handleMouseEvent);
function handleMouseEvent(e) {
ship.style.left = (e.pageX - ship.width / 2) + 'px';
}
I am trying to animate a square fading into a canvas element. When I use setInterval for my animation, everything works fine, but if I try to use setTimeout, everything falls apart. Here is my code:
http://jsbin.com/OyiRIVa/1/edit
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
/*class canvasUiElement*/
function canvasUiElement() {}
canvasUiElement.prototype = {
canvas: document.getElementById("canvas"),
context: canvas.getContext("2d")
}
/* ---------------------*/
function rectangle(x,y,length,width){
this.x = x;
this.y = y;
this.opacity = 0 ;
this.length = length;
this.width = width;
}
rectangle.prototype = new canvasUiElement();
rectangle.prototype.renderSelf = function(){
this.context.clearRect(this.x,this.y,this.length,this.width);
this.context.fillStyle = "rgba(0,0,255,".concat(this.opacity.toString().concat(")"));
this.context.fillRect(this.x,this.y,this.length,this.width);
}
rectangle.prototype.drawFrame = function(){
this.opacity += .01;
this.renderSelf();
x = this.drawFrame;
setTimeout(function(){x()}, 5);
}
rect = new rectangle(20,10,50,50);
rect.drawFrame();
/*window.setInterval(function() {
rect.drawFrame();
}, 1); */
The problem probably lies in the this keyword in drawFrame. When the setTimeout fires, this in side is no longer rect.
The solution is using apply or call.
f.apply(self) bind the this keyword in function f to the first argument f.
So change this way:
rectangle.prototype.drawFrame = function draw(){
var self = this;
this.opacity += 0.005;
this.renderSelf();
if (this.opacity < 1) {
requestAnimationFrame(function(){
draw.call(self)
});
}
};
check out this JSBin. http://jsbin.com/OwaHALUF/4/edit
========================
edited upon a valid comment:
x in the original code is not semantic and misses var declaration. Fixed.
prefer requestAnimationFrame to setTimeout
stop call drawFrame if opacity >= 1 (useful if requestAnimationFrame is not availlable)
prefer named function expression over re-assignment. It reduces closure overhead.(This overhead may be not neglected if the animation lasts long enough). And more concise code is bonus.
I wrote a quick program to bounce a ball on the screen. Everything works, but the image is prone to flickering and is not smooth.
I suspect that the image flickers because the velocity is significant at the bottom of the screen.
I was wondering if anybody had any ideas on how to interpolate the motion of the ball to reduce the flicker.
Called to update the position
this.step = function()
{
thegame.myface.y = thegame.myface.y + thegame.myface.vSpeed;
if (thegame.myface.y > thegame.height)
{
thegame.myface.vSpeed = -thegame.myface.vSpeed;
}
else
{
thegame.myface.vSpeed = thegame.myface.vSpeed + 1;
}
}
},
Called to redraw
draw: function()
{
//clears the canvas
thegame.ctx.clearRect(0,0,thegame.width,thegame.height);
//draw the objects
thegame.ctx.drawImage(thegame.imgFace,this.x-this.width/2,this.y-this.height/2);
return;
},
Call framework in index.html
<script type="text/javascript">
thegame.init(450,450);
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
(function()
{
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x)
{
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelRequestAnimationFrame = window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
{
var f = function(callback, element)
{
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16-(currTime-lastTime));
var id = window.setTimeout(function()
{
callback(currTime+timeToCall);
}, timeToCall);
lastTime = currTime+timeToCall;
return id;
};
window.requestAnimationFrame = f;
}
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id)
{
clearTimeout(id);
};
}());
(function gameloop()
{
thegame.update();
requestAnimationFrame(gameloop);
thegame.draw();
})();
</script>
edit definition for thegame
init: function(width, height)
{
var canvas = $("<canvas width='"+width+"' height='"+height+"'></canvas>");
canvas.appendTo("body");
thegame.ctx = canvas.get(0).getContext("2d");
thegame.width = width;
thegame.height = height;
thegame.imgFace = new Image();
thegame.imgFace.src = "face.png";
thegame.myface = new thegame.makeFace(width/2,height/2);
},
It's about visual perception. First find out at what rate the game loop is called by the browser via requestanimationframe. If it's Chrome its task manager will help. If not, calc the rate by yourself with timestamps. It should be at least 60 times per second. If the browser is running at this rate and the movement is still not smooth, the speed is simply too high for that rate.
However, you have options to trick the perception of motion. One is to make the image smaller (simple), another is motion blur (complicated). To do the latter, you basically run the game hidden at double speed and draw two blended frames onto the visible canvas. Or at same speed and a bit simpler, keep track of the last two images and draw both with 50% alpha at the canvas. If you want more background info follow the discussion why latest hobbit movie was filmed at 48 instead of the usual 24 frames per second.
If it appears the image is horizontally chopped/cut in half then the browser is not properly synchronized to the monitor. In this case make sure the vertical sync (vsync) isn't overridden somewhere by the system or display options.
How large is your canvas? Not sure if it will solve your flicker issue, but an additional optimization you can try is to modify your clearRect() call to only clear the region which is dirty, before each update.
Ex: thegame.ctx.clearRect(this.x-this.width/2, this.y-this.height/2, thegame.imgFace.width, thegame.imgFace.height);