• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Canvas- javascript figury i text

Object Storage Arubacloud
0 głosów
210 wizyt
pytanie zadane 23 listopada 2019 w JavaScript przez Młody programista Obywatel (1,200 p.)

Witam, moim problemem jest to, że chciałbym napisać funkcje, która rysuje kwadrat (tak jak w paint'cie) oraz funkcje która będzie dodawać tekst, tzn. wpisywać go w pole. Chcę stworzyć prostego paint'a, ale moje próby łączenia wszystkich funkcji, by prawidłowo działały, kończą się klęską. Proszę o pomoc.

* {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

body {
    margin: 0;
}

canvas {
    display: block;
}

#toolbar {
    width: 100%;
    padding: 10px;
    position: absolute;
    top: 0;
    background-color: #2e0909;
    overflow: auto;
}

#colors {
    position: relative;
    float: left;
    margin-left: 20px;
    margin-right: 20px;
    font-size: 20px;
    font-weight: 500;
    font-family: Verdana;
    color: white;
    white-space: nowrap;
}

#range {
    position: relative;
    float: left;
    font-size: 20px;
    font-weight: 500;
    font-family: Verdana;
    color: white;
    white-space: nowrap;
    margin-right: 20px;
}

#myColor,
#myRange {
    cursor: pointer;
}

#brush,
#erase {
    position: relative;
    float: left;
    height: 30px;
    width: 40px;
    background-color: white;
    text-align: center;
    cursor: pointer;
    outline: none;
}

#rectangle {
    position: relative;
    float: left;
    height: 30px;
    width: 40px;
    background-color: white;
    text-align: center;
    cursor: pointer;
    outline: none;
}

#text {
    position: relative;
    float: left;
    height: 30px;
    width: 40px;
    background-color: white;
    text-align: center;
    cursor: pointer;
    outline: none;
}

#brush {
    margin-right: 20px;
}

#reset,
#save {
    position: relative;
    float: right;
    font-size: 20px;
    font-family: Verdana;
    font-weight: 500;
    background-color: white;
    color: #4f4f4f;
    text-align: center;
    cursor: pointer;
}

#reset {
    height: 30px;
    width: 70px;
    margin-right: 15px;
}

#save {
    height: 30px;
    width: 77px;
    margin-right: 10px;
}
<!DOCTYPE html>
<html>

<head>
    <title>Paint</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="style.css" />
</head>

<body>
    <div id="toolbar">
        <div id="colors">Kolor: <input type="color" value="#ffff00" name="myColor" id="myColor"></div>
        <div id="range">Rozmiar: 1<input type="range" id="myRange" value="5" min="1" max="100">100</div>
        <button id="brush"><img src="images/brush.png"></button>
        <button id="erase"><img src="images/eraser.png"></button>
        <button id="rectangle"><img src="images/rectangle.png"></button>
        <button id="text"><img src="images/text.png"></button>
        <a href="" id="saveLink"><button id="save">Zapisz</button></a>
        <button id="reset">Reset</button>
        <br>
    </div>
    <canvas id="canvas">Twoja przeglądarka nie wspiera canvas. Zaktualizuj ją !</canvas>
    <script>
        //Inicjalizacja okna canvas
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        var mouse = false;
        ctx.lineJoin = "round";
        ctx.lineCap = "round";
        var positionX, positionY;

        //Pobieranie id przyciskow 
        var brush = document.getElementById("brush");
        var eraser = document.getElementById("erase");
        var rectangle = document.getElementById("rectangle");
        var text = document.getElementById("text");
        var color = document.getElementById("myColor");
        var size = document.getElementById("myRange");
        var reset = document.getElementById("reset");
        var saveLink = document.getElementById("saveLink");

        //Kolor
        var myColor = color.value;
        ctx.strokeStyle = myColor;

        //Rysowanie
        var mySize = size.value;
        ctx.lineWidth = mySize;

        brush.style.border = "2px solid red";
        canvas.style.cursor = "pointer";

        canvas.addEventListener("mousedown", brushDown, false);
        canvas.addEventListener("mousemove", brushMove, false);
        canvas.addEventListener("mouseup", brushUp, false);

        //Wybor koloru
        function colorChange() {
            myColor = color.value;
            ctx.strokeStyle = myColor;
        }

        //Wybor rozmiaru
        function sizeChange() {
            mySize = size.value;
            ctx.lineWidth = mySize;
        }

        //Praca pedzla
        function getCoordinates(canvas, e) {
            var rect = canvas.getBoundingClientRect();
            return {
                x: e.clientX - rect.left,
                y: e.clientY - rect.top
            };
        }

        function brushDraw(canvas, positionX, positionY) {
            if (mouse) {
                ctx.lineTo(positionX, positionY);
                ctx.stroke();
                canvas.style.cursor = "pointer";
            }
        }

        function brushDown(e) {
            mouse = true;
            var coordinates = getCoordinates(canvas, e);
            canvas.style.cursor = "pointer";
            positionX = coordinates.x;
            positionY = coordinates.y;
            ctx.beginPath();
            ctx.moveTo(positionX, positionY);
            ctx.lineTo(positionX, positionY);
            ctx.stroke();
        }

        function brushMove(e) {
            var coordinates = getCoordinates(canvas, e);
            positionX = coordinates.x;
            positionY = coordinates.y;
            brushDraw(canvas, positionX, positionY);
        }

        function brushUp() {
            mouse = false;
            canvas.style.cursor = "default";
        }

        function brushClick() {
            var brushColor = document.getElementById("myColor");
            ctx.strokeStyle = brushColor.value;
            brush.style.border = "2px solid red";
            eraser.style.border = "none";
            rectangle.style.border = "none";
            text.style.border = "none";

            canvas.addEventListener("mousedown", brushDown, false);
            canvas.addEventListener("mousemove", brushMove, false);
            canvas.addEventListener("mouseup", brushUp, false);
        }

        //Praca gumki 
        function eraserClick() {
            ctx.strokeStyle = "white";
            eraser.style.border = "2px solid red";
            brush.style.border = "none";
            rectangle.style.border = "none";
            text.style.border = "none";

            canvas.addEventListener("mousedown", brushDown, false);
            canvas.addEventListener("mousemove", brushMove, false);
            canvas.addEventListener("mouseup", brushUp, false);
        }

        //Reset okna
        function resetClick() {
            window.location.reload();
        }

        //Zapisywanie 
        function saveClick() {
            var data = canvas.toDataURL();
            console.log(data);
            saveLink.href = data;
            saveLink.download = "myImage.png";
        }

        //Text
        function Text() {
            text.style.border = "2px solid red";
            rectangle.style.border = "none";
            eraser.style.border = "none";
            brush.style.border = "none";

            canvas.addEventListener("mousedown", brushDown, false);
            canvas.addEventListener("mousemove", brushMove, false);
            canvas.addEventListener("mouseup", brushUp, false);

        }

        //figura
        function changerectangle() {
            rectangle.style.border = "2px solid red";
            text.style.border = "none";
            eraser.style.border = "none";
            brush.style.border = "none";


            canvas.addEventListener("mousedown", brushDown, false);
            canvas.addEventListener("mousemove", brushMove, false);
            canvas.addEventListener("mouseup", brushUp, false);

        }
        brush.addEventListener("click", brushClick);
        eraser.addEventListener("click", eraserClick);
        rectangle.addEventListener('click', changerectangle);
        text.addEventListener('click', Text);
        color.addEventListener("change", colorChange);
        size.addEventListener("change", sizeChange);
        reset.addEventListener("click", resetClick);
        saveLink.addEventListener("click", saveClick);
    </script>
</body>

</html>

 

1 odpowiedź

0 głosów
odpowiedź 24 listopada 2019 przez DawidK Nałogowiec (37,910 p.)

