Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Рисование линии на CANVAS (https://javascript.ru/forum/dom-window/40306-risovanie-linii-na-canvas.html)

essere 31.07.2013 09:49

Рисование линии на CANVAS
 
Всем добра!
Господа, у меня есть опыт работы с JS/Jquery, но никогда не работал с CANVAS'ом.
Есть задачка:
Есть холст, на нем пользователь ставит первую точку, вторую точку. И, между ними рисуется линия.
Потом пользователь рисует вторую линию, точно так же.
Задача: найти середины этих линий и провести от них перпендикуляры (эта линия, которая лежит под углом 90 градусов).
Синьоры, я хочу разобраться, может быть есть библиотечка какая-нибудь по работе с канвасом, ну и вообще, как логически решить задачу. Список методов по работе с этим объектом то найти не проблема, а вот как стартануть.
Спасибо

essere 31.07.2013 11:20

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 265190)
А в чем проблема? Нарисовать линию или вычислить перпендикуляр?
Для таких простых вещей библиотеки не нужны.)

Ну например, для того чтобы поставить на канве точки.
Полагаю как то надо сначала получить координаты "клика", потом координаты второго клика.
Нашел функцию получения координат:
function cnvs_getCoordinates(e) {
            x=e.clientX;
            y=e.clientY;
            document.getElementById("xycoordinates").innerHTML="Coordinates: (" + x + "," + y + ")";
}

