Creating a click event in Javascript Canvas - javascript

I'm having trouble creating a click event for my Javascript canvas game. So far I have been following a tutorial, however the way you interact with the game is through mouse hover. I would like to change it so that instead of hovering over objects in the canvas to interact, I instead use a mouse click.
The following is the code I use to detect the mouse hover.
getDistanceBetweenEntity = function (entity1,entity2) //return distance
{
var vx = entity1.x - entity2.x;
var vy = entity1.y - entity2.y;
return Math.sqrt(vx*vx+vy*vy);
}
testCollisionEntity = function (entity1,entity2) //return if colliding
{
var distance = getDistanceBetweenEntity(entity1,entity2);
return distance < 50;
}
I then use this in a loop to interact with it.
var isColliding = testCollisionEntity(player,nounList[key]);
if(isColliding)
{
delete nounList[key];
player.score = player.score + 10;
}
Below is a complete copy of my game at its current state.
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
<script>
var ctx = document.getElementById("ctx").getContext("2d");
ctx.font = '30px Arial';
//Setting the height of my canvas
var HEIGHT = 500;
var WIDTH = 500;
//Player class
var player =
{
x:50,
spdX:30,
y:40,
spdY:5,
name:'P',
score:0,
};
//Creating arrays
var nounList ={};
var adjectivesList ={};
var verbsList ={};
getDistanceBetweenEntity = function (entity1,entity2) //return distance
{
var vx = entity1.x - entity2.x;
var vy = entity1.y - entity2.y;
return Math.sqrt(vx*vx+vy*vy);
}
testCollisionEntity = function (entity1,entity2) //return if colliding
{
var distance = getDistanceBetweenEntity(entity1,entity2);
return distance < 50;
}
Nouns = function (id,x,y,name)
{
var noun =
{
x:x,
y:y,
name:name,
id:id,
};
nounList[id] = noun;
}
Adjectives = function (id,x,y,name)
{
var adjective =
{
x:x,
y:y,
name:name,
id:id,
};
adjectivesList[id] = adjective;
}
Verbs = function (id,x,y,name)
{
var verb =
{
x:x,
y:y,
name:name,
id:id,
};
verbsList[id] = verb;
}
document.onmousemove = function(mouse)
{
var mouseX = mouse.clientX;
var mouseY = mouse.clientY;
player.x = mouseX;
player.y = mouseY;
}
updateEntity = function (something)
{
updateEntityPosition(something);
drawEntity(something);
}
updateEntityPosition = function(something)
{
}
drawEntity = function(something)
{
ctx.fillText(something.name,something.x,something.y);
}
update = function ()
{
ctx.clearRect(0,0,WIDTH,HEIGHT);
drawEntity(player);
ctx.fillText("Score: " + player.score,0,30);
for(var key in nounList)
{
updateEntity(nounList[key]);
var isColliding = testCollisionEntity(player,nounList[key]);
if(isColliding)
{
delete nounList[key];
player.score = player.score + 10;
}
}
for(var key in adjectivesList)
{
updateEntity(adjectivesList[key])
var isColliding = testCollisionEntity(player,adjectivesList[key]);
if(isColliding)
{
delete adjectivesList[key];
player.score = player.score - 1;
}
}
for(var key in verbsList)
{
updateEntity(verbsList[key])
var isColliding = testCollisionEntity(player,verbsList[key]);
if(isColliding)
{
delete verbsList[key];
player.score = player.score - 1;
}
}
if(player.score >= 46)
{
ctx.clearRect(0,0,WIDTH,HEIGHT);
ctx.fillText("Congratulations! You win!",50,250);
ctx.fillText("Refresh the page to play again.",50,300);
}
}
Nouns('N1',150,350,'Tea');
Nouns('N2',400,450,'Park');
Nouns('N3',250,150,'Knee');
Nouns('N4',50,450,'Wall');
Nouns('N5',410,50,'Hand');
Adjectives('A1',50,100,'Broken');
Adjectives('A2',410,300,'Noisy');
Verbs('V1',50,250,'Smell');
Verbs('V2',410,200,'Walk');
setInterval(update,40);
To summarize all I want to do is change it so that instead of mousing over words to delete them you have to click.
(Apologies for not using correct terminology in places, my programming knowledge is quite limited.)

You can have your canvas listen for mouse clicks on itself like this:
// get a reference to the canvas element
var canvas=document.getElementById('ctx');
// tell canvas to listen for clicks and call "handleMouseClick"
canvas.onclick=handleMouseClick;
In the click handler, you'll need to know the position of your canvas relative to the viewport. That's because the browser always reports mouse coordinates relative to the viewport. You can get the canvas position relative to the viewport like this:
// get the bounding box of the canvas
var BB=canvas.getBoundingClientRect();
// get the left X position of the canvas relative to the viewport
var BBoffsetX=BB.left;
// get the top Y position of the canvas relative to the viewport
var BBoffsetY=BB.top;
So your mouseClickHandler might look like this:
// this function will be called when the user clicks
// the mouse in the canvas
function handleMouseClick(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// get the canvas postion relative to the viewport
var BB=canvas.getBoundingClientRect();
var BBoffsetX=BB.left;
var BBoffsetY=BB.top;
// calculate the mouse position
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// report the mouse position using the h4
$position.innerHTML='Click at '+parseInt(mouseX)+' / '+parseInt(mouseY);
}
If your game doesn't let the window scroll or resize then the canvas postion won't change relative to the viewport. Then, for better performance, you can move the 3 lines relating to getting the canvas position relative to the viewport to the top of your app.
// If the browser window won't be scrolled or resized then
// get the canvas postion relative to the viewport
// once at the top of your app
var BB=canvas.getBoundingClientRect();
var BBoffsetX=BB.left;
var BBoffsetY=BB.top;
function handleMouseClick(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// calculate the mouse position
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// report the mouse position using the h4
$position.innerHTML='Click at '+parseInt(mouseX)+' / '+parseInt(mouseY);
}

Related

move mouse but only on the width of the div

I just adapted this code to play a sequence of images when you move the mouse on the x axis. I have two questions about this code:
I can't adapt the length to the width of the div, not to the width of the whole window.
There are "flashes" when I move the mouse, I have the impression that it comes from the loading of the images?
Thanks for your help.
Live: https://codepen.io/nicolastilly/pen/jOBKxKK
Code:
var blocWidth;
var imgblock = ['https://assets.codepen.io/265602/frame0.png',
'https://assets.codepen.io/265602/frame1.png',
'https://assets.codepen.io/265602/frame2.png',
'https://assets.codepen.io/265602/frame3.png',
'https://assets.codepen.io/265602/frame4.png',
'https://assets.codepen.io/265602/frame5.png',
'https://assets.codepen.io/265602/frame6.png',
'https://assets.codepen.io/265602/frame7.png',
'https://assets.codepen.io/265602/frame8.png',
'https://assets.codepen.io/265602/frame9.png',
'https://assets.codepen.io/265602/frame10.png',
'https://assets.codepen.io/265602/frame11.png',
'https://assets.codepen.io/265602/frame12.png',
'https://assets.codepen.io/265602/frame13.png',
'https://assets.codepen.io/265602/frame14.png',
'https://assets.codepen.io/265602/frame15.png',
'https://assets.codepen.io/265602/frame16.png',
'https://assets.codepen.io/265602/frame17.png',
'https://assets.codepen.io/265602/frame18.png',
'https://assets.codepen.io/265602/frame19.png',
'https://assets.codepen.io/265602/frame20.png'];
function onMouseMove(e) {
var x = e.pageX;
var theimg = imgblock[parseInt(x / blocWidth * imgblock.length)];
$('.bloc1').css("background-image", "url('" + theimg + "')");
}
function onResize() {
blocWidth = $('.bloc1').width();
}
function onResize() {
blocWidth = $(document).width();
}
$(window).on('mousemove', onMouseMove);
$(window).resize(onResize);
onResize();
As for flickering, you can circumvent that by preloading the images
let loaded = 0 ;
imgblock.forEach(url => {
let img=new Image();
img.src=url;
img.onload = onImgLoaded
})
function onImgLoaded() {
loaded++;
if (loaded == imgblock.length-1) console.log('all images have pre-loaded');
}
As for the sizing issue, you need to take into account if you're mousing over the target and accounting for the div's left value in your calculations. Get rid of both these:
function onResize() {
blocWidth = $('.bloc1').width();
}
function onResize() {
blocWidth = $(document).width();
}
replace with:
let blocStartX;
function onResize() {
let pos = $(".bloc1")[0].getBoundingClientRect()
console.log(pos)
blocWidth = pos.width;
blocStartX = pos.x
}
Detect the mouseover:
let isOnDiv = false
$(".bloc1").mouseenter(function(){isOnDiv=true;});
$(".bloc1").mouseleave(function(){isOnDiv=false;});
and add this to the top of your mousemove function:
if (!isOnDiv) return
var x = e.pageX - blocStartX;
https://codepen.io/john-tyner/pen/wvJXXQZ

