Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Dynamic Snapshot Background & Customization #21 #35

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zen Note</title>

<link rel="stylesheet" href="style.css">
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>


<!-- Favicons -->
<link rel="shortcut icon" href="Images/logo.png">
<link rel="apple-touch-icon" href="Images/logo.png">
<link rel="apple-touch-icon" sizes="72x72" href="Images/logo.png">
<link rel="apple-touch-icon" sizes="114x114" href="Images/logo.png">
<link rel="apple-touch-icon" sizes="144x144" href="Images/logo.png">



</head>
<nav>
<ul>
Expand All @@ -29,9 +17,9 @@
<body class="light-mode">
<div class="container">
<div class="container-head">
<h1>Zen Note</h1>
<button id="darkModeToggle">🌙</button>
</div>
<h1>Zen Note</h1>
<button id="darkModeToggle">🌙</button>
</div>
<form id="entryForm">
<div id="fake-textarea" class="fake-textarea" contenteditable="true" data-placeholder="What did you learn today?"></div>
<input type="hidden" id="hiddenTextArea" name="textareaValue">
Expand All @@ -40,8 +28,8 @@ <h1>Zen Note</h1>
</form>
<ul id="entriesList"></ul>
</div>


<!-- Snapshot Modal -->
<div id="snapshotModal" class="modal">
<div class="modal-content">
<canvas id="snapshotCanvas"></canvas>
Expand All @@ -52,6 +40,19 @@ <h1>Zen Note</h1>
</div>
</div>
</div>

<!-- Snapshot Settings Menu -->
<div id="snapshotMenu" style="margin: 20px;">
<label for="backgroundUpload">Upload Background:</label>
<input type="file" id="backgroundUpload" accept="image/*">

<label for="fontColorPicker">Font Color:</label>
<input type="color" id="fontColorPicker" value="#000000">

<label for="fontSizePicker">Font Size:</label>
<input type="number" id="fontSizePicker" min="10" max="50" value="20">
</div>

<script src="script.js"></script>
</body>
</html>
</html>
179 changes: 68 additions & 111 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const snapshotCanvas = document.getElementById('snapshotCanvas');
const downloadSnapshotBtn = document.getElementById('downloadSnapshot');
const copySnapshotBtn = document.getElementById('copySnapshot');
const closeModalBtn = document.getElementById('closeModal');
const backgroundUpload = document.getElementById('backgroundUpload');
const fontColorPicker = document.getElementById("fontColorPicker");
const fontSizePicker = document.getElementById("fontSizePicker");

let entries = JSON.parse(localStorage.getItem('entries')) || [];

Expand All @@ -30,38 +33,26 @@ function addEntry(content) {
}

function editEntry(id) {
console.log("Id to be edited", id);
const entryDiv = document.querySelector(`.entry-content[data-id='${id}']`);
const entryActions = document.querySelector(`.entry-actions[data-id='${id}']`);
console.log(entryDiv.innerText);

const textarea = document.createElement('textarea');
textarea.className = 'edit-input';
textarea.placeholder = 'Enter text here...';
textarea.value = entryDiv.innerText;

entryActions.style.display = 'none'; // Hide the actions
entryDiv.style.display = 'none'; // Hide the original content
entryDiv.parentNode.insertBefore(textarea, entryDiv.nextSibling); // Insert textarea after entryDiv
entryActions.style.display = 'none';
entryDiv.style.display = 'none';
entryDiv.parentNode.insertBefore(textarea, entryDiv.nextSibling);

textarea.addEventListener('blur', () => {
const newContent = textarea.value.trim();
console.log("Edited content:", newContent);

// Update the content in the entries array
const index = entries.findIndex(entry => entry.id === id);
if (index !== -1) {
entries[index].content = replaceLineBreak(newContent); // Update the content
saveEntries(entries); // Save the updated entries

// Re-render entries after saving
entries[index].content = replaceLineBreak(newContent);
saveEntries(entries);
renderEntries();
}
});
}



function deleteEntry(id) {
Swal.fire({
title: 'Are you sure?',
Expand All @@ -72,19 +63,14 @@ function deleteEntry(id) {
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'No, cancel',
}).then((result) => {
}).then((result) => {
if (result.isConfirmed) {
entries = entries.filter(entry => entry.id !== id);
saveEntries();
renderEntries();

Swal.fire(
'Deleted!',
'Your entry has been deleted.',
'success'
);
entries = entries.filter(entry => entry.id !== id);
saveEntries();
renderEntries();
Swal.fire('Deleted!', 'Your entry has been deleted.', 'success');
}
});
});
}

