How to program javascript radio buttons - javascript

I have this piece of code that will eventually be a little drawing tool in which the user will be able switch between a pencil and an eraser. I am trying to program the eraser at the moment. However, if the user selects the eraser radio button and then selects the pencil radio button(deselects the eraser), the eraser does not 'turn off'.
This is all done with HTML's canvas element and the eraser takes advantage of:
context.globalCompositeOperation="destination-out";
As the code below shows, I thought I might be able to go through and reverse some of the properties depending on which button was clicked, for instance changing the globalCompositeOperation to equal 'source-over' or another property of globalCompositeOperation, however as far as I know, once a property has been set for it the only way to change it is to reset the entire canvas, which would delete everything.
Then I thought I might be able to set the opacity of the brush using:
context.globalAlpha=0;
so that when the pencil tool is selected the eraser tool still erases, but at 0% opacity, so it shouldn't do anything. Unfortunatly, none of this worked.
I'm self taught so although I know a moderate amount about the HTML canvas, I've found it difficult to learn about the JS side of programming radio buttons.
I guess my question is, if some code is activated through a radiobutton onclick event, how do I deactivate the code once the radiobutton is deselected.
Thanks to any suggestions, any help is wanted!
Here's my code:
(sorry about the formatting, stack overflow didn't like my indents)
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="main">
<div class="tools" style="position:fixed;">Pencil:<input type="radio" name="toolSelect" onclick="pencilCheck();" id="pencilSelect"></div>
<div class="tools" style="position:fixed; left: 80px;">Rubber:<input type="radio" name="toolSelect" onclick="rubberCheck()" id="rubberSelect"></div>
<canvas id="canvas">This is a web application, you need to update your browser.</canvas><!-- the canvas -->
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
//Makes the canvas the size of the browser window
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
context.fillStyle = "red";
context.fillRect(40,40,250,100);
function rubberCheck(){
var dragging = false;
var erase = function(rubber){
if(dragging){
context.beginPath();
context.arc(rubber.clientX, rubber.clientY, 10, 0, Math.PI*2);
context.fill();
context.globalCompositeOperation="destination-out";
context.globalAlpha=1;
}
}
var click = function(rubber){
dragging = true;
erase(rubber);
}
var unclick = function(){
dragging = false;
}
canvas.addEventListener('mousedown', click);
canvas.addEventListener('mousemove', erase);
canvas.addEventListener('mouseup', unclick);
}
if(pencilCheck){
var dragging = false;
var erase = function(rubber){
if(dragging){
context.beginPath();
context.arc(rubber.clientX, rubber.clientY, 10, 0, Math.PI*2);
context.fill();
context.globalCompositeOperation="destination-over";
context.globalAlpha=0;
}
}
var click = function(rubber){
dragging = true;
erase(rubber);
}
var unclick = function(){
dragging = false;
}
canvas.addEventListener('mousedown', click);
canvas.addEventListener('mousemove', erase);
canvas.addEventListener('mouseup', unclick);
}
</script>
</body>

You have:
> <input type="radio" name="toolSelect" onclick="pencilCheck();" id="pencilSelect">
but there is no pencilCheck function. Later there is:
> if (pencilCheck) {
The function should probably be called "setTool" or similar. Pass a reference to the button that was clicked to the function using this and add a value attribute that is the tool that the button represents:
<input type="radio" ... value="pencil" onclick="setTool(this);" ...>
Then set the value of a variable to indicate the selected tool, say selectedTool:
// Initial state is no tool selected (?)
var selectedTool = null;
function setTool(el) {
if (el.checked) selectedTool = el.value;
}
Do the same with other radio buttons so selectedTool always represents the currently checked checkbox. Note that you have a reset button, you need to add a listener so when it's clicked you reset the value of selectedTool (that can use a click listener on the button or a reset listener on the form, if you're using a form, but you don't seem to be using one).

Related

Zimjs pressmove event doesn't work outer the elements

I'm using zimjs library for my canvas project. I'm trying to do continued pressing around the circles. When pressing and moving over the circles, circles must be change color. But pressmove event don't start outer the circles. You need to start to press over the circle. if I start pressing over the circle, the other circle is not affected.
Here is zimjs events:
https://zimjs.com/tips.html (See Events)
What do I want approximately?
https://zimjs.com/intro/index.html (See drag to eraser example. I want like this but without eraser. Only single pressing)
Note: I can't use mouse events. They didn't work on phone touchs.
See snippet:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>ZIM Frame - Outside Template</title>
<script src="https://zimjs.org/cdn/1.3.0/createjs.js"></script>
<script src="https://zimjs.org/cdn/10.9.0/zim.js"></script>
<!-- use zimjs.com/distill for minified individual functions! -->
<script>
var scaling = "fit"; // this will resize to fit inside the screen dimensions
var width = 600;
var height = 400;
var color = white; // or any HTML color such as "violet" or "#333333"
var outerColor = light;
var frame = new Frame(scaling, width, height, color, outerColor);
frame.on("ready", function() {
var stage = frame.stage;
var circle1 = new Circle(20, "red").pos(100,40, stage)
var circle2 = new Circle(20, "blue").pos(200,40, stage)
circle1.on("pressmove", () => {
circle1.color = "green"
stage.update()
console.log("Circle - 1 || Circles pressmove doesn't work when pressing start the outside")
})
circle2.on("pressmove", () => {
circle2.color = "green"
stage.update()
console.log("Circle - 2 || Circles pressmove doesn't work when pressing start the outside")
})
var button = new Button(140, 100, "reset", grey, dark).center(stage).tap(() => {
circle1.color = "red"
circle2.color = "blue"
stage.update()
})
new Label("Pressmove can be start anywhere", 16).pos(0, 300)
new Label("When pressing and moving over the circles,", 16).pos(0, 320)
new Label("circles must be select and change color,", 16).pos(0, 340)
stage.on("pressmove", () => console.log("Stage !!. Stage pressmove doesn't work when pressing outside the circles"))
stage.update();
}); // end of ready
</script>
<meta name="viewport" content="width=device-width, user-scalable=no" />
</head>
<body>
</body>
</html>
It is true that the pressmove event only works as you press on an object and move. If you want to start the press off the object or indeed anywhere then you use stage.on("stagemousedown", function); Mouse events DO work on mobile they are triggered by a touch so you do not even have to think of it. There is also "stagemousemove" and "stagemouseup". Objects on the stage get "mousedown", "presssmove", "pressup", "mouseover", "mouseout", etc. Usually we would change color on "mouseover" and change back on "mouseout" - ZIM has hov() that will do that. Or a Button() and Label() have built in backgroundColor and rollBackgroundColor.
If you really need to press anywhere before activating a change of color you could do something like this to remember the mousedown stage in general:
let mousedown = false;
stage.on("stagemousedown", ()=>{mousedown=true});
stage.on("stagemouseup", ()=>{mousedown=false});
const circle = new Circle().center();
circle.on("mouseover", ()=>{
if (mousedown) {
circle.color = red;
stage.update();
}
});
Or you could specifically add a stagemousemove event inside a stagemousedown event and remove it in a stagemouseup event to get the equivalent to a stage pressmove event. The pressmove event was created to help with dragging objects and usually, we do not drag the stage.
Hope this helps and apologies for the delay - you are welcome to join us at https://zimjs.com/slack for discussion! Cheers.

HTM5 Canvas Drawing App: How Do I Select The Color?

I am building this drawing app with HTML5 and Javascript.
I've made it possible to be able to draw on the canvas, however when it comes to being able to select the different colors that I have and use it as a way to draw on the canvas, I feel stuck.
Here's my current JS:
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var radius = 10;
var dragging = false;
context.lineWidth = radius * 2;
var putPoint = function(e){
if(dragging){
context.lineTo(e.offsetX, e.offsetY);
context.stroke();
context.beginPath();
context.arc(e.offsetX, e.offsetY, radius, 0, Math.PI*2);
context.fill();
context.beginPath();
context.moveTo(e.offsetX, e.offsetY);
}
}
var engage = function(e){
dragging = true;
putPoint(e);
}
var disengage = function(){
dragging = false;
}
canvas.addEventListener('mousedown', engage);
canvas.addEventListener('mousemove', putPoint);
canvas.addEventListener('mouseup', disengage);
/////////////////////
Here's the link to the codepen to get a clear idea of where I am at :
https://codepen.io/teenicarus/pen/oGVwdB
How do I make it possible to click on the different divs so I can use their color ?
I appreciate all answers.
The first thing you need to do is create a color variable at the top of your code to hold the value of the current color the user is using:
var color = "black"; // Initial, default color
Now you need to get all your html color elements and apply the click eventListener to each of your DOM (html element) objects.
To get all the color elements you can do this:
var colors = document.getElementsByClassName("color");
Then you can loop through each of your color elements and add the click event listener to it by doing this:
for (var i = 0; i < colors.length; i++) {
colors[i].addEventListener('click', changeColor, false); // Adds the click event listener to each color element
}
The above code says that once a color element is clicked, it will call the changeColor function. Thus, we can write a function that gets the color of the element we clicked and to change the value of color to the color we clicked on (the color defined by the elements data-color attribute
var changeColor = function(e) {
color = this.getAttribute("data-color"); // Change the color to what is defined in "data-color"
}
Now, everytime you click on your color html elements, the changeColor function will be called, and thus change the value of color to the value you have defined in data-color for that particular element.
Now all you need to do is apply the color to your draw method (in your putPoint function) so it shows on the canvas. You can do this by using:
context.strokeStyle = color;
context.fillStyle = color;
This will change the stroke color and the inside/fill color.
A working example can be found here: https://codepen.io/clapynick/pen/pWYrPj?editors=1010
You might want to use a color input. This solution gives you ALL the colors.
Add this input element to your HTML file:
<input type="color" class="color" />
The user will now be able to pick a color.
Next, target the input element or its class to get the value (the user's selection). You can use a function:
function getColor() {
return document.querySelector(".color").value;
}
Finally, set strokeStyle to call getColor():
context.strokeStyle = getColor();
Alternatively, store the input value in a variable (name it color or userColor) and set strokeStyle to that variable.
I hope this helps.
Visit my CodePen to see this in action.

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);

Stop a Function/ EventListener once another has been called

I'm attempting to write a drawing app using html5 canvas.
I have set an image as background. A stroked rectangle animated with clearRect is used to select a square from the background image. On mousedown the canvas is transformed and scaled and the selected square of image is drawn on to the canvas.
Once a square is selected I want to stop the clearRect function so that I can start the drawing function. Unfortunately, and despite checking historical posts, I can't get the scaled image to stay and it is immediately cleared because the select function is still active.
Here's my javascript code:
function doFirst(){
var x = document.getElementById('canvas')
canvas=x.getContext('2d');
canvas.strokeStyle = "red";
canvas.fillStyle="black";
canvas.font = "bold 36px Arial";
}
function select(e){
xPos=Math.floor(e.clientX/100)*100;
yPos=Math.floor(e.clientY/100)*100;
canvas.clearRect(0,0,500,800);
canvas.strokeRect(xPos+1,yPos+1,99,99);
}
function zoom(e) {
var xPos=e.clientX;
var yPos=e.clientY;
canvas.scale(5,5);
canvas.translate(-Math.floor(xPos/100)*100,-Math.floor(yPos/100)*100);
canvas.strokeStyle="transparent";
var pic= new Image();
pic.src = "tut.jpg";
pic.addEventListener ("load",function(){canvas.drawImage(pic,0,0)},false);
}
window.addEventListener ("load", doFirst, false);
window.addEventListener ("mousemove", select, false);
window.addEventListener ("mousedown", zoom, false);
Thanks very much,
Nick
this?
window.removeEventListener ("mousemove", select, false);
Not quite following what you mean, but the mousemove listener is fired many times a second while the mouse moves?
Try this:
document.addEventListener("load", function(e){e.stopPropagation();doFirst}, true);
document.addEventListener("mousemove", function(e){e.stopPropagation();select}, true);
document.addEventListener("mousedown", function(e){e.stopPropagation();zoom}, true);

javascript canvas detect click on shape

I have a problem with the click function in javascript. This is my code:
var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext('2d');
BigCircle = function(x, y, color, circleSize) {
ctx.shadowBlur = 10;
ctx.shadowColor = color;
ctx.beginPath();
ctx.arc(x, y, circleSize, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();
};
var bigGreen = new BigCircle(1580, 800, '#5eb62b', 180);
function init() {
$("#bigGreen").click(function(e){
alert("test");
});
}
$(document).ready(function() {
init();
});
But the click event is not working! Does anybody know why? Thank you so much in advance!
You can now use hit regions in Chrome and Firefox:
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility#Hit_regions
(Edit: Hit regions are now obsolete)
or just use one of the many canvas APIs:
http://www.fabricjs.com/
http://www.createjs.com/easeljs
http://www.paperjs.org
etc...
without seeing your html this question is a little bit unclear, it seems you would like to draw something on a canvas and use jquery to add click events for the circle, this isn't possible.
you can use jquery to get the click event ON the canvas and from the cursor position you can calculate if the user clicked the circle or not, but jquery won't help you here you have to do the math yourself.
jquery does only work for dom elements.
BigCircle = function(ctx,x, y, color, circleSize) {
ctx.beginPath();
ctx.arc(x, y, circleSize, 0, Math.PI * 2, true);
ctx.fillStyle=color
ctx.fill();
ctx.closePath();
this.clicked=function(){
ctx.fillStyle='#ff0000'
ctx.fill();
}
};
function init() {
var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext('2d');
var bigGreen = new BigCircle(ctx,50, 50, '#5eb62b', 50);
$('#canvas').click(function(e){
var x = e.clientX
, y = e.clientY
if(Math.pow(x-50,2)+Math.pow(y-50,2) < Math.pow(50,2))
bigGreen.clicked()
})
}
$(document).ready(function() {
init();
});
​
jsfiddle is here
http://jsfiddle.net/yXVrk/1/
Canvas API function isPointInPath() can be used to assist with hit detection. This function can at least tell if mouse coordinates are within a complex shape without doing sophisticated math yourself. May work for simple shapes as well but my use case was for on a bezier curve path. However, you need to either incorporate this function in your drawing logic to test while paths are open or keep an array of Path2d objects to test against. I redraw on onClick handler and pass in mouse coords from event args, but I think I could have kept an array of Path2d objects instead.
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isPointInPath
bigGreen is not in the HTML, so $("#bigGreen") selects nothing. You can't put a click function on things like JavaScript functions; since they don't exist in the DOM, how could you click one? You should replace #bigGreen with #canvas, since "canvas" is your HTML element.
I forked your fiddle to show this here.
Edit: If you want to see that the user clicked on a particular circle, you use the canvas click event, and then, you determine which circle was clicked by the coordinates passed into the click event.

Categories

Resources