Skip to content

Instantly share code, notes, and snippets.

@pzp1997
Created March 24, 2019 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pzp1997/6e56d2ff46b3c0e95f612c765aa0abdd to your computer and use it in GitHub Desktop.
Save pzp1997/6e56d2ff46b3c0e95f612c765aa0abdd to your computer and use it in GitHub Desktop.
JS Bin // source https://jsbin.com/somosim
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style id="jsbin-css">
/* Source: Bootstrap 4.2.1 */
/* BEGIN BOOTSTRAP */
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
.container {
/* width: 100%; */
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
.btn {
display: inline-block;
font-weight: 400;
color: #212529;
text-align: center;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: 1rem;
line-height: 1.5;
border-radius: 0.25rem;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.btn-light {
color: #212529;
background-color: #f8f9fa;
border-color: #f8f9fa;
}
.btn-light:hover {
color: #212529;
background-color: #e2e6ea;
border-color: #dae0e5;
}
.btn-light:focus, .btn-light.focus {
box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
}
.btn-light.disabled, .btn-light:disabled {
color: #212529;
background-color: #f8f9fa;
border-color: #f8f9fa;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
.text-center {
text-align: center !important;
}
.float-left {
float: left !important;
}
.float-right {
float: right !important;
}
/* END BOOTSTRAP */
body {
background-color: #333;
}
#canvas {
border: 1px solid black;
margin-top: 20px;
}
#toolbar {
margin: 0 auto;
width: 100px;
}
.dot {
display: inline-block;
height: 31px;
width: 31px;
border-radius: 50%;
margin: 0 3px;
}
.color-option-selected {
height: 25px;
width: 25px;
border: 3px solid white;
}
/* .bg-red {
background-color: red;
}
.bg-blue {
background-color: blue;
}
.bg-yellow {
background-color: yellow;
}
.bg-orange {
background-color: orange;
}
.bg-green {
background-color: green;
}
.bg-purple {
background-color: purple;
} */
body
</style>
</head>
<body>
<div class="container text-center">
<canvas id="canvas"></canvas>
<div id="toolbar">
<div id="color-selector" class="float-left">
<!-- <span id="option-red" class="dot bg-red"></span>
<span id="option-blue" class="dot bg-blue"></span>
<span id="option-yellow" class="dot bg-yellow"></span>
<span id="option-orange" class="dot bg-orange"></span>
<span id="option-green" class="dot bg-green"></span>
<span id="option-purple" class="dot bg-purple"></span> -->
</div>
<div class="float-right">
<button id="undo" class="btn btn-light" disabled>Undo</button>
</div>
</div>
</div>
<script id="jsbin-javascript">
/* CONSTANTS */
var pictureWidth = 60;
var pictureHeight = 40;
var dotDiameter = 10;
var colors = ["red", "blue", "yellow", "orange", "green", "purple", "brown", "black", "white"];
/* STATE */
var selectedColor = colors[0];
var dots = [];
var countNewDots = 0;
// for (var r = 0; r < pictureHeight; r++) {
// var row = [];
// for (var c = 0; c < pictureWidth; c++) {
// row.push(null);
// }
// dots.push(row);
// }
/* CANVAS SETUP */
var canvas = document.getElementById("canvas");
canvas.width = pictureWidth * dotDiameter;
canvas.height = pictureHeight * dotDiameter;
document.getElementById("toolbar").style.width = (pictureWidth * dotDiameter) + "px";
var ctx = canvas.getContext("2d");
drawDots();
/* DRAWING */
function drawDot(x, y, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, dotDiameter, 0, 2 * Math.PI);
ctx.fill();
}
function drawDots() {
var oldAlpha = ctx.globalAlpha;
ctx.globalAlpha = 1;
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 0.75;
for (var i = 0; i < dots.length; i++) {
var dot = dots[i];
drawDot(dot.c * dotDiameter, dot.r * dotDiameter, dot.color);
}
// for (var r = 0; r < pictureHeight; r++) {
// for (var c = 0; c < pictureWidth; c++) {
// var color = dots[r][c];
// if (color) {
// drawDot(c * dotDiameter, r * dotDiameter, color);
// }
// }
// }
ctx.globalAlpha = oldAlpha;
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
/* PREVIEW DOT */
canvas.addEventListener("mousemove", function(evt) {
var mousePos = getMousePos(canvas, evt);
var col = Math.floor(mousePos.x / dotDiameter);
var row = Math.floor(mousePos.y / dotDiameter);
drawDots();
drawDot(col * dotDiameter, row * dotDiameter, selectedColor);
// console.log("[MOVE] x: " + xPos + ", y: " + yPos);
});
canvas.addEventListener("mouseleave", function(evt) {
drawDots();
});
/* ADD DOT */
canvas.addEventListener("click", function(evt) {
var mousePos = getMousePos(canvas, evt);
var col = Math.floor(mousePos.x / dotDiameter);
var row = Math.floor(mousePos.y / dotDiameter);
if (!dotAtPosition(row, col)) {
dots.push({
c: col,
r: row,
color: selectedColor
});
countNewDots++;
undoButton.removeAttribute("disabled");
drawDots();
}
// console.log("[CLICK] x: " + xPos + ", y: " + yPos);
});
function dotAtPosition(row, col) {
for (var i = 0; i < dots.length; i++) {
var dot = dots[i];
if (dot.r === row && dot.c === col) {
return dot;
}
}
return null;
}
/* UNDO BUTTON */
var undoButton = document.getElementById("undo");
undoButton.addEventListener("click", function() {
if (countNewDots > 0) {
dots.pop();
if (--countNewDots === 0) {
console.log("disabling undo button");
undoButton.setAttribute("disabled", "");
}
}
drawDots();
});
/* COLOR SELECTOR */
var SELECTED_CLASS = "color-option-selected";
function selectColorOption(color) {
return function() {
selectedColor = color;
var selectedColorOptions = document.getElementsByClassName(SELECTED_CLASS);
for (var i = 0; i < selectedColorOptions.length; i++) {
selectedColorOptions[i].classList.remove(SELECTED_CLASS);
}
document.getElementById("option-" + color).classList.add(SELECTED_CLASS);
};
}
var colorSelector = document.getElementById("color-selector");
for (var i = 0; i < colors.length; i++) {
var color = colors[i];
var colorOption = document.createElement("span");
colorOption.id = "option-" + color;
colorOption.classList.add("dot");
if (color === selectedColor) {
colorOption.classList.add(SELECTED_CLASS);
}
colorOption.style.backgroundColor = color;
colorOption.addEventListener("click", selectColorOption(color));
colorSelector.appendChild(colorOption);
}
</script>
<script id="jsbin-source-css" type="text/css">/* Source: Bootstrap 4.2.1 */
/* BEGIN BOOTSTRAP */
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
.container {
/* width: 100%; */
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
.btn {
display: inline-block;
font-weight: 400;
color: #212529;
text-align: center;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: 1rem;
line-height: 1.5;
border-radius: 0.25rem;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.btn-light {
color: #212529;
background-color: #f8f9fa;
border-color: #f8f9fa;
}
.btn-light:hover {
color: #212529;
background-color: #e2e6ea;
border-color: #dae0e5;
}
.btn-light:focus, .btn-light.focus {
box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
}
.btn-light.disabled, .btn-light:disabled {
color: #212529;
background-color: #f8f9fa;
border-color: #f8f9fa;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
.text-center {
text-align: center !important;
}
.float-left {
float: left !important;
}
.float-right {
float: right !important;
}
/* END BOOTSTRAP */
body {
background-color: #333;
}
#canvas {
border: 1px solid black;
margin-top: 20px;
}
#toolbar {
margin: 0 auto;
width: 100px;
}
.dot {
display: inline-block;
height: 31px;
width: 31px;
border-radius: 50%;
margin: 0 3px;
}
.color-option-selected {
height: 25px;
width: 25px;
border: 3px solid white;
}
/* .bg-red {
background-color: red;
}
.bg-blue {
background-color: blue;
}
.bg-yellow {
background-color: yellow;
}
.bg-orange {
background-color: orange;
}
.bg-green {
background-color: green;
}
.bg-purple {
background-color: purple;
} */
body</script>
<script id="jsbin-source-javascript" type="text/javascript">/* CONSTANTS */
var pictureWidth = 60;
var pictureHeight = 40;
var dotDiameter = 10;
var colors = ["red", "blue", "yellow", "orange", "green", "purple", "brown", "black", "white"];
/* STATE */
var selectedColor = colors[0];
var dots = [];
var countNewDots = 0;
// for (var r = 0; r < pictureHeight; r++) {
// var row = [];
// for (var c = 0; c < pictureWidth; c++) {
// row.push(null);
// }
// dots.push(row);
// }
/* CANVAS SETUP */
var canvas = document.getElementById("canvas");
canvas.width = pictureWidth * dotDiameter;
canvas.height = pictureHeight * dotDiameter;
document.getElementById("toolbar").style.width = (pictureWidth * dotDiameter) + "px";
var ctx = canvas.getContext("2d");
drawDots();
/* DRAWING */
function drawDot(x, y, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, dotDiameter, 0, 2 * Math.PI);
ctx.fill();
}
function drawDots() {
var oldAlpha = ctx.globalAlpha;
ctx.globalAlpha = 1;
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 0.75;
for (var i = 0; i < dots.length; i++) {
var dot = dots[i];
drawDot(dot.c * dotDiameter, dot.r * dotDiameter, dot.color);
}
// for (var r = 0; r < pictureHeight; r++) {
// for (var c = 0; c < pictureWidth; c++) {
// var color = dots[r][c];
// if (color) {
// drawDot(c * dotDiameter, r * dotDiameter, color);
// }
// }
// }
ctx.globalAlpha = oldAlpha;
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
/* PREVIEW DOT */
canvas.addEventListener("mousemove", function(evt) {
var mousePos = getMousePos(canvas, evt);
var col = Math.floor(mousePos.x / dotDiameter);
var row = Math.floor(mousePos.y / dotDiameter);
drawDots();
drawDot(col * dotDiameter, row * dotDiameter, selectedColor);
// console.log("[MOVE] x: " + xPos + ", y: " + yPos);
});
canvas.addEventListener("mouseleave", function(evt) {
drawDots();
});
/* ADD DOT */
canvas.addEventListener("click", function(evt) {
var mousePos = getMousePos(canvas, evt);
var col = Math.floor(mousePos.x / dotDiameter);
var row = Math.floor(mousePos.y / dotDiameter);
if (!dotAtPosition(row, col)) {
dots.push({
c: col,
r: row,
color: selectedColor
});
countNewDots++;
undoButton.removeAttribute("disabled");
drawDots();
}
// console.log("[CLICK] x: " + xPos + ", y: " + yPos);
});
function dotAtPosition(row, col) {
for (var i = 0; i < dots.length; i++) {
var dot = dots[i];
if (dot.r === row && dot.c === col) {
return dot;
}
}
return null;
}
/* UNDO BUTTON */
var undoButton = document.getElementById("undo");
undoButton.addEventListener("click", function() {
if (countNewDots > 0) {
dots.pop();
if (--countNewDots === 0) {
console.log("disabling undo button");
undoButton.setAttribute("disabled", "");
}
}
drawDots();
});
/* COLOR SELECTOR */
var SELECTED_CLASS = "color-option-selected";
function selectColorOption(color) {
return function() {
selectedColor = color;
var selectedColorOptions = document.getElementsByClassName(SELECTED_CLASS);
for (var i = 0; i < selectedColorOptions.length; i++) {
selectedColorOptions[i].classList.remove(SELECTED_CLASS);
}
document.getElementById("option-" + color).classList.add(SELECTED_CLASS);
};
}
var colorSelector = document.getElementById("color-selector");
for (var i = 0; i < colors.length; i++) {
var color = colors[i];
var colorOption = document.createElement("span");
colorOption.id = "option-" + color;
colorOption.classList.add("dot");
if (color === selectedColor) {
colorOption.classList.add(SELECTED_CLASS);
}
colorOption.style.backgroundColor = color;
colorOption.addEventListener("click", selectColorOption(color));
colorSelector.appendChild(colorOption);
}</script></body>
</html>
/* Source: Bootstrap 4.2.1 */
/* BEGIN BOOTSTRAP */
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
.container {
/* width: 100%; */
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
.btn {
display: inline-block;
font-weight: 400;
color: #212529;
text-align: center;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: 1rem;
line-height: 1.5;
border-radius: 0.25rem;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.btn-light {
color: #212529;
background-color: #f8f9fa;
border-color: #f8f9fa;
}
.btn-light:hover {
color: #212529;
background-color: #e2e6ea;
border-color: #dae0e5;
}
.btn-light:focus, .btn-light.focus {
box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);
}
.btn-light.disabled, .btn-light:disabled {
color: #212529;
background-color: #f8f9fa;
border-color: #f8f9fa;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
.text-center {
text-align: center !important;
}
.float-left {
float: left !important;
}
.float-right {
float: right !important;
}
/* END BOOTSTRAP */
body {
background-color: #333;
}
#canvas {
border: 1px solid black;
margin-top: 20px;
}
#toolbar {
margin: 0 auto;
width: 100px;
}
.dot {
display: inline-block;
height: 31px;
width: 31px;
border-radius: 50%;
margin: 0 3px;
}
.color-option-selected {
height: 25px;
width: 25px;
border: 3px solid white;
}
/* .bg-red {
background-color: red;
}
.bg-blue {
background-color: blue;
}
.bg-yellow {
background-color: yellow;
}
.bg-orange {
background-color: orange;
}
.bg-green {
background-color: green;
}
.bg-purple {
background-color: purple;
} */
body
/* CONSTANTS */
var pictureWidth = 60;
var pictureHeight = 40;
var dotDiameter = 10;
var colors = ["red", "blue", "yellow", "orange", "green", "purple", "brown", "black", "white"];
/* STATE */
var selectedColor = colors[0];
var dots = [];
var countNewDots = 0;
// for (var r = 0; r < pictureHeight; r++) {
// var row = [];
// for (var c = 0; c < pictureWidth; c++) {
// row.push(null);
// }
// dots.push(row);
// }
/* CANVAS SETUP */
var canvas = document.getElementById("canvas");
canvas.width = pictureWidth * dotDiameter;
canvas.height = pictureHeight * dotDiameter;
document.getElementById("toolbar").style.width = (pictureWidth * dotDiameter) + "px";
var ctx = canvas.getContext("2d");
drawDots();
/* DRAWING */
function drawDot(x, y, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, dotDiameter, 0, 2 * Math.PI);
ctx.fill();
}
function drawDots() {
var oldAlpha = ctx.globalAlpha;
ctx.globalAlpha = 1;
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 0.75;
for (var i = 0; i < dots.length; i++) {
var dot = dots[i];
drawDot(dot.c * dotDiameter, dot.r * dotDiameter, dot.color);
}
// for (var r = 0; r < pictureHeight; r++) {
// for (var c = 0; c < pictureWidth; c++) {
// var color = dots[r][c];
// if (color) {
// drawDot(c * dotDiameter, r * dotDiameter, color);
// }
// }
// }
ctx.globalAlpha = oldAlpha;
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
/* PREVIEW DOT */
canvas.addEventListener("mousemove", function(evt) {
var mousePos = getMousePos(canvas, evt);
var col = Math.floor(mousePos.x / dotDiameter);
var row = Math.floor(mousePos.y / dotDiameter);
drawDots();
drawDot(col * dotDiameter, row * dotDiameter, selectedColor);
// console.log("[MOVE] x: " + xPos + ", y: " + yPos);
});
canvas.addEventListener("mouseleave", function(evt) {
drawDots();
});
/* ADD DOT */
canvas.addEventListener("click", function(evt) {
var mousePos = getMousePos(canvas, evt);
var col = Math.floor(mousePos.x / dotDiameter);
var row = Math.floor(mousePos.y / dotDiameter);
if (!dotAtPosition(row, col)) {
dots.push({
c: col,
r: row,
color: selectedColor
});
countNewDots++;
undoButton.removeAttribute("disabled");
drawDots();
}
// console.log("[CLICK] x: " + xPos + ", y: " + yPos);
});
function dotAtPosition(row, col) {
for (var i = 0; i < dots.length; i++) {
var dot = dots[i];
if (dot.r === row && dot.c === col) {
return dot;
}
}
return null;
}
/* UNDO BUTTON */
var undoButton = document.getElementById("undo");
undoButton.addEventListener("click", function() {
if (countNewDots > 0) {
dots.pop();
if (--countNewDots === 0) {
console.log("disabling undo button");
undoButton.setAttribute("disabled", "");
}
}
drawDots();
});
/* COLOR SELECTOR */
var SELECTED_CLASS = "color-option-selected";
function selectColorOption(color) {
return function() {
selectedColor = color;
var selectedColorOptions = document.getElementsByClassName(SELECTED_CLASS);
for (var i = 0; i < selectedColorOptions.length; i++) {
selectedColorOptions[i].classList.remove(SELECTED_CLASS);
}
document.getElementById("option-" + color).classList.add(SELECTED_CLASS);
};
}
var colorSelector = document.getElementById("color-selector");
for (var i = 0; i < colors.length; i++) {
var color = colors[i];
var colorOption = document.createElement("span");
colorOption.id = "option-" + color;
colorOption.classList.add("dot");
if (color === selectedColor) {
colorOption.classList.add(SELECTED_CLASS);
}
colorOption.style.backgroundColor = color;
colorOption.addEventListener("click", selectColorOption(color));
colorSelector.appendChild(colorOption);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment