How can I draw with mouse on html canvas? - javascript

I have two problems: how can I draw rectangles with mouse o html canvas, and why isn't my timer showing up.
I have tried every code in here but nothing seems to work. Thank you!
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas Resize</title>
<style>
canvas {
border: 1px solid black;
}
body {
margin: 0px;
}
</style>
</head>
<body>
<canvas></canvas>
<p id="timer"></p>
<script src="canvas.js"></script>
</body>
</html>
JAVASCRIPT
var canvas = document.querySelector('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var c = canvas.getContext('2d');
//TIMER
var timer = document.getElementById('timer');
var counter = 0;
function setup(){
timer = createP('timer');
setInterval(timeIt, 1);
}
function timeIt (){
timer.html(counter);
counter+=134;
}
Here's the fiddle
https://jsfiddle.net/rita24/0vLwj3go/2/
Thank you!

For the canvas part, you can just add the event listener to keep track on the mouseup, mousemove and mousedown event.
canvas.addEventListener("mousedown", function (e) {
drawing = true;
lastPos = getMousePos(canvas, e);
}, false);
canvas.addEventListener("mouseup", function (e) {
drawing = false;
}, false);
canvas.addEventListener("mousemove", function (e) {
mousePos = getMousePos(canvas, e);
}, false);
// Get the position of the mouse relative to the canvas
function getMousePos(canvasDom, mouseEvent) {
var rect = canvasDom.getBoundingClientRect();
return {
x: mouseEvent.clientX - rect.left,
y: mouseEvent.clientY - rect.top
};
}
This will help you create the rectangle on canvas.
ctx.rect(mousePos.x,mousePos.y,lastPos.x-mousePos.x,lastPos.y-mousePos.y);
ctx.stroke();
You can check this out on how to work with mouse drawing on the canvas: http://bencentra.com/code/2014/12/05/html5-canvas-touch-events.html
For the timer part, you haven't called the setup() function and you are using jQuery html() function to setup the text inside the p element. Use .innerHTML to change the text inside the p element.
Here is the updated link for your JSfiddle: https://jsfiddle.net/0vLwj3go/7/
Hope this can help!

Elvis' answer is great, but since I had already started mine this morning, I'll post it anyway.
For one thing, you aren't calling setup() anywhere, so the timer never gets set and the timer <p> never gets any content. Here's my jsfiddle, which is very similar to Elvis', but shows the timer without scrolling, and includes an example of how to animate the drawing of rectangles.

Related

Javascript / HTML adding an image to center position on the mouse click

I want to print out a picture whenever the mouse is clicked on the screen.
This is my current Javascript and HTML code. It only prints the h1, I don't know what I am doing wrong.
var image = document.getElementById("im"); // idenfitifes span eleme nt
var roll = false; // to know the image is moving or not , intitally it is not moving state hence value is false
image.addEventListener("mousedown", start, false); // at starting image is in rest
function mouse_move(x) // funciton to move image with mouse
{
var newX = x.clientX; // copies mouse x position
var newY = x.clientY; // copies mouse y position
image.style.left = newY + "px"; // assigns latest mouse position to span (image)
image.style.top = newX + "px";
}
function start(x) // span (image) starting no rolling mode
{
if(roll){ // when the mouse is moving
document.removeEventListener("mousemove", mouse_move); // initiages image span move
roll = !roll;
return;
}
roll = !roll; // when the mouse is not moving
document.addEventListener("mousemove", mouse_move, false);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title> Picture of Me! </title>
</head>
<body>
<h1> HTML File to move image along with mouse movement. </h1>
<script type="text/javascript" src="h5j.js">
<span id="im">
<img src="https://static01.nyt.com/images/2020/04/27/us/politics/00-trump-cand-page/00-trump-cand-page-mediumSquareAt3X.jpg" height="120" width="120"></img>
</span>
</body>
</html>
You Use The AddEventListener Function Like This
document.addEventListener("mousedown", mouse_move, false);
the syntax for addEventListener is:
addEventListener("Event Name", "Your Function name, the function you want to run after event happening")
when you need to run in the click event, you simply need to change Event name from "mousedown" to "click" , example:
document.addEventListener("click", mouse_move, false);
you have to use "click" event instead of "mousedown"
like:
document.addEventListener("click", mouse_move, false);
<code>
var image = document.getElementById("im");
var roll = false;
image.addEventListener("click", start, false);
function mouse_move(x)
{
var newX = x.clientX; // copies mouse x position
var newY = x.clientY; // copies mouse y position
image.style.left = newX + "px";
image.style.top = newY+ "px";
}
function start(x) // span (image) starting no rolling mode
{
if (roll) { // when the mouse is moving
document.removeEventListener("click", mouse_move); // initiages image span move
roll = !roll;
return;
}
roll = !roll; // when the mouse is not moving
}
document.addEventListener("click", mouse_move, false);
</code>
It looks like your trying to get the image element by id, before the DOM has finished loading.
I would suggest one of the following:
Move the <script> tag to the bottom of the page between </body> and </html>
Add defer to the <script> tag, which will cause the script to be loaded after the DOM.
Move the first block of your JavaScript into a DOMContentLoaded event listener as shown below.
var roll = false;
var image;
document.addEventListener('DOMContentLoaded', function(){
image = document.getElementById("im");
image.addEventListener("mousedown", start, false);
});

Object under cursor not found

I tried three different approaches but none worked.
I place two rectangles on the canvas and want to catch the object under the mouse cursor when a mousedown event occurred.
The stagemousedown works, but the objects are not found. Watching the debugger I see that the rectangle has still the drawrect coordinates, not the one that I set later. There is also a 'hitarea' which I don't know how to use since it is checked during hittest and getObjectUnderPoint.
Approach 1: makeButton creates a handler on lines 66ff -> it never fires
Approach 2: getObjectUnderPoint when a mousedown evt happens. -> returns always null
Approach 3: loop through each child and apply the hitttest -> returns always false.
I come from Java and C# and am far from being experienced in JS, but I had hoped that I could catch the mousedown with at least one approach.
What makes me wonder is that the x and y in the rectangle never change from the ones used during creation (0,0). That's not the current position which I set for example in 73 and 74!
I don't seem to find the REAL x and y of the object and neither does approaches 2 and 3. I wished, approach 1 would work since that makes the most sense to me.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="./css/style.css">
<meta charset="utf-8" />
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/EaselJS/1.0.2/easeljs.js"></script>
<script>
function init() {
var followme = 0;
var canvas = document.getElementById("canvas");
var stage=new createjs.Stage(canvas);
var shape=new createjs.Shape();
var dispO = new createjs.Shape();
makeBtn(3,3);
makeBtn(300,300);
stage.on("stagemousedown", function (evt) {
followme = 1;
found=stage.getObjectUnderPoint(stage.mouseX, stage.mouseY,0)
if(found != null)
{
console.log(found);
}
var xxx=stage.children;
for (i=0; i<xxx.length;i++)
{
if (xxx[i].hitTest(stage.mouseX, stage.mouseY))
{
shape.alpha=1;
}
}
});
stage.on("stagemouseup", function (evt) {
followme = 0;
});
stage.update();
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", handleTick);
function handleTick(event)
{
if ((followme === 1) && (dispO != null))
{
var difX = stage.mouseX - dispO.x - 100;
var difY = stage.mouseY - dispO.y - 50;
dispO.x += difX / 20;
dispO.y += difY / 20;
stage.update();
}
else
if(dispO != null)
{
var dmy=dispO;
}
}
function makeBtn(x,y)
{
shape = new createjs.Shape();
shape.graphics.beginStroke("black").setStrokeStyle(2, 0, 1).drawRect(0, 0, 200, 100);
dispO=shape;
dispO.mouseEventsEnabled = true;
var handler=dispO.on("mousedown",
function(event) {console.log(instance == this); },// true, "on" uses dispatcher scope by default.
null,
once=true,
'theButton',
useCapture=true
);
dispO.x=x;
dispO.y=y;
stage.addChild(dispO);
}
}
</script>
</head>
<body onload="init();">
<div id="outer">
<canvas id="canvas" width="500" height="600">
</canvas>
<menu id="controls">
</menu>
</div>
</body>
</html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/EaselJS/1.0.2/easeljs.js"></script>
Your demo works fine -- its just that your square has no fill, so only the border is clickable. If you add a fill, then it works great:
https://jsfiddle.net/lannymcnie/ozcr6tna/
shape.graphics.beginStroke("black")
.setStrokeStyle(2, 0, 1)
.beginFill("white") // <----- Fill call
.drawRect(0, 0, 200, 100);
If you want the clickable area to be transparent, then you can use a hitArea. Just assign a different shape with a fill as a hitArea (and don't add that shape to the stage). Hit testing in EaselJS uses pixel fill - so if there are no pixels, then there is no hit!
Hope that helps!

How to use player own-made sprite as in-game sprite

I am seeking for a way that allows players to draw their own characters and later to be able to play with them in-game. To make the concept very simple lets make the drawn player just a 2d shape or a group of lines and circles or even a mix of both. I think this can be decomposed in these steps:
An empty canvas is made for the user to create what he wants:
By painting or something of that genre
By using a specific polygon creation interface that allows dragging and molding shapes;
Note: I was able to create a way to paint on canvas *** but I didn't find a way to let user drag and create shapes or something of that kind. I would more likely opt for the second option so some suggestions on how do this would be really appreciated.
window.onload = init;
function init() {
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var painting = document.getElementById('paint');
var paint_style = getComputedStyle(painting);
canvas.width = "1024"
canvas.height = "1024";
var mouse = {
x: 0,
y: 0
};
canvas.addEventListener('mousemove', function(e) {
mouse.x = e.pageX - this.offsetLeft;
mouse.y = e.pageY - this.offsetTop;
}, false);
ctx.lineWidth = 3;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = '#00CC99';
canvas.addEventListener('mousedown', function(e) {
ctx.beginPath();
ctx.moveTo(mouse.x, mouse.y);
canvas.addEventListener('mousemove', onPaint, false);
}, false);
canvas.addEventListener('mouseup', function() {
canvas.removeEventListener('mousemove', onPaint, false);
}, false);
var onPaint = function() {
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();
};
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tojo - canvas draw</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<script src="app.js"></script>
<div id="paint"></div>
<canvas id="myCanvas" style="border: 3px solid black;"></canvas>
</body>
</html>
(paint on canvas snippet) ***
Somehow, I need to only get the user drawn / shaped creation from all the canvas. There should be a way to "surround" what the user has created and then save it:
By (in the drawing case probably) checking only for the color comparison between the white and the player color;
By, somehow, defining different points that all together would countain the user creation (either drawn or shaped);
Note: In this case I am kind of lost. I have almost no clue of how this could be made. However, I have heard of box2d but I think it was more focused in C or something of that kind? Would it work and how could I do it?
I would finally have the user creation stored and ready to load it in game as an image of a sprite.
I hope I could explain it all correctly. Can someone give me some orientation on this? FYI I am using Phaser.js as js game engine. (sorry for any mistakes, I am not very experienced with this matters).
Hopefully this will get you headed in the right direction:
Instead of drawing to the canvas, create a Phaser bitmapData object and have the user draw to that object. See this example that shows how to draw to a bitmapData object.
If you follow #1, then all of the data that you want will be stored in the bitmapData object, and you can create a Sprite directly from your bitmapData object, e.g.:
// Create a bitmapData object for the user to draw on
var bmd = this.game.make.bitmapData(64, 64);
// code to draw on `bmd` goes here
// Create a Sprite based on the bitmapData from above
var userSprite = this.game.add.sprite(0, 0, bmd);

Javascript Onclick Functions

Writing a simple script to have two buttons. One button animates a "painting" feature where rectangles follow the cursor around the canvas. The other button would display a rectangle that follows the canvas but doesn't leave a trail like the other. I have the buttons linked to do different functions. Right now the follow button doesn't work, it does clear the canvas but it still allows you to paint. It seems that the paint function is still running after I hit the follow button. Any help is appreciated.
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Canvas</title>
</head>
<body>
<input type="button" value="Paint" onclick="isPaint()">
<input type="button" value="Follow" onclick="isFollow()">
<canvas id="myCanvas" width="500" height="500"></canvas>
<script>
function isPaint(){
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
//change draw color
ctx.fillStyle = "#FF0000";
ctx.clearRect(0,0,500,500);
canvas.addEventListener("mousemove", function(event) {
ctx.fillRect(event.x,event.y,10,10);
})
}
function isFollow(){
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
//change draw color
ctx.fillStyle = "#FF0000";
ctx.clearRect(0,0,500,500);
}
</script>
</body>
</html>
Work for me : http://jsfiddle.net/XF7m4/1/
Using document.getElementById("paint").onclick= function (){
PS :And think to remove the mousemouse listener ;)
To achieve what you are trying to do you will need to enhance your code a little more.
The main idea is to bind the mousemove event only once and clear the canvas if it is to behave like a follow.
Try using the following code:
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Canvas</title>
</head>
<body>
<input type="button" value="Paint" onclick="CanvasPainter.paint()" />
<input type="button" value="Follow" onclick="CanvasPainter.follow()" />
<canvas id="myCanvas" width="500" height="500"></canvas>
<script type="text/javascript">
(function () {
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
//change draw color
ctx.fillStyle = "#FF0000";
var CanvasPainter = {
isPaint: false,
isFollow: false,
paint: function () {
this.isPaint = true;
this.isFollow = false;
return;
},
follow: function () {
this.isPaint = false;
this.isFollow = true;
return;
}
};
window.CanvasPainter = CanvasPainter;
canvas.addEventListener("mousemove", function (event) {
if (CanvasPainter.isPaint || CanvasPainter.isFollow) {
if (CanvasPainter.isFollow) {
// Clear canvas on every mousemove if it is a follow
ctx.clearRect(0, 0, 500, 500);
}
ctx.fillRect(event.x, event.y, 10, 10);
}
return;
});
return;
})();
</script>
</body>
</html>
Hope this helps!
Your isPaint() function is adding an event listener for "mousemove" to the canvas, but it isn't getting removed in the isFollow() function. If you remove your listener in the isFollow() function this should fix your problem.

Why does a specific method have to be located at a specific location inside of JavaScript and cannot be moved around?

My question is why does drawScreen have to be located where it is and cannot be moved outside of the method. It is like a method inside a method. I think that this is where I am still weak on JavaScript because there seems times when method, like this one, should be able to be moved outside of where it is as long as it can be called from some point inside of the script.
Question: Why does the drawScreen() method have to be located where it is in the code?
Code Here:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chapter 1 Example 6 Canvas Sub Dom Example </title>
<script src="modernizr.js"></script>
<script type="text/javascript">
window.addEventListener("load", eventWindowLoaded, false);
var Debugger = function () { };
Debugger.log = function (message) {
try {
console.log(message);
} catch (exception) {
return;
}
}
function eventWindowLoaded () {
canvasApp();
}
function canvasSupport () {
return Modernizr.canvas;
}
function canvasApp () {
if (!canvasSupport()) {
return;
}
var theCanvas = document.getElementById("canvasOne");
var context = theCanvas.getContext("2d");
Debugger.log("Drawing Canvas");
**function drawScreen() {
//background
context.fillStyle = "#ffffaa";
context.fillRect(0, 0, 500, 300);
//text
context.fillStyle = "#000000";
context.font = "20px Sans-Serif";
context.textBaseline = "top";
context.fillText ("Hello World!", 195, 80 );
//image
var helloWorldImage = new Image();
helloWorldImage.onload = function () {
context.drawImage(helloWorldImage, 155, 110);
}
helloWorldImage.src = "helloworld.gif";
//box
context.strokeStyle = "#000000";
context.strokeRect(5, 5, 490, 290);
}**
drawScreen();
}
</script>
</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvasOne" width="500" height="300">
<div>A yellow background with an image and text on top
<ol>
<li>The text says "Hello World"</li>
<li>The image is of the planet earth.</li>
</ol>
</div>
</canvas>
</div>
</body>
</html>
JavaScript has lexical scope, so it inherits the scope of outer functions (scope is dependant on where functions are located in source code).
In order to move it out, you'd need to either pass it the data it needs (context) or make it available via some other means.

Categories

Resources