calling function twice in canvas - html

actually I'm new in html5 and tring to do something using canvas , the function that i create is drawing a short ray length start from point and end in point , the problem is when I duplicate the function to run twice in the same time it doesn't work correctly , where is the problem in my code ?
first I create the canvas
<canvas id="mycanvas" width="1120" height="700" style="margin:auto;border:1px solid #000000;position:relative;z-index: 10;">
</canvas>
Then i create call a function twice
var path1Number=0;
window.addEventListener('load', function () {
var x = 185, y = 185;
direction1(x,y , path1Number);
direction1(x+91,y+91 , path1Number);
}, false);
then i create a function that draw a path start from point to point
function direction1(x,y , path1Number){
//draw canvas line
var canvas1 = document.getElementById('mycanvas');
var context = canvas1.getContext('2d');
var x2 = x;
var y2 = y;
var ini_x = x;
var ini_y = y;
var done = false;
var interval = setInterval(function() {
context.clearRect(0, 0, canvas1.width, canvas1.height);
context.beginPath();
context.moveTo(x, y);
if(x2<x+20 && !done){
context.lineTo(x2, y2);
context.closePath();
context.strokeStyle = 'red';
context.stroke();
x2+=1;
y2+=1;
}else{
done = true;
x+=1;
y+=1;
if(x2 >= ini_x + 91){
if(x2 == x){
clearInterval(interval);
context.closePath();
context.clearRect(0, 0, canvas1.width, canvas1.height);
path1Number+=1;
path1(x,y,path1Number);
}
}else{
x2+=1;
y2+=1;
}
context.lineTo(x2, y2);
context.closePath();
context.strokeStyle = 'red';
context.stroke();
}
},10);
}
the problem happened when i call this function twice it doesn't work correctly so what is the reason ? Thanks .

Related

HTML Canvas to WPF XAML Canvas

I have an ASP.NET application that allows users to click or tap on a Canvas to indicate pain locations on a body image. A body image is displayed on the Canvas and is the same size as the Canvas.
function drawBodyMap() {
var c = document.getElementById('myCanvas');
var ctx = c.getContext('2d');
var imageObj = new Image();
imageObj.src = 'https://.../body.jpg';
imageObj.onload = function () {
ctx.drawImage(imageObj, 0, 0, 600, 367);
};
}
<canvas id="myCanvas" width="600" height="367"></canvas>
<script>
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
canvas.addEventListener('mouseup', function (evt) {
if (ixPos > 9)
return;
var mousePos = getMousePos(canvas, evt);
bodyX[ixPos] = mousePos.x;
bodyY[ixPos] = mousePos.y;
painType[ixPos] = pain_type;
ixPos++;
ctx.beginPath();
ctx.arc(mousePos.x, mousePos.y, 8, 0, 2 * Math.PI);
if (pain_type == 1)
ctx.fillStyle = "#DC143C";
else if (pain_type == 2)
ctx.fillStyle = "#EA728A";
else if (pain_type == 3)
ctx.fillStyle = "#DAA520";
else if (pain_type == 4)
ctx.fillStyle = "#008000";
else if (pain_type == 5)
ctx.fillStyle = "#4169E1";
ctx.fill();
}, false);
</script>
The X,Y points added to the Canvas on the body image are saved to a database. These points are then loaded into a WPF application that displays the same body image on an XAML Canvas. C# code then adds the points over the image.
WPF CODE:
private void DisplayBodyPain()
{
List<BodyPain> pain = gFunc.sws.GetBodyPain(MemberID);
foreach (BodyPain bp in pain)
{
Border b = new Border();
b.Tag = bp.PainType.ToString();
b.Cursor = Cursors.Hand;
b.Width = 16;
b.Height = 16;
b.CornerRadius = new CornerRadius(8);
b.Background = GetPainBrush((byte)bp.PainType);
cvsBody.Children.Add(b);
Canvas.SetTop(b, bp.YPos);
Canvas.SetLeft(b, bp.XPos);
}
}
The problem I have is that the points drawn on the XAML Canvas are all slightly different from the points that were drawn on the HTML Canvas. Each point is not in exactly the same location.
Is there a way I can fix this? Should I be doing it differently?
HTML Canvas
WPF Canvas
I think you need to subtract the size of the marker from the coordinate where you want to place it. For the last two lines, try this instead:
Canvas.SetTop(b, bp.YPos - (b.Height / 2));
Canvas.SetLeft(b, bp.XPos - (b.Width / 2));
By subtracting half the marker's height and width, the center of the marker is placed on the desired coordinates.

