להורדה | מחולל מנדלות איכותי ופשוט
-
הוספתי תיבת בחירה לרקע שקוף, בדרך גם תיקנתי את התיבה של הפקדים - שתהיה מימין לשמאל.
זה רלוונטי רק לתמונה שיורדת בלחיצה על שמור - לא רואים את השינוי במחולל עצמו.
עריכה: אני רואה שבאתר לא שמים לב להבדל, אבל אם תורידו את התמונות תראו שהראשון בעל רקע לבן והשני בעל רקע שקוף.
-
@רפאל-vnkl תקשיב, זה מטורף!
טוב לדקות של שיעמום...
@ישראל-142 הצבעים בהשראת הפרופיל שלך...
המלצה לשיפור, אם אפשר לעשות שיהיה אפשרות לביטול פעולה אחרונה (קונטרול Z)
הייתה לי תזוזה לא נכונה והייתי צריך להתחיל מהתחלה...
-
-
-
@יוסף-אלחנן כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@חטח כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
בטח לקח לך שעות!
ממש לא!
זה כל כך קל...
כשאתה עושה משהו קטן
כמו זה
אז זה קל, אבל מה שאתה עשית לוקח זמן...
-
@רפאל-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 כתב בלהורדה | מחולל מנדלות איכותי ופשוט:
@נחמן-פלח אחלה...
אבל התפריט תופס שתי שליש מהמסך (ועל חשבון הקנבס...)
לא עדיף להקטין אותו?אני ינסה