Почему то не работает в секции $(document).ready(function() {...

essere 31.07.2013 11:23

Во, даже вот так:
function cnvs_getCoordinates(e) {
            $("#xycoordinates").text( e.clientX + "," + e.clientY );
}

essere 31.07.2013 11:35

Потом, логично создать функцию рисования самой линии. Объявив ее вне секции $(document).ready(function() {...
А уже в $(document).ready(function() {... мы ее вызываем.
function drowLine(x_first, y_first, x_second, y_second) {
            var canvas = document.getElementById("myCanvas");  
            var ctx = canvas.getContext("2d");
            ctx.moveTo( x_first, y_first );
            ctx.lineTo( x_second, y_second );
            ctx.stroke();
        }

essere 31.07.2013 11:44

Но ведь промежуточный итог тоже же где то хранить надо т.е. координаты точка1 и координаты точка2, а потооом уже только вызывать функцию рисования.

essere 31.07.2013 12:25

Спасибо, изучу.
Но дошел до
var coords = [];

        function getCoords(e)
        {
            coords.push(e.clientX, e.clientY);

            if (coords.length === 4) {
                //alert(coords[0] +','+ coords[1] +','+ coords[2] +','+ coords[3]);

                drowLine(coords[0], coords[1], coords[2], coords[3]);

                coords = [];
            }
        }

Вот так хранить координаты

essere 31.07.2013 14:24

Вобщем вот такая красота получилась:
<body>  
    <canvas onclick="getCoords(event)" style="border: 1px solid #c6c6c6" id="myCanvas" width="500" height="500">
          <!-- Insert fallback content here -->  
    </canvas>  
    <script>  

    var coords = [];
    var perps = [];

    var ctx = document.getElementById("myCanvas").getContext("2d");

        function getCoords(e)
        {
            //alert(e.clientX + " на " + e.clientY);

            drawCircle(e.clientX, e.clientY, 3);
                
            coords.push(e.clientX, e.clientY);

            if (coords.length === 4) {
                x1 = coords[0]; y1 = coords[2];
                x2 = coords[1]; y2 = coords[3];

                var perpX = (x1 + y1)/2;
                var perpY = (x2 + y2)/2;

                drawCircle(perpX, perpY, 3);

                //drawLine(perpX, perpY, perpX+200, perpY+200);
                drawLine(coords[0], coords[1], coords[2], coords[3]);
                coords = [];

            }
        }


    function drawLine(x_first, y_first, x_second, y_second) 
    {
        ctx.beginPath();   
        ctx.moveTo( x_first, y_first );
        ctx.lineTo( x_second, y_second );
        ctx.lineWidth = 2; 
        ctx.stroke();
    }

    function drawCircle(x, y, radius) 
    {
        ctx.beginPath();  
        ctx.arc(x, y, radius, 0, Math.PI*2, false);  
        ctx.closePath();  
        ctx.fill();  
    }

    $(document).ready(function() 
    {  
        //drawLine(100, 100, 250, 300);
         //var canvas = document.getElementById("myCanvas");  
         //var ctx = canvas.getContext("2d");  
         //...
    });  

   </script>  
   </body>

Вот только не могу понять, как перпендикуляр отвести, старт то известно откуда "вести" его, а вот куда ...

essere 31.07.2013 15:50

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 265274)
Комментарии в коде для кого написаны? :cray:

// половинный вектор перпендикуляра
var perpHalfDX = -dy / lineLen * perpLen / 2;
var perpHalfDY = +dx / lineLen * perpLen / 2;

...


// перпендикуляр

ctx.beginPath();
ctx.moveTo( midX - perpHalfDX, midY - perpHalfDY );
ctx.lineTo( midX + perpHalfDX, midY + perpHalfDY );
ctx.stroke();

Да это я пробовал:
var coords = [];
    var perps = [];

    var ctx = document.getElementById("myCanvas").getContext("2d");

        function getCoords(e)
        {
            //alert(e.clientX + " на " + e.clientY);

            drawCircle(e.clientX, e.clientY, 3);
                
            coords.push(e.clientX, e.clientY);

            if (coords.length === 4) {
                x1 = coords[0]; y1 = coords[2];
                x2 = coords[1]; y2 = coords[3];

                var dx = x2 - x1;
                var dy = y2 - y1;
                var lineLen = Math.sqrt( dx * dx + dy * dy );

                var perpHalfDX = -dy / lineLen * perpLen / 2;
                var perpHalfDY = +dx / lineLen * perpLen / 2;

        
                var perpX = (x1 + y1)/2;
                var perpY = (x2 + y2)/2;
                
                ctx.beginPath();
                ctx.moveTo( perpX - perpHalfDX, perpY - perpHalfDY );
                ctx.lineTo( perpX + perpHalfDX, perpY + perpHalfDY );
                ctx.stroke();

                drawCircle(perpX, perpY, 3);

                //drawLine(perpX, perpY, perpX+200, perpY+200);
                drawLine(coords[0], coords[1], coords[2], coords[3]);
                coords = [];

            }
        }


    function drawLine(x_first, y_first, x_second, y_second) 
    {
        ctx.beginPath();   
        ctx.moveTo( x_first, y_first );
        ctx.lineTo( x_second, y_second );
        ctx.lineWidth = 2; 
        ctx.stroke();
    }

    function drawCircle(x, y, radius) 
    {
        ctx.beginPath();  
        ctx.arc(x, y, radius, 0, Math.PI*2, false);  
        ctx.closePath();  
        ctx.fill();  
    }

    $(document).ready(function() 
    {  
        //drawLine(100, 100, 250, 300);
         //var canvas = document.getElementById("myCanvas");  
         //var ctx = canvas.getContext("2d");  
         //...
    });

Только не работает оно.
Математика чертова ;[

essere 31.07.2013 16:22

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 265280)
почему perpLen не определен?

и почему
var perpX = (x1 + y1)/2;
var perpY = (x2 + y2)/2;

если нужно
var perpX = (x1 + x2)/2;
var perpY = (y1 + y2)/2;

???

coords.push(e.clientX, e.clientY);

x1 = coords[0]; y1 = coords[2];
x2 = coords[1]; y2 = coords[3];

тут вообще иксы и игреки перепутаны...

блин, ну нельзя же быть настолько невнимательным)

Почему перепутаны то) Это я сам писал.

essere 31.07.2013 16:26

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 265284)
А мой код, который я писал в соответствии с тем что x - это всегда икс, а y - всегда игрек, должен заработать на неправильном сопоставлении переменных автоматически?

Просто из курса школьной геометрии помнится х1 у1, х2 у2 и т.д.


Часовой пояс GMT +3, время: 13:02.