Change colour of each rectangle in canvas
I create 6 buttons for 6 rectangles. When click the button, It will change/random colour of that rectangle following colour in an array. How can I do?
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var c = canvas.getContext('2d');
c.fillRect(500, 100, 100, 100);
c.fillRect(250, 100, 100, 100);
c.fillRect(500, 500, 100, 100);
c.fillRect(700, 600, 100, 100);
c.fillRect(800, 100, 100, 100);
function changeColor() {
//????
}
javascript canvas html5-canvas
add a comment |
I create 6 buttons for 6 rectangles. When click the button, It will change/random colour of that rectangle following colour in an array. How can I do?
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var c = canvas.getContext('2d');
c.fillRect(500, 100, 100, 100);
c.fillRect(250, 100, 100, 100);
c.fillRect(500, 500, 100, 100);
c.fillRect(700, 600, 100, 100);
c.fillRect(800, 100, 100, 100);
function changeColor() {
//????
}
javascript canvas html5-canvas
add a comment |
I create 6 buttons for 6 rectangles. When click the button, It will change/random colour of that rectangle following colour in an array. How can I do?
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var c = canvas.getContext('2d');
c.fillRect(500, 100, 100, 100);
c.fillRect(250, 100, 100, 100);
c.fillRect(500, 500, 100, 100);
c.fillRect(700, 600, 100, 100);
c.fillRect(800, 100, 100, 100);
function changeColor() {
//????
}
javascript canvas html5-canvas
I create 6 buttons for 6 rectangles. When click the button, It will change/random colour of that rectangle following colour in an array. How can I do?
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var c = canvas.getContext('2d');
c.fillRect(500, 100, 100, 100);
c.fillRect(250, 100, 100, 100);
c.fillRect(500, 500, 100, 100);
c.fillRect(700, 600, 100, 100);
c.fillRect(800, 100, 100, 100);
function changeColor() {
//????
}
javascript canvas html5-canvas
javascript canvas html5-canvas
asked Nov 15 '18 at 11:38
GlufflixGlufflix
104
104
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
I'm using the method isPointInPath to detect if the mouse is in the current rectangle and if it is I change the color from white to the color c in the rects array.
const canvas = document.getElementById("canvas");
const c = canvas.getContext("2d");
let cw = canvas.width = 700,
cx = cw / 2;
let ch = canvas.height = 700,
cy = ch / 2;
c.translate(-200,0);
c.fillStyle = "white";
let mouse = {}
let rects = [
{c:'#CEF19E',data:[500, 100, 100, 100]},
{c:'#A7DDA7',data:[250, 100, 100, 100]},
{c:'#78BE97',data:[500, 500, 100, 100]},
{c:'#398689',data:[700, 600, 100, 100]},
{c:'#0B476D',data:[800, 100, 100, 100]}
]
rects.forEach(r=>{
c.fillRect(...r.data);
})
canvas.addEventListener("mousemove",(evt)=>{
// clear the canvas
c.clearRect(200,0,cw,ch);
mouse = oMousePos(canvas, evt);
//for each rect in the rects array
rects.forEach((r,i)=>{
c.beginPath();
// draw the rect
c.rect(...r.data);
// if thr mouse is inside the rect
if(c.isPointInPath(mouse.x,mouse.y)){
// fill the rect with the color in the rects array
c.fillStyle = r.c;//color
// fill the rect
c.beginPath();
c.fillRect(...r.data);
}else{
// if the mouse is not in the rects array let it be white
c.fillStyle = "white";
c.fillRect(...r.data);
}
})
})
// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}body {
background-color: #222;
}
canvas {
background-color: #000;
display: block;
margin: 0 auto;
margin:calc(50vh - 250px - 5em) auto;
}<canvas id="canvas"></canvas>I hope this helps.
add a comment |
Does this short example help? You can duplicate buttons and call same function or use an alias.
Run Code Snippet.
var c = document.getElementById("myCanvas");
var ctx = c.getContext('2d');
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var fillCombo = [
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80]
];
function changeColor() {
var randomFill = fillCombo[Math.floor(Math.random() * fillCombo.length)];
var randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
ctx.beginPath();
ctx.rect(randomFill[0], randomFill[1], randomFill[2], randomFill[3]);
ctx.fillStyle = randomColor;
ctx.fill();
}<!DOCTYPE HTML>
<html>
<head>
<TITLE>Canvas Example</TITLE>
<META http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
<button onclick="changeColor()">Click Me!!</button>
</body>
</html>add a comment |
Don't! render on mouse events!
I am adding this answer as the answer given by enxaneta is an example of bad practice in regard to rendering from mouse events.
Mouse events (depending on the device config and mouse type) can fire up to 1000 times a second. If you render from the mouse events this can mean you force a full render at a rate many times higher than can be displayed (60 times a second max). Doing such can quickly drain a laptops batteries for no reason.
Decouple mouse listeners and rendering.
Mouse events should always be decoupled from rendering. Use the event listener to just record the mouse state.
When ever you render anything to the DOM you should always do it via a frame request. This ensures you don't present new context out of sync with the display hardware, and don't add additional unseen and needless render and DOM composite cycles to the page.
Example rendering and mouse event handling.
In the following example I use a update loop that is called via requestAnimationFrame to check the state of the mouse and make changes if needed.
To ensure that there are no needless renders there is a global semaphore redraw that must be set to true for the canvas contents to be drawn. That means in the example below the only renders are the first and when a rectangle has changed color.
requestAnimationFrame(update); // will start the update loop when ready.
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 260;
var redraw = true; // When this is true the whole scene is rendered in time for the next display referesh
const colors = (() => {
// Warning: MUST have more than one colour.
// At least one colour MUST be different than others.
const cols = ["#CEF19E","#A7DDA7","#78BE97","#398689","#0B476D"];
return {
get random() { return cols[Math.random() * cols.length | 0] },
get default() { return "#DDD" },
};
})();
const rectPos = [[10,10], [150, 10], [290, 10], [10, 150], [150, 150], [290, 150]];
const rectSize = 100;
const rectangle = (x, y, w = rectSize, h= rectSize, style = colors.default) => ({x, y, w, h, style});
const rects = Object.assign(rectPos.map(rect => rectangle(...rect)), {
getUnder(x, y) { return this.find(r => x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h) },
draw() {
for (const r of this) {
ctx.fillStyle = r.style;
ctx.fillRect(r.x, r.y, r.w, r.h);
}
},
}
);
const mouse = {x: 0, y: 0, button: 0, over: false, changed : true};
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
const x = mouse.x = e.pageX - bounds.left - scrollX;
const y = mouse.y = e.pageY - bounds.top - scrollY;
mouse.over = x >= 0 && x < bounds.width && y >= 0 && y < bounds.height;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.changed = true;
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
function update() {
var cursor = "default";
if (mouse.changed) {
if (mouse.over) {
const rectUnderMouse = rects.getUnder(mouse.x, mouse.y);
if (rectUnderMouse) {
if (mouse.button) {
var newCol = colors.random;
while (newCol === rectUnderMouse.style) { newCol = colors.random };
rectUnderMouse.style = newCol;
mouse.button = false;
redraw = true;
} else {
cursor = "pointer";
}
}
}
}
if (redraw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
rects.draw();
redraw = false;
}
canvas.style.cursor = cursor;
requestAnimationFrame(update);
}canvas { position : absolute; top : 0px; left : 0px; }<canvas id="canvas"></canvas>add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53318646%2fchange-colour-of-each-rectangle-in-canvas%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
I'm using the method isPointInPath to detect if the mouse is in the current rectangle and if it is I change the color from white to the color c in the rects array.
const canvas = document.getElementById("canvas");
const c = canvas.getContext("2d");
let cw = canvas.width = 700,
cx = cw / 2;
let ch = canvas.height = 700,
cy = ch / 2;
c.translate(-200,0);
c.fillStyle = "white";
let mouse = {}
let rects = [
{c:'#CEF19E',data:[500, 100, 100, 100]},
{c:'#A7DDA7',data:[250, 100, 100, 100]},
{c:'#78BE97',data:[500, 500, 100, 100]},
{c:'#398689',data:[700, 600, 100, 100]},
{c:'#0B476D',data:[800, 100, 100, 100]}
]
rects.forEach(r=>{
c.fillRect(...r.data);
})
canvas.addEventListener("mousemove",(evt)=>{
// clear the canvas
c.clearRect(200,0,cw,ch);
mouse = oMousePos(canvas, evt);
//for each rect in the rects array
rects.forEach((r,i)=>{
c.beginPath();
// draw the rect
c.rect(...r.data);
// if thr mouse is inside the rect
if(c.isPointInPath(mouse.x,mouse.y)){
// fill the rect with the color in the rects array
c.fillStyle = r.c;//color
// fill the rect
c.beginPath();
c.fillRect(...r.data);
}else{
// if the mouse is not in the rects array let it be white
c.fillStyle = "white";
c.fillRect(...r.data);
}
})
})
// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}body {
background-color: #222;
}
canvas {
background-color: #000;
display: block;
margin: 0 auto;
margin:calc(50vh - 250px - 5em) auto;
}<canvas id="canvas"></canvas>I hope this helps.
add a comment |
I'm using the method isPointInPath to detect if the mouse is in the current rectangle and if it is I change the color from white to the color c in the rects array.
const canvas = document.getElementById("canvas");
const c = canvas.getContext("2d");
let cw = canvas.width = 700,
cx = cw / 2;
let ch = canvas.height = 700,
cy = ch / 2;
c.translate(-200,0);
c.fillStyle = "white";
let mouse = {}
let rects = [
{c:'#CEF19E',data:[500, 100, 100, 100]},
{c:'#A7DDA7',data:[250, 100, 100, 100]},
{c:'#78BE97',data:[500, 500, 100, 100]},
{c:'#398689',data:[700, 600, 100, 100]},
{c:'#0B476D',data:[800, 100, 100, 100]}
]
rects.forEach(r=>{
c.fillRect(...r.data);
})
canvas.addEventListener("mousemove",(evt)=>{
// clear the canvas
c.clearRect(200,0,cw,ch);
mouse = oMousePos(canvas, evt);
//for each rect in the rects array
rects.forEach((r,i)=>{
c.beginPath();
// draw the rect
c.rect(...r.data);
// if thr mouse is inside the rect
if(c.isPointInPath(mouse.x,mouse.y)){
// fill the rect with the color in the rects array
c.fillStyle = r.c;//color
// fill the rect
c.beginPath();
c.fillRect(...r.data);
}else{
// if the mouse is not in the rects array let it be white
c.fillStyle = "white";
c.fillRect(...r.data);
}
})
})
// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}body {
background-color: #222;
}
canvas {
background-color: #000;
display: block;
margin: 0 auto;
margin:calc(50vh - 250px - 5em) auto;
}<canvas id="canvas"></canvas>I hope this helps.
add a comment |
I'm using the method isPointInPath to detect if the mouse is in the current rectangle and if it is I change the color from white to the color c in the rects array.
const canvas = document.getElementById("canvas");
const c = canvas.getContext("2d");
let cw = canvas.width = 700,
cx = cw / 2;
let ch = canvas.height = 700,
cy = ch / 2;
c.translate(-200,0);
c.fillStyle = "white";
let mouse = {}
let rects = [
{c:'#CEF19E',data:[500, 100, 100, 100]},
{c:'#A7DDA7',data:[250, 100, 100, 100]},
{c:'#78BE97',data:[500, 500, 100, 100]},
{c:'#398689',data:[700, 600, 100, 100]},
{c:'#0B476D',data:[800, 100, 100, 100]}
]
rects.forEach(r=>{
c.fillRect(...r.data);
})
canvas.addEventListener("mousemove",(evt)=>{
// clear the canvas
c.clearRect(200,0,cw,ch);
mouse = oMousePos(canvas, evt);
//for each rect in the rects array
rects.forEach((r,i)=>{
c.beginPath();
// draw the rect
c.rect(...r.data);
// if thr mouse is inside the rect
if(c.isPointInPath(mouse.x,mouse.y)){
// fill the rect with the color in the rects array
c.fillStyle = r.c;//color
// fill the rect
c.beginPath();
c.fillRect(...r.data);
}else{
// if the mouse is not in the rects array let it be white
c.fillStyle = "white";
c.fillRect(...r.data);
}
})
})
// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}body {
background-color: #222;
}
canvas {
background-color: #000;
display: block;
margin: 0 auto;
margin:calc(50vh - 250px - 5em) auto;
}<canvas id="canvas"></canvas>I hope this helps.
I'm using the method isPointInPath to detect if the mouse is in the current rectangle and if it is I change the color from white to the color c in the rects array.
const canvas = document.getElementById("canvas");
const c = canvas.getContext("2d");
let cw = canvas.width = 700,
cx = cw / 2;
let ch = canvas.height = 700,
cy = ch / 2;
c.translate(-200,0);
c.fillStyle = "white";
let mouse = {}
let rects = [
{c:'#CEF19E',data:[500, 100, 100, 100]},
{c:'#A7DDA7',data:[250, 100, 100, 100]},
{c:'#78BE97',data:[500, 500, 100, 100]},
{c:'#398689',data:[700, 600, 100, 100]},
{c:'#0B476D',data:[800, 100, 100, 100]}
]
rects.forEach(r=>{
c.fillRect(...r.data);
})
canvas.addEventListener("mousemove",(evt)=>{
// clear the canvas
c.clearRect(200,0,cw,ch);
mouse = oMousePos(canvas, evt);
//for each rect in the rects array
rects.forEach((r,i)=>{
c.beginPath();
// draw the rect
c.rect(...r.data);
// if thr mouse is inside the rect
if(c.isPointInPath(mouse.x,mouse.y)){
// fill the rect with the color in the rects array
c.fillStyle = r.c;//color
// fill the rect
c.beginPath();
c.fillRect(...r.data);
}else{
// if the mouse is not in the rects array let it be white
c.fillStyle = "white";
c.fillRect(...r.data);
}
})
})
// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}body {
background-color: #222;
}
canvas {
background-color: #000;
display: block;
margin: 0 auto;
margin:calc(50vh - 250px - 5em) auto;
}<canvas id="canvas"></canvas>I hope this helps.
const canvas = document.getElementById("canvas");
const c = canvas.getContext("2d");
let cw = canvas.width = 700,
cx = cw / 2;
let ch = canvas.height = 700,
cy = ch / 2;
c.translate(-200,0);
c.fillStyle = "white";
let mouse = {}
let rects = [
{c:'#CEF19E',data:[500, 100, 100, 100]},
{c:'#A7DDA7',data:[250, 100, 100, 100]},
{c:'#78BE97',data:[500, 500, 100, 100]},
{c:'#398689',data:[700, 600, 100, 100]},
{c:'#0B476D',data:[800, 100, 100, 100]}
]
rects.forEach(r=>{
c.fillRect(...r.data);
})
canvas.addEventListener("mousemove",(evt)=>{
// clear the canvas
c.clearRect(200,0,cw,ch);
mouse = oMousePos(canvas, evt);
//for each rect in the rects array
rects.forEach((r,i)=>{
c.beginPath();
// draw the rect
c.rect(...r.data);
// if thr mouse is inside the rect
if(c.isPointInPath(mouse.x,mouse.y)){
// fill the rect with the color in the rects array
c.fillStyle = r.c;//color
// fill the rect
c.beginPath();
c.fillRect(...r.data);
}else{
// if the mouse is not in the rects array let it be white
c.fillStyle = "white";
c.fillRect(...r.data);
}
})
})
// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}body {
background-color: #222;
}
canvas {
background-color: #000;
display: block;
margin: 0 auto;
margin:calc(50vh - 250px - 5em) auto;
}<canvas id="canvas"></canvas>const canvas = document.getElementById("canvas");
const c = canvas.getContext("2d");
let cw = canvas.width = 700,
cx = cw / 2;
let ch = canvas.height = 700,
cy = ch / 2;
c.translate(-200,0);
c.fillStyle = "white";
let mouse = {}
let rects = [
{c:'#CEF19E',data:[500, 100, 100, 100]},
{c:'#A7DDA7',data:[250, 100, 100, 100]},
{c:'#78BE97',data:[500, 500, 100, 100]},
{c:'#398689',data:[700, 600, 100, 100]},
{c:'#0B476D',data:[800, 100, 100, 100]}
]
rects.forEach(r=>{
c.fillRect(...r.data);
})
canvas.addEventListener("mousemove",(evt)=>{
// clear the canvas
c.clearRect(200,0,cw,ch);
mouse = oMousePos(canvas, evt);
//for each rect in the rects array
rects.forEach((r,i)=>{
c.beginPath();
// draw the rect
c.rect(...r.data);
// if thr mouse is inside the rect
if(c.isPointInPath(mouse.x,mouse.y)){
// fill the rect with the color in the rects array
c.fillStyle = r.c;//color
// fill the rect
c.beginPath();
c.fillRect(...r.data);
}else{
// if the mouse is not in the rects array let it be white
c.fillStyle = "white";
c.fillRect(...r.data);
}
})
})
// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}body {
background-color: #222;
}
canvas {
background-color: #000;
display: block;
margin: 0 auto;
margin:calc(50vh - 250px - 5em) auto;
}<canvas id="canvas"></canvas>edited Nov 15 '18 at 13:32
answered Nov 15 '18 at 13:26
enxanetaenxaneta
7,3292517
7,3292517
add a comment |
add a comment |
Does this short example help? You can duplicate buttons and call same function or use an alias.
Run Code Snippet.
var c = document.getElementById("myCanvas");
var ctx = c.getContext('2d');
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var fillCombo = [
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80]
];
function changeColor() {
var randomFill = fillCombo[Math.floor(Math.random() * fillCombo.length)];
var randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
ctx.beginPath();
ctx.rect(randomFill[0], randomFill[1], randomFill[2], randomFill[3]);
ctx.fillStyle = randomColor;
ctx.fill();
}<!DOCTYPE HTML>
<html>
<head>
<TITLE>Canvas Example</TITLE>
<META http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
<button onclick="changeColor()">Click Me!!</button>
</body>
</html>add a comment |
Does this short example help? You can duplicate buttons and call same function or use an alias.
Run Code Snippet.
var c = document.getElementById("myCanvas");
var ctx = c.getContext('2d');
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var fillCombo = [
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80]
];
function changeColor() {
var randomFill = fillCombo[Math.floor(Math.random() * fillCombo.length)];
var randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
ctx.beginPath();
ctx.rect(randomFill[0], randomFill[1], randomFill[2], randomFill[3]);
ctx.fillStyle = randomColor;
ctx.fill();
}<!DOCTYPE HTML>
<html>
<head>
<TITLE>Canvas Example</TITLE>
<META http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
<button onclick="changeColor()">Click Me!!</button>
</body>
</html>add a comment |
Does this short example help? You can duplicate buttons and call same function or use an alias.
Run Code Snippet.
var c = document.getElementById("myCanvas");
var ctx = c.getContext('2d');
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var fillCombo = [
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80]
];
function changeColor() {
var randomFill = fillCombo[Math.floor(Math.random() * fillCombo.length)];
var randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
ctx.beginPath();
ctx.rect(randomFill[0], randomFill[1], randomFill[2], randomFill[3]);
ctx.fillStyle = randomColor;
ctx.fill();
}<!DOCTYPE HTML>
<html>
<head>
<TITLE>Canvas Example</TITLE>
<META http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
<button onclick="changeColor()">Click Me!!</button>
</body>
</html>Does this short example help? You can duplicate buttons and call same function or use an alias.
Run Code Snippet.
var c = document.getElementById("myCanvas");
var ctx = c.getContext('2d');
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var fillCombo = [
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80]
];
function changeColor() {
var randomFill = fillCombo[Math.floor(Math.random() * fillCombo.length)];
var randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
ctx.beginPath();
ctx.rect(randomFill[0], randomFill[1], randomFill[2], randomFill[3]);
ctx.fillStyle = randomColor;
ctx.fill();
}<!DOCTYPE HTML>
<html>
<head>
<TITLE>Canvas Example</TITLE>
<META http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
<button onclick="changeColor()">Click Me!!</button>
</body>
</html>var c = document.getElementById("myCanvas");
var ctx = c.getContext('2d');
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var fillCombo = [
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80]
];
function changeColor() {
var randomFill = fillCombo[Math.floor(Math.random() * fillCombo.length)];
var randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
ctx.beginPath();
ctx.rect(randomFill[0], randomFill[1], randomFill[2], randomFill[3]);
ctx.fillStyle = randomColor;
ctx.fill();
}<!DOCTYPE HTML>
<html>
<head>
<TITLE>Canvas Example</TITLE>
<META http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
<button onclick="changeColor()">Click Me!!</button>
</body>
</html>var c = document.getElementById("myCanvas");
var ctx = c.getContext('2d');
var colorArray = [
'#CEF19E',
'#A7DDA7',
'#78BE97',
'#398689',
'#0B476D'
];
var fillCombo = [
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80],
[20, 20, 150, 80],
[10, 10, 150, 80]
];
function changeColor() {
var randomFill = fillCombo[Math.floor(Math.random() * fillCombo.length)];
var randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
ctx.beginPath();
ctx.rect(randomFill[0], randomFill[1], randomFill[2], randomFill[3]);
ctx.fillStyle = randomColor;
ctx.fill();
}<!DOCTYPE HTML>
<html>
<head>
<TITLE>Canvas Example</TITLE>
<META http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
<button onclick="changeColor()">Click Me!!</button>
</body>
</html>edited Nov 15 '18 at 13:55
answered Nov 15 '18 at 13:25
Olayinka OOlayinka O
473113
473113
add a comment |
add a comment |
Don't! render on mouse events!
I am adding this answer as the answer given by enxaneta is an example of bad practice in regard to rendering from mouse events.
Mouse events (depending on the device config and mouse type) can fire up to 1000 times a second. If you render from the mouse events this can mean you force a full render at a rate many times higher than can be displayed (60 times a second max). Doing such can quickly drain a laptops batteries for no reason.
Decouple mouse listeners and rendering.
Mouse events should always be decoupled from rendering. Use the event listener to just record the mouse state.
When ever you render anything to the DOM you should always do it via a frame request. This ensures you don't present new context out of sync with the display hardware, and don't add additional unseen and needless render and DOM composite cycles to the page.
Example rendering and mouse event handling.
In the following example I use a update loop that is called via requestAnimationFrame to check the state of the mouse and make changes if needed.
To ensure that there are no needless renders there is a global semaphore redraw that must be set to true for the canvas contents to be drawn. That means in the example below the only renders are the first and when a rectangle has changed color.
requestAnimationFrame(update); // will start the update loop when ready.
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 260;
var redraw = true; // When this is true the whole scene is rendered in time for the next display referesh
const colors = (() => {
// Warning: MUST have more than one colour.
// At least one colour MUST be different than others.
const cols = ["#CEF19E","#A7DDA7","#78BE97","#398689","#0B476D"];
return {
get random() { return cols[Math.random() * cols.length | 0] },
get default() { return "#DDD" },
};
})();
const rectPos = [[10,10], [150, 10], [290, 10], [10, 150], [150, 150], [290, 150]];
const rectSize = 100;
const rectangle = (x, y, w = rectSize, h= rectSize, style = colors.default) => ({x, y, w, h, style});
const rects = Object.assign(rectPos.map(rect => rectangle(...rect)), {
getUnder(x, y) { return this.find(r => x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h) },
draw() {
for (const r of this) {
ctx.fillStyle = r.style;
ctx.fillRect(r.x, r.y, r.w, r.h);
}
},
}
);
const mouse = {x: 0, y: 0, button: 0, over: false, changed : true};
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
const x = mouse.x = e.pageX - bounds.left - scrollX;
const y = mouse.y = e.pageY - bounds.top - scrollY;
mouse.over = x >= 0 && x < bounds.width && y >= 0 && y < bounds.height;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.changed = true;
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
function update() {
var cursor = "default";
if (mouse.changed) {
if (mouse.over) {
const rectUnderMouse = rects.getUnder(mouse.x, mouse.y);
if (rectUnderMouse) {
if (mouse.button) {
var newCol = colors.random;
while (newCol === rectUnderMouse.style) { newCol = colors.random };
rectUnderMouse.style = newCol;
mouse.button = false;
redraw = true;
} else {
cursor = "pointer";
}
}
}
}
if (redraw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
rects.draw();
redraw = false;
}
canvas.style.cursor = cursor;
requestAnimationFrame(update);
}canvas { position : absolute; top : 0px; left : 0px; }<canvas id="canvas"></canvas>add a comment |
Don't! render on mouse events!
I am adding this answer as the answer given by enxaneta is an example of bad practice in regard to rendering from mouse events.
Mouse events (depending on the device config and mouse type) can fire up to 1000 times a second. If you render from the mouse events this can mean you force a full render at a rate many times higher than can be displayed (60 times a second max). Doing such can quickly drain a laptops batteries for no reason.
Decouple mouse listeners and rendering.
Mouse events should always be decoupled from rendering. Use the event listener to just record the mouse state.
When ever you render anything to the DOM you should always do it via a frame request. This ensures you don't present new context out of sync with the display hardware, and don't add additional unseen and needless render and DOM composite cycles to the page.
Example rendering and mouse event handling.
In the following example I use a update loop that is called via requestAnimationFrame to check the state of the mouse and make changes if needed.
To ensure that there are no needless renders there is a global semaphore redraw that must be set to true for the canvas contents to be drawn. That means in the example below the only renders are the first and when a rectangle has changed color.
requestAnimationFrame(update); // will start the update loop when ready.
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 260;
var redraw = true; // When this is true the whole scene is rendered in time for the next display referesh
const colors = (() => {
// Warning: MUST have more than one colour.
// At least one colour MUST be different than others.
const cols = ["#CEF19E","#A7DDA7","#78BE97","#398689","#0B476D"];
return {
get random() { return cols[Math.random() * cols.length | 0] },
get default() { return "#DDD" },
};
})();
const rectPos = [[10,10], [150, 10], [290, 10], [10, 150], [150, 150], [290, 150]];
const rectSize = 100;
const rectangle = (x, y, w = rectSize, h= rectSize, style = colors.default) => ({x, y, w, h, style});
const rects = Object.assign(rectPos.map(rect => rectangle(...rect)), {
getUnder(x, y) { return this.find(r => x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h) },
draw() {
for (const r of this) {
ctx.fillStyle = r.style;
ctx.fillRect(r.x, r.y, r.w, r.h);
}
},
}
);
const mouse = {x: 0, y: 0, button: 0, over: false, changed : true};
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
const x = mouse.x = e.pageX - bounds.left - scrollX;
const y = mouse.y = e.pageY - bounds.top - scrollY;
mouse.over = x >= 0 && x < bounds.width && y >= 0 && y < bounds.height;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.changed = true;
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
function update() {
var cursor = "default";
if (mouse.changed) {
if (mouse.over) {
const rectUnderMouse = rects.getUnder(mouse.x, mouse.y);
if (rectUnderMouse) {
if (mouse.button) {
var newCol = colors.random;
while (newCol === rectUnderMouse.style) { newCol = colors.random };
rectUnderMouse.style = newCol;
mouse.button = false;
redraw = true;
} else {
cursor = "pointer";
}
}
}
}
if (redraw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
rects.draw();
redraw = false;
}
canvas.style.cursor = cursor;
requestAnimationFrame(update);
}canvas { position : absolute; top : 0px; left : 0px; }<canvas id="canvas"></canvas>add a comment |
Don't! render on mouse events!
I am adding this answer as the answer given by enxaneta is an example of bad practice in regard to rendering from mouse events.
Mouse events (depending on the device config and mouse type) can fire up to 1000 times a second. If you render from the mouse events this can mean you force a full render at a rate many times higher than can be displayed (60 times a second max). Doing such can quickly drain a laptops batteries for no reason.
Decouple mouse listeners and rendering.
Mouse events should always be decoupled from rendering. Use the event listener to just record the mouse state.
When ever you render anything to the DOM you should always do it via a frame request. This ensures you don't present new context out of sync with the display hardware, and don't add additional unseen and needless render and DOM composite cycles to the page.
Example rendering and mouse event handling.
In the following example I use a update loop that is called via requestAnimationFrame to check the state of the mouse and make changes if needed.
To ensure that there are no needless renders there is a global semaphore redraw that must be set to true for the canvas contents to be drawn. That means in the example below the only renders are the first and when a rectangle has changed color.
requestAnimationFrame(update); // will start the update loop when ready.
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 260;
var redraw = true; // When this is true the whole scene is rendered in time for the next display referesh
const colors = (() => {
// Warning: MUST have more than one colour.
// At least one colour MUST be different than others.
const cols = ["#CEF19E","#A7DDA7","#78BE97","#398689","#0B476D"];
return {
get random() { return cols[Math.random() * cols.length | 0] },
get default() { return "#DDD" },
};
})();
const rectPos = [[10,10], [150, 10], [290, 10], [10, 150], [150, 150], [290, 150]];
const rectSize = 100;
const rectangle = (x, y, w = rectSize, h= rectSize, style = colors.default) => ({x, y, w, h, style});
const rects = Object.assign(rectPos.map(rect => rectangle(...rect)), {
getUnder(x, y) { return this.find(r => x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h) },
draw() {
for (const r of this) {
ctx.fillStyle = r.style;
ctx.fillRect(r.x, r.y, r.w, r.h);
}
},
}
);
const mouse = {x: 0, y: 0, button: 0, over: false, changed : true};
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
const x = mouse.x = e.pageX - bounds.left - scrollX;
const y = mouse.y = e.pageY - bounds.top - scrollY;
mouse.over = x >= 0 && x < bounds.width && y >= 0 && y < bounds.height;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.changed = true;
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
function update() {
var cursor = "default";
if (mouse.changed) {
if (mouse.over) {
const rectUnderMouse = rects.getUnder(mouse.x, mouse.y);
if (rectUnderMouse) {
if (mouse.button) {
var newCol = colors.random;
while (newCol === rectUnderMouse.style) { newCol = colors.random };
rectUnderMouse.style = newCol;
mouse.button = false;
redraw = true;
} else {
cursor = "pointer";
}
}
}
}
if (redraw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
rects.draw();
redraw = false;
}
canvas.style.cursor = cursor;
requestAnimationFrame(update);
}canvas { position : absolute; top : 0px; left : 0px; }<canvas id="canvas"></canvas>Don't! render on mouse events!
I am adding this answer as the answer given by enxaneta is an example of bad practice in regard to rendering from mouse events.
Mouse events (depending on the device config and mouse type) can fire up to 1000 times a second. If you render from the mouse events this can mean you force a full render at a rate many times higher than can be displayed (60 times a second max). Doing such can quickly drain a laptops batteries for no reason.
Decouple mouse listeners and rendering.
Mouse events should always be decoupled from rendering. Use the event listener to just record the mouse state.
When ever you render anything to the DOM you should always do it via a frame request. This ensures you don't present new context out of sync with the display hardware, and don't add additional unseen and needless render and DOM composite cycles to the page.
Example rendering and mouse event handling.
In the following example I use a update loop that is called via requestAnimationFrame to check the state of the mouse and make changes if needed.
To ensure that there are no needless renders there is a global semaphore redraw that must be set to true for the canvas contents to be drawn. That means in the example below the only renders are the first and when a rectangle has changed color.
requestAnimationFrame(update); // will start the update loop when ready.
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 260;
var redraw = true; // When this is true the whole scene is rendered in time for the next display referesh
const colors = (() => {
// Warning: MUST have more than one colour.
// At least one colour MUST be different than others.
const cols = ["#CEF19E","#A7DDA7","#78BE97","#398689","#0B476D"];
return {
get random() { return cols[Math.random() * cols.length | 0] },
get default() { return "#DDD" },
};
})();
const rectPos = [[10,10], [150, 10], [290, 10], [10, 150], [150, 150], [290, 150]];
const rectSize = 100;
const rectangle = (x, y, w = rectSize, h= rectSize, style = colors.default) => ({x, y, w, h, style});
const rects = Object.assign(rectPos.map(rect => rectangle(...rect)), {
getUnder(x, y) { return this.find(r => x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h) },
draw() {
for (const r of this) {
ctx.fillStyle = r.style;
ctx.fillRect(r.x, r.y, r.w, r.h);
}
},
}
);
const mouse = {x: 0, y: 0, button: 0, over: false, changed : true};
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
const x = mouse.x = e.pageX - bounds.left - scrollX;
const y = mouse.y = e.pageY - bounds.top - scrollY;
mouse.over = x >= 0 && x < bounds.width && y >= 0 && y < bounds.height;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.changed = true;
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
function update() {
var cursor = "default";
if (mouse.changed) {
if (mouse.over) {
const rectUnderMouse = rects.getUnder(mouse.x, mouse.y);
if (rectUnderMouse) {
if (mouse.button) {
var newCol = colors.random;
while (newCol === rectUnderMouse.style) { newCol = colors.random };
rectUnderMouse.style = newCol;
mouse.button = false;
redraw = true;
} else {
cursor = "pointer";
}
}
}
}
if (redraw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
rects.draw();
redraw = false;
}
canvas.style.cursor = cursor;
requestAnimationFrame(update);
}canvas { position : absolute; top : 0px; left : 0px; }<canvas id="canvas"></canvas>requestAnimationFrame(update); // will start the update loop when ready.
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 260;
var redraw = true; // When this is true the whole scene is rendered in time for the next display referesh
const colors = (() => {
// Warning: MUST have more than one colour.
// At least one colour MUST be different than others.
const cols = ["#CEF19E","#A7DDA7","#78BE97","#398689","#0B476D"];
return {
get random() { return cols[Math.random() * cols.length | 0] },
get default() { return "#DDD" },
};
})();
const rectPos = [[10,10], [150, 10], [290, 10], [10, 150], [150, 150], [290, 150]];
const rectSize = 100;
const rectangle = (x, y, w = rectSize, h= rectSize, style = colors.default) => ({x, y, w, h, style});
const rects = Object.assign(rectPos.map(rect => rectangle(...rect)), {
getUnder(x, y) { return this.find(r => x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h) },
draw() {
for (const r of this) {
ctx.fillStyle = r.style;
ctx.fillRect(r.x, r.y, r.w, r.h);
}
},
}
);
const mouse = {x: 0, y: 0, button: 0, over: false, changed : true};
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
const x = mouse.x = e.pageX - bounds.left - scrollX;
const y = mouse.y = e.pageY - bounds.top - scrollY;
mouse.over = x >= 0 && x < bounds.width && y >= 0 && y < bounds.height;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.changed = true;
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
function update() {
var cursor = "default";
if (mouse.changed) {
if (mouse.over) {
const rectUnderMouse = rects.getUnder(mouse.x, mouse.y);
if (rectUnderMouse) {
if (mouse.button) {
var newCol = colors.random;
while (newCol === rectUnderMouse.style) { newCol = colors.random };
rectUnderMouse.style = newCol;
mouse.button = false;
redraw = true;
} else {
cursor = "pointer";
}
}
}
}
if (redraw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
rects.draw();
redraw = false;
}
canvas.style.cursor = cursor;
requestAnimationFrame(update);
}canvas { position : absolute; top : 0px; left : 0px; }<canvas id="canvas"></canvas>requestAnimationFrame(update); // will start the update loop when ready.
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 260;
var redraw = true; // When this is true the whole scene is rendered in time for the next display referesh
const colors = (() => {
// Warning: MUST have more than one colour.
// At least one colour MUST be different than others.
const cols = ["#CEF19E","#A7DDA7","#78BE97","#398689","#0B476D"];
return {
get random() { return cols[Math.random() * cols.length | 0] },
get default() { return "#DDD" },
};
})();
const rectPos = [[10,10], [150, 10], [290, 10], [10, 150], [150, 150], [290, 150]];
const rectSize = 100;
const rectangle = (x, y, w = rectSize, h= rectSize, style = colors.default) => ({x, y, w, h, style});
const rects = Object.assign(rectPos.map(rect => rectangle(...rect)), {
getUnder(x, y) { return this.find(r => x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h) },
draw() {
for (const r of this) {
ctx.fillStyle = r.style;
ctx.fillRect(r.x, r.y, r.w, r.h);
}
},
}
);
const mouse = {x: 0, y: 0, button: 0, over: false, changed : true};
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
const x = mouse.x = e.pageX - bounds.left - scrollX;
const y = mouse.y = e.pageY - bounds.top - scrollY;
mouse.over = x >= 0 && x < bounds.width && y >= 0 && y < bounds.height;
mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
mouse.changed = true;
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));
function update() {
var cursor = "default";
if (mouse.changed) {
if (mouse.over) {
const rectUnderMouse = rects.getUnder(mouse.x, mouse.y);
if (rectUnderMouse) {
if (mouse.button) {
var newCol = colors.random;
while (newCol === rectUnderMouse.style) { newCol = colors.random };
rectUnderMouse.style = newCol;
mouse.button = false;
redraw = true;
} else {
cursor = "pointer";
}
}
}
}
if (redraw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
rects.draw();
redraw = false;
}
canvas.style.cursor = cursor;
requestAnimationFrame(update);
}canvas { position : absolute; top : 0px; left : 0px; }<canvas id="canvas"></canvas>edited Nov 16 '18 at 15:51
answered Nov 16 '18 at 14:15
Blindman67Blindman67
26.6k52762
26.6k52762
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53318646%2fchange-colour-of-each-rectangle-in-canvas%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown