I want to get the value of clicked portion of the canvas element. The canvas contains multiple elements looks like the below image.
flow chart .
I have tried with the click event of addEventListener but I am unable to get the value. Below I shared the code for reference.
canvas.addEventListener('click',function(evt){
console.log(evt);
});
You should have the position of the each flow chart and when user clicks you should calculate canvas position with flow chart position.This will satisfy your requirement.
enter link description here
var elem = document.getElementById('myCanvas'),
elemLeft = elem.offsetLeft,
elemTop = elem.offsetTop,
context = elem.getContext('2d'),
elements = [];
// Add event listener for `click` events.
elem.addEventListener('click', function (event) {
// var leftWidth = $("#leftPane").css("width")
// var x = event.pageX - (elemLeft + parseInt(leftWidth) + 220),
// y = event.pageY - (elemTop + 15);
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
elements.forEach(function (element) {
if (y > element.top && y < element.top + element.height && x > element.left && x < element.left + element.width) {
alert(element.text);
}
});
}, false);
// Set the value content (x,y) axis
var x = 15, y = 20, maxWidth = elem.getAttribute("width"),
maxHeight = elem.getAttribute("height"), type = 'TL',
width = 50, height = 60, text = "", topy = 0, leftx = 0;
for (i = 1; i <= 15; i++) {
y = 10;
for (j = 1; j <= 6; j++) {
width = 50, height = 60
switch (j) {
case 1:
type = 'TL'; // Trailer
height = 60;
width = 85;
text = i + 'E';
break;
case 2:
type = 'DR'; // Door
height = 35;
width = 85;
text = i;
break;
case 3:
type = 'FL'; // Floor
height = 30;
width = 40;
break;
case 4:
type = 'FL'; // Floor
height = 30;
width = 40;
y -= 10;
break;
case 5:
type = 'DR'; // Door
height = 35;
width = 85;
text = i*10 + 1;
y = topy;
break;
case 6:
type = 'TL'; // Trailer
height = 60;
width = 85;
text = i + 'F';
y += 5;
break;
}
topy = y;
leftx = x;
if (type == 'FL') {
for (k = 1; k <= 12; k++) {
elements.push({
colour: '#05EFFF',
width: width,
height: height,
top: topy,
left: leftx,
text: k,
textColour: '#fff',
type: type
});
if (k % 2 == 0) {
topy = y + elements[j - 1].height + 5;
leftx = x;
y = topy;
}
else {
topy = y;
leftx = x + elements[j - 1].width + 5;
}
}
x = leftx;
y = topy;
}
else {
elements.push({
colour: '#05EFFF',
width: width,
height: height,
top: y,
left: x,
text: text,
textColour: '#fff',
type: type
});
}
//get the y axis for next content
y = y + elements[j-1].height + 6
if (y >= maxHeight - elements[j-1].height) {
break;
}
}
//get the x axis for next content
x = x + elements[0].width + 15
if (x >= maxWidth - elements[0].width) {
break;
}
}
// Render elements.
elements.forEach(function (element) {
context.font = "14pt Arial";
context.strokeStyle = "#000";
context.rect(element.left, element.top, element.width, element.height);
if (element.type == 'FL') {
context.fillText(element.text, element.left + element.width / 4, element.top + element.height / 1.5);
}
else {
context.fillText(element.text, element.left + element.width / 2.5, element.top + element.height / 1.5);
}
context.lineWidth = 1;
context.stroke()
});
<canvas id="myCanvas" width="1125" height="668" style="border: 3px solid #ccc; margin:0;padding:0;" />
please see this snippet that define do you clicked on rectangle in canvas or not.
var startRectPoint = {
x: 10,
y: 10
};
var endRectPoint = {
x: 100,
y: 50
};
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillRect(startRectPoint.x, startRectPoint.y, endRectPoint.x, endRectPoint.y);
function mouseDown(e) {
var x, y;
x = e.clientX - canvas.offsetLeft - pageXOffset;
y = e.clientY - canvas.offsetTop - pageYOffset;
var minX = Math.min(startRectPoint.x, endRectPoint.x);
var maxX = Math.max(startRectPoint.x, endRectPoint.x);
var minY = Math.min(startRectPoint.y, endRectPoint.y);
var maxY = Math.max(startRectPoint.y, endRectPoint.y);
if (x > minX && x < maxX && y > minY && y < maxY) {
alert("you clicked inside of rectangle");
} else {
alert("you clicked outside of rectangle");
}
}
canvas {
border: 1px solid;
}
<canvas id="myCanvas" width="400" height="200" onmousedown="mouseDown(event)"></canvas>
Related
I dont know how to register click event on each rectangle.
here is the sample:
http://jsfiddle.net/9WWqG/1/
You're basically going to have to track where your rectangles are on the canvas, then set up an event listener on the canvas itself. From there you can take the coordinates of the click event and go through all your rectangles to test for 'collisions'.
Here's an example of doing just that: http://jsfiddle.net/9WWqG/2/
html:
<canvas id="myCanvas" width="300" height="150"></canvas>
javascript:
// get canvas element.
var elem = document.getElementById('myCanvas');
function collides(rects, x, y) {
var isCollision = false;
for (var i = 0, len = rects.length; i < len; i++) {
var left = rects[i].x, right = rects[i].x+rects[i].w;
var top = rects[i].y, bottom = rects[i].y+rects[i].h;
if (right >= x
&& left <= x
&& bottom >= y
&& top <= y) {
isCollision = rects[i];
}
}
return isCollision;
}
// check if context exist
if (elem && elem.getContext) {
// list of rectangles to render
var rects = [{x: 0, y: 0, w: 50, h: 50},
{x: 75, y: 0, w: 50, h: 50}];
// get context
var context = elem.getContext('2d');
if (context) {
for (var i = 0, len = rects.length; i < len; i++) {
context.fillRect(rects[i].x, rects[i].y, rects[i].w, rects[i].h);
}
}
// listener, using W3C style for example
elem.addEventListener('click', function(e) {
console.log('click: ' + e.offsetX + '/' + e.offsetY);
var rect = collides(rects, e.offsetX, e.offsetY);
if (rect) {
console.log('collision: ' + rect.x + '/' + rect.y);
} else {
console.log('no collision');
}
}, false);
}
This is an old question but what was once hard to do when it was posted is now much easier.
There are many libraries that keep track of the position of your objects that were drawn on canvas and handle all of the complexities of handling mouse interactions. See EaselJS,
KineticJS,
Paper.js or
Fabric.js and this comparison of canvas libraries for more.
You can also take a different approach and use
Raphaël and gRaphaël
to have a solution that uses SVG and VML instead of canvas and works even on IE6.
Your example changed to use Raphaël would look like this:
var r = Raphael(0, 0, 300, 150);
r.rect(0, 0, 50, 50)
.attr({fill: "#000"})
.click(function () {
alert('first rectangle clicked');
});
r.rect(75, 0, 50, 50)
.attr({fill: "#000"})
.click(function () {
alert('second rectangle clicked');
});
See DEMO.
Update 2015
You may also be able to use ART, a retained mode vector drawing API for HTML5 canvas - see this answer for more info.
I found a way to make this work in mozilla using the clientX,clientY instead of offsetX/offsetY.
Also, if your canvas extends beyond the innerHeight, and uses the scroll, add the window.pageYOffset to the e.clientY. Goes the same way, if your canvas extends beyond the width.
Another example is at my github: https://github.com/michaelBenin/fi-test
Here is another link that explains this: http://eli.thegreenplace.net/2010/02/13/finding-out-the-mouse-click-position-on-a-canvas-with-javascript/
Please use below function if you want to support more than one rectangle in canvas and handle its click event
<canvas id="myCanvas" width="1125" height="668" style="border: 3px solid #ccc; margin:0;padding:0;" />
var elem = document.getElementById('myCanvas'),
elemLeft = elem.offsetLeft,
elemTop = elem.offsetTop,
context = elem.getContext('2d'),
elements = [];
// Add event listener for `click` events.
elem.addEventListener('click', function (event) {
// var leftWidth = $("#leftPane").css("width")
// var x = event.pageX - (elemLeft + parseInt(leftWidth) + 220),
// y = event.pageY - (elemTop + 15);
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
elements.forEach(function (element) {
if (y > element.top && y < element.top + element.height && x > element.left && x < element.left + element.width) {
alert(element.text);
}
});
}, false);
// Set the value content (x,y) axis
var x = 15, y = 20, maxWidth = elem.getAttribute("width"),
maxHeight = elem.getAttribute("height"), type = 'TL',
width = 50, height = 60, text = "", topy = 0, leftx = 0;
for (i = 1; i <= 15; i++) {
y = 10;
for (j = 1; j <= 6; j++) {
width = 50, height = 60
switch (j) {
case 1:
type = 'TL'; // Trailer
height = 60;
width = 85;
text = i + 'E';
break;
case 2:
type = 'DR'; // Door
height = 35;
width = 85;
text = i;
break;
case 3:
type = 'FL'; // Floor
height = 30;
width = 40;
break;
case 4:
type = 'FL'; // Floor
height = 30;
width = 40;
y -= 10;
break;
case 5:
type = 'DR'; // Door
height = 35;
width = 85;
text = i*10 + 1;
y = topy;
break;
case 6:
type = 'TL'; // Trailer
height = 60;
width = 85;
text = i + 'F';
y += 5;
break;
}
topy = y;
leftx = x;
if (type == 'FL') {
for (k = 1; k <= 12; k++) {
elements.push({
colour: '#05EFFF',
width: width,
height: height,
top: topy,
left: leftx,
text: k,
textColour: '#fff',
type: type
});
if (k % 2 == 0) {
topy = y + elements[j - 1].height + 5;
leftx = x;
y = topy;
}
else {
topy = y;
leftx = x + elements[j - 1].width + 5;
}
}
x = leftx;
y = topy;
}
else {
elements.push({
colour: '#05EFFF',
width: width,
height: height,
top: y,
left: x,
text: text,
textColour: '#fff',
type: type
});
}
//get the y axis for next content
y = y + elements[j-1].height + 6
if (y >= maxHeight - elements[j-1].height) {
break;
}
}
//get the x axis for next content
x = x + elements[0].width + 15
if (x >= maxWidth - elements[0].width) {
break;
}
}
// Render elements.
elements.forEach(function (element) {
context.font = "14pt Arial";
context.strokeStyle = "#000";
context.rect(element.left, element.top, element.width, element.height);
if (element.type == 'FL') {
context.fillText(element.text, element.left + element.width / 4, element.top + element.height / 1.5);
}
else {
context.fillText(element.text, element.left + element.width / 2.5, element.top + element.height / 1.5);
}
context.lineWidth = 1;
context.stroke()
});
Here's an example of doing just that: http://jsfiddle.net/BmeKr/1291/
Please use below function if you want to support more than one rectangle in canvas and handle its click event..... modified logic given by Matt King.
function collides(myRect, x, y) {
var isCollision = false;
for (var i = 0, len = myRect.length; i < len; i++) {
var left = myRect[i].x, right = myRect[i].x+myRect[i].w;
var top = myRect[i].y, bottom = myRect[i].y+myRect[i].h;
if ((left + right) >= x
&& left <= x
&& (top +bottom) >= y
&& top <= y) {
isCollision = json.Major[i];
}
}
}
return isCollision;
}
I have three canvas-elements that lay over the another. the first is a picture the second a filter and the third should be a text. I made the filter resizeable und draggable with the mouse events, but somehow this does not work with the text the same way. and i want to resize the text with four corner buttons and want to make it draggable. The text is added via a self-programmed simple texteditor.
click me please
click me please
The red square is where the rectangles are drawn now, but htey should be around the text, and the blue square is the hitbox to drag the text.
Now my Js-Code for the text.
var colorButton = document.getElementById("primary_color");
var textArea = document.getElementById("text");
var editor = document.getElementById("text");
var overlay = document.getElementById("overlay");
var textFontFamily = document.getElementById("selectForFonts");
var textColor;
var fontStyleFamily = 'Arial';
var boldness = 'normal';
var italicness = 'normal';
var data;
/**Function to get the color and color the text*/
colorButton.onchange = function() {
textColor = colorButton.value;
textArea.style.color = textColor;
}
function showOverlay() {
overlay.style.display = "block";
}
function writeText() {
$(function() {
var canvasText = document.getElementById("canvasText");
var ctxText = canvasText.getContext("2d");
var $canvasText = $("#canvasText");
var canvasOffset;
var offsetX;
var offsetY;
var isDown;
var dx;
var dy;
var lastX = 0;
var lastY = 0;
var iW;
var iH;
var iLeft = 0;
var iTop = 0;
var iRight, iBottom, iOrientation;
canvasText.height = renderableHeight;
canvasText.width = renderableWidth;
overlay.style.display = "none";
data = textArea.value;
canvasText.style.display = "block";
canvasOffset = $canvasText.offset();
offsetX = canvasOffset.left;
offsetY = canvasOffset.top;
isDown = false;
var textWidthtemp = ctxText.measureText(data);
var textWidth = textWidthtemp.width;
var textHeight = parseInt("50");
var font = italicness + " " + boldness + " " + textHeight + "px " + fontStyleFamily;
iW = textWidth;
iH = textHeight;
facW = 1; // canvasText.width / canvasText.offsetWidth;
facH = 1; //canvasText.height / canvasText.offsetHeight;
console.log(facW + " " + facH);
iRight = iLeft + iW;
iBottom = iTop + iH;
console.log(iTop);
console.log(iBottom);
console.log(iRight);
console.log(iBottom);
iOrientation = "Wide"; //(iW >= iH) ? "Wide" : "Tall";
draw(true);
var border = 10;
var isLeft = false;
var isRight = false;
var isTop = false;
var isBottom = false;
var iAnchor;
canvasText.onmousedown = handleMousedown;
canvasText.onmousemove = handleMousemove;
canvasText.onmouseup = handleMouseup;
canvasText.onmouseout = handleMouseup;
function hitResizeAnchor(x, y) {
// which borders are under the mouse
isLeft = (x * facW > iLeft && x * facW < iLeft + border);
isRight = (x * facW < iRight && x * facW > iRight - border);
isTop = (y * facH > iTop && y * facH < iTop + border);
isBottom = (y * facH < iBottom && y * facH > iBottom - border);
isDragged = (x * facW > iLeft && x * facW < iRight && y * facH > iTop && y * facH < iBottom);
// return the appropriate anchor
if (isTop && isLeft) {
return (iOrientation + "TL");
}
if (isTop && isRight) {
return (iOrientation + "TR");
}
if (isBottom && isLeft) {
return (iOrientation + "BL");
}
if (isBottom && isRight) {
return (iOrientation + "BR");
}
if (isDragged) {
return "DR"
}
return (null);
}
var resizeFunctions = {
WideTR: function(x, y) {
iRight = x * facW;
iTop = iBottom - (iH * (iRight - iLeft) / iW);
},
TallTR: function(x, y) {
iTop = y * facH;
iRight = iLeft + (iW * (iBottom - iTop) / iH);
},
WideBR: function(x, y) {
iRight = x * facW;
iBottom = iTop + (iH * (iRight - iLeft) / iW);
},
TallBR: function(x, y) {
iBottom = y * facH;
iRight = iLeft + (iW * (iBottom - iTop) / iH);
},
WideBL: function(x, y) {
iLeft = x * facW;
iBottom = iTop + (iH * (iRight - iLeft) / iW);
},
TallBL: function(x, y) {
iBottom = y * facH;
iLeft = iRight - (iW * (iBottom - iTop) / iH);
},
WideTL: function(x, y) {
iLeft = x * facW;
iTop = iBottom - (iH * (iRight - iLeft) / iW);
},
TallTL: function(x, y) {
iBottom = y * facH;
iLeft = iRight - (iW * (iBottom - iTop) / iH);
},
DR: function(x, y) {
console.log("DX: " + dx + "DY: " + dy);
iLeft += dx;
iRight += dx;
iTop += dy;
iBottom += dy;
}
};
function handleMousedown(e) {
// tell the browser we'll handle this mousedown
e.preventDefault();
e.stopPropagation();
var mouseX = e.clientX - offsetX;
var mouseY = e.clientY - offsetY;
iAnchor = hitResizeAnchor(mouseX, mouseY);
if (iAnchor == "DR") {
lastX = mouseX;
lastY = mouseY;
isDown = (true);
} else {
isDown = (iAnchor);
}
}
function handleMouseup(e) {
// tell the browser we'll handle this mouseup
e.preventDefault();
e.stopPropagation();
if (iAnchor == "DR") {
isDown = false;
} else {
isDown = false;
draw(true);
}
}
function handleMousemove(e) {
// tell the browser we'll handle this mousemove
e.preventDefault();
e.stopPropagation();
// return if we're not dragging
if (!isDown) {
return;
}
// get MouseX/Y
var mouseX = e.clientX - offsetX;
var mouseY = e.clientY - offsetY;
//if Picture is dragged
if (iAnchor == "DR") {
dx = mouseX - lastX;
dy = mouseY - lastY;
// set the lastXY for next time we're here
lastX = mouseX;
lastY = mouseY;
resizeFunctions[iAnchor](mouseX, mouseY);
draw(true);
} else {
// reset iLeft,iRight,iTop,iBottom based on drag
resizeFunctions[iAnchor](mouseX, mouseY);
// redraw the resized image
draw(false);
}
}
function draw(withAnchors) {
ctxText.clearRect(0, 0, canvasText.width, canvasText.height);
ctxText.font = font;
ctxText.fillStyle = textColor;
ctxText.fillText(data, iLeft, iTop - textHeight);
if (withAnchors) {
ctxText.fillRect(iLeft, iTop - textHeight, border, border);
ctxText.fillRect(iRight - border, iTop - textHeight, border, border);
ctxText.fillRect(iRight - border, iBottom - border - textHeight, border, border);
ctxText.fillRect(iLeft, iBottom - border - textHeight, border, border);
}
}
});
}
function bold() {
var temp = textArea.style.fontWeight;
if (temp == 'normal') {
textArea.style.fontWeight = 'bold';
boldness = 'bold';
} else {
textArea.style.fontWeight = 'normal';
boldness = 'normal';
}
}
function italic() {
var temp = textArea.style.fontStyle;
if (temp == 'normal') {
textArea.style.fontStyle = 'italic';
italicness = 'italic';
} else {
textArea.style.fontStyle = 'normal';
italicness = 'normal';
}
}
function changeFont() {
var temp = textFontFamily.options[textFontFamily.selectedIndex].value;
console.log(temp);
textArea.style.fontFamily = temp;
fontStyleFamily = temp;
}
<div id="display" class="flex-workspace-item-big z-depth-2">
<canvas id=canvas style="width:inherit ;height:inherit; position: absolute; z-index: 0;"></canvas>
<canvas id=canvasFilter style="width:inherit ;height:inherit; position: absolute; display: none; z-index: 1"></canvas>
<canvas id=canvasText style="width:inherit ;height:inherit; position: absolute; display: none; z-index: 2"></canvas>
</div>
I'm coding a basic game and in that game, the score is based on how long you survive. However, the score isn't recording how long the player survives in seconds, instead it's doing so in milliseconds (I presume). How can I fix this so the score keeps track in seconds?
I've tried using setInterval([insert parameter], 1000) but still my code ran in milliseconds.
/*Down below I am bringing the canvas into JavaScript so we can code and "draw" our canvas.*/
var thecanvas = document.getElementById("thecanvas").getContext("2d");
thecanvas.font = "30px Arial";
var HEIGHT = 500;
var WIDTH = 500;
var TimeWhenTheGameStarted = Date.now(); /*This will return the time in miliseconds.*/
var CountofTheFrames = 0;
var TheScore = 0;
/*The Player - Variable will be the object, as indicated by the {}*/
var player = {
x: 50,
speedX: 30,
y: 40,
speedY: 5,
name: "P",
hp: 10,
width: 20,
height: 20,
color: "blue",
};
var enemyList = {};
gettingDistanceBetweenEntities = function(entity1, entity2) {
/*Return Distance (number)*/
var vx = entity1.x - entity2.x;
var vy = entity1.y - entity2.y;
return Math.sqrt(vx * vx + vy * vy);
};
testingCollisionOfEntities = function(entity1, entity2) {
/*Return if colliding (true.false)*/
var rectangle1 = {
x: entity1.x - entity1.width / 2,
y: entity1.y - entity1.height / 2,
width: entity1.width,
height: entity1.height,
};
var rectangle2 = {
x: entity2.x - entity2.width / 2,
y: entity2.y - entity2.height / 2,
width: entity2.width,
height: entity2.height,
};
return testingCollusionofRectangles(rectangle1, rectangle2);
};
Enemy = function(id, x, y, speedX, speedY, width, height) {
var theenemy = {
x: x,
speedX: speedX,
y: y,
speedY: speedY,
name: "E",
id: id,
width: width,
height: height,
color: "red",
};
enemyList[id] = theenemy;
};
UpdatingTheEntity = function(entityParameter) {
UpdatingTheEntityPosition(entityParameter);
DrawingTheEntity(entityParameter);
};
document.onmousemove = function(mouse) {
var mouseX =
mouse.clientX -
document.getElementById("thecanvas").getBoundingClientRect().left;
var mouseY =
mouse.clientY -
document.getElementById("thecanvas").getBoundingClientRect().top;
/*Makes sure that the mouse does not go out of bounds of the canvas.*/
if (mouseX < player.width / 2) mouseX = player.width / 2;
if (mouseX > WIDTH - player.width / 2) mouseX = WIDTH - player.width / 2;
if (mouseY < player.height / 2) mouseY = player.height / 2;
if (mouseY > HEIGHT - player.height / 2) mouseY = HEIGHT - player.height / 2;
player.x = mouseX;
player.y = mouseY;
};
/*Speed of the Entities*/
UpdatingTheEntityPosition = function(entityParameter) {
entityParameter.x += entityParameter.speedX;
entityParameter.y += entityParameter.speedY;
if (entityParameter.x < 0 || entityParameter.x > WIDTH) {
entityParameter.speedX = -entityParameter.speedX;
}
if (entityParameter.y < 0 || entityParameter.y > HEIGHT) {
entityParameter.speedY = -entityParameter.speedY;
}
};
testingCollusionofRectangles = function(rectangle1, rectangle2) {
return (
rectangle1.x <= rectangle2.x + rectangle2.width &&
rectangle2.x <= rectangle1.x + rectangle1.width &&
rectangle1.y <= rectangle2.y + rectangle2.height &&
rectangle2.y <= rectangle1.y + rectangle1.height
);
};
/*Physical Appearance of the Entities*/
DrawingTheEntity = function(entityParameter) {
thecanvas.save();
thecanvas.fillStyle = entityParameter.color;
thecanvas.fillRect(
entityParameter.x - entityParameter.width / 2,
entityParameter.y - entityParameter.height / 2,
entityParameter.width,
entityParameter.height,
);
thecanvas.restore(); /*So we do not override the color of HP*/
};
runningTheCode = function() {
thecanvas.clearRect(0, 0, WIDTH, HEIGHT);
/*Increase by 1*/
CountofTheFrames++;
TheScore++;
CountofTheFrames = CountofTheFrames + 1;
/*This will generate more random enemies over time*/
if (CountofTheFrames % 300 === 0)
/*Only when the frame count reaches 300, it will generate new enemies every 8 seconds*/
RandomlyGeneratingEnemies();
for (var id in enemyList) {
UpdatingTheEntity(enemyList[id]);
var isColliding = testingCollisionOfEntities(player, enemyList[id]);
if (isColliding) {
player.hp = player.hp - 1;
if (player.hp <= 0) {
var TimeSurvived = Date.now() - TimeWhenTheGameStarted;
console.log(
"You lost! You survived for " + TimeSurvived + " miliseconds!",
);
//TimeWhenTheGameStarted = Date.now(); /*Restarts*/
player.hp = 10;
StartingNewGame();
}
}
}
DrawingTheEntity(player);
thecanvas.fillText(player.hp + "HP", 0, 30);
thecanvas.fillText("Score: " + TheScore, 325, 30);
};
RandomlyGeneratingEnemies = function() {
/* Math.random () returns a number between 0 and 1 by default*/
var id = Math.random();
var x = Math.random() * WIDTH;
var y = Math.random() * HEIGHT;
var height = 24 + Math.random() * 10;
var width = 10 + Math.random() * 23;
var speedX = 4 + Math.random() * 6;
var speedY = 4 + Math.random() * 6;
Enemy(id, x, y, speedX, speedY, height, width);
};
StartingNewGame = function() {
player.hp = 10;
TimeWhenTheGameStarted = Date.now();
CountofTheFrames = 0;
TheScore = 0;
enemyList = {};
RandomlyGeneratingEnemies();
RandomlyGeneratingEnemies();
RandomlyGeneratingEnemies();
};
setInterval(
runningTheCode,
40,
); /*Meaning, the code will run every [blank] miliseconds, 40 = 22 frames*/
<center><h1>Dodge Box: The Game</h1></center>
<center><canvas id="thecanvas" width="500" height="500" style="border: 4px solid #000000;"></canvas></center>
When running the code, the score will run in seconds, not in milliseconds.
Divide milliseconds by 1000 to get seconds.
var TimeSurvived = (Date.now() - TimeWhenTheGameStarted) / 1000;
I am new to Canvas, I am creating a website to increase text as I re-sizes rectangle.I tried so much but nothing works for me. Actually I want if I re size rectangle just by its width( stretch To Left /To Right), only text width should be increased not the fontsize. I have done with fontsize but finding difficulty in increasing isolated Text Height and Width. your suggestions are most welcome
function Box2() {
this.x = 0;
this.y = 0;
this.w = 1; // default width and height?
this.h = 1;
this.fill = '#CC0000';
this.Owntext = "";
this.fontsize = '20';
this.TextColor = '';
this.TextFontFamily = '';
this.Angle = 0;
this.ScaleHeight = 1;
this.ScaleWidth = 1;
}
// New methods on the Box class
Box2.prototype = {
// we used to have a solo draw function
// but now each box is responsible for its own drawing
// mainDraw() will call this with the normal canvas
// myDown will call this with the ghost canvas with 'black'
draw: function (context, optionalColor) {
if (context === gctx) {
context.fillStyle = 'black'; // always want black for the ghost canvas
} else {
context.fillStyle = this.fill;
}
// alert('Box2.prototype');
// We can skip the drawing of elements that have moved off the screen:
if (this.x > WIDTH || this.y > HEIGHT) return;
if (this.x + this.w < 0 || this.y + this.h < 0) return;
context.fillRect(this.x, this.y, this.w, this.h);
// draw selection
// this is a stroke along the box and also 8 new selection handles
if (mySel === this) {
context.strokeStyle = mySelColor;
context.lineWidth = mySelWidth;
context.strokeRect(this.x, this.y, this.w, this.h);
// draw the boxes
var half = mySelBoxSize / 2;
// 0 1 2
// 3 4
// 5 6 7
// top left, middle, right
selectionHandles[0].x = this.x - half;
selectionHandles[0].y = this.y - half;
selectionHandles[1].x = this.x + this.w / 2 - half;
selectionHandles[1].y = this.y - half;
selectionHandles[2].x = this.x + this.w - half;
selectionHandles[2].y = this.y - half;
//middle left
selectionHandles[3].x = this.x - half;
selectionHandles[3].y = this.y + this.h / 2 - half;
//middle right
selectionHandles[4].x = this.x + this.w - half;
selectionHandles[4].y = this.y + this.h / 2 - half;
//bottom left, middle, right
selectionHandles[6].x = this.x + this.w / 2 - half;
selectionHandles[6].y = this.y + this.h - half;
selectionHandles[5].x = this.x - half;
selectionHandles[5].y = this.y + this.h - half;
selectionHandles[7].x = this.x + this.w - half;
selectionHandles[7].y = this.y + this.h - half;
context.fillStyle = mySelBoxColor;
for (var i = 0; i < 8; i++) {
var cur = selectionHandles[i];
context.fillRect(cur.x, cur.y, mySelBoxSize, mySelBoxSize);
}
}
} // end draw
}
//Initialize a new Box, add it, and invalidate the canvas
function addRect(x, y, w, h, fill,text,FontSize,TextColor,TextFontFamily,Angle,ScaleWidth,ScaleHeight) {
var rect = new Box2;
rect.x = x;
rect.y = y;
rect.w = w
rect.h = h;
rect.Owntext = text;
rect.FontSize = FontSize;
rect.TextColor = TextColor;
rect.TextFontFamily = TextFontFamily;
rect.Angle = Angle;
rect.ScaleWidth = ScaleWidth;
rect.ScaleHeight = ScaleHeight;
// alert(TextFontFamily);
// rect.fontsize = FontSize;
// alert(fill);
rect.fill = fill;
boxes2.push(rect);
invalidate();
}
var CanvasHeight = 0;
var CanvasWidth = 0;
// initialize our canvas, add a ghost canvas, set draw loop
// then add everything we want to intially exist on the canvas
function init2() {
// alert('init2')
dropdownTextFamily = document.getElementById('drpFontFamily');
dropdown = document.getElementById('drpTextColor');
Button = document.getElementById('Mybtn');
canvas = document.getElementById('canvas2');
HEIGHT = canvas.height;
WIDTH = canvas.width;
// CanvasHeight=
ctx = canvas.getContext('2d');
ghostcanvas = document.createElement('canvas');
ghostcanvas.height = HEIGHT;
ghostcanvas.width = WIDTH;
gctx = ghostcanvas.getContext('2d');
//fixes a problem where double clicking causes text to get selected on the canvas
canvas.onselectstart = function () { return false; }
// fixes mouse co-ordinate problems when there's a border or padding
// see getMouse for more detail
if (document.defaultView && document.defaultView.getComputedStyle) {
stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0;
stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0;
styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0;
}
// make mainDraw() fire every INTERVAL milliseconds
setInterval(mainDraw, INTERVAL);
// set our events. Up and down are for dragging,
// double click is for making new boxes
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
Button.onclick = myDblClickButton;
dropdown.onchange = ChangeTextColor;
dropdownTextFamily.onchange = ChangeTextFontFamily;
// lblCheck.onclick = myclick;
// textBox.onkeyup = myDblClick;
// canvas.ondblclick = myDblClick;
// alert('ethe');
canvas.onmousemove = myMove;
// set up the selection handle boxes
for (var i = 0; i < 8; i++) {
// alert();
var rect = new Box2;
selectionHandles.push(rect);//WATCHED ******* A New Reactangle Added To The Canvas
}
// add custom initialization here:
// add a large green rectangle
// addRect(260, 70, 60, 65, 'rgba(0,205,0,0.7)');
// add a green-blue rectangle
// addRect(240, 120, 40, 40, 'rgba(2,165,165,0.7)');
// add a smaller purple rectangle
// addRect(45, 60, 25, 25, 'rgba(150,150,250,0.7)');
// get a reference to the canvas element, and its context
var canvas2 = document.getElementById('canvas2');
var ctx1 = canvas2.getContext('2d');
// sets maximum line width, line height, and x /y coords for text
var maxWidth = canvas2.width - 10;
var lineHeight = 23;
var x_pos = (canvas2.width - maxWidth) / 2;
var y_pos = 15;
var DbClickCount=0;
// register onkeyup event for #text_cnv text field to add the text in canvas as it is typed
document.getElementById('textBox').onkeyup = function () {
// clearCanvas(canvas2); // clears the canvas
//alert(ctx1);
// mySel.Owntext = this.value;
//alert(mySel.w);
if (mySel == null) {
// alert('I am Here');
myDblClick();
var x = 10;
var y = 10;
// alert(x);
myDown1(x, y);
addTextCnv(ctx1, this.value, mySel.x, mySel.y, mySel.h, mySel.w);
// addTextCnv(ctx1, this.value, 260, 120, 60, 65);
// myDown1();
// mySel.x = 260;
// mySel.y = 100;
// myDown1(260,100);
// mySel.h = 50;
// mySel.w = 5;
// addTextCnv(ctx1, this.value, 260, 100, 50, 5);
//// addTextCnv(ctx1, this.value, mySel.x, mySel.y, mySel.h, mySel.w);
}
else
{
// addTextCnv(ctx1, this.value, 260, 120, 60, 65);
// alert(mySel.x);
// alert(mySel.y);
// alert(mySel.h);
// alert(mySel.w);
addTextCnv(ctx1, this.value, mySel.x, mySel.y, mySel.h, lineHeight);
}
//alert(mySel.x);
//addTextCnv(ctx1, this.value, 260, 120, 60, 65);
// mainDraw(this.value);
//alert(this.value);
//addTextCnv(ctx1, this.value, x_pos, y_pos, maxWidth, 23);
}
var text2 = "Sachdeva";
// document.write("<p>Fontsize: " + text2.fontsize(6) + "</p>");
// text2.fontsize(6);
//alert(mySel.Owntext);
// ctx1.font = 'italic 20px Calibri';
ctx1.font = '20pt Calibri';
//TextFontFamily
var text1 = "rajay";
// var text3 = "rajay1";
// addRect(260, 70, 60, 15, 'rgba(0,205,0,0.7)',text1);
// add a smaller purple rectangle
// alert('hi');
// addRect(45, 60, 25, 15, 'rgba(150,150,250,0.7)', text2);
//addRect(260, 85, 60, 65, 'rgba(0,205,0,0.7)', text3);
}
function myMove(e) {
ctx = canvas.getContext('2d');
if (isDrag) {
// alert('hi');
getMouse(e);
// alert(e.x);
// alert('drag');
mySel.x = mx - offsetx;
// alert(mySel.x);
mySel.y = my - offsety;
// something is changing position so we better invalidate the canvas!
invalidate();
} else if (isResizeDrag) {
// alert('hi');
// time ro resize!
getMouse(e);
var oldx = mySel.x;
var oldy = mySel.y;
var oldw = mySel.w;
var oldh = mySel.h;
//alert(mySel.h);
//alert(expectResize)
switch (expectResize) {
case 0:
// mySel.x = mx;
// mySel.y = my;
// mySel.w += oldx - mx;
// mySel.h += oldy - my;
// mySel.ScaleWidth = 2;
// mySel.ScaleHeight = 1;
// alert(mySel.w);
// mySel.FontSize = (mySel.h/2)+(mySel.w/4);
// alert(mySel.FontSize);
// alert(mySel.h);
// alert(mySel.w);
// alert(mySel.Angle);
// var clickAngle = getAngle(mySel.x, mySel.y, mx, my) - mySel.Angle;
//alert(clickAngle);
//var clickAngle = getAngle(cX + offX, cY + offY, event.clientX, event.clientY) - model.angle;
// mySel.Angle = (getAngle(mySel.x, mySel.y, mx, my) - clickAngle);
// alert(mySel.Angle);
// mySel.Angle = 45;
// alert(mySel.Angle);
// alert(mySel.h);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
// ctx.font = 'italic ' + (2 / 3) * mySel.h+'px' + ' Calibri';
// alert(ctx.font);
break;
case 1:
mySel.y = my;
mySel.h += oldy - my;
// alert(mySel.h);
if (mySel.FontSize>mySel.h){
mySel.FontSize = mySel.h;
}
else
{
// alert('Hi');
mySel.FontSize = mySel.FontSize;
}
// mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
// ctx.scale(1, 2);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
case 2:
mySel.y = my;
mySel.w = mx - oldx;
mySel.h += oldy - my;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
case 3:
mySel.x = mx;
mySel.w += oldx - mx;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
break;
case 4:
mySel.w = mx - oldx;
// mySel.FontSize = mySel.FontSize;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
break;
case 5:
mySel.x = mx;
mySel.w += oldx - mx;
mySel.h = my - oldy;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
case 6:
//mySel.h = my - oldy;
//mySel.FontSize = mySel.h;
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
case 7:
mySel.w = mx - oldx;
mySel.h = my - oldy;
mySel.FontSize = (mySel.h / 2) + (mySel.w / 4);
// ctx.font = 'italic ' + (2 / 3) * mySel.h + 'px' + ' Calibri';
break;
}
// alert(mySel.FontSize);
invalidate();
}
getMouse(e);
// if there's a selection see if we grabbed one of the selection handles
if (mySel !== null && !isResizeDrag) {
for (var i = 0; i < 8; i++) {
// 0 1 2
// 3 4
// 5 6 7
var cur = selectionHandles[i];
// alert('Here');
// we dont need to use the ghost context because
// selection handles will always be rectangles
if (mx >= cur.x && mx <= cur.x + mySelBoxSize &&
my >= cur.y && my <= cur.y + mySelBoxSize) {
// we found one!
expectResize = i;
invalidate();
switch (i) {
case 0:
this.style.cursor = 'nw-resize';
break;
case 1:
this.style.cursor = 'n-resize';
break;
case 2:
this.style.cursor = 'ne-resize';
break;
case 3:
this.style.cursor = 'w-resize';
break;
case 4:
this.style.cursor = 'e-resize';
break;
case 5:
this.style.cursor = 'sw-resize';
break;
case 6:
this.style.cursor = 's-resize';
break;
case 7:
this.style.cursor = 'se-resize';
break;
}
return;
}
}
// not over a selection box, return to normal
isResizeDrag = false;
expectResize = -1;
this.style.cursor = 'auto';
}
}
You need to perform some computation to have the bounding box of the text, then use scale on the context to have it match the rect you want to fill.
You get the width of a text by using measureText. Unfortunately, only the text width is provided, but the height value is always close from the fontSize.
var cv = document.getElementById('cv');
var ctx = cv.getContext('2d');
function drawTextInBox(txt, font, x, y, w, h, angle) {
angle = angle || 0;
var fontHeight = 20;
var hMargin = 4;
ctx.font = fontHeight + 'px ' + font;
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
var txtWidth = ctx.measureText(txt).width + 2 * hMargin;
ctx.save();
ctx.translate(x+w/2, y);
ctx.rotate(angle);
ctx.strokeRect(-w/2, 0, w, h);
ctx.scale(w / txtWidth, h / fontHeight);
ctx.translate(hMargin, 0)
ctx.fillText(txt, -txtWidth/2, 0);
ctx.restore();
}
drawTextInBox('This is a line', 'Arial', 2, 2, 60, 20);
drawTextInBox('Another line here', 'Arial', 2, 32, 160, 40, 0.1);
drawTextInBox('The Last line', 'Arial', 2, 82, 220, 90);
drawTextInBox('! Now with an angle !', 'Arial', 42, 190, 120, 30, -Math.PI/12);
<canvas width=400 height=300 id='cv'></canvas>
I'm trying to draw a one pixel width line going form the canvas center and evolving with the canvas width/height ratio as it's drawn.
var x = 0;
var y = 0;
var dx = 0;
var dy = -1;
var width = 200;
var height = 40;
//var i = width * height;
var counter = 0;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
setInterval(function(){
//for (i = Math.pow(Math.max(width, height), 2); i>0; i--) {
if ((-width/2 < x <= width/2) && (-height/2 < y <= height/2)) {
console.log("[ " + x + " , " + y + " ]");
ctx.fillStyle = "#FF0000";
ctx.fillRect(width/2 + x, height/2 - y,1,1);
}
if (x === y || (x < 0 && x === -y) || (x > 0 && x === 1-y) || ( -width/2 > x > width/2 ) || ( -height/2 > y > height/2 ) ) {
// change direction
var tempdx = dx;
dx = -dy;
dy = tempdx;
}
counter += 1;
//alert (counter);
x += dx;
y += dy;
}, 1);
I want the spiral to evolve as such:
I'd like to be able to get the ratio between height and width on the equation, so I don't need to calculate the coordinates for points outside the canvas. Also, the purpose is for it to adjust the spiral drawing to the canvas proportions.
Any help would be appreciated.
A friend helped me handling a proper solution. I only have a 1 pixel offset to solve where I need to move all the drawing to the left by one pixel.
Here's the fiddle for the solution achieved: http://jsfiddle.net/hitbyatruck/c4Kd6/
And the Javascript code below:
var width = 150;
var height = 50;
var x = -(width - height)/2;
var y = 0;
var dx = 1;
var dy = 0;
var x_limit = (width - height)/2;
var y_limit = 0;
var counter = 0;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
setInterval(function(){
if ((-width/2 < x && x <= width/2) && (-height/2 < y && y <= height/2)) {
console.log("[ " + x + " , " + y + " ]");
ctx.fillStyle = "#FF0000";
ctx.fillRect(width/2 + x, height/2 - y,1,1);
}
if( dx > 0 ){//Dir right
if(x > x_limit){
dx = 0;
dy = 1;
}
}
else if( dy > 0 ){ //Dir up
if(y > y_limit){
dx = -1;
dy = 0;
}
}
else if(dx < 0){ //Dir left
if(x < (-1 * x_limit)){
dx = 0;
dy = -1;
}
}
else if(dy < 0) { //Dir down
if(y < (-1 * y_limit)){
dx = 1;
dy = 0;
x_limit += 1;
y_limit += 1;
}
}
counter += 1;
//alert (counter);
x += dx;
y += dy;
}, 1);
I nearly crashed my browser trying this. Here, have some code before I hurt myself!
It computes y=f(x) for the diagonal, and y2=f(x) for the antidiagonal, then checks if we're above or below the diagonals when needed.
var x = 0;
var y = 0;
var dx = 0;
var dy = -1;
var width = 200;
var height = 40;
//var i = width * height;
var counter = 0;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
function diag1(x) {
return x*height/width;
}
function diag2(x) {
return -1/diag(x);
}
setInterval(function(){
//for (i = Math.pow(Math.max(width, height), 2); i>0; i--) {
if ((-width/2 < x && x <= width/2) && (-height/2 < y && y <= height/2)) {
console.log("[ " + x + " , " + y + " ]");
ctx.fillStyle = "#FF0000";
ctx.fillRect(width/2 + x, height/2 - y,1,1);
}
if (dx == 0) {
if (dy == 1) {
// moving up
if (y >= diag1(x)) {
// then move left
dy = 0;
dx = -1;
}
}
else {
// moving down
if (y <= diag2(x)) {
// then move right
dy = 0;
dx = 1;
}
}
}
else {
if (dx == 1) {
// moving right
if (y <= diag1(x)) {
// then move up
dy = 1;
dx = 0;
}
}
else {
// moving left
if (y <= diag2(x)) {
// then move down
dy = -1;
dx = 0;
}
}
}
counter += 1;
//alert (counter);
x += dx;
y += dy;
}, 1);