Skip to content

Commit

Permalink
feat: Save with background color and other options
Browse files Browse the repository at this point in the history
  • Loading branch information
myckgoncalves committed Oct 9, 2022
1 parent f48ed10 commit 2817b64
Show file tree
Hide file tree
Showing 5 changed files with 358 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
1 change: 1 addition & 0 deletions assets/ico/download.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 7 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@
</div>
<div class="canvas-container">
<canvas id="black-board"></canvas>
<script src="script.js"></script>
<div class="clear-button">
<button onclick="onClear()">Clear</button>
</div>
</div>


<div class="clear-download-button">
<button class="clear" onclick="onClear()">Clear</button>
<button id="download">
<img src="/assets/ico/download.svg">
</button>
</div>

<script src="script.js"></script>
<script src="colorChanges.js"></script>
</body>
</html>
141 changes: 141 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,144 @@
const buttonDownload = document.getElementById("download");
buttonDownload.addEventListener("click", downloadOptions);

function download(name, format) {
// get width and height and background color - original draw
const canvas = document.getElementById("black-board");
const width = canvas.width;
const height = canvas.height;

let boardBackground;

const background = canvas.style.backgroundColor;
boardBackground = background;

if (!background) {
boardBackground = "rgba(255,255,255)";
}

// generate a new canvas with background
const backgroundCanvasGenerate = document.createElement("canvas");
backgroundCanvasGenerate.width = width;
backgroundCanvasGenerate.height = height;
const ctx2 = backgroundCanvasGenerate.getContext("2d");
ctx2.fillStyle = boardBackground;
ctx2.fillRect(0, 0, width, height);

// merge background with draw
const canvas3 = document.createElement("canvas");
canvas3.width = width;
canvas3.height = height;
const ctx3 = canvas3.getContext("2d");

ctx3.drawImage(backgroundCanvasGenerate, 0, 0);
ctx3.drawImage(canvas, 0, 0);

const newCanvas = canvas3.toDataURL();

fetch(newCanvas)
.then((resp) => resp.blob())
.then((blobobject) => {
const blob = window.URL.createObjectURL(blobobject);
const anchor = document.createElement("a");
anchor.style.display = "none";
anchor.href = blob;
anchor.download = `${name}.${format}`;
document.body.appendChild(anchor);
anchor.click();
window.URL.revokeObjectURL(blob);

document.getElementById("modal").remove();
});
}

function downloadOptions() {
const modal = document.createElement("div");
modal.classList.add("modal");
modal.setAttribute("id", "modal");

const content = document.createElement("div");
content.classList.add("modal-content");
modal.appendChild(content);

const labelInput = document.createElement("div");

labelInput.classList.add("label-input");

const label = document.createElement("label");
label.appendChild(document.createTextNode("File Name"));
labelInput.appendChild(label);

const inputName = document.createElement("input");
inputName.addEventListener("keydown", () => {
const error = inputName.classList.contains("error");
if (error) {
inputName.classList.remove("error");
}
});
inputName.classList.add("input-name");
labelInput.appendChild(inputName);

content.appendChild(labelInput);

const formats = ["png", "jpeg"];

const listFormats = document.createElement("div");
listFormats.classList.add("download-list-formats");
content.appendChild(listFormats);

formats.map((format) => {
const label = document.createElement("label");
label.classList.add("download-format-control");

const input = document.createElement("input");
if (format == "png") {
input.checked = true;
}
input.setAttribute("type", "radio");
input.setAttribute("name", "radio");
input.setAttribute("value", format);
label.appendChild(document.createTextNode(format));
label.appendChild(input);

listFormats.appendChild(label);
});

const downloadCancel = document.createElement("div");
downloadCancel.classList.add("download-cancel");

const btnDownload = document.createElement("button");
btnDownload.addEventListener("click", () => {
let nameFile = inputName.value;

if (!nameFile) {
inputName.classList.add("error");
return;
}

nameFile = nameFile.replace(/\s+/g, "-").toLowerCase();

const format = document.querySelector('input[name="radio"]:checked').value;

download(nameFile, format);
});

btnDownload.classList.add("btn-download");
btnDownload.appendChild(document.createTextNode("Download"));
downloadCancel.appendChild(btnDownload);

const btnCancelClose = document.createElement("button");
btnCancelClose.classList.add("btn-cancel");
btnCancelClose.addEventListener("click", () => {
modal.remove();
});
btnCancelClose.appendChild(document.createTextNode("Cancel"));
downloadCancel.appendChild(btnCancelClose);

content.appendChild(downloadCancel);

document.body.appendChild(modal);
}

