Asem75's picture
Update HTML
fa31ba2 verified
Raw
History Blame Contribute Delete
7.39 kB
def whiteboard_iframe():
board_html = r"""
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>سبورة الطالب</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, sans-serif;
background: #f1f5f9;
color: #0f172a;
overflow: hidden;
}
.app {
padding: 10px;
height: 100vh;
display: flex;
flex-direction: column;
}
.toolbar {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
background: #ffffff;
border: 1px solid #cbd5e1;
border-radius: 14px;
padding: 10px;
margin-bottom: 10px;
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
}
button {
border: 1px solid #94a3b8;
background: #ffffff;
color: #0f172a;
padding: 9px 12px;
border-radius: 10px;
font-size: 14px;
font-weight: bold;
cursor: pointer;
}
button.active {
background: #0f172a;
color: #ffffff;
}
.tool-label {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
font-weight: bold;
}
input[type="range"] {
width: 100px;
}
.board-shell {
flex: 1;
overflow: auto;
background: #e2e8f0;
border: 2px solid #334155;
border-radius: 16px;
position: relative;
min-height: 560px;
}
canvas {
display: block;
background:
linear-gradient(#e5e7eb 1px, transparent 1px),
linear-gradient(90deg, #e5e7eb 1px, transparent 1px),
#ffffff;
background-size: 32px 32px;
touch-action: none;
cursor: crosshair;
}
.note {
font-size: 12px;
line-height: 1.5;
color: #475569;
background: #ffffff;
padding: 8px;
border-radius: 10px;
border: 1px solid #cbd5e1;
margin-top: 8px;
}
</style>
</head>
<body>
<div class="app">
<div class="toolbar">
<button id="penBtn" class="active">✏️ قلم</button>
<button id="eraserBtn">🧽 محاية</button>
<button id="panBtn">🤚 تحريك</button>
<button id="undoBtn">↩️ تراجع</button>
<button id="clearBtn">🗑️ مسح</button>
<label class="tool-label">
الحجم
<input id="sizeInput" type="range" min="1" max="10" value="3">
</label>
<label class="tool-label">
اللون
<input id="colorInput" type="color" value="#000000">
</label>
</div>
<div id="boardShell" class="board-shell">
<canvas id="board" width="1800" height="5200"></canvas>
</div>
<div class="note">
اكتب بالقلم. استخدم "تحريك" للتمرير داخل السبورة. استخدم المحاية للمسح الجزئي.
</div>
</div>
<script>
const canvas = document.getElementById("board");
const shell = document.getElementById("boardShell");
const ctx = canvas.getContext("2d");
const penBtn = document.getElementById("penBtn");
const eraserBtn = document.getElementById("eraserBtn");
const panBtn = document.getElementById("panBtn");
const undoBtn = document.getElementById("undoBtn");
const clearBtn = document.getElementById("clearBtn");
const sizeInput = document.getElementById("sizeInput");
const colorInput = document.getElementById("colorInput");
let mode = "pen";
let drawing = false;
let lastX = 0;
let lastY = 0;
let history = [];
ctx.lineCap = "round";
ctx.lineJoin = "round";
function setMode(nextMode) {
mode = nextMode;
penBtn.classList.toggle("active", mode === "pen");
eraserBtn.classList.toggle("active", mode === "eraser");
panBtn.classList.toggle("active", mode === "pan");
if (mode === "pan") {
canvas.style.touchAction = "auto";
canvas.style.cursor = "grab";
} else {
canvas.style.touchAction = "none";
canvas.style.cursor = "crosshair";
}
}
function saveHistory() {
try {
if (history.length > 15) {
history.shift();
}
history.push(canvas.toDataURL("image/png"));
} catch (e) {
console.log(e);
}
}
function restoreFromDataUrl(dataUrl) {
const img = new Image();
img.onload = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
};
img.src = dataUrl;
}
function getPoint(event) {
const rect = canvas.getBoundingClientRect();
let clientX;
let clientY;
if (event.touches && event.touches.length > 0) {
clientX = event.touches[0].clientX;
clientY = event.touches[0].clientY;
} else {
clientX = event.clientX;
clientY = event.clientY;
}
return {
x: clientX - rect.left,
y: clientY - rect.top
};
}
function startDraw(event) {
if (mode === "pan") {
return;
}
event.preventDefault();
saveHistory();
drawing = true;
const point = getPoint(event);
lastX = point.x;
lastY = point.y;
}
function draw(event) {
if (!drawing || mode === "pan") {
return;
}
event.preventDefault();
const point = getPoint(event);
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(point.x, point.y);
if (mode === "eraser") {
ctx.globalCompositeOperation = "destination-out";
ctx.lineWidth = Math.max(12, parseInt(sizeInput.value, 10) * 3);
} else {
ctx.globalCompositeOperation = "source-over";
ctx.strokeStyle = colorInput.value;
ctx.lineWidth = parseInt(sizeInput.value, 10);
}
ctx.stroke();
lastX = point.x;
lastY = point.y;
}
function stopDraw() {
drawing = false;
ctx.globalCompositeOperation = "source-over";
}
penBtn.addEventListener("click", function () {
setMode("pen");
});
eraserBtn.addEventListener("click", function () {
setMode("eraser");
});
panBtn.addEventListener("click", function () {
setMode("pan");
});
undoBtn.addEventListener("click", function () {
if (history.length > 0) {
const last = history.pop();
restoreFromDataUrl(last);
}
});
clearBtn.addEventListener("click", function () {
if (confirm("هل تريد مسح السبورة؟")) {
saveHistory();
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
});
canvas.addEventListener("mousedown", startDraw);
canvas.addEventListener("mousemove", draw);
window.addEventListener("mouseup", stopDraw);
canvas.addEventListener("touchstart", startDraw, { passive: false });
canvas.addEventListener("touchmove", draw, { passive: false });
window.addEventListener("touchend", stopDraw);
setMode("pen");
</script>
</body>
</html>
"""
escaped_board = html.escape(board_html, quote=True)
return f"""
<iframe
srcdoc="{escaped_board}"
style="width:100%; height:780px; border:1px solid #cbd5e1; border-radius:14px; background:white;"
title="السبورة">
</iframe>
"""