function renderEntries() {
Expand All @@ -106,75 +92,63 @@ function renderEntries() {
<div class="entry-content" data-id="${entry.id}">${entry.content}</div>
<div class="entry-actions" data-id="${entry.id}">
<span class="snapshot-btn" data-id="${entry.id}" title="Create Snapshot">📷</span>
<span class="edit-btn" data-id="${entry.id}" title="Edit Entry">✏️</span> <!-- Edit button -->
<span class="delete-btn" data-id="${entry.id}" title="Delete Entry">🗑️</span></div>
`;
<span class="edit-btn" data-id="${entry.id}" title="Edit Entry">✏️</span>
<span class="delete-btn" data-id="${entry.id}" title="Delete Entry">🗑️</span>
</div>`;
entriesList.appendChild(li);
});
}

function toggleDarkMode() {
document.body.classList.toggle('dark-mode');
document.body.classList.toggle('light-mode');
darkModeToggle.textContent = document.body.classList.contains('dark-mode') ? '☀️' : '🌙';
document.body.classList.toggle('light-mode');
darkModeToggle.textContent = document.body.classList.contains('dark-mode') ? '☀️' : '🌙';
}

function createSnapshot(entry) {
const canvas = snapshotCanvas;
const ctx = canvas.getContext("2d");
const width = 500;
const height = 300;
let height = 300; // Adjust this based on content
const lines = entry.content.split("<br>").length;
height = 100 + lines * 30;
canvas.width = width;
canvas.height = height;

// Create gradient background
const gradient = ctx.createLinearGradient(0, 0, width, height);
gradient.addColorStop(0, "#1a2a6c");
gradient.addColorStop(0.5, "#b21f1f");
gradient.addColorStop(1, "#fdbb2d");
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);

// Add glassmorphism effect
ctx.fillStyle = "rgba(255, 255, 255, 0.1)";
ctx.fillRect(20, 20, width - 40, height - 40);
if (backgroundUpload.files.length > 0) {
const img = new Image();
img.src = URL.createObjectURL(backgroundUpload.files[0]);
img.onload = function () {
ctx.drawImage(img, 0, 0, width, height);
addTextToSnapshot(entry, ctx, width, height);
};
} else {
const gradient = ctx.createLinearGradient(0, 0, width, height);
gradient.addColorStop(0, "#f5f7fa");
gradient.addColorStop(1, "#c3cfe2");
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);
addTextToSnapshot(entry, ctx, width, height);
}
}

// Add text
ctx.fillStyle = "#ffffff";
ctx.font = "16px Arial";
function addTextToSnapshot(entry, ctx, width, height) {
const fontColor = fontColorPicker.value;
const fontSize = fontSizePicker.value + "px";
ctx.fillStyle = fontColor;
ctx.font = fontSize + " Arial";
ctx.fillText(entry.date, 30, 50);

ctx.fillStyle = "#ffff00";
ctx.font = "20px Arial";
const contentLines = entry.content.split("<br>");
let y = 80;
for(let contentLine of contentLines) {
const words = contentLine.split(' ');
let line = '';
for (let i = 0; i < words.length; i++) {
const testLine = line + words[i] + ' ';
const metrics = ctx.measureText(testLine);
if (metrics.width > width - 60 && i > 0) {
ctx.fillText(line, 30, y);
line = words[i] + ' ';
y += 30;
} else {
line = testLine;
}
}
ctx.fillText(line, 30, y);
for (let contentLine of contentLines) {
ctx.fillText(contentLine, 30, y);
y += 30;
}

// Add website name with glow effect
ctx.fillStyle = "#ffffff";
ctx.fillStyle = "#888";
ctx.font = "16px Arial";
ctx.shadowColor = "#ffffff";
ctx.shadowBlur = 10;
ctx.fillText("Made with Zen Note", width - 180, height - 20);
ctx.shadowBlur = 0;

snapshotModal.style.display = "block";
}

document.addEventListener("DOMContentLoaded", function () {
Expand All @@ -183,7 +157,6 @@ document.addEventListener("DOMContentLoaded", function () {
const errorMessage = document.getElementById("error-message");
const entryForm = document.getElementById("entryForm");

// Function to toggle placeholder appearance
function togglePlaceholder() {
if (fakeTextarea.textContent.trim() === "") {
fakeTextarea.classList.add("empty");
Expand All @@ -192,29 +165,25 @@ document.addEventListener("DOMContentLoaded", function () {
}
}

// Validate the form on submission
entryForm.addEventListener("submit", function (event) {
const textContent = fakeTextarea.textContent.trim();

if (textContent === "") {
errorMessage.style.display = "block"; // Show error message
errorMessage.style.display = "block";
fakeTextarea.classList.add("error");
event.preventDefault(); // Prevent form submission
event.preventDefault();
} else {
errorMessage.style.display = "none"; // Hide error message
errorMessage.style.display = "none";
fakeTextarea.classList.remove("error");
hiddenTextArea.value = textContent; // Set the hidden input value to send with form
hiddenTextArea.value = textContent;
fakeTextarea.innerText = "";
setTimeout(() => {
fakeTextarea.focus(); // Focus on the fake textarea after submission
fakeTextarea.focus();
}, 50);
}
});

// Initialize placeholder on load
togglePlaceholder();

// Add event listeners
fakeTextarea.addEventListener("input", togglePlaceholder);
fakeTextarea.addEventListener("focus", togglePlaceholder);
fakeTextarea.addEventListener("blur", togglePlaceholder);
Expand All @@ -223,26 +192,21 @@ document.addEventListener("DOMContentLoaded", function () {
entryForm.addEventListener("submit", (e) => {
e.preventDefault();
const content = entryInput.innerText.trim();
console.log(content);
if (content) {
addEntry(content);
entryInput.value = "";
}
});

entriesList.addEventListener("click", (e) => {
if (e.target.classList.contains("delete-btn") ) {
if (e.target.classList.contains("delete-btn")) {
const id = parseInt(e.target.getAttribute("data-id"));

deleteEntry(id);

} else if (e.target.classList.contains("snapshot-btn")) {
const id = parseInt(e.target.getAttribute("data-id"));
const entry = entries.find((entry) => entry.id === id);
createSnapshot(entry);
}
if( e.target.classList.contains("edit-btn"))
{
} else if (e.target.classList.contains("edit-btn")) {
const id = parseInt(e.target.getAttribute("data-id"));
editEntry(id);
}
Expand All @@ -261,24 +225,21 @@ downloadSnapshotBtn.addEventListener("click", () => {
copySnapshotBtn.addEventListener("click", () => {
snapshotCanvas.toBlob((blob) => {
const item = new ClipboardItem({ "image/png": blob });
navigator.clipboard
.write([item])
.then(() => {
Swal.fire({
title: "Snapshot Copied!",
text: "Your snapshot has been successfully copied to the clipboard.",
icon: "success",
confirmButtonText: "OK",
});
})
.catch(() => {
Swal.fire({
title: "Oops!",
text: "Something went wrong. Couldn’t copy the snapshot to the clipboard.",
icon: "error",
confirmButtonText: "Try Again",
});
navigator.clipboard.write([item]).then(() => {
Swal.fire({
title: "Snapshot Copied!",
text: "Your snapshot has been successfully copied to the clipboard.",
icon: "success",
confirmButtonText: "OK",
});
}).catch(() => {
Swal.fire({
title: "Oops!",
text: "Couldn’t copy the snapshot to the clipboard.",
icon: "error",
confirmButtonText: "Try Again",
});
});
});
});

Expand All @@ -292,11 +253,7 @@ window.addEventListener("click", (e) => {
}
});

// Initialize dark mode based on user preference
if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
toggleDarkMode();
}

Expand Down
5 changes: 3 additions & 2 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ body {

body.light-mode {
background: var(--bg-gradient-light);
color: var(--text-color-light);
color: var(--text-color-dark); /* Ensure higher contrast in light mode */
}

body.dark-mode {
background: var(--bg-gradient-dark);
color: var(--text-color-dark);
color: var(--text-color-light); /* Higher contrast in dark mode */
}


.container {
max-width: 800px;
margin: 0 auto;
Expand Down