mirror of
https://github.com/rudy3333/eversync.git
synced 2025-07-02 00:56:02 +00:00
early image wip
This commit is contained in:
parent
bfc4ff0429
commit
0b6f9d8e72
1 changed files with 112 additions and 40 deletions
144
whiteboard.html
144
whiteboard.html
|
@ -8,6 +8,7 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
<link rel="icon" href="{% static 'favicon.ico' %}">
|
<link rel="icon" href="{% static 'favicon.ico' %}">
|
||||||
<link rel="stylesheet" href="{% static 'index-style.css' %}" ">
|
<link rel="stylesheet" href="{% static 'index-style.css' %}" ">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.0/fabric.min.js"></script>
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
{% include "sentry_replay.html" %}
|
{% include "sentry_replay.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -106,9 +107,33 @@
|
||||||
</div>
|
</div>
|
||||||
<h2 style="text-align: center;">{{ whiteboard.title }}</h2>
|
<h2 style="text-align: center;">{{ whiteboard.title }}</h2>
|
||||||
<canvas id="whiteboard" width="800" height="600"></canvas>
|
<canvas id="whiteboard" width="800" height="600"></canvas>
|
||||||
|
<input type="file" id="imageUpload" accept="image/*" />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('export-png').addEventListener('click', function() {
|
let imagesOnCanvas = []; // Stores added image objects
|
||||||
|
let draggingImage = null;
|
||||||
|
let dragOffsetX = 0;
|
||||||
|
let dragOffsetY = 0;
|
||||||
|
|
||||||
|
document.getElementById('imageUpload').addEventListener('change', function (e) {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
const imageObj = {
|
||||||
|
img,
|
||||||
|
x: 100,
|
||||||
|
y: 100,
|
||||||
|
width: img.width * 0.3,
|
||||||
|
height: img.height * 0.3,
|
||||||
|
};
|
||||||
|
imagesOnCanvas.push(imageObj);
|
||||||
|
redrawCanvas();
|
||||||
|
};
|
||||||
|
img.src = URL.createObjectURL(file);
|
||||||
|
});
|
||||||
|
document.getElementById('export-png').addEventListener('click', function() {
|
||||||
const canvas = document.getElementById('whiteboard');
|
const canvas = document.getElementById('whiteboard');
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
alert('Canvas not found!');
|
alert('Canvas not found!');
|
||||||
|
@ -212,29 +237,49 @@
|
||||||
deleteButton.textContent = deleteMode ? '✅ Delete Mode ON' : '✖️ Toggle Delete Mode';
|
deleteButton.textContent = deleteMode ? '✅ Delete Mode ON' : '✖️ Toggle Delete Mode';
|
||||||
});
|
});
|
||||||
canvas.addEventListener('mousedown', (e) => {
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
const x = e.offsetX;
|
const x = e.offsetX;
|
||||||
const y = e.offsetY;
|
const y = e.offsetY;
|
||||||
|
|
||||||
if (deleteMode) {
|
if (draggingImage) {
|
||||||
// Detect and delete stroke
|
draggingImage.x = x - dragOffsetX;
|
||||||
for (let i = 0; i < savedStrokes.length; i++) {
|
draggingImage.y = y - dragOffsetY;
|
||||||
|
redrawCanvas(); // re-renders images and strokes
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (deleteMode) {
|
||||||
|
for (let i = 0; i < savedStrokes.length; i++) {
|
||||||
const stroke = savedStrokes[i];
|
const stroke = savedStrokes[i];
|
||||||
for (const point of stroke.points || stroke) {
|
for (const point of stroke.points || stroke) {
|
||||||
const dx = point.x - x;
|
const dx = point.x - x;
|
||||||
const dy = point.y - y;
|
const dy = point.y - y;
|
||||||
const dist = Math.sqrt(dx * dx + dy * dy);
|
const dist = Math.sqrt(dx * dx + dy * dy);
|
||||||
if (dist < 10) {
|
if (dist < 10) {
|
||||||
deleteStrokeFromServer(i);
|
deleteStrokeFromServer(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawing = true;
|
for (let i = imagesOnCanvas.length - 1; i >= 0; i--) {
|
||||||
currentStroke = [{ x, y }];
|
const img = imagesOnCanvas[i];
|
||||||
});
|
if (
|
||||||
|
x >= img.x &&
|
||||||
|
x <= img.x + img.width &&
|
||||||
|
y >= img.y &&
|
||||||
|
y <= img.y + img.height
|
||||||
|
) {
|
||||||
|
draggingImage = img;
|
||||||
|
dragOffsetX = x - img.x;
|
||||||
|
dragOffsetY = y - img.y;
|
||||||
|
return; // Don’t start drawing if dragging an image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawing = true;
|
||||||
|
currentStroke = [{ x, y }];
|
||||||
|
});
|
||||||
function deleteStrokeFromServer(index) {
|
function deleteStrokeFromServer(index) {
|
||||||
fetch(`/whiteboard/{{ whiteboard.id }}/delete-stroke/`, {
|
fetch(`/whiteboard/{{ whiteboard.id }}/delete-stroke/`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -257,40 +302,67 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function redrawCanvas() {
|
function redrawCanvas() {
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
savedStrokes.forEach(drawStroke);
|
|
||||||
|
// Draw images
|
||||||
|
for (const imgObj of imagesOnCanvas) {
|
||||||
|
ctx.drawImage(imgObj.img, imgObj.x, imgObj.y, imgObj.width, imgObj.height);
|
||||||
}
|
}
|
||||||
canvas.addEventListener('mousemove', (e) => {
|
|
||||||
if (!drawing) return;
|
|
||||||
const point = { x: e.offsetX, y: e.offsetY };
|
|
||||||
currentStroke.push(point);
|
|
||||||
|
|
||||||
ctx.lineWidth = 2;
|
// Draw strokes
|
||||||
ctx.strokeStyle = '#4B0082'; // purple-ish
|
savedStrokes.forEach(drawStroke);
|
||||||
ctx.lineCap = 'round';
|
}
|
||||||
|
canvas.addEventListener('mousemove', (e) => {
|
||||||
|
const x = e.offsetX;
|
||||||
|
const y = e.offsetY;
|
||||||
|
|
||||||
ctx.beginPath();
|
if (draggingImage) {
|
||||||
const prevPoint = currentStroke[currentStroke.length - 2];
|
draggingImage.x = x - dragOffsetX;
|
||||||
ctx.moveTo(prevPoint.x, prevPoint.y);
|
draggingImage.y = y - dragOffsetY;
|
||||||
ctx.lineTo(point.x, point.y);
|
redrawCanvas();
|
||||||
ctx.stroke();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!drawing) return;
|
||||||
|
|
||||||
|
const point = { x, y };
|
||||||
|
currentStroke.push(point);
|
||||||
|
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.strokeStyle = '#4B0082'; // purple-ish
|
||||||
|
ctx.lineCap = 'round';
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
const prevPoint = currentStroke[currentStroke.length - 2];
|
||||||
|
ctx.moveTo(prevPoint.x, prevPoint.y);
|
||||||
|
ctx.lineTo(point.x, point.y);
|
||||||
|
ctx.stroke();
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener('mouseup', () => {
|
canvas.addEventListener('mouseup', () => {
|
||||||
if (!drawing) return;
|
if (draggingImage) {
|
||||||
drawing = false;
|
draggingImage = null;
|
||||||
console.log('Stroke points:', currentStroke);
|
return;
|
||||||
saveStrokeToServer(currentStroke);
|
}
|
||||||
|
|
||||||
|
if (!drawing) return;
|
||||||
|
drawing = false;
|
||||||
|
saveStrokeToServer(currentStroke);
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener('mouseleave', () => {
|
canvas.addEventListener('mouseleave', () => {
|
||||||
if (drawing) {
|
if (draggingImage) {
|
||||||
drawing = false;
|
draggingImage = null;
|
||||||
console.log('Stroke points:', currentStroke);
|
return;
|
||||||
saveStrokeToServer(currentStroke);
|
}
|
||||||
}
|
|
||||||
|
if (drawing) {
|
||||||
|
drawing = false;
|
||||||
|
saveStrokeToServer(currentStroke);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function saveStrokeToServer(stroke) {
|
function saveStrokeToServer(stroke) {
|
||||||
fetch(`/whiteboard/{{ whiteboard.id }}/save-stroke/`, {
|
fetch(`/whiteboard/{{ whiteboard.id }}/save-stroke/`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue