<div id="container_div">
<div id="palette_div">
<div id="slider_track"></div>
<div id="slider">
<img id="slider_icon" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/409445/drawing_app_slider_icon.svg">
<div id="slider_mask"></div>
</div>
<div class="color" id="red" style="background:red"></div>
<div class="color" id="purple" style="background:purple"></div>
<div class="color" id="blue" style="background:blue"></div>
<div class="color" id="green" style="background:green"></div>
<div class="color" id="yellow" style="background:yellow"></div>
<div class="color" id="orange" style="background:orange"></div>
<div class="color" id="black" style="background:black"></div>
<div class="color" id="gray" style="background:gray"></div>
<div class="color" id="white" style="background:white"></div>
</div>
<div id="canvas_div">
<canvas id="sheet"></canvas>
</div>
<div id="footer_div">
<a id="clear" class="buttons">
<img class="footer_icons" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/409445/drawing_app_clear_icon.svg">
</a>
<a id="save" class="buttons">
<img class="footer_icons" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/409445/drawing_app_download_icon.svg">
</a>
</div>
</div>
#container_div {
position: absolute;
right: 50%;
top: 48.5%;
transform: translate(50%,-50%);
}
#palette_div {
position: absolute;
width: 100%;
height: 20%;
background: #E5E5E5;
box-shadow: 0 0 2px 1px rgba(0,0,0,.4);
}
#slider_track {
position: relative;
width: 94%;
margin: auto;
height: 4%;
top: 18%;
border-radius: 100px;
box-shadow: inset 0 0 2px 1px rgba(0,0,0,.4);
}
#slider {
position: absolute;
width: 5%;
height: 15%;
top: 12%;
left: 2%;
border-radius: 100px;
background: #E5E5E5;
box-shadow: 0 0 2px 1px rgba(0,0,0,.4);
cursor: pointer;
}
#slider_icon {
position: absolute;
width: 50%;
right: 50%;
top: 50%;
transform: translate(50%,-50%);
user-select: none; /* prevents browser from highlighting the icon when sliding */
}
/* a transparent surface that prevents browser from grabbing the icon when sliding */
#slider_mask {
position: relative;
width: 100%;
height: 100%;
opacity: 0;
}
.color {
position: relative;
float: left;
height: 47%;
width: 9%;
top: 36%;
margin-left: 1.9%;
border-radius: 6px;
box-shadow: inset 0 0 2px 1px rgba(0,0,0,.6);
cursor: pointer;
}
.color:hover {
box-shadow: inset 0 0 2px 1px rgba(0,0,0,.6), inset 0 0 20px 8px rgba(0,0,0,.25);
}
#black:hover {
box-shadow: inset 0 0 2px 1px rgba(0,0,0,.6), inset 0 0 40px 15px rgba(255,255,255,.2);
}
#canvas_div {
position: absolute;
bottom: 0px;
width: 100%;
height: 78%;
box-shadow: 0 0 2px 1px rgba(0,0,0,.35);
}
#footer_div {
position: absolute;
bottom: -6%;
width: 100%;
height: 4%;
}
.buttons {
position: absolute;
width: 8%;
height: 100%;
border-radius: 100px;
box-shadow: 0 0 2px 1px rgba(0,0,0,.3);
background: #E5E5E5;
}
.buttons:hover {
background: #E0E0E0;
}
.buttons:hover > .footer_icons {
opacity: 1;
}
#clear {
left: 0;
}
#save {
right: 0;
}
.footer_icons {
position: absolute;
width: 23%;
right: 50%;
top: 51%;
transform: translate(50%,-50%);
opacity: .65;
cursor: pointer;
}
#save img {
top: 50%;
width: 27%;
}
/////////////////////////////////////////////
/// SCALABLE CANVAS PAINTING APP ///
/////////////////////////////////////////////
///---INITIATION---///
//primary variables
var container = document.getElementById("container_div");
var sliderTrack = document.getElementById("slider_track");
var slider = document.getElementById("slider");
var canvas = document.getElementById("sheet");
var ctx = canvas.getContext("2d");
//scale to window size
resizeForWindow();
var canvasPositionLeft = canvas.getBoundingClientRect().left + window.scrollX;
var canvasPositionTop = canvas.getBoundingClientRect().top + window.scrollY;
//prep slider
var mouseX;
var sliderLeft = $("#slider").position().left;
var sliderLeftMin = sliderLeft;
var sliderLeftMax = sliderLeft + $("#slider_track").width()*.965;
var currentlySliding = false;
//prep canvas for downloads with a white background
clearCanvas();
//prep markers
var markerWidth = 2; // min = 2, max = 100
ctx.lineWidth = markerWidth;
//colors
var colors = document.getElementsByClassName("color"); //an HTMLCollection of .class elements
var currentColor = "black";
//prep drawing
var currentlyDrawing = false;
///---FUNCTIONS---///
//scaling
function resizeForWindow() {
if (window.innerWidth > window.innerHeight) {
container.style.height = window.innerHeight*.8+"px";
container.style.width = container.style.height;
} else {
container.style.width = window.innerWidth*.8+"px";
container.style.height = container.style.width;
}
canvas.width = document.getElementById("canvas_div").clientWidth;
canvas.height = document.getElementById("canvas_div").clientHeight;
canvasPositionLeft = canvas.getBoundingClientRect().left + window.scrollX;
canvasPositionTop = canvas.getBoundingClientRect().top + window.scrollY;
clearCanvas();
slider.style.left = "2%";
sliderLeft = $("#slider").position().left;
sliderLeftMin = sliderLeft;
sliderLeftMax = sliderLeft + $("#slider_track").width()*.965;
}
//slider
function grab_slider(e) {
mouseX = e.pageX;
currentlySliding = true;
}
function drag_slider(e) {
if (currentlySliding) {
var mouseXChange = e.pageX - mouseX;
if (sliderLeft + mouseXChange < sliderLeftMin) {
slider.style.left = sliderLeftMin + "px";
} else if (sliderLeft + mouseXChange > sliderLeftMax) {
slider.style.left = sliderLeftMax + "px";
} else {
slider.style.left = (sliderLeft + mouseXChange) + "px";
};
}
}
function drop_slider(e) {
sliderLeft = $("#slider").position().left;
updateMarker();
currentlySliding = false;
}
function updateMarker() {
//converts slider position to a proportional marker width of 2px-100px
markerWidth = (sliderLeft-sliderLeftMin)*98/(sliderLeftMax-sliderLeftMin-sliderLeftMin)+2;
ctx.lineWidth = markerWidth;
}
//colors
function bindColors() {
for (i = 0; i < colors.length; i++) {
colors[i].addEventListener('click', selectColor);
}
}
function selectColor(e) {
currentColor = e.target.style.background;
}
//drawing
function markerDown(e) {
currentlyDrawing = true;
var canvasX = e.pageX - canvasPositionLeft;
var canvasY = e.pageY - canvasPositionTop;
ctx.beginPath();
ctx.arc(canvasX, canvasY, markerWidth/2, 0, Math.PI * 2);
ctx.fillStyle = currentColor;
ctx.fill();
ctx.beginPath();
}
function draw(e) {
var canvasX = e.pageX - canvasPositionLeft;
var canvasY = e.pageY - canvasPositionTop;
if(currentlyDrawing) {
ctx.strokeStyle = currentColor;
ctx.fillStyle = currentColor;
ctx.lineTo(canvasX, canvasY);
ctx.stroke();
ctx.beginPath();
ctx.arc(canvasX, canvasY, markerWidth/2, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.moveTo(canvasX, canvasY);
}
}
function markerUp(e) {
currentlyDrawing = false;
}
//image actions
function saveImage() {
var image = canvas.toDataURL("image/png");
var download = document.getElementById("save");
download.href = image;
download.download = 'drawing.png';
}
function clearCanvas() {
ctx.fillStyle = "white";
ctx.fillRect(0,0,canvas.width, canvas.height);
}
///---EVENTS---///
//window
window.addEventListener('resize', resizeForWindow);
//slider
slider.addEventListener("mousedown", grab_slider);
document.addEventListener("mousemove", drag_slider);
document.addEventListener("mouseup", drop_slider);
slider.addEventListener("touchstart", grab_slider);
document.addEventListener("touchmove", drag_slider);
document.addEventListener("touchend", drop_slider);
//color selection
bindColors();
//drawing
canvas.addEventListener("mousedown", markerDown);
canvas.addEventListener("mousemove", draw);
document.addEventListener("mouseup", markerUp);
canvas.addEventListener("touchstart", markerDown);
canvas.addEventListener("touchmove", draw);
document.addEventListener("touchend", markerUp);
//image actions
document.getElementById("save").addEventListener('click', saveImage);
document.getElementById("clear").addEventListener('click', clearCanvas);
This Pen doesn't use any external CSS resources.