function blackBoard() {
const canvas = document.getElementById("black-board");
const ctx = canvas.getContext("2d");
Expand Down
209 changes: 208 additions & 1 deletion styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,216 @@ canvas:active {
height: 78vh;
cursor: grabbing;
}
button {

.canvas-container button {
position: relative;
right: -90px;
bottom: -180px;
}
}

.clear-download-button button {
background: unset;
border: unset;
cursor: pointer;
}

.clear-download-button .clear {
border: none;
color: white;
padding: 15px 30px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
background: linear-gradient(to left, purple, rgb(187, 62, 187));
border-radius: 15px;
width: 100%;
}

.modal {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
}

.modal-content {
background-color: #fefefe;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 450px;
display: grid;
gap: 2rem;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}

.modal-content .input-name {
padding: 1rem;
border: 2px solid #2c3131;
font-size: 1rem;
font-weight: bold;
}

.modal-content .input-name:focus {
border: 2px solid #bb3ebb;
outline: none;
}


.clear-download-button {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
/* Temporary workaround for responsive issue to be fixed */
}

.label-input {
display: grid;
gap: 10px;
font-size: 1.4rem;
font-weight: bold;
line-height: 1.1;
margin-top: 1rem;
}

.download-list-formats {
display: flex;
align-items: center;
gap: 50px;

}

.download-format-control {
font-size: 1.4rem;
font-weight: bold;
line-height: 1.1;
display: flex;
grid-template-columns: 1em auto;
gap: 0.5em;
cursor: pointer;
}

.download-format-control:focus-within {
color: #bb3ebb;
}

.download-format-control input[type=radio] {
cursor: pointer;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
margin: 0;
font: inherit;
color: currentColor;
width: 1.15em;
height: 1.15em;
border: 0.15em solid currentColor;
border-radius: 50%;
transform: translateY(-0.075em);
display: grid;
place-content: center;
}

.download-format-control input[type=radio]::before {
content: "";
width: 0.65em;
height: 0.65em;
border-radius: 50%;
transform: scale(0);
transition: 120ms transform ease-in-out;
box-shadow: inset 1em 1em #bb3ebb;
background-color: CanvasText;
}

.download-format-control input[type=radio]:checked::before {
transform: scale(1);
}

.download-cancel {
display: flex;
margin-top: 1rem;
gap: 2rem;
justify-items: center;
align-items: center;
}

.download-cancel button {
cursor: pointer;
border: none;
font-size: 20px;
height: fit-content;
}

.btn-cancel {
padding: 0;
color: #2c3131;
text-align: center;
display: inline-block;
font-size: 20px;
border-radius: 15px;
background: unset;
}

.btn-download {
border: none;
color: white;
padding: 15px 30px;
text-align: center;
font-size: 20px;
background: linear-gradient(to left, purple, rgb(187, 62, 187));
border-radius: 15px;
}


.error {
-webkit-animation: shake 0.2s ease-in-out 0s 2;
animation: shake 0.2s ease-in-out 0s 2;
border: 2px solid red !important;
}

@-webkit-keyframes shake {
0% {
margin: 0;
}

25% {
margin: 0 0.5rem;
}


75% {
margin: 0 -0.5rem;
}

100% {
margin: 0;
}
}

@keyframes shake {
0% {
margin: 0;
}

25% {
margin: 0 0.5rem;
}

75% {
margin: 0 -0.5rem;
}

100% {
margin: 0;
}
}

0 comments on commit 2817b64

Please sign in to comment.