How can i determine in which box i clicked?

First off i'm new to javascript and still learning its basics, i'm trying to determine in which box i clicked(canvas).
My boxes are a list of dictionaries that look like this if we use console.log to visualize them, let's call that list labels:
[
{"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141"},
{"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141"},
{"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145"},
{"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145"}
]
Here we can see we have 4 rectangles and their coordinates.
The function i used to get mouse clicks is :
canvas.addEventListener("contextmenu", getPosition, false);
function getPosition(event) {
event.preventDefault();
var x = event.x;
var y = event.y;
var canvas = document.getElementById("canvas");
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
console.log("x:" + x + " y:" + y);
}
The part where i'm struggling is to find out if where i clicked are inside any of the boxes and if the click is inside one i want the id.
What i tried:
I tried adding this after the console.log in the previous code snippet:
for (i = 0,i < labels.length; i++) {
if (x>labels[i].xMin) and (x<labels[i].xMax) and (y>labels[i].yMin) and (y<labels[i].yMax) {
log.console(labels[i].id)
}
}
but it didn't work
The rects in Labels are all very far to the right, so probably you need to add the scroll position to the mouse position.
Made a working example (open the console to see the result):
https://jsfiddle.net/dgw0sxu5/
<html>
<head>
<style>
body{
background: #000;
margin: 0
}
</style>
<script>
//Some object which is used to return an id from a click
//Added a fillStyle property for testing purposes
var Labels = [
{"id":"0","image":"1-0.png","name":"","xMax":"4956","xMin":"0","yMax":"50","yMin":"0","fillStyle":"pink"},
{"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141","fillStyle":"red"},
{"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141","fillStyle":"blue"},
{"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145","fillStyle":"limegreen"},
{"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145","fillStyle":"aqua"}
];
//Initialisiing for the testcase
window.onload = function(){
//The canvas used for click events
var tCanvas = document.body.appendChild(document.createElement('canvas'));
tCanvas.width = 4956; //Highest xMax value from labels
tCanvas.height = 157; //Highest yMax value from labels
//The graphical object
var tCTX = tCanvas.getContext('2d');
//Drawing the background
tCTX.fillStyle = '#fff';
tCTX.fillRect(0, 0, tCanvas.width, tCanvas.height);
//Drawing the rects for testing purposes
//The rectangles are kinda far on the right side
for(var i=0, j=Labels.length; i<j; i++){
tCTX.fillStyle = Labels[i].fillStyle;
tCTX.fillRect(+(Labels[i].xMin), +(Labels[i].yMin), +(Labels[i].xMax)-+(Labels[i].xMin), +(Labels[i].yMax)-+(Labels[i].yMin));
};
tCanvas.onclick = function(event){
var tX = event.clientX - this.offsetLeft + (document.body.scrollLeft || document.documentElement.scrollLeft), //X-Position of click in canvas
tY = event.clientY - this.offsetTop + (document.body.scrollTop || document.documentElement.scrollTop), //Y-Position of click in canvas
tR = []; //All found id at that position (can be more in theory)
//Finding the Labels fitting the click to their bounds
for(var i=0, j=Labels.length; i<j; i++){
if(tX >= +(Labels[i].xMin) && tX <= +(Labels[i].xMax) && tY >= +(Labels[i].yMin) && +(tY) <= +(Labels[i].yMax)){
tR.push(Labels[i].id)
}
};
console.log(
'Following ids found at the position #x. #y.: '
.replace('#x.', tX)
.replace('#y.', tY),
tR.join(', ')
)
}
}
</script>
</head>
<body></body>
</html>
First of all: what exactly did not work?
var canvas = document.getElementById("canvas"); should be outside of your function to save performance at a second call.
And getting coordinates is not complicated, but complex.
There is a great resource on how to get the right ones: http://javascript.info/coordinates
Be sure about the offset measured relative to the parent element (offsetParent and also your offsetLeft), document upper left (pageX) or viewport upper left (clientX).
Your logic seems to be correct, you just need to fix the syntax.
for (i = 0; i < labels.length; i++) {
if ((x>labels[i].xMin) && (x<labels[i].xMax) && (y>labels[i].yMin) && (y<labels[i].yMax)) {
console.log(labels[i].id)
}
}
Here is a complete example:
labels = [
{"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141"},
{"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141"},
{"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145"},
{"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145"}
]
var canvas = document.getElementById("canvas");
canvas.addEventListener("contextmenu", getPosition, false);
function getPosition(event) {
event.preventDefault();
var x = event.clientX;
var y = event.clientY;
var label = labels.find(function(label){
return (x>label.xMin) && (x<label.xMax) && (y>label.yMin) && (y<label.yMax)
});
if(label){
console.log("clicked label", label.id);
}else{
console.log("no label was clicked");
}
}

Javascript - "print" mouse on document by cords

I have list of mouse cords (x,y)
Because it is impossible to move mouse with javascript, I would like to print a fake mouse on the document followed by the cords that I already have.
Is it possible? How?
My solution was to print PNG that shows the mouse and hide the original one with css:
createCursor: function() {
var cursor = document.createElement("img");
cursor.src = chrome.extension.getURL('pics/cursor.png');
cursor.style.zIndex = "9999";
cursor.setAttribute("id", "recordMeCursor");
var body = document.getElementsByTagName("BODY")[0];
body.style.cursor = 'none';
body.appendChild(cursor);
},
moveCursor: function(cords, i, callback) {
var cursor = document.getElementById("recordMeCursor");
setTimeout(function() {
cursor.style.position = "absolute";
cursor.style.left = cords.x+'px';
cursor.style.top =cords.y+'px';
return callback('OK');
}, i * 50);
},
destroyMouse: function() {
var cursor = document.getElementById("recordMeCursor");
cursor.parentNode.removeChild(cursor);
var body = document.getElementsByTagName("BODY")[0];
body.style.cursor = 'default';
}

Popover overlay in OpenLayers 3 does not extend beyond view

In the OpenLayers overlay example:
http://openlayers.org/en/v3.11.2/examples/overlay.html
If you click near the top of map most of the overlay is hidden. Is there a CSS trick, or an OpenLayers setting (I do not want to use the autoPan, which doesn't seem to work for popovers anyway), that will enable the entire popover to be shown even if it extends beyond the map view?
Here's a screenshot that illustrates the problem.
autoPan does work for popups, see here: http://openlayers.org/en/v3.11.2/examples/popup.html
However, I also had some trouble with autoPan so I didi it like this (Fiddle demo):
// move map if popop sticks out of map area:
var extent = map.getView().calculateExtent(map.getSize());
var center = map.getView().getCenter();
var pixelPosition = map.getPixelFromCoordinate([ coordinate[0], coordinate[1] ]);
var mapWidth = $("#map").width();
var mapHeight = $("#map").height();
var popoverHeight = $("#popup").height();
var popoverWidth = $("#popup").width();
var thresholdTop = popoverHeight+50;
var thresholdBottom = mapHeight;
var thresholdLeft = popoverWidth/2-80;
var thresholdRight = mapWidth-popoverWidth/2-130;
if(pixelPosition[0] < thresholdLeft || pixelPosition[0] > thresholdRight || pixelPosition[1]<thresholdTop || pixelPosition[1]>thresholdBottom) {
if(pixelPosition[0] < thresholdLeft) {
var newX = pixelPosition[0]+(thresholdLeft-pixelPosition[0]);
} else if(pixelPosition[0] > thresholdRight) {
var newX = pixelPosition[0]-(pixelPosition[0]-thresholdRight);
} else {
var newX = pixelPosition[0];
}
if(pixelPosition[1]<thresholdTop) {
var newY = pixelPosition[1]+(thresholdTop-pixelPosition[1]);
} else if(pixelPosition[1]>thresholdBottom) {
var newY = pixelPosition[1]-(pixelPosition[1]-thresholdBottom);
} else {
var newY = pixelPosition[1];
}
newCoordinate = map.getCoordinateFromPixel([newX, newY]);
newCenter = [(center[0]-(newCoordinate[0]-coordinate[0])), (center[1]-(newCoordinate[1]-coordinate[1])) ]
map.getView().setCenter(newCenter);
}
I added this code to the Popover Official Example in this fiddle demo:
// get DOM element generated by Bootstrap
var bs_element = document.getElementById(element.getAttribute('aria-describedby'));
var offset_height = 10;
// get computed popup height and add some offset
var popup_height = bs_element.offsetHeight + offset_height;
var clicked_pixel = evt.pixel;
// how much space (height) left between clicked pixel and top
var height_left = clicked_pixel[1] - popup_height;
var view = map.getView();
// get the actual center
var center = view.getCenter();
if (height_left < 0) {
var center_px = map.getPixelFromCoordinate(center);
var new_center_px = [
center_px[0],
center_px[1] + height_left
];
map.beforeRender(ol.animation.pan({
source: center,
start: Date.now(),
duration: 300
}));
view.setCenter(map.getCoordinateFromPixel(new_center_px));
}
To make the popup always appear inside the map view, I reversed the ol3 autopan function
So that it the popup is offset from the feature towards the view, instead of panning the view.
I am not sure why so many ol3 fiddles are not loading the map anymore.
http://jsfiddle.net/bunjil/L6rztwj8/48/
var getOverlayOffsets = function(mapInstance, overlay) {
const overlayRect = overlay.getElement().getBoundingClientRect();
const mapRect = mapInstance.getTargetElement().getBoundingClientRect();
const margin = 15;
// if (!ol.extent.containsExtent(mapRect, overlayRect)) //could use, but need to convert rect to extent
const offsetLeft = overlayRect.left - mapRect.left;
const offsetRight = mapRect.right - overlayRect.right;
const offsetTop = overlayRect.top - mapRect.top;
const offsetBottom = mapRect.bottom - overlayRect.bottom;
console.log('offsets', offsetLeft, offsetRight, offsetTop, offsetBottom);
const delta = [0, 0];
if (offsetLeft < 0) {
// move overlay to the right
delta[0] = margin - offsetLeft;
} else if (offsetRight < 0) {
// move overlay to the left
delta[0] = -(Math.abs(offsetRight) + margin);
}
if (offsetTop < 0) {
// will change the positioning instead of the offset to move overlay down.
delta[1] = margin - offsetTop;
} else if (offsetBottom < 0) {
// move overlay up - never happens if bottome-center is default.
delta[1] = -(Math.abs(offsetBottom) + margin);
}
return (delta);
};
/**
* Add a click handler to the map to render the popup.
*/
map.on('click', function(evt) {
var coordinate = evt.coordinate;
var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(
coordinate, 'EPSG:3857', 'EPSG:4326'));
content.innerHTML = '<p>You clicked here:</p><code>' + hdms +
'</code>';
//overlay.setPosition(coordinate);
overlay.setOffset([0, 0]); // restore default
overlay.setPositioning('bottom-right'); // restore default
//overlay.set('autopan', true, false); //only need to do once.
overlay.setPosition(coordinate);
const delta = getOverlayOffsets(map, overlay);
if (delta[1] > 0) {
overlay.setPositioning('bottom-center');
}
overlay.setOffset(delta);
})
In this fiddle, the setPositioning() isn't working, so when you click near the top, the popup is under your mouse - it would be better to setPositioning('bottom-center');
automove would be a good feature to complement autopan.
In case of popover where "autoPan" option is not available you have to check extent's limits (top/bottom/right - left is skipped since popover is spawned on the center right of feature). So extending previous answer of Jonatas Walker a bit:
var bs_element = $('.popover');
var popup_height = bs_element.height();
var popup_width = bs_element.width();
var clicked_pixel = evt.pixel;
var view = map.getView();
var center = view.getCenter();
var height_left = clicked_pixel[1] - popup_height / 2; // from top
var height_left2 = clicked_pixel[1] + popup_height / 2; // from bottom
var width_left = clicked_pixel[0] + popup_width; // from right
var center_px = map.getPixelFromCoordinate(center);
var new_center_px = center_px;
var needs_recenter = false;
if (height_left2 > $("#map").height()) {
new_center_px[1] = height_left2 - center_px[1] + 30;
needs_recenter = true;
}
else if (height_left < 0) {
new_center_px[1] = center_px[1] + height_left;
needs_recenter = true;
}
if (width_left > $("#map").width()) {
new_center_px[0] = width_left - center_px[0] + 30;
needs_recenter = true;
}
if (needs_recenter)
view.setCenter(map.getCoordinateFromPixel(new_center_px));

