להורדה | מחולל מנדלות איכותי ופשוט
-
@יוסף-אלחנן כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@חטח כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
בטח לקח לך שעות!
ממש לא!
זה כל כך קל...
כשאתה עושה משהו קטן
כמו זה
אז זה קל, אבל מה שאתה עשית לוקח זמן...
-
@רפאל-vnkl
וואהו ממש יפה וכייף
אהבתי לגמרי
-
-
@למה-מה-קרה בכיף
אגב אתה מבין ב JS? ()
אם כן אשמח אם תוסיף את מה ש @יוסף-אלחנן אמר פה ומה ש @ישראל-142 אמר פה.
תודה רבה! -
@רפאל-vnkl
בהחלט רעיון
מקווה בהמשך לעשות את זה בלי נדר. -
@רפאל-vnkl
זה מה שיצא לי בינתיים
הלך לי בזריזות בעזרת המודלים
יוצר-המנדלות.zip -
פוסט זה נמחק!
-
@למה-מה-קרה אחלה!
אבל לא עדיף לעשות בחירת צבע רגילה, ולא מתוך רשימה מצומצמת? -
@רפאל-vnkl כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@למה-מה-קרה אחלה!
אבל לא עדיף לעשות בחירת צבע רגילה, ולא מתוך רשימה מצומצמת?עובד על זה...
<!DOCTYPE html> <html lang="he"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>יוצר מנדלות</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; flex-wrap: wrap; height: 100vh; background-color: #f4f4f4; font-family: Arial, sans-serif; gap: 20px; } .canvas-container { position: relative; width: 90%; max-width: 500px; height: auto; aspect-ratio: 1; } canvas { width: 100%; height: 100%; background-color: transparent; border-radius: 50%; touch-action: none; cursor: crosshair; } #controls { display: flex; flex-direction: column; gap: 10px; background-color: #333; color: white; padding: 20px; border-radius: 10px; max-width: 500px; width: 90%; } label { margin-bottom: 5px; } input[type="color"], input[type="range"], button, select { width: 100%; margin-top: 5px; } button { padding: 10px; border: none; border-radius: 5px; background-color: #555; color: white; cursor: pointer; } button:hover { background-color: #777; } </style> </head> <body> <div class="canvas-container"> <canvas id="mandalaCanvas"></canvas> </div> <div id="controls" dir="rtl"> <label>צבע קו: <input type="color" id="colorPicker" value="#000000"></label> <label>צבע רקע: <input type="color" id="backgroundPicker" 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> סימטריה</label> <label><input type="checkbox" id="transparentBackground" checked> רקע שקוף</label> <button id="clearCanvas">ניקוי</button> <button id="undo">ביטול פעולה</button> <button id="saveImage">שמור</button> </div> <script> const canvas = document.getElementById('mandalaCanvas'); const ctx = canvas.getContext('2d'); const colorPicker = document.getElementById('colorPicker'); const backgroundPicker = document.getElementById('backgroundPicker'); const sectorsInput = document.getElementById('sectors'); const lineWidthInput = document.getElementById('lineWidth'); const mirrorCheckbox = document.getElementById('mirror'); const transparentBackgroundCheckbox = document.getElementById('transparentBackground'); const clearCanvasButton = document.getElementById('clearCanvas'); const saveImageButton = document.getElementById('saveImage'); const undoButton = document.getElementById('undo'); let isDrawing = false; let previousX, previousY; let drawings = []; let centerX, centerY; // Adjust canvas size to match container function resizeCanvas() { canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; centerX = canvas.width / 2; centerY = canvas.height / 2; initializeCanvas(); } window.addEventListener('resize', resizeCanvas); function initializeCanvas() { if (transparentBackgroundCheckbox.checked) { ctx.clearRect(0, 0, canvas.width, canvas.height); } else { ctx.fillStyle = backgroundPicker.value; ctx.fillRect(0, 0, canvas.width, canvas.height); } drawGuidelines(sectorsInput.value); } function drawGuidelines(sectors) { const angleStep = (2 * Math.PI) / sectors; ctx.save(); ctx.strokeStyle = "#ddd"; ctx.lineWidth = 1; ctx.translate(centerX, centerY); for (let i = 0; i < sectors; i++) { ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(canvas.width / 2, 0); ctx.stroke(); ctx.rotate(angleStep); } ctx.restore(); } 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.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 saveState() { drawings.push(ctx.getImageData(0, 0, canvas.width, canvas.height)); } function undo() { if (drawings.length > 0) { const previousState = drawings.pop(); ctx.putImageData(previousState, 0, 0); } } function getPos(e) { const rect = canvas.getBoundingClientRect(); if (e.touches) { return { x: e.touches[0].clientX - rect.left, y: e.touches[0].clientY - rect.top }; } else { return { x: e.clientX - rect.left, y: e.clientY - rect.top }; } } canvas.addEventListener('pointerdown', (e) => { isDrawing = true; const pos = getPos(e); previousX = pos.x; previousY = pos.y; saveState(); }); canvas.addEventListener('pointermove', (e) => { if (!isDrawing) return; const pos = getPos(e); const color = colorPicker.value; const lineWidth = lineWidthInput.value; const sectors = sectorsInput.value; const mirror = mirrorCheckbox.checked; drawLine(previousX, previousY, pos.x, pos.y, color, lineWidth, sectors, mirror); previousX = pos.x; previousY = pos.y; }); canvas.addEventListener('pointerup', () => { isDrawing = false; }); clearCanvasButton.addEventListener('click', () => { drawings = []; initializeCanvas(); }); saveImageButton.addEventListener('click', () => { const link = document.createElement('a'); link.download = 'mandala.png'; link.href = canvas.toDataURL(); link.click(); }); sectorsInput.addEventListener('input', () => { initializeCanvas(); }); backgroundPicker.addEventListener('input', () => { initializeCanvas(); }); transparentBackgroundCheckbox.addEventListener('change', () => { initializeCanvas(); }); undoButton.addEventListener('click', () => { undo(); }); resizeCanvas(); </script> </body> </html>
זה הקוד.... עובד גם בטלפון
-
@נחמן-פלח כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@רפאל-vnkl כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@למה-מה-קרה אחלה!
אבל לא עדיף לעשות בחירת צבע רגילה, ולא מתוך רשימה מצומצמת?עובד על זה...
<!DOCTYPE html> <html lang="he"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>יוצר מנדלות</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; flex-wrap: wrap; height: 100vh; background-color: #f4f4f4; font-family: Arial, sans-serif; gap: 20px; } .canvas-container { position: relative; width: 90%; max-width: 500px; height: auto; aspect-ratio: 1; } canvas { width: 100%; height: 100%; background-color: transparent; border-radius: 50%; touch-action: none; cursor: crosshair; } #controls { display: flex; flex-direction: column; gap: 10px; background-color: #333; color: white; padding: 20px; border-radius: 10px; max-width: 500px; width: 90%; } label { margin-bottom: 5px; } input[type="color"], input[type="range"], button, select { width: 100%; margin-top: 5px; } button { padding: 10px; border: none; border-radius: 5px; background-color: #555; color: white; cursor: pointer; } button:hover { background-color: #777; } </style> </head> <body> <div class="canvas-container"> <canvas id="mandalaCanvas"></canvas> </div> <div id="controls" dir="rtl"> <label>צבע קו: <input type="color" id="colorPicker" value="#000000"></label> <label>צבע רקע: <input type="color" id="backgroundPicker" 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> סימטריה</label> <label><input type="checkbox" id="transparentBackground" checked> רקע שקוף</label> <button id="clearCanvas">ניקוי</button> <button id="undo">ביטול פעולה</button> <button id="saveImage">שמור</button> </div> <script> const canvas = document.getElementById('mandalaCanvas'); const ctx = canvas.getContext('2d'); const colorPicker = document.getElementById('colorPicker'); const backgroundPicker = document.getElementById('backgroundPicker'); const sectorsInput = document.getElementById('sectors'); const lineWidthInput = document.getElementById('lineWidth'); const mirrorCheckbox = document.getElementById('mirror'); const transparentBackgroundCheckbox = document.getElementById('transparentBackground'); const clearCanvasButton = document.getElementById('clearCanvas'); const saveImageButton = document.getElementById('saveImage'); const undoButton = document.getElementById('undo'); let isDrawing = false; let previousX, previousY; let drawings = []; let centerX, centerY; // Adjust canvas size to match container function resizeCanvas() { canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; centerX = canvas.width / 2; centerY = canvas.height / 2; initializeCanvas(); } window.addEventListener('resize', resizeCanvas); function initializeCanvas() { if (transparentBackgroundCheckbox.checked) { ctx.clearRect(0, 0, canvas.width, canvas.height); } else { ctx.fillStyle = backgroundPicker.value; ctx.fillRect(0, 0, canvas.width, canvas.height); } drawGuidelines(sectorsInput.value); } function drawGuidelines(sectors) { const angleStep = (2 * Math.PI) / sectors; ctx.save(); ctx.strokeStyle = "#ddd"; ctx.lineWidth = 1; ctx.translate(centerX, centerY); for (let i = 0; i < sectors; i++) { ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(canvas.width / 2, 0); ctx.stroke(); ctx.rotate(angleStep); } ctx.restore(); } 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.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 saveState() { drawings.push(ctx.getImageData(0, 0, canvas.width, canvas.height)); } function undo() { if (drawings.length > 0) { const previousState = drawings.pop(); ctx.putImageData(previousState, 0, 0); } } function getPos(e) { const rect = canvas.getBoundingClientRect(); if (e.touches) { return { x: e.touches[0].clientX - rect.left, y: e.touches[0].clientY - rect.top }; } else { return { x: e.clientX - rect.left, y: e.clientY - rect.top }; } } canvas.addEventListener('pointerdown', (e) => { isDrawing = true; const pos = getPos(e); previousX = pos.x; previousY = pos.y; saveState(); }); canvas.addEventListener('pointermove', (e) => { if (!isDrawing) return; const pos = getPos(e); const color = colorPicker.value; const lineWidth = lineWidthInput.value; const sectors = sectorsInput.value; const mirror = mirrorCheckbox.checked; drawLine(previousX, previousY, pos.x, pos.y, color, lineWidth, sectors, mirror); previousX = pos.x; previousY = pos.y; }); canvas.addEventListener('pointerup', () => { isDrawing = false; }); clearCanvasButton.addEventListener('click', () => { drawings = []; initializeCanvas(); }); saveImageButton.addEventListener('click', () => { const link = document.createElement('a'); link.download = 'mandala.png'; link.href = canvas.toDataURL(); link.click(); }); sectorsInput.addEventListener('input', () => { initializeCanvas(); }); backgroundPicker.addEventListener('input', () => { initializeCanvas(); }); transparentBackgroundCheckbox.addEventListener('change', () => { initializeCanvas(); }); undoButton.addEventListener('click', () => { undo(); }); resizeCanvas(); </script> </body> </html>
זה הקוד.... עובד גם בטלפון
-
@עם-ישראל-חיי כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@נחמן-פלח איך מפעילים את זה בטלפון?
אתה פותח קובץ טקסט חדש, מעתיק לשם את הקוד ושומר, ואז תשנה את הסיומת ל html,
ואז תפתח את זה עם הדפדפן -
@רפאל-vnkl כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@נחמן-פלח אחלה...
אבל התפריט תופס שתי שליש מהמסך (ועל חשבון הקנבס...)
לא עדיף להקטין אותו?אני ינסה
-
הקטנתי את התפריט, ואפשרתי להחליף רקע בלי לאבד את כל העבודה הקודמת.
התבססתי על הסקריפט המקורי + כפתור הביטול של @נחמן-פלח (מקווה שלא הפרתי זכויות יוצרים או משהו).
שימו לב שביטול הפעולה האחרונה חלה רק על הקווים המצוירים ולא על צבע הרקע.
כמו כן - לפני שאתם קובעים צבע רקע, הורידו את הסימון מ"רקע שקוף" על מנת שתוכלו לראות את הצבע.יוצר המנדלות + ביטול פעולה אחרונה.zip
עריכה: @נחמן-פלח אני רואה שתיקנת את השגיאה, אם תרצה שאמחק את הפוסט - תעדכן.
-
עדכון ניתן לבחור גודל קנבס מותאם אישית במידה ושינתם גודל זה מוחק הכל
ברירת מחדל רקע שקוף לא מסומן אם בחרתם צבע ואז אתם רוצים רקע שקוף אתם צריכים לסמן רקע שקוף ואז לשנות צבע וזה יהפך לרקע שקוף
לדוגמה בחרתם צבע כחול ואז אתם רוצים לשנות לשקוף תסמנו שקוף ואז תשנו צבע לא לצבע שבחרתם (כחול) אלה לצבע אחר ואז זה יהפוך לרקע שקוף.