This is my pseudocode:
when move button is pressed:
currentCirclePos = circleX;
moveTimer = setInterval(move, 10);
My move function looks like this:
var move = function() {
circleX += move a bit;
};
In some cases, the element does not move at all. For those situations, I have the following code :
while(Math.abs(circleX - currentCirclePos) < some distance away){
drawCircle(circleX, circleY);
circleX += gradual shift;
}
This does not change the position of my circle gradually but draws it abruptly some distance away. I don't understand why is that happening. Could anyone help me debug the issue? Let me know if I need to post more code.
This is my requestAnimationFrame code:
requestAnimationFrame(animate);
function animate(){
ctx.clearRect(0,0,cw,ch);
ctx.rect(0, 0, cw, ch);
ctx.fillStyle = 'white';
ctx.fill();
drawCircle(circleX, circleY);
requestAnimationFrame(animate);
}
UPDATE : The while loop was not inside the animation function but now it is. However, it did not make any difference at all.
The problem is that You're using setInterval instead of requestAnimationFrame - it's more reliable way to do this kind of operations on canvas.
Please check this tutorial - author solves this problem pretty straightforward on example.
Related
I'm coding a game in the style of agar.io where I want to move the player to the direction relative to the mouse position.
This is how I check the mouse position, returning a Vector object;
let mouse_vector = new Vector();
canvas.onmousemove = function() {
mouse_vector = mouse(event);
}
function mouse(evt) {
mouse_vector = new Vector(evt.clientX - canvas.width/2, evt.clientY - canvas.height/2);
return mouse_vector;
}
The player is an object with an x and y coordinate to which I add the vector pointing towards the mouse. I have 1 canvas that represents the world and is hidden. The other canvas is my viewport, on which I draw the cropped world relative to the player position.
I'm using requestAnimationFrame here, but I tried using Interval as well.
function draw() {
player.x += mouse_vector.x * 0.005;
player.y += mouse_vector.y * 0.005;
canvasCtx.clearRect(0, 0, canvas.width, canvas.height);
canvasCtx.drawImage(game, player.x-canvas.width/2, player.y-canvas.height/2, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
canvasCtx.arc(canvas.width/2, canvas.height/2, player.r, 0, 2*Math.PI);
canvasCtx.fill();
requestAnimationFrame(draw);
}
My issue is that the game starts stuttering over time. I would like it to be as smooth as at the start. I'm suspecting the issue is related to some kind of caching. I've noticed the game uses a lot of CPU power. Any ideas?
The issue I was having was that I was not using the beginPath() method when filling arcs. Seems that not reseting the previous draw builds up and causes performance loss over time.
canvasCtx.beginPath(); // addition
canvasCtx.arc(canvas.width/2, canvas.height/2, player.r, 0, 2*Math.PI);
canvasCtx.fill();
So at the end of the day, you'll be re-drawing the whole map every 16ms to get 60fps which is the target of requestAnimationFrame - so you'll not be escaping the CPU hogging problem, unless you do some optimisation about the drawing.
About the logic you are doing: it doesn't seem from this piece of code that there can be anything that could be building up or leaking memory, so I suggest pasting your code to a code-sharing site like codepen.io and sharing it with the community, we'd have more chance of debugging it.
Good evening, first i'm not sure i should post this here, since i have litteraly no idea what's wrong here (only clue is it happened after i moved all my variables at the top of my code while trying to "clean up" a little).
but here is the problem: i've created a canvas game and after moving my variables (i think) i started getting major framedrops. Game weighs less than 20Ko, images are super tiny and simple, i have a for loop in the update loop but it never seemed to be a problem (it's not infinite) so in short i do not know what's wrong here
here is a bit of code since links to code "must be accompanied by code" (dont know what's up with that)
for (var i = 0; i<boxes.length; i++){
ctx.rect(boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);
var col = coli(player,boxes[i])
};
i've tried different things, like disabling functions (anim and colision), friction and gravity but nothing seems to have any effect, and i dont know that much about the dom except how to look at my own variables so i havent found anything with firebug.
Really hope someone has an idea
You need to add ctx.beginPath() before using ctx.rect, moveTo, lineTo, arc, and any function you need to use ctx.stroke() or ctx.fill() to see.
beginPath tell the canvas 2D context that you wish to start a new shape. If you do not do this you end up adding more and more shapes each update.
From your fiddle
function update() {
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = pat;
//===============================================================
ctx.beginPath() // <=== this will fix your problem. It removes all the
// previous rects
//===============================================================
for (var i = 0; i < boxes.length; i++) {
ctx.rect(boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);
// or use ctx.fillRect(...
var col = coli(player, boxes[i])
};
ctx.fill();
Edit: Ran the code on a more powerful computer and the grid rendered correctly. Possible hardware limitation? Computer where the problem occurred was a Samsung series 3 Chromebook. I'm thinking it has to do with trying to draw too many lines at the same time. Will test later.
I'm trying to draw a grid onto a canvas using the lineTo() method. The lines draw properly in the beginning, but any line that is drawn completely past 2048 pixels either down or to the right doesn't show up. Line going from inside this point to past it still show up on the other side, just lines that only are only drawn past the point don't show up.
Here's my JavaScript:
function drawGrid() {
//data.tiles is the map stored as an array of arrays
//tilesize = 60
var bw = data.tiles[0].length * tilesize;
var bh = data.tiles.length * tilesize;
ctx.beginPath();
for (i = bw; i >= 0; i -= tilesize) {
ctx.moveTo(i, 0);
ctx.lineTo(i, bh);
}
for (i = bh; i >= 0; i -= tilesize) {
ctx.moveTo(0, i);
ctx.lineTo(bw,i);
}
ctx.strokeStyle = "black";
ctx.stroke();
}
I've checked the data.tiles variable, and it's reading the right number. Really have no idea what I messed up here.
HTML Canvas has a maximum render area depending on your browser & hardware.
once you exceed these limits well your done pretty much.
try pre-rendering or use multiple canvas' positioned with CSS.
If you can see images drawn beyond 2048 then there's no reason a lineTo wouldn't be drawn also.
In the code you calculate bw and bh in different ways. You might check if this is a problem. If not, we'll need to see more code.
// bw uses data.tiles[0]
var bw = data.tiles[0].length * tilesize;
// bh uses data.tiles with no subscript
var bh = data.tiles.length * tilesize;
See here - http://schnell.dreamhosters.com/nysbc/test6.php
JSFiddle - http://jsfiddle.net/VauFH/
The piece that draws text...
function draw_arc_text(ctx, str, radius){
ctx.save();
str = str.toUpperCase();
var radians_per_letter = 8 * Math.PI/180;
ctx.rotate((105 - (radius/60)) * Math.PI/180);
for (var n = 0; n < str.length; n++) {
ctx.save();
ctx.rotate(n * radians_per_letter);
ctx.fillText(str[n], 0, -radius);
ctx.restore();
}
ctx.restore();
}
As you can probably tell the spacing between the text on top of the colored discs is a little off. I've tried having a set amount of radians/degrees per letter, but the further out in radius you go the more that spacing becomes, so outermost text starts separating at a rapid pace. I've also tried working out some kind of formula that will incorporate radius into how much spacing each letter gets, but I can't seem to get that quite right either. Anyone have any ideas?
Also any tweaks in efficiency would be appreciated as well. I like to be as optimized as I can whenever possible.
Live Demo
probably a mathematicians worst nightmare :P. The following works though. Basically I just divide the result by the radius / 100. It gives the impression of equal spacing.
Another change I made, was to use requestAnimationFrame instead of interval. Intervals aren't very performant when compared to setTimeout and especially when compare to requestAnimationFrame for canvas. You'll notice you don't get a nasty hangup anymore when you leave the tab and go back to it.
I also got rid of the jQuery dependency because all you were using was document.ready so it seemed unneeded.
function draw_arc_text(ctx, str, radius){
ctx.save();
str = str.toUpperCase();
var textWidth = Math.round(ctx.measureText(str).width);
var radians_per_letter = (((textWidth/str.length)) * Math.PI/180)/(radius*.01);
ctx.rotate(95 * Math.PI/180);
for (var n = 0; n < str.length; n++) {
ctx.save();
ctx.rotate(n * radians_per_letter);
ctx.fillText(str[n], 0, -radius);
ctx.restore();
}
ctx.restore();
}
I don't have much experience with the canvas element, but is there any way you could use CSS' letter-spacing property on the text?
For a personal project, I'm tyring to make a timer application (for controlling Poker blind schedules). I know there are several solutions already on the market, but for reasons which are too lengthy to go into here, we need a bespoke system. Although the output template of the system will ultimately be definable by the end user, we would like to include a widget which shows a circle that gets animated as the time counts down. Here's an illustration of a working example, showing the yellow circle and what we'd like to achieve (or something similar, anyway):
My question is, how would one code the animation as shown below using either jQuery or raw HTML5 / CSS3 animations? This is for a web application using jQuery, so there are no other library options I can use.
Advanced thanks!
If you can use HTML5, canvas is probably your best bet. Mozilla has some decent tutorials on drawing arcs. This should be enough to get you started.
var canvas = document.getElementById('canvasid'),
width = canvas.width,
height = canvas.height,
ctx = canvas.getContext('2d');
function drawTimer(deg) {
var x = width / 2, // center x
y = height / 2, // center y
radius = 100,
startAngle = 0,
endAngle = deg * (Math.PI/180),
counterClockwise = true;
ctx.clearRect(0, 0, height, width);
ctx.save();
ctx.fillStyle = '#fe6';
// Set circle orientation
ctx.translate(x, y);
ctx.rotate(-90 * Math.PI/180);
ctx.beginPath();
ctx.arc(0, 0, radius, startAngle, endAngle, counterClockwise);
ctx.lineTo(0, 0);
ctx.fill();
}
setInterval(function() {
// Determine the amount of time elapsed; converted to degrees
var deg = (elapsedTime / totalTime) * 360;
drawTimer(deg);
}, 1000);
You can achieve this with CSS3 and jQuery.
Check out my example here http://blakek.us/css3-pie-graph-timer-with-jquery/ which with slight modification you could make the timer look how you want it.
In HTML5 you can draw in a canvas.
For example:
// Create the yellow face
context.strokeStyle = "#000000";
context.fillStyle = "#FFFF00";
context.beginPath();
context.arc(100,100,50,0,Math.PI*2,true);
context.closePath();
context.stroke();
context.fill();
Link
You should really check out Processing!
Especially Processing.js. There have been some interesting things made with it for iPhone
First solution i can think of is html5 canvas implementation. From the example above it becomes clear we're talking mobile, so what support does canvas get around mobile browsers i can't tell. developer.mozilla.org provides sufficient documentation. Using canvas to achieve such count down should be pretty simple task. Good luck.
HTML5 Canvas arc command (MDN) is probably what you're looking for. Just decrease the end angle over time to have your timer decrease.