Draw on click or touch event

im learnig javascript and try to develop a page to draw on. Change colors and linewidth are already in place. Now it is drawing, but just when I move the mouse. I'd like to add also on click on just on move. So I'm able to draw also points. I have put the drawCircle function in the function stopDraw, but this is not working as it should. Any ideas?
Second problem is that, I'd like to draw a circle without stroke. But as soon as I change the lineWidth, also my circle gets a stroke around. Please help...
// Setup event handlers
cb_canvas = document.getElementById("cbook");
cb_lastPoints = Array();
if (cb_canvas.getContext) {
cb_ctx = cb_canvas.getContext('2d');
cb_ctx.lineWidth = 14;
cb_ctx.strokeStyle = "#0052f8";
cb_ctx.lineJoin="round";
cb_ctx.lineCap="round"
cb_ctx.beginPath();
cb_canvas.onmousedown = startDraw;
cb_canvas.onmouseup = stopDraw;
cb_canvas.ontouchstart = startDraw;
cb_canvas.ontouchend = stopDraw;
cb_canvas.ontouchmove = drawMouse;
}
function startDraw(e) {
if (e.touches) {
// Touch event
for (var i = 1; i <= e.touches.length; i++) {
cb_lastPoints[i] = getCoords(e.touches[i - 1]); // Get info for finger #1
}
}
else {
// Mouse event
cb_lastPoints[0] = getCoords(e);
cb_canvas.onmousemove = drawMouse;
}
return false;
}
// Called whenever cursor position changes after drawing has started
function stopDraw(e) {
drawCircle(e);
e.preventDefault();
cb_canvas.onmousemove = null;
}
//Draw circle
function drawCircle(e) {
var canvasOffset = canvas.offset();
var canvasX = Math.floor(e.pageX-canvasOffset.left);
var canvasY = Math.floor(e.pageY-canvasOffset.top);
//var canvasPos = getCoords(e);
cb_ctx.beginPath();
cb_ctx.arc(canvasX, canvasY, cb_ctx.lineWidth/2, 0, Math.PI*2, true);
cb_ctx.fillStyle = cb_ctx.strokeStyle;
cb_ctx.fill();
}
function drawMouse(e) {
cb_ctx.beginPath();
if (e.touches) {
// Touch Enabled
for (var i = 1; i <= e.touches.length; i++) {
var p = getCoords(e.touches[i - 1]); // Get info for finger i
cb_lastPoints[i] = drawLine(cb_lastPoints[i].x, cb_lastPoints[i].y, p.x, p.y);
}
}
else {
// Not touch enabled
var p = getCoords(e);
cb_lastPoints[0] = drawLine(cb_lastPoints[0].x, cb_lastPoints[0].y, p.x, p.y);
}
cb_ctx.stroke();
cb_ctx.closePath();
//cb_ctx.beginPath();
return false;
}
// Draw a line on the canvas from (s)tart to (e)nd
function drawLine(sX, sY, eX, eY) {
cb_ctx.moveTo(sX, sY);
cb_ctx.lineTo(eX, eY);
return { x: eX, y: eY };
}
// Get the coordinates for a mouse or touch event
function getCoords(e) {
if (e.offsetX) {
return { x: e.offsetX, y: e.offsetY };
}
else if (e.layerX) {
return { x: e.layerX, y: e.layerY };
}
else {
return { x: e.pageX - cb_canvas.offsetLeft, y: e.pageY - cb_canvas.offsetTop };
}
}
Your drawCircle function is wrapped in the canvas's onclick event. It should be
function drawCircle(e) {
var canvasOffset = canvas.offset();
var canvasX = Math.floor(e.pageX-canvasOffset.left);
var canvasY = Math.floor(e.pageY-canvasOffset.top);
cb_ctx.beginPath();
cb_ctx.lineWidth = 0;
cb_ctx.arc(canvasX,canvasY,cb_ctx.lineWidth/2,0,Math.PI*2,true);
cb_ctx.fillStyle = cb_ctx.strokeStyle;
cb_ctx.fill();
}
So you'll have to pass the event object from stop draw as well
function stopDraw(e) {
drawCircle(e); //notice the change here
e.preventDefault();
cb_canvas.onmousemove = null;
}
Note that you're also setting you circle's radius to 0 which might be another reason why it's not showing up.
cb_ctx.lineWidth = 0;
cb_ctx.arc(canvasX,canvasY,cb_ctx.lineWidth/2,0,Math.PI*2,true);
0 divided by 2 is always zero. If you don't want to stroke around the circle just don't call stroke(). the drawCircle function isn't causing that, since there's a beginPath() call. I suspect it's because you don't beginPath() before calling stroke() in drawMouse.

Categories