להורדה | מחולל מנדלות איכותי ופשוט
-
@נחמן-פלח
אם יורשה לי - שתי הצעות לשיפור.ביטול פעולה אחרונה באמצעות ctrl+z (צריך להגדיר id ל-body).
body.addEventListener("keydown", (event) => { if (event.code === "KeyZ" && event.ctrlKey) { undoLastAction(); } });
להוציא את החלפת צבע הרקע לפונקציה נפרדת. ולקרוא לה גם בשינוי תיבת הצבע וגם בשינוי תיבת הבחירה של השקיפות:
function transparencyBackgroundColor() { const bgColor = bgColorPicker.value; if (!transparencyCheckBox.checked) { // רק אם הרקע לא שקוף, עדכן את צבע הרקע canvas.style.backgroundColor = bgColor; } else { // אם הרקע שקוף, אפס את צבע הרקע canvas.style.backgroundColor = "transparent"; } } bgColorPicker.addEventListener("input", transparencyBackgroundColor); transparencyCheckBox.addEventListener("input", transparencyBackgroundColor);
מלבד זאת אם ברירת המחדל היא רקע שקוף - עדיף להשאיר את הסימון של התיבה.
(ראיתי שאתה מבטל את הסימון בקוד - אבל זה לא גורם לעדכון של צבע הרקע - הוא נשאר שקוף). -
-
@ישראל-142 כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@נחמן-פלח
זה לא שומר לי את הרקעגם לי נחכה לרנדומלי
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mandala Generator</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; font-family: Arial, sans-serif; gap: 40px; } .canvas-container { position: relative; display: flex; justify-content: center; align-items: center; } canvas { border-radius: 50%; cursor: crosshair; } svg { position: absolute; top: 0; left: 0; pointer-events: none; width: 100%; height: 100%; } #controls { display: flex; flex-direction: column; gap: 10px; background-color: #333; color: white; padding: 20px; border-radius: 10px; max-width: 300px; min-width: 200px; } #controls label { margin-bottom: 5px; } #controls input[type="color"], #controls input[type="range"] { width: 100%; } button { padding: 10px; border: none; border-radius: 5px; background-color: #555; color: white; cursor: pointer; font-size: 14px; } button:hover { background-color: #777; } </style> </head> <body> <div class="canvas-container"> <canvas id="mandalaCanvas" width="600" height="600"></canvas> <svg id="overlay"></svg> </div> <div id="controls" dir="rtl"> <label>רוחב קנבס: <input type="number" id="canvasWidth" value="600" min="100"> </label> <label>גובה קנבס: <input type="number" id="canvasHeight" value="600" min="100"> </label> <button id="resizeCanvas">שנה גודל</button> <label>צבע קו: <input type="color" id="colorPicker" value="#000000"> </label> <label>צבע רקע: <input type="color" id="bgColorPicker" value="#ffffff"> </label> <label>חלקים: <input type="range" id="sectors" min="4" max="32" value="16"> </label> <label>עובי הקו: <input type="range" id="lineWidth" min="1" max="10" value="2"> </label> <label> <input type="checkbox" id="mirror" checked> סימטריה <input type="checkbox" id="transparency" checked> רקע שקוף </label> <button id="clearCanvas">ניקוי</button> <button id="undoAction">ביטול פעולה אחרונה</button> <button id="saveImage">שמור</button> </div> <script> // בחירת אלמנטים מהתפריט const canvas = document.getElementById("mandalaCanvas"); const ctx = canvas.getContext("2d"); const colorPicker = document.getElementById("colorPicker"); const bgColorPicker = document.getElementById("bgColorPicker"); const sectorsInput = document.getElementById("sectors"); const lineWidthInput = document.getElementById("lineWidth"); const mirrorCheckbox = document.getElementById("mirror"); const clearCanvasButton = document.getElementById("clearCanvas"); const undoActionButton = document.getElementById("undoAction"); const saveImageButton = document.getElementById("saveImage"); const overlay = document.getElementById("overlay"); const transparencyCheckBox = document.getElementById("transparency"); const canvasWidthInput = document.getElementById("canvasWidth"); const canvasHeightInput = document.getElementById("canvasHeight"); const resizeCanvasButton = document.getElementById("resizeCanvas"); // משתנים גלובליים let centerX = canvas.width / 2; let centerY = canvas.height / 2; let isDrawing = false; let previousX, previousY; let undoStack = []; // שמירה של מצב הקנבס לפני כל פעולה function saveState() { undoStack.push(ctx.getImageData(0, 0, canvas.width, canvas.height)); } function transparencyBackgroundColor() { const bgColor = bgColorPicker.value; if (!transparencyCheckBox.checked) { // רק אם הרקע לא שקוף, עדכן את צבע הרקע canvas.style.backgroundColor = bgColor; } else { // אם הרקע שקוף, אפס את צבע הרקע canvas.style.backgroundColor = "transparent"; } } bgColorPicker.addEventListener("input", transparencyBackgroundColor); transparencyCheckBox.addEventListener("input", transparencyBackgroundColor); // ביטול פעולה אחרונה function undoLastAction() { if (undoStack.length > 0) { const lastState = undoStack.pop(); ctx.putImageData(lastState, 0, 0); } } // ציור קווים במנדלה function drawLine(x1, y1, x2, y2, color, lineWidth, sectors, mirror) { ctx.save(); ctx.translate(centerX, centerY); const angleStep = (2 * Math.PI) / sectors; for (let i = 0; i < sectors; i++) { ctx.strokeStyle = color; ctx.lineWidth = lineWidth; ctx.lineJoin = "round"; ctx.lineCap = "round"; ctx.beginPath(); ctx.moveTo(x1 - centerX, y1 - centerY); ctx.lineTo(x2 - centerX, y2 - centerY); ctx.stroke(); if (mirror) { ctx.beginPath(); ctx.moveTo(-(x1 - centerX), y1 - centerY); ctx.lineTo(-(x2 - centerX), y2 - centerY); ctx.stroke(); } ctx.rotate(angleStep); } ctx.restore(); } // ציור סקטורים function drawSectorLines(sectors) { overlay.innerHTML = ""; // נקה את הקווים הקודמים const angleStep = (2 * Math.PI) / sectors; // עדכון הקואורדינטות של הקווים בהתאם לגודל הקנבס החדש const centerX = canvas.width / 2; const centerY = canvas.height / 2; for (let i = 0; i < sectors; i++) { const x1 = centerX; const y1 = 0; const x2 = centerX + Math.cos(angleStep * i) * centerX; const y2 = centerY + Math.sin(angleStep * i) * centerY; const line = document.createElementNS("http://www.w3.org/2000/svg", "line"); const angle = angleStep * i; line.setAttribute("x1", centerX); line.setAttribute("y1", centerY); line.setAttribute("x2", x2); line.setAttribute("y2", y2); line.setAttribute("stroke", "#cccccc"); // אפור בהיר line.setAttribute("stroke-width", 1); // קווים דקים line.setAttribute("stroke-dasharray", "5,5"); // קווים מקווקווים overlay.appendChild(line); } } // התחלת ציור function startDrawing(e) { isDrawing = true; const rect = canvas.getBoundingClientRect(); previousX = e.clientX - rect.left; previousY = e.clientY - rect.top; saveState(); // שמור מצב לפני התחלת ציור } // ציור בפועל function draw(e) { if (!isDrawing) return; const rect = canvas.getBoundingClientRect(); const currentX = e.clientX - rect.left; const currentY = e.clientY - rect.top; const color = colorPicker.value; const lineWidth = lineWidthInput.value; const sectors = sectorsInput.value; const mirror = mirrorCheckbox.checked; drawLine(previousX, previousY, currentX, currentY, color, lineWidth, sectors, mirror); previousX = currentX; previousY = currentY; } // סיום ציור function endDrawing() { isDrawing = false; } // התחלת ציור מגע canvas.addEventListener("mousedown", startDrawing); canvas.addEventListener("mousemove", draw); canvas.addEventListener("mouseup", endDrawing); canvas.addEventListener("mouseleave", endDrawing); // ציור בטלפון canvas.addEventListener("touchstart", (e) => { e.preventDefault(); startDrawing(e.touches[0]); }); canvas.addEventListener("touchmove", (e) => { e.preventDefault(); draw(e.touches[0]); }); canvas.addEventListener("touchend", endDrawing); canvas.addEventListener("touchcancel", endDrawing); // שינוי גודל הקנבס resizeCanvasButton.addEventListener("click", () => { const newWidth = parseInt(canvasWidthInput.value); const newHeight = parseInt(canvasHeightInput.value); canvas.width = newWidth; canvas.height = newHeight; centerX = canvas.width / 2; centerY = canvas.height / 2; drawSectorLines(sectorsInput.value); // מחדש את הסקטורים עם הגודל החדש }); // ניקוי הקנבס clearCanvasButton.addEventListener("click", () => { ctx.clearRect(0, 0, canvas.width, canvas.height); undoStack = []; // מנקה את הסטאק של הפעולות }); // ביטול פעולה אחרונה undoActionButton.addEventListener("click", undoLastAction); // שמירת התמונה // שמירת התמונה saveImageButton.addEventListener("click", () => { const backgroundColor = transparencyCheckBox.checked ? "transparent" : bgColorPicker.value; // שמור את התמונה הקיימת (הציור) לפני צביעת הרקע const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); // אם הרקע לא שקוף, צייר את הרקע בצבע שנבחר ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, canvas.width, canvas.height); // החזר את הציור שנשמר לאחר צביעת הרקע ctx.putImageData(imageData, 0, 0); // שמירה של התמונה עם הצבע הנכון const dataUrl = canvas.toDataURL("image/png"); const link = document.createElement("a"); link.href = dataUrl; link.download = "mandala.png"; link.click(); }); // הגדרת ברירת המחדל של רקע שקוף לתיבה של הרקע שקוף לא תהיה מסומנת // עדכון סקטורים ודברים נוספים sectorsInput.addEventListener("input", () => { const sectors = sectorsInput.value; drawSectorLines(sectors); // עדכון המנדלה עם סקטורים חדשים }); // עדכון צבעים colorPicker.addEventListener("input", () => { const color = colorPicker.value; ctx.strokeStyle = color; // עדכון צבע הקו }); bgColorPicker.addEventListener("input", () => { const bgColor = bgColorPicker.value; if (!transparencyCheckBox.checked) { // רק אם הרקע לא שקוף, עדכן את צבע הרקע canvas.style.backgroundColor = bgColor; } else { // אם הרקע שקוף, אפס את צבע הרקע canvas.style.backgroundColor = "transparent"; } }); // הגדרת ברירת המחדל - יצירת קווים ראשוניים drawSectorLines(sectorsInput.value); </script> </body> </html>
זה הקוד
-
@רנדומלי כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
הקטנתי את התפריט, ואפשרתי להחליף רקע בלי לאבד את כל העבודה הקודמת.
התבססתי על הסקריפט המקורי + כפתור הביטול של @נחמן-פלח (מקווה שלא הפרתי זכויות יוצרים או משהו).
שימו לב שביטול הפעולה האחרונה חלה רק על הקווים המצוירים ולא על צבע הרקע.
כמו כן - לפני שאתם קובעים צבע רקע, הורידו את הסימון מ"רקע שקוף" על מנת שתוכלו לראות את הצבע.זה למשל כן שומר את הרקע
-
@ישראל-142 כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@רנדומלי כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
הקטנתי את התפריט, ואפשרתי להחליף רקע בלי לאבד את כל העבודה הקודמת.
התבססתי על הסקריפט המקורי + כפתור הביטול של @נחמן-פלח (מקווה שלא הפרתי זכויות יוצרים או משהו).
שימו לב שביטול הפעולה האחרונה חלה רק על הקווים המצוירים ולא על צבע הרקע.
כמו כן - לפני שאתם קובעים צבע רקע, הורידו את הסימון מ"רקע שקוף" על מנת שתוכלו לראות את הצבע.זה למשל כן שומר את הרקע
נכון... משהו התפקשש לgpt או ההתאמה אישית עושה בעיות
-
@נחמן-פלח
אני לא מצליח להבין מה הוא עושה בפונקציה של השמירה.
הנה פונקציה שעובדת:saveImageButton.addEventListener("click", () => { // קבע את צבע הרקע או קבע רקע כשקוף const backgroundColor = transparencyCheckBox.checked ? "rgba(255, 255, 255, 0)" : bgColorPicker.value; // צור אלמנט זמני const tempCanvas = document.createElement("canvas"); const tempCtx = tempCanvas.getContext("2d"); tempCanvas.width = canvas.width; tempCanvas.height = canvas.height; tempCtx.fillStyle = backgroundColor; tempCtx.beginPath(); tempCtx.arc(centerX, centerY, centerX, 0, 2 * Math.PI); tempCtx.closePath(); tempCtx.fill(); // צייר את המנדלה tempCtx.save(); tempCtx.beginPath(); tempCtx.arc(centerX, centerY, centerX, 0, 2 * Math.PI); tempCtx.closePath(); tempCtx.clip(); tempCtx.drawImage(canvas, 0, 0); tempCtx.restore(); // שמור את התמונה const link = document.createElement("a"); link.download = "mandala.png"; link.href = tempCanvas.toDataURL(); link.click(); });
-
@ישראל-142 כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
קוד חדש כולל כל הפונקציות
בשילוב הפונקציה (מהקטע קוד של @רנדומלי)
ותיקון השמירה של הרקע הנבחר.הייתי בטוח שכללת גם את הקטע הזה:
@רנדומלי כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
ביטול פעולה אחרונה באמצעות ctrl+z (צריך להגדיר id ל-body).
-
@רנדומלי כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
ביטול פעולה אחרונה באמצעות ctrl+z
הוספתי עכשיו גם את זה
יוצר המנדלות מעודכן2.zip
וגם בדקתי שזה עובד
(בהתחלה זה עבד רק באנגלית ואז עשיתי שזה יעבוד גם בעברית)כמובן יש גם את השמירה עם צבע הרקע הנבחר (ואת כל שאר הפונקציות)
-
בס"ד הצלחתי להשלים את כל מה שהציעו, כולל תיקונים ושיפורים...
יוצר המנדלות מעודכן2 סופי.zip
תיקונים ועדכונים:
ביטול פעולה אחרונה
- וגם אפשר באמצעות ctrl+z
- וגם במצב עברית
- הוספת סימן לכפתור
- החזרת השמירה של צבע הרקע
- וגם בקודם שהעלתי היה בעיה
שזה לא היה משנה את מספר הקווים לפי החלקים תוקן
קרדיטים:
על הרעיון והקוד הראשוני: @רפאל-vnkl
הוספת פונקציות ושיפורים: @נחמן-פלח @רנדומלי -
-
@נחמן-פלח כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@ישראל-142 כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
הוספת סימת לכפתור
מה
זה רק שינוי קוסמטי קטן, אבל המטרה בעיקר שידעו איזה גרסה זה
-
@ישראל-142 כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@נחמן-פלח כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@ישראל-142 כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
הוספת סימת לכפתור
מה
סימן*