To co przychodzi mi do głowy to tam gdzie masz eventListenery na 'onclick' do zmiany obramowania przycisku i pobrania aktualnych wielkości i koloru linii rozbudować na funkcje rozpoznające rodzaj akcji czyli powiedzmy:

napisanie jednej funkcja usuwająca eventListenery np removeAllCanvasListeners();

napisanie funkcji dodającej eventListenery do poszczególnych akcji addBrushListeners(), addErasterListeners() itd

 

        brush.addEventListener("click", brushChoosed);

        function brushChoosed() {
            brushClick(); //bez eventlistenerów
            removeAllCanvasListeners();
            addBrushListeners();
        }

i podobnie dla pozostałych funkcji czyli onclick -> wybór akcji -> zaznaczenie przycisku -> odpięcie nieaktualnych listenerów -> podpięcie listenerów odpowiedzialnych za tą akcje

komentarz 24 listopada 2019 przez Młody programista Obywatel (1,200 p.)
A mógłbyś zmodyfikować mój kod, tak by działał jak mówisz.
komentarz 25 listopada 2019 przez DawidK Nałogowiec (37,910 p.)

1) style.css

Tutaj dodałem tylko klasę .active-button na końcu, wcześniej po kliknięciu na któryś z buttów a następnie jakiś inny pozostałe buttony traciły "wypukły" wygląd przez  element.style.border = "none";

* {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
 
body {
    margin: 0;
}
 
canvas {
    display: block;
}
 
#toolbar {
    width: 100%;
    padding: 10px;
    position: absolute;
    top: 0;
    background-color: #2e0909;
    overflow: auto;
}
 
#colors {
    position: relative;
    float: left;
    margin-left: 20px;
    margin-right: 20px;
    font-size: 20px;
    font-weight: 500;
    font-family: Verdana;
    color: white;
    white-space: nowrap;
}
 
#range {
    position: relative;
    float: left;
    font-size: 20px;
    font-weight: 500;
    font-family: Verdana;
    color: white;
    white-space: nowrap;
    margin-right: 20px;
}
 
#myColor,
#myRange {
    cursor: pointer;
}
 
#brush,
#erase {
    position: relative;
    float: left;
    height: 30px;
    width: 40px;
    background-color: white;
    text-align: center;
    cursor: pointer;
    outline: none;
}
 
#rectangle {
    position: relative;
    float: left;
    height: 30px;
    width: 40px;
    background-color: white;
    text-align: center;
    cursor: pointer;
    outline: none;
}
 
#text {
    position: relative;
    float: left;
    height: 30px;
    width: 40px;
    background-color: white;
    text-align: center;
    cursor: pointer;
    outline: none;
}
 
#brush {
    margin-right: 20px;
}
 
#reset,
#save {
    position: relative;
    float: right;
    font-size: 20px;
    font-family: Verdana;
    font-weight: 500;
    background-color: white;
    color: #4f4f4f;
    text-align: center;
    cursor: pointer;
}
 
#reset {
    height: 30px;
    width: 70px;
    margin-right: 15px;
}
 
#save {
    height: 30px;
    width: 77px;
    margin-right: 10px;
}

.active-button {
    border: 2px solid red;
}

2) index.html (razem z js)

Większość elementów tak naprawdę miałeś. Nie podmieniałem ikonek akcji (nie chciało mi się szukać grafik) - zmieniłem je po prostu na symbole liter.

Funkcje dla pędzla i gumki to jedno i to samo różnią się tylko kolorem, albo z inputa albo biały - stąd pojawiła się zmienna isEraster - wykorzystywana później w brushDown do nadania odpowiedniego koloru. Rysowanie prostokąta zostało zreaizowane w trochę uproszczony sposób tzn. bez pokazywania aktualnej wartości gdyby puścić przycisk myszki - rectangleStart stawia tylko kropkę w miejscu początkowego narożnika a rectangleEnd wylicza długość i szerokość i ostatecznie go rysuje. Funkcja dla tekstu też jest dosyć uproszczona pobierane są współrzędne napisu oraz wyskakuje okienko, żeby go wpisać. Obie te funkcje możnaby pewnie zrealizować lepiej dzięki metodom canvas save() i restore().

