I'm trying to create a 2d canvas with the accelerometer API.
The API full example works when I tilt the phone the acceleration.x and acceleration.y changes.
So I made a canvas 2d circle and implemented the acceleration.x and acceleration.y but when I did that, the circle is gone.
This is my html
<canvas id="myCanvas" width="200" height="200" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
This is my partial script
function movingCircle (acceleration) {
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var x = acceleration.x;
var y = acceleration.y;
ctx.fillStyle = "rgba(255, 255, 0, .5)";
ctx.beginPath();
ctx.arc(x,y,20,0,2*Math.PI, true);
ctx.stroke();
ctx.closePath();
ctx.fill();
c.innerHTML = 'testing';
}
ctx.arc(x,y,20,0,2*Math.PI, true); if I change the x and y into 47.5, 25 then I can see my circle clearly positioned near the top left corner.
Anyone can give me a hand what I did wrong here?
Acceleration's x & y keys are not absolute cordinates on which you can plot your circle. Acceleration is difference in velocity over time. So rather you them as quantities to add to your current circle position.
Something like: x = x + acceleration.x;
Related
I have this code to draw a Bezier curve:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.bezierCurveTo(30, 100, 200, 100, 200, 200);
ctx.stroke();
<canvas id="myCanvas" width="300" height="400" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
This code results in a S shaped Beizer curve:
My problem is that I want to change the start and end control points as per my wish but at the same time I want that S shape to be there.
I have observed whenever I change the control points, the overall shape of the curve becomes strange.
What is the way out?
If the S shape is currently displayed as you wish, then the middle control points are such that their X-coordinate roughly matches the X-coordinate of the end point they are closest to, and the Y-coordinate is the same for both middle control points: it is about half-way the Y range of the end points.
So you can calculate the control points dynamically if you only have the two end points:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
function drawS(start, end) {
ctx.beginPath();
ctx.moveTo(...start);
let midY = (start[1] + end[1]) / 2;
ctx.bezierCurveTo(start[0], midY, end[0], midY, ...end);
ctx.stroke();
}
drawS([20, 20], [200, 180]);
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>
I write code but it's not run.
I have 2 tag canvas. When i change properties height of canvas < 100 then arrow hidden. And if i didn't write tag div before tag canvas its run normal. Thank you for support!!!!
Source code:
<body>
<div id="yendau">LOL</div>
<canvas id="c" width="500" height="100">Brower of you doesn't not support Canvas</canvas>
<div>Yolooooooooooo</div>
<canvas id="d" width="500" height="300">Brower of you doesn't not support Canvas</canvas>
<script src="jquery-1.9.1.js"></script>
<script langauage="javascript">
function canvas_arrow(context, fromx, fromy, tox, toy){
var headlen = 20; // length of head in pixels
var dx = tox-fromx;
var dy = toy-fromy;
var angle = Math.atan2(dy,dx);
context.moveTo(fromx, fromy);
context.lineTo(tox, toy);
context.lineWidth=2;
context.moveTo(tox, toy);
context.lineTo(tox-headlen*Math.cos(angle+Math.PI/6),toy-headlen*Math.sin(angle+Math.PI/6));
context.moveTo(tox, toy);
context.lineTo(tox-headlen*Math.cos(angle-Math.PI/6),toy-headlen*Math.sin(angle-Math.PI/6));
}
$('document').ready(function(){
var count= parseInt($("canvas").length);
for(var i=0; i< count; i++){
var ctx= $("canvas")[i].getContext('2d');
ctx.beginPath();
//var x= $('#c').offset().left-15;
//var y= $('#c').offset().top-15;
var x= $('#'+$("canvas")[i].id).offset().left;
var y= $('#'+$("canvas")[i].id).offset().top+15;
var x1= x+100;
canvas_arrow(ctx,x,y,x1,y);
ctx.stroke();
}
});
You don't need to add the offset of the canvas when calculating x,y. In your case, doing that will quickly push your arrow off the canvas.
The canvas offset is useful when calculating the mouse position, but not useful when drawing on the canvas itself. That's because the mouse coordinates are always relative to the top-left of the page--not the top left of the canvas.
The top-left corner of the canvas is x=0, y=0. So just set x,y to your desired coordinates bases on:
x increases from zero as you move rightward across the canvas.
y increased from zero as you move downward across the canvas.
I can draw a line as per direction but I am not being able to draw a text as per line direction. My paint will be like this...
You need to figure out how wide the text will be and that can be solved with:
ctx.measureText(text).width;
Then just create a funtion that draws lines on either side of it (and a arrow head). Finish everything off with rotating the whole canvas before drawing it, like so:
Original answer: http://jsfiddle.net/txrvLLjp
EDIT
New code allows for adding starting and stopping points instead.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var text = "Knows";
var TO_RADIANS = Math.PI / 180;
ctx.font = "12px Arial";
drawArrow(text,40,40,200,200);
function drawArrow(text,startX,startY,stopX,stopY) {
var deltaX = (stopX-startX);
var deltaY = (stopY-startY)
//calculating the total length of the line
var arrowLength=Math.sqrt(deltaX*deltaX+deltaY*deltaY);
//calculating the angle
var angle=Math.atan2(deltaY,deltaX) * 180 / Math.PI;
ctx.save();
ctx.translate(startX,startY);
ctx.rotate(angle*TO_RADIANS);
var textLength = ctx.measureText(text).width;
var padding=(arrowLength-textLength)/2;
ctx.moveTo(0,0);
ctx.lineTo(padding,0);
ctx.stroke();
ctx.fillText(text,padding,4);
ctx.moveTo(padding+textLength,0);
ctx.lineTo(padding+textLength+padding,0);
ctx.stroke();
//Arrow point below
ctx.moveTo(padding+textLength+padding,0);
ctx.lineTo(padding+textLength+padding-8,8);
ctx.stroke();
ctx.moveTo(padding+textLength+padding,0);
ctx.lineTo(padding+textLength+padding-8,-8);
ctx.stroke();
ctx.restore();
}
<canvas id="myCanvas" width="200" height="400"></canvas>
I am trying to figure out how one can detect if the user's mouse hits a line on an HTML 5 canvas with jQuery.
Here is the code that generates the canvas lines:
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
window.onload = function(){
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.moveTo(40,0);
ctx.lineTo(40,360);
ctx.stroke();
ctx.moveTo(80,400);
ctx.lineTo(80,40);
ctx.stroke();
ctx.moveTo(120,0);
ctx.lineTo(120,360);
ctx.stroke();
ctx.moveTo(160,400);
ctx.lineTo(160,40);
ctx.stroke();
};
</script>
I'm using a modified jQuery script that I actually found in another question on here, but now I can't figure out how to detect the line, mainly the difference in color from white to black, in the canvas. I know that this can be done with images, but I haven't seen anyone with something like this.
I guess my real question is, is there a way to detect color changes on a canvas element with jQuery?
Its possible to do with javascript. In fact you aren't using any jQuery in your example above. An easy way to do it is by grabbing the pixel data from the canvas, and checking the alpha at the specified x and y position. If the alpha isn't set to 0, then you have something drawn on the canvas. Below is a function I put together real quick that does that.
Live Demo
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 400;
height = 400;
canvas.width = canvas.height = 200;
// draw
ctx.moveTo(40, 0);
ctx.lineTo(40, 360);
ctx.stroke();
ctx.moveTo(80, 400);
ctx.lineTo(80, 40);
ctx.stroke();
ctx.moveTo(120, 0);
ctx.lineTo(120, 360);
ctx.stroke();
ctx.moveTo(160, 400);
ctx.lineTo(160, 40);
ctx.stroke();
function detectLine(x, y) {
var imageData = ctx.getImageData(0, 0, width, height),
inputData = imageData.data,
pData = (~~x + (~~y * width)) * 4;
if (inputData[pData + 3]) {
return true;
}
return false;
}
canvas.addEventListener("mousemove", function(e){
var x = e.pageX,
y = e.pageY;
console.log(detectLine(x, y));
});
console.log(detectLine(40, 100));
console.log(detectLine(200, 200));
I'm trying to figure out how to rotate a single object on an html 5 canvas.
For example: http://screencast.com/t/NTQ5M2E3Mzct - I want each one of those cards to be rotated at a different degree.
So far, all I've seen are articles and examples that demonstrate ways to rotate the entire canvas. Right now, I'm guessing I'll have to rotate the canvas, draw an image, and then rotate the canvas back to it's original position before drawing the second image. If that's the case, then just let me know! I just have a feeling that there's another way.
Anyone have any idea?
I ran into the same problem in a recent project (where I kicked rotating aliens all over the place). I just used this humble function that does the same thing and can be used the same way as ctx.rotate but can be passed an angle. Works fine for me.
function drawImageRot(img,x,y,width,height,deg){
// Store the current context state (i.e. rotation, translation etc..)
ctx.save()
//Convert degrees to radian
var rad = deg * Math.PI / 180;
//Set the origin to the center of the image
ctx.translate(x + width / 2, y + height / 2);
//Rotate the canvas around the origin
ctx.rotate(rad);
//draw the image
ctx.drawImage(img,width / 2 * (-1),height / 2 * (-1),width,height);
// Restore canvas state as saved from above
ctx.restore();
}
Yay, my first answer!
Unfortunately in the HTML5 canvas element you can't rotate individual elements.
Animation works like drawing in MS Paint: You draw something, make a screen.. use the eraser to remove some stuff, draw something differently, make a screen.. Draw something else on top, make a screen.. etc etc.
If you have an existing item on the canvas - you'll have to erase it ( use ctx.fillRect() or clearRect() for example ), and then draw the rotated object.
If you're not sure how to rotate it while drawing in the first place:
ctx.save();
ctx.rotate(0.17);
// draw your object
ctx.restore();
To rotate a individual object you have to set the transformation matrix. This is really simple:
var context = document.getElementById('pageCanvas').getContext('2d');
var angle = 0;
function convertToRadians(degree) {
return degree*(Math.PI/180);
}
function incrementAngle() {
angle++;
if(angle > 360) {
angle = 0;
}
}
function drawRandomlyColoredRectangle() {
// clear the drawing surface
context.clearRect(0,0,1280,720);
// you can also stroke a rect, the operations need to happen in order
incrementAngle();
context.save();
context.lineWidth = 10;
context.translate(200,200);
context.rotate(convertToRadians(angle));
// set the fill style
context.fillStyle = '#'+Math.floor(Math.random()*16777215).toString(16);
context.fillRect(-25,-25,50,50);
context.strokeRect(-25,-25,50,50);
context.restore();
}
// Ideally use getAnimationFrame but for simplicity:
setInterval(drawRandomlyColoredRectangle, 20);
<canvas width="1280" height="720" id="pageCanvas">
You do not have a canvas enabled browser
</canvas>
Basically, to make an object rotate properly without having other shape rotating around, you need to:
save the context: ctx.save()
move the pivot point to the desired location: ctx.translate(200, 200);
rotate: context.rotate(45 * Math.PI / 180);
draw the shape, sprite, whatever: ctx.draw...
reset the pivot: ctx.translate(-200, -200);
restore the context to its original state: ctx.restore();
function spinDrawing() {
ctx.save();
ctx.translate(200, 200);
context.rotate(45 * Math.PI / 180);
ctx.draw //your drawing function
ctx.translate(-200, -200);
ctx.restore();
}
Caveats: After you translating , the origin of the canvas changed, which means when you drawing the shape, the coordinate of the shape should be aligned accordingly.
Shapes drawn outside the list mentioned above won´t be affected. I hope it helps.
This html/javascript code might shed some light on the matter:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="233" height="233" style="border:1px solid #d3d3d3;">
your browser does not support the canvas tag </canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var canvasWidth=233;
var canvasHeight=233;
var rectWidth=100;
var rectHeight=150;
var x=30;
var y=30;
var translateX= x+(rectWidth/2);
var translateY= y+(rectHeight/2);
ctx.fillRect(x,y,rectWidth,rectHeight);
ctx.translate(translateX,translateY);
ctx.rotate(5*Math.PI/64); /* just a random rotate number */
ctx.translate(-translateX,-translateY);
ctx.fillRect(x,y,rectWidth,rectHeight);
</script>
</body>
</html>
I find it helpful to see the math related to rotating, I hope this was helpful to you too.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="500" height="450" style="border:1px solid #d3d3d3;">
</canvas>
<Button id = "right" onclick = "rotateRight()">Right</option>
<Button id = "left" onclick = "rotateLeft()">Left</option>
<script src = "zoom.js">
</script>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
createRect();
function rotateRight()
{
ctx.save();
ctx.clearRect(0,0,500,450);
ctx.translate(c.width/2,c.height/2);
ctx.rotate(10*Math.PI/180 );
ctx.translate(-c.width/2,-c.height/2);
createRect();
}
function rotateLeft()
{
ctx.save();
ctx.clearRect(0,0,500,450);
ctx.translate(c.width/2,c.height/2);
ctx.rotate(-10*Math.PI/180 );
ctx.translate(-c.width/2,-c.height/2);
createRect();
}
function createRect()
{
ctx.beginPath();
ctx.fillStyle = "#AAAA00";
ctx.fillRect(250,250,90,50);
}
</script>
</body>
</html>
To rotate an object you can use rotate() method. Here the example how to rotate a rectangular object to 135 degrees of clockwise.
<script>
var canvas = document.getElementById('Canvas01');
var ctx = canvas.getContext('2d');
var rectWidth = 100;
var rectHeight = 50;
//create line
ctx.strokeStyle= '#ccc';
ctx.beginPath();
ctx.moveTo(canvas.width / 2, 0);
ctx.lineTo(canvas.width / 2, canvas.height);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(0, canvas.height/2);
ctx.lineTo(canvas.width, canvas.height/2);
ctx.stroke();
ctx.closePath();
// translate ctx to center of canvas
ctx.translate(canvas.width / 2, canvas.height / 2);
// rotate the rect to 135 degrees of clockwise
ctx.rotate((Math.PI / 180)*135);
ctx.fillStyle = 'blue';
ctx.fillRect(0, 0, rectWidth, rectHeight);
</script>
</body>
Here the demo and you can try yourself: http://okeschool.com/examples/canvas/html5-canvas-rotate
I found this question because I had a bunch of stuff on a canvas, drawn with canvas lines, painstakingly, and then decided some of them should be rotated. Not wanting to do a whole bunch of complex stuff again I wanted to rotate what I had. A simple solution I found was this:
ctx.save();
ctx.translate(x+width_of_item/2,y+height_of_item/2);
ctx.rotate(degrees*(Math.PI/180));
ctx.translate(-(x+width_of_item/2),-(y+height_of_item/2));
// THIS IS THE STUFF YOU WANT ROTATED
// do whatever it is you need to do here, moveto and lineto is all i used
// I would expect anything to work. use normal grid coordinates as if its a
// normal 0,0 in the top left kind of grid
ctx.stroke();
ctx.restore();
Anyway - it might not be particularly elegant but its a dead easy way to rotate one particular element onto your canvas.
Look at all those rotated elements!