Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing arrows on a chess board in Javascript

I am trying to make my own chess analysis board to use when teaching chess. I currently have the board, pieces that I can drag and drop, as well as a method for clearing the board and setting up different board positions. I can also click on squares to highlight them.

I want to be able to draw arrows from one square to another to show lines of attack and influence but have no idea how to accomplish this. My board is made up of <div> tags. A short example is below (pseudo-code and actual code for brevity).

// a couple of CSS styles to define the width, height, and color of the squares CSS Style Class "dark square" CSS Style Class "light square"

//my board is made up of <div> tags

<div id="board">
    <div id="a1" class="lightsquare"></div>
    <div id="a2" class="darksquare"></div>
    <div id="a3" class="lightsquare"></div>
    //second rank
    <div id="b1" class="darksquare"></div>
    <div id="b2" class="lightsquare"></div>
    <div id="b3" class="darksquare"></div>

    //third rank
    <div id="c1" class="lightsquare"></div>
    <div id="c2" class="darksquare"></div>
    <div id="c3" class="lightsquare"></div>
</div>

I can place pieces on the board, move them around, take other pieces, clear the board, set up unique positions, and highlight individual squares just fine, but would also like to be able to have the user click, drag, and draw arrows live on the board while still being able to manipulate the pieces on the board.

I looked at using the tag but based on my reading and research, it doesn't seem like the <canvas> tag was designed to do what I am looking for.

Does anyone have any ideas on how to do this in JavaScript? I have not learned to use JQuery yet, and would prefer to avoid using JQuery as I don't want to have to download an extra file or necessarily be on the internet to use this program.

like image 219
SteampunkWizard Avatar asked Aug 27 '14 13:08

SteampunkWizard


People also ask

How do you draw arrows in chess Mac?

The members (owner and students) can draw an arrow from one square to another right-clicking, holding the mouse button down and dragging the mouse to the square they want to land on.

How do you draw on chess com?

On Chess.com, this draw happens automatically on the third repetition in Live games. The repeated position does not need to happen on 3 consecutive moves, any time the same position occurs three times, at any point in a game, on the third time that game is declared a draw.


2 Answers

So after a month of tinkering I have finally found a solution. As much effort as I put into using < div > tags and images to solve this problem, I could never get the arrow to position itself correctly when rotated. I therefore went back to trying out the < canvas > tag and I did finally find a solution that works.

function drawArrow(fromx, fromy, tox, toy){
            //variables to be used when creating the arrow
            var c = document.getElementById("myCanvas");
            var ctx = c.getContext("2d");
            var headlen = 10;

            var angle = Math.atan2(toy-fromy,tox-fromx);

            //starting path of the arrow from the start square to the end square and drawing the stroke
            ctx.beginPath();
            ctx.moveTo(fromx, fromy);
            ctx.lineTo(tox, toy);
            ctx.strokeStyle = "#cc0000";
            ctx.lineWidth = 22;
            ctx.stroke();

            //starting a new path from the head of the arrow to one of the sides of the point
            ctx.beginPath();
            ctx.moveTo(tox, toy);
            ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));

            //path from the side point of the arrow, to the other side point
            ctx.lineTo(tox-headlen*Math.cos(angle+Math.PI/7),toy-headlen*Math.sin(angle+Math.PI/7));

            //path from the side point back to the tip of the arrow, and then again to the opposite side point
            ctx.lineTo(tox, toy);
            ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));

            //draws the paths created above
            ctx.strokeStyle = "#cc0000";
            ctx.lineWidth = 22;
            ctx.stroke();
            ctx.fillStyle = "#cc0000";
            ctx.fill();
        }

This code will get its start and end coordinates based on the coordinates of the squares at the mouse down and mouse up events. It will then use those coordinates to determine how the arrow should be drawn with the proper rotation.

like image 101
SteampunkWizard Avatar answered Sep 21 '22 15:09

SteampunkWizard


If your asking how to approach this (fun) problem, I would go about it like this.

  1. Make your arrow with 2 pngs: 2 divs with background images (body and point of the arrow) inside one container div.
  2. Once you have the code to properly display the arrow, make sure you know how to append it to the DOM using javascript.
  3. Now try to make the arrow longer and shorter with javascript (by changing the size of the div containing the body of the arrow)
  4. Once you can do this, it's time for math. Use javascript to calculate the coordinates of the DIV that is clicked first when making an arrow, and the DIV that is clicked second. When you have these coordinates, calculate (using Pythagoras) the length of the arrow you need, and the amound of rotation you need (this is the tricky part, but I have done it before so it can certainly be done if you know some basic math). You are essentially creating triangles on the board.
  5. With the coordinates, length and rotation, you can now place your arrow on the playing board, adjust the length and the rotation, to display it just the way you need it. And remember you can also turn the arrow for say 350 degrees to get to -10 degrees.

This is by no means easy but a lot of fun if you like math, and considering chess, I guess you do.

By the way, this problem can certainly be solved with plain JS but using jQuery would make it easier en less work. You can also use jQuery offline by downloading the library.

like image 43
Derk Arts Avatar answered Sep 22 '22 15:09

Derk Arts