<!DOCTYPE html>
<html>
 
<head>
    <title>Paint</title>
    <meta charset='utf-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <link rel='stylesheet' type='text/css' href='style.css' />
</head>
 
<body>
    <div id='toolbar'>
        <div id='colors'>Kolor: <input type='color' value='#ffff00' name='myColor' id='myColor'></div>
        <div id='range'>Rozmiar: 1<input type='range' id='myRange' value='5' min='1' max='100'>100</div>
        <button id='brush'><b>O</b></button>
        <button id='erase'><b>G</b></button>
        <button id="rectangle"><b>P</b></button>
        <button id='text'><b>T</b></button>
        <a href='' id='saveLink'><button id='save'>Zapisz</button></a>
        <button id='reset'>Reset</button>
        <br>
    </div>
    <canvas id="canvas">Twoja przeglądarka nie wspiera canvas. Zaktualizuj ją !</canvas>
    <script>
        //Inicjalizacja okna canvas
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        ctx.lineJoin = 'round';
        ctx.lineCap = 'round';
        canvas.style.cursor = 'pointer'; //przeniesione
 
        //Pobieranie id przyciskow 
        const brush = document.getElementById('brush');
        const eraser = document.getElementById('erase');
        const rectangle = document.getElementById('rectangle');
        const text = document.getElementById('text');
        const color = document.getElementById('myColor');
        const size = document.getElementById('myRange');
        const reset = document.getElementById('reset');
        const saveLink = document.getElementById('saveLink');
 
        //Kolor
        let myColor = color.value;
        ctx.strokeStyle = myColor;
 
        //Rysowanie
        let mySize = size.value;
        ctx.lineWidth = mySize;

        let isEraster = false;
        
        brush.addEventListener('click',brushChoosed, false);
        eraser.addEventListener('click', eraserChoosed, false);
        rectangle.addEventListener('click', rectangleChoosed, false);
        text.addEventListener('click', textChoosed, false);
        color.addEventListener('change', colorChange);
        size.addEventListener('change', sizeChange);
        reset.addEventListener('click', resetClick);
        saveLink.addEventListener('click', saveClick);

        function brushChoosed() {
            isEraster = false;
            removeButtonsBorder();
            removeAllCanvasListeners();
            brush.classList.add('active-button');
            addBrushEvents();
        }

        function addBrushEvents() {
            canvas.addEventListener('mousedown',brushDown, false);
            canvas.addEventListener('mouseup',brushUp, false);
        }

        function brushDown(e) {
            const coordinates = getCoordinates(canvas, e);
            canvas.style.cursor = 'pointer';
            positionX = coordinates.x;
            positionY = coordinates.y;
            ctx.lineWidth = mySize;
            if(isEraster) {
                ctx.strokeStyle = 'white';
            } else {
                ctx.strokeStyle = myColor;
            }
            ctx.beginPath();
            ctx.moveTo(positionX, positionY);
            ctx.lineTo(positionX, positionY);
            ctx.stroke();
            canvas.addEventListener('mousemove',brushMove,false);
        }

        function brushMove(e) {
            const coordinates = getCoordinates(canvas, e);
            positionX = coordinates.x;
            positionY = coordinates.y;
            brushDraw(canvas, positionX, positionY);
        }

        function brushDraw(canvas, positionX, positionY) {
            ctx.lineTo(positionX, positionY);
            ctx.stroke();
            canvas.style.cursor = 'pointer';
        }

        function brushUp() {
            canvas.style.cursor = 'default';
            canvas.removeEventListener('mousemove', brushMove, false);
        }

        function eraserChoosed() {
            isEraster = true;
            removeButtonsBorder();
            removeAllCanvasListeners();
            eraser.classList.add('active-button');
            addBrushEvents();
        }

        function rectangleChoosed() {
            removeButtonsBorder();
            removeAllCanvasListeners();
            rectangle.classList.add('active-button');
            addRectangleEvents();
        }

        function addRectangleEvents() {
            canvas.addEventListener('mousedown',rectangleStart, false);
            canvas.addEventListener('mouseup',rectangleEnd, false);
        }

        function rectangleStart(e) {
            const coordinates = getCoordinates(canvas, e);
            canvas.style.cursor = 'pointer';
            positionX = coordinates.x;
            positionY = coordinates.y;
            ctx.lineWidth = mySize;
            ctx.strokeStyle = myColor;
            ctx.beginPath();
            ctx.arc(positionX,positionY,1,0,Math.PI*2,false);
            ctx.fill();
            ctx.stroke();
        }

        function rectangleEnd(e) {
            const coordinates = getCoordinates(canvas, e);
            canvas.style.cursor = 'pointer';
            positionXend = coordinates.x;
            positionYend = coordinates.y;
            let rectangleWidth = positionXend-positionX;
            let rectangleHeight = positionYend-positionY;
            ctx.beginPath();
            ctx.rect(positionX, positionY,rectangleWidth, rectangleHeight);
            ctx.stroke();
        }

        function textChoosed() {
            removeButtonsBorder();
            removeAllCanvasListeners();
            text.classList.add('active-button');
            addTextEvents();
        }

        function addTextEvents() {
            canvas.addEventListener('mousedown',writeText, false);
        }

        function writeText(e) {
            const coordinates = getCoordinates(canvas, e);
            positionX = coordinates.x;
            positionY = coordinates.y;
            ctx.fillStyle = myColor;
            let font = `${mySize}pt Arial`;
            ctx.font=font;
            let text = prompt('wpisz tekst');
            ctx.fillText(text, positionX, positionY);
        }

        function removeButtonsBorder() {
            brush.classList.remove('active-button');
            eraser.classList.remove('active-button');
            rectangle.classList.remove('active-button');
            text.classList.remove('active-button');

        }

        function removeAllCanvasListeners() {
            canvas.removeEventListener('mousedown',brushDown, false);
            canvas.removeEventListener('mouseup',brushUp, false);
            canvas.removeEventListener('mousedown',rectangleStart, false);
            canvas.removeEventListener('mouseup',rectangleEnd, false);
            canvas.removeEventListener('mousedown',writeText, false);
        }

        //Wybor koloru
        function colorChange() {
            myColor = color.value;
            ctx.strokeStyle = myColor;
        }
 
        //Wybor rozmiaru
        function sizeChange() {
            mySize = size.value;
            ctx.lineWidth = mySize;
        }
 
        //Praca pedzla
        function getCoordinates(canvas, e) {
            const rect = canvas.getBoundingClientRect();
            return {
                x: e.clientX - rect.left,
                y: e.clientY - rect.top
            };
        }
 
        //Reset okna
        function resetClick() {
            window.location.reload();
        }
 
        //Zapisywanie 
        function saveClick() {
            var data = canvas.toDataURL();
            console.log(data);
            saveLink.href = data;
            saveLink.download = "myImage.png";
        }
    </script>
</body>
 
</html>

 

komentarz 27 listopada 2019 przez Młody programista Obywatel (1,200 p.)

Wielkie dzięki, trochę jeszcze pokombinowałem i działa tak jak chciałem.laugh

Podobne pytania

0 głosów
1 odpowiedź 112 wizyt
pytanie zadane 24 kwietnia 2020 w JavaScript przez DanexZ Obywatel (1,270 p.)
0 głosów
0 odpowiedzi 73 wizyt
pytanie zadane 4 lutego 2023 w JavaScript przez TOWaD Mądrala (6,000 p.)

92,576 zapytań

141,426 odpowiedzi

319,651 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...