Canvas, animate line to move up and down

I have created a horizontal line in HTML5 Canvas. I want to animate the line to move infinity up and down. Is it possible?
function horizontal_line() {
context.beginPath();
context.moveTo(100, 100);
context.lineTo(5000, 100);
context.strokeStyle = "Green";
context.stroke();
}
For an animation you will need to have a way to draw different frames, and in each frame you have to delete the previous one, calculate the new position of the line, and then draw the line again:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.strokeStyle = "Green";
var posY = 0;
var lineLength = 10;
var speed = 2;
function drawLine() {
ctx.beginPath();
ctx.moveTo(10, posY);
ctx.lineTo(10, posY+lineLength);
ctx.stroke();
}
function moveLine () {
posY += speed;
if (posY < 0 || posY > canvas.height) {
speed = speed * -1;
}
}
function loop() {
// clear old frame;
ctx.clearRect(0,0,canvas.width, canvas.height);
moveLine();
drawLine();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
<canvas id="canvas"></canvas>
In this example requestAnimationFrame is what provides you the frames you need, so the function loop() gets called over and over again. In there we clear the old frame with clearRect(), calculate the new position, and then we draw the new Line with drawLine().

Converting multi (move-to) commands to simple (x,y)

EDIT::
I have converted the various points to (x,y) just as I wanted. I changed the name from bolt to drop because I already have an established shape named drop. However, it will not draw on the canvas. I replaced the coordinates with a leaf shape I also drew and converted to (x,y) and it worked fine. I can't figure out what's so different about my bolt shape.
context.beginPath();
context.moveTo(drop.x,drop.y);
context.moveTo(drop.x+140,drop.y+28);
context.lineTo(drop.x+24,drop.y+28);
context.moveTo(drop.x+24,drop.y+28);
context.lineTo(drop.x-2,drop.y+25);
context.moveTo(drop.x-2,drop.y+25);
context.lineTo(drop.x+17,drop.y+25);
context.moveTo(drop.x+17,drop.y+25);
context.lineTo(drop.x-18,drop.y+53);
context.moveTo(drop.x-18,drop.y+53);
context.lineTo(drop.x-3,drop.y+54);
context.moveTo(drop.x-3,drop.y+54);
context.lineTo(drop.x-47,drop.y+77);
context.moveTo(drop.x-47,drop.y+77);
context.lineTo(drop.x-31,drop.y+59);
context.moveTo(drop.x-31,drop.y+59);
context.lineTo(drop.x-40,drop.y+59);
context.moveTo(drop.x-40,drop.y+59);
context.lineTo(drop.x-14,drop.y+33);
context.moveTo(drop.x-14,drop.y+33);
context.lineTo(drop.x-30,drop.y+32);
context.moveTo(drop.x-30,drop.y+32);
context.lineTo(drop.x+140,drop.y+28);
context.closePath();
context.fillStyle = 'yellow';
context.fill();
I'm not sure what I want to do is called. This is the code my professor provided for a cloud.
function drawCloud(cloud) {
context.beginPath();
context.moveTo(cloud.x, cloud.y);
context.bezierCurveTo(cloud.x-40, cloud.y+20, cloud.x-40, cloud.y+70, cloud.x+60, cloud.y+70);
context.bezierCurveTo(cloud.x+80, cloud.y+100, cloud.x+170, cloud.y+100, cloud.x+170, cloud.y+70);
context.bezierCurveTo(cloud.x+250, cloud.y+70, cloud.x+250, cloud.y+40, cloud.x+210, cloud.y+20);
context.bezierCurveTo(cloud.x+260, cloud.y-40, cloud.x+200, cloud.y+50, cloud.x+170, cloud.y-30);
context.bezierCurveTo(cloud.x+150, cloud.y-75, cloud.x+80, cloud.y-60, cloud.x+80, cloud.y-30);
context.bezierCurveTo(cloud.x+30, cloud.y-75, cloud.x-20, cloud.y-60, cloud.x, cloud.y);
// complete custom shape
context.closePath();
context.lineWidth = 5;
context.strokeStyle = cloud.color;
context.stroke();
}
I found the shape generator and made this shape
function drawBolt(bolt){
context.beginPath()
context.moveTo(140,28);
context.lineTo(164,28);
context.moveTo(164,28);
context.lineTo(138,53);
context.moveTo(138,53);
context.lineTo(157,53);
context.moveTo(157,53);
context.lineTo(122,81);
context.moveTo(122,81);
context.lineTo(137,82);
context.moveTo(137,82);
context.lineTo(93,105);
context.moveTo(93,105);
context.lineTo(109,87);
context.moveTo(109,87);
context.lineTo(100,87);
context.moveTo(100,87);
context.moveTo(126,61);
context.lineTo(110,60);
context.moveTo(110,60);
context.lineTo(140,28);
context.closePath();
context.fill();
};
She told me that I had to change those points to x,y and I imagine there is math involved? Is there an easy way of doing that?
So how she has (cloud.x-40) I suppose I need bolt.x(?)
Where is a good starting point?
var canvas;
var context;
var shapes = []
var timer;
var timerTwo;
var possibleShapes = ['drop','triangle','square','circle','cloud'];
function Shape(x, y, color) {
this.x = x;
this.y = y;
this.size = Math.random()*20+5;
this.dx = Math.random()*4-2;
this.dy = Math.random()*4-2;
this.color = color;
this.shape = possibleShapes[Math.floor(Math.random()*possibleShapes.length)];
}
function init() {
canvas = document.getElementById('canvas');
context = canvas.getContext("2d");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas();
canvas.onclick = function(event) {
handleClick(event.clientX, event.clientY);
};
timer = setInterval(resizeCanvas, 20);
timerTwo = setInterval(newShape, 200);
}
function newShape() {
var x = Math.random() * canvas.width;
var y = Math.random() * canvas.height;
var colors = ["red", "green", "blue", "orange", "purple", "yellow"];
var color = colors[Math.floor(Math.random()*colors.length)];
shapes.push(new Shape(x, y, color));
}
function drawCircle(circle) {
context.beginPath();
context.arc(circle.x, circle.y, circle.size, 0, degreesToRadians(360), true);
context.fillStyle = circle.color;
context.fill();
}
function drawSquare(square) {
context.beginPath();
context.fillStyle = square.color;
context.fillRect(square.x, square.y, square.size, square.size);
}
function drawTriangle(triangle) {
context.beginPath();
context.fillStyle = triangle.color;
context.moveTo(triangle.x+triangle.size,triangle.y);
context.lineTo(triangle.x,triangle.y);
context.lineTo(triangle.x,triangle.y+triangle.size);
context.closePath();
context.fill();
}
function drawCloud(cloud) {
context.beginPath();
context.moveTo(cloud.x, cloud.y);
context.bezierCurveTo(cloud.x-40, cloud.y+20, cloud.x-40, cloud.y+70, cloud.x+60, cloud.y+70);
context.bezierCurveTo(cloud.x+80, cloud.y+100, cloud.x+170, cloud.y+100, cloud.x+170, cloud.y+70);
context.bezierCurveTo(cloud.x+250, cloud.y+70, cloud.x+250, cloud.y+40, cloud.x+210, cloud.y+20);
context.bezierCurveTo(cloud.x+260, cloud.y-40, cloud.x+200, cloud.y+50, cloud.x+170, cloud.y-30);
context.bezierCurveTo(cloud.x+150, cloud.y-75, cloud.x+80, cloud.y-60, cloud.x+80, cloud.y-30);
context.bezierCurveTo(cloud.x+30, cloud.y-75, cloud.x-20, cloud.y-60, cloud.x, cloud.y);
// complete custom shape
context.closePath();
context.lineWidth = 5;
context.strokeStyle = cloud.color;
context.stroke();
}
function drawDrop(drop) {
context.beginPath();
context.lineJoin = 'miter';
context.moveTo(drop.x, drop.y);
context.arc(drop.x, drop.y+68, 34.5, 5.75, 3.66, false);
context.quadraticCurveTo(drop.x-3.5, drop.y+15, drop.x, drop.y);
context.closePath();
context.lineWidth = 2;
context.fillStyle = drop.color;
context.fill();
}
function drawText() {
context.fillStyle = 'white';
context.font = 'bold 2em sans-serif';
context.textAlign = 'right';
context.fillText('Art?', canvas.width-40, canvas.height-40);
}
function resizeCanvas() {
canvas.width = window.innerWidth-20;
canvas.height = window.innerHeight-20;
fillBackgroundColor();
for (var i=0; i<shapes.length; i++) {
if (shapes[i].shape == 'square') {
drawSquare(shapes[i]);
} else if (shapes[i].shape == 'circle') {
drawCircle(shapes[i]);
} else if (shapes[i].shape == 'triangle') {
drawTriangle(shapes[i]);
} else if (shapes[i].shape == 'drop') {
drawDrop(shapes[i]);
} else if (shapes[i].shape == 'cloud') {
drawCloud(shapes[i]);
}
if (shapes[i].x + shapes[i].dx > canvas.width || shapes[i].x + shapes[i].dx < 0)
shapes[i].dx = -shapes[i].dx;
if (shapes[i].y + shapes[i].dy > canvas.height || shapes[i].y + shapes[i].dy < 0)
shapes[i].dy = -shapes[i].dy;
shapes[i].x += shapes[i].dx;
shapes[i].y += shapes[i].dy;
}
drawText();
}
function fillBackgroundColor() {
//var colors = ["white", "yellow", "blue", "red"];
//var bgColor = colors[Math.floor(Math.random() * colors.length)];
context.fillStyle = 'black';
context.fillRect(0, 0, canvas.width, canvas.height);
}
function degreesToRadians(degrees) {
//converts from degrees to radians and returns
return (degrees * Math.PI)/180;
}
window.onload = init;
You can translate entire canvas instead of modifying your code.
let's suppose that bolt is an object with x and y as properties.
function drawBolt(bolt){
context.save();
context.translate(bolt.x, bolt.y);
context.beginPath()
context.moveTo(140,28);
context.lineTo(164,28);
context.moveTo(164,28);
context.lineTo(138,53);
context.moveTo(138,53);
context.lineTo(157,53);
context.moveTo(157,53);
context.lineTo(122,81);
context.moveTo(122,81);
context.lineTo(137,82);
context.moveTo(137,82);
context.lineTo(93,105);
context.moveTo(93,105);
context.lineTo(109,87);
context.moveTo(109,87);
context.lineTo(100,87);
context.moveTo(100,87);
context.moveTo(126,61);
context.lineTo(110,60);
context.moveTo(110,60);
context.lineTo(140,28);
context.closePath();
context.fill();
context.restore();
};
This is equivalent to drawing the bolt modifying all the points adding x and y to each of them.

Rotation wheel with 12 fields like a chart

I have to create a rotation wheel with 12 fields like in the image below link :http://www.resilienciacomunitaria.org/
How i create through which approach?
I used canvas for this but not successful i used d3.js svg but not successful .
<!DOCTYPE html>
<html>
<body>
<canvas id="canvas" width="600" height="600"
style="background-color:#ffff">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height /2; //400
//alert(radius);
//draw a circle again and agian
ctx.translate(radius, radius);
radius =radius*0.85;
setInterval(drawCircle, 50);
function drawCircle() {
var pos = .01;
var length = 100;
var width = 40;
drawFace(ctx, radius);
drawHand(ctx, pos, length, width);
}
function drawFace(ctx,radius){
ctx.beginPath();
ctx.arc(0, 0, 50, 0, 2 * Math.PI, false);
ctx.fillStyle = '#ffff';
ctx.strokeStyle = 'blue';
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI, false);
ctx.strokeStyle = 'yellow';
ctx.fillStyle = 'blue';
ctx.lineWidth = 50;
ctx.fill();
ctx.stroke();
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = 30;
ctx.moveTo(-radius,0);
ctx.lineTo(radius, 0);
ctx.moveTo(-radius,150);
ctx.lineTo(radius, -150);
ctx.moveTo(-radius,-150);
ctx.lineTo(radius, 150);
ctx.moveTo(-radius,380);
ctx.lineTo(radius, -380);
ctx.moveTo(-radius,-380);
ctx.lineTo(radius, 380);
ctx.moveTo(0, -radius);
ctx.lineTo(0, radius);
ctx.stroke();
/*
ctx.globalCompositeOperation='destination-over';
ctx.font="20px Verdana";
ctx.fillStyle = 'white';
ctx.fillText("Explore Zero",180,180);
ctx.stroke();
ctx.globalCompositeOperation='source-over';*/
ctx.rotate(-pos);
}
</script>
</body>
</html>
Thanks in advance
Here's code to get you started:
You can style it to your specific needs
Create an in-memory canvas containing your wheel.
Create an in-memory canvas containing your spike-indicator.
Rotate the canvas and draw the wheel on the main canvas.
Draw the indicator on the main canvas.
Change the rotation angle for the next loop.
Repeat, repeat, repeat using requestAnimationFrame.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var PI2=Math.PI*2;
var myData = [1,2,3,4,5,6,7,8,9,10,11,12];
var cx=150;
var cy=150;
var radius=150;
var wheel=document.createElement('canvas');
var wheelCtx=wheel.getContext('2d');
var indicator=document.createElement('canvas');
var indicatorCtx=indicator.getContext('2d');
var angle=PI2-PI2/4;
var myColor = [];
for(var i=0;i<myData.length;i++){ myColor.push(randomColor()); }
makeWheel();
makeIndicator();
requestAnimationFrame(animate);
function makeWheel(){
wheel.width=wheel.height=radius*2+2;
wheelCtx.lineWidth=1;
wheelCtx.font='24px verdana';
wheelCtx.textAlign='center';
wheelCtx.textBaseline='middle';
var cx=wheel.width/2;
var cy=wheel.height/2;
var sweepAngle=PI2/myData.length;
var startAngle=0;
for(var i=0;i<myData.length;i++){
// calc ending angle based on starting angle
var endAngle=startAngle+sweepAngle;
// draw the wedge
wheelCtx.beginPath();
wheelCtx.moveTo(cx,cy);
wheelCtx.arc(cx,cy,radius,startAngle,endAngle,false);
wheelCtx.closePath();
wheelCtx.fillStyle=myColor[i];
wheelCtx.strokeStyle='black';
wheelCtx.fill();
wheelCtx.stroke();
// draw the label
var midAngle=startAngle+(endAngle-startAngle)/2;
var labelRadius=radius*.85;
var x=cx+(labelRadius)*Math.cos(midAngle);
var y=cy+(labelRadius)*Math.sin(midAngle);
wheelCtx.fillStyle='gold';
wheelCtx.fillText(myData[i],x,y);
wheelCtx.strokeText(myData[i],x,y);
// increment angle
startAngle+=sweepAngle;
}
}
function makeIndicator(){
indicator.width=indicator.height=radius+radius/10;
indicatorCtx.font='18px verdana';
indicatorCtx.textAlign='center';
indicatorCtx.textBaseline='middle';
indicatorCtx.fillStyle='skyblue';
indicatorCtx.strokeStyle='blue';
indicatorCtx.lineWidth=1;
var cx=indicator.width/2;
var cy=indicator.height/2;
indicatorCtx.beginPath();
indicatorCtx.moveTo(cx-radius/8,cy);
indicatorCtx.lineTo(cx,cy-indicator.height/2);
indicatorCtx.lineTo(cx+radius/8,cy);
indicatorCtx.closePath();
indicatorCtx.fillStyle='skyblue'
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.beginPath();
indicatorCtx.arc(cx,cy,radius/3,0,PI2);
indicatorCtx.closePath();
indicatorCtx.fill();
indicatorCtx.stroke();
indicatorCtx.fillStyle='blue';
indicatorCtx.fillText('Prizes',cx,cy);
}
function animate(time){
ctx.clearRect(0,0,cw,ch);
ctx.translate(cw/2,ch/2);
ctx.rotate(angle);
ctx.drawImage(wheel,-wheel.width/2,-wheel.height/2);
ctx.rotate(-angle);
ctx.translate(-cw/2,-ch/2);
ctx.drawImage(indicator,cw/2-indicator.width/2,ch/2-indicator.height/2)
angle+=PI2/360;
requestAnimationFrame(animate);
}
function randomColor(){
return('#'+Math.floor(Math.random()*16777215).toString(16));
}
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
<canvas id="canvas" width=400 height=300></canvas>
You can just put the "wheel" image on the website and just rotate it.
document.getElementById("TheImage").style.transform = "rotate("+YourAngle+"deg)";
Also you will need to put the "pointer" image on top of "wheel" image. (you will not rotate this one)
This is a fiddle written in 20 minutes, hope it helps.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
var lines = new Array();
lines[0] = new Array();
lines[0] = ["Prize 1","#000000"];
lines[1] = new Array();
lines[1] = ["Prize 2","#ffff00"];
lines[2] = new Array();
lines[2] = ["Prize 3","#ff00ff"];
lines[3] = new Array();
lines[3] = ["Prize 4","#00ffff"];
lines[4] = new Array();
lines[4] = ["Prize 5","#00ff00"];
var TO_RADIANS = Math.PI / 180;
var angle = 360 / lines.length; //to see how far apart the lines need to be
var angle_offset = 0; //this will determine the spinning
var angle_speed = 1; //degrees per cycle
var center_offset = 20; //the radius of your spinner in the middle
function animate() {
ctx.clearRect(0,0,canvas.width,canvas.height);
angle_offset+=angle_speed;
ctx.font="20px Verdana";
ctx.fillStyle="#000000";
for (i=0; i<lines.length; i++) {
ctx.fillStyle=lines[i][1];
ctx.save();
ctx.translate(canvas.width/2, canvas.height/2);
ctx.rotate((angle * i + angle_offset) * TO_RADIANS);
//Here you can also decorate with boxes and stuff
ctx.fillText(lines[i][0],center_offset,0);
ctx.restore();
}
requestAnimationFrame(animate);
}
animate();
<canvas id="canvas"></canvas>

HTML5 Canvas Line Problem

I can create lines but I want to create it like you can change the direction of it and size of line anyway like http://devfiles.myopera.com/articles/649/example5.html in this link.
This is my code
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
$("canvas").mousedown(function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var a = x;
var b = y;
context.beginPath();
context.lineWidth = 2;
context.lineCap = "round";
context.moveTo(a, b);
$("canvas").mousemove(function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
context.lineTo(x, y);
context.stroke();
});
$("canvas").mouseup(function(e) {
$("canvas").unbind("mousemove").unbind("mouseup");
});
});
Also you can look from.
http://jsfiddle.net/nSnDC/ How can I solve it
http://devfiles.myopera.com/articles/649/example5.js
The answer is just one short step away....
Basically you need to clean the line drawn every time the mouse move (your script failed to do so).