Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove current line between 2 DIVs created if user want to change the answer

I was created 2 lines between 2 DIVs once user click the DIVs. Now I got problem on how to reset the unwanted line if I want to change my answer.

You may see my current code for your references:

var lastSelection;

// Add click listener for answer-container
function listenToClick() {
    var rows = document.querySelectorAll('.row'),
        row;
    var cols, col;

    for (row = 0; row < rows.length; row++) {
        cols = rows[row].children;

        for (col = 0; col < cols.length; col++) {
            // Bind information about which answer is this,
            // so we can prevent from connecting two answers on
            // same column.
            cols[col].addEventListener('click', selectAnswer.bind({
                row: row,
                col: col,
                element: cols[col]
            }));
        }
    }
}

// This is fired when a answer-container is clicked.
function selectAnswer(event) {
    if (lastSelection) {
        lastSelection.element.classList.remove('selected');
    }

    if (!lastSelection || lastSelection.col === this.col) {
        lastSelection = this;
        this.element.classList.add('selected');
    } else {
        drawLine(getPoint(this.element), getPoint(lastSelection.element));
        lastSelection = null;
    }
}

function getPoint(answerElement) {
    var roundPointer = answerElement.lastElementChild;

    return {
        y: answerElement.offsetTop + roundPointer.offsetTop + roundPointer.offsetHeight / 2,
        x: answerElement.offsetLeft + roundPointer.offsetLeft + roundPointer.offsetWidth / 2
    };
}

function drawLine(p1, p2) {
    var canvas = document.getElementById("connection-canvas");
    var ctx = canvas.getContext("2d");

    ctx.beginPath();
    ctx.moveTo(p1.x, p1.y);
    ctx.lineTo(p2.x, p2.y);
    ctx.stroke();
}

function resizeCanvas() {
    var canvas = document.getElementById("connection-canvas");
    var ctx = canvas.getContext("2d");

    ctx.canvas.width  = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
}

listenToClick();
resizeCanvas();
.padding-answer-line-mapping
{
    padding-bottom:8px;
}

.answer-container
{
    width:40px;
    height:40px;
    background-color:#ccc;
    border:1px solid #ccc;
    margin:2px;
    float:left;
    text-align:center;
    padding-top:8px;
    cursor:pointer;
    position:relative;
}

.answer-container:hover, .answer-container:focus, .answer-container:active
{
    background-color: #0076e9;
    color: white;
    border: 1px solid #0076e9;
}

.round-pointer-right
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    right:0px;
    top:14px;
    margin-right:-20px;
}

.round-pointer-left
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    left:0px;
    top:14px;
    margin-left:-20px;
}

.selected {
    background-color: red;
}
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet"/>
Match the following items.

 <canvas id="connection-canvas" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></canvas>
<div class="row padding-answer-line-mapping">
    <div class="col answer-container">
        One
        <div class="round-pointer-right"></div>
    </div>
    <div class="col">
        
    </div>
    <div class="col answer-container">
        2
        <div class="round-pointer-left"></div>
    </div>
</div>
<div class="row padding-answer-line-mapping">
    <div class="col answer-container">
        Two
        <div class="round-pointer-right"></div>
    </div>
    <div class="col">
        
    </div>
    <div class="col answer-container">
        1
        <div class="round-pointer-left"></div>
    </div>
</div>
like image 655
Nere Avatar asked Oct 04 '16 06:10

Nere


3 Answers

Let me know if you have any issue.

var lastSelection;
var p = 0;
var canvasPoints = [];

function listenToClick() {
  var rows = document.querySelectorAll('.row'),
    row;
  var cols, col;

  for (row = 0; row < rows.length; row++) {
    cols = rows[row].children;

    for (col = 0; col < cols.length; col++) {
      cols[col].addEventListener('click', selectAnswer.bind({
        row: row,
        col: col,
        element: cols[col]
      }));
    }
  }
}
var question = null;
var answer = null;

// This is fired when a answer-container is clicked.
function selectAnswer(event) {

  if (this.element.classList.contains("answer")) {
    answer = this.element;
  } else if (this.element.classList.contains("question")) {
    question = this.element;
    answer = null;
  }
  if (question && answer) {
    if (!removeObjects()) {
      var points = {};
      points.answer = getPoint(answer);
      points.question = getPoint(question);
      canvasPoints.push(points);
    }
  } else if (answer) {
    console.log("Please select Left option");
  }
  resizeCanvas();
}

function getPoint(answerElement) {
  var roundPointer = answerElement.lastElementChild;
  return {
    y: answerElement.offsetTop + roundPointer.offsetTop + roundPointer.offsetHeight / 2,
    x: answerElement.offsetLeft + roundPointer.offsetLeft + roundPointer.offsetWidth / 2,
    text: answerElement.innerText
  };
}

function drawLine(p1, p2) {
  var canvas = document.getElementById("connection-canvas");
  var ctx = canvas.getContext("2d");
  ctx.beginPath();
  ctx.moveTo(p1.x, p1.y);
  ctx.lineTo(p2.x, p2.y);
  ctx.stroke();
}

function resizeCanvas() {
  var canvas = document.getElementById("connection-canvas");
  var ctx = canvas.getContext("2d");
  ctx.canvas.width = window.innerWidth;
  ctx.canvas.height = window.innerHeight;

  for (var i = 0; i < canvasPoints.length; i++) {
    drawLine(canvasPoints[i].answer, canvasPoints[i].question);
  }
  output();
}

function removeObjects() {

  var answerPoints = getPoint(answer);
  var questionPoints = getPoint(question);
  for (var i = 0; i < canvasPoints.length; i++) {

    if (canvasPoints[i].answer.x == answerPoints.x && canvasPoints[i].answer.y == answerPoints.y && canvasPoints[i].question.x == questionPoints.x && canvasPoints[i].question.y == questionPoints.y) {
      canvasPoints.splice(i, 1);
      return true;
    }
  }
  return false;
}
listenToClick();
resizeCanvas();

function output() {
  var outputObject = [];
  for (var i = 0; i < canvasPoints.length; i++) {
    var obj = {
      "left": canvasPoints[i].question.text,
      right: []
    };
    for (var j = 0; j < outputObject.length; j++) {
      if (outputObject[j].left == canvasPoints[i].question.text) {
        obj = outputObject[j];
        outputObject.splice(j, 1);
      }
    }
    obj.right.push(canvasPoints[i].answer.text)
    outputObject.push(obj);
  }
  console.log(outputObject);
}
.padding-answer-line-mapping {
  padding-bottom: 8px;
}
.answer-container {
  width: 40px;
  height: 40px;
  background-color: #ccc;
  border: 1px solid #ccc;
  margin: 2px;
  float: left;
  text-align: center;
  padding-top: 8px;
  cursor: pointer;
  position: relative;
}
.answer-container:hover,
.answer-container:focus,
.answer-container:active {
  background-color: #0076e9;
  color: white;
  border: 1px solid #0076e9;
}
.round-pointer-right {
  position: absolute;
  background-color: #ccc;
  cursor: pointer;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  right: 0px;
  top: 14px;
  margin-right: -20px;
}
.round-pointer-left {
  position: absolute;
  background-color: #ccc;
  cursor: pointer;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  left: 0px;
  top: 14px;
  margin-left: -20px;
}
.selected {
  background-color: red;
}
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet" />Match the following items.

<canvas id="connection-canvas" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></canvas>
<div class="row padding-answer-line-mapping" id="id1">
  <div class="col answer-container question" id="id1-One">
    One
    <div class="round-pointer-right"></div>
  </div>
  <div class="col" id="id1-cols">

  </div>
  <div class="col answer-container answer" id="id1-2">
    2
    <div class="round-pointer-left"></div>
  </div>
</div>
<div class="row padding-answer-line-mapping" id="id2">
  <div class="col answer-container question" id="id2-two">
    Two
    <div class="round-pointer-right"></div>
  </div>
  <div class="col" id="id2-cols">

  </div>
  <div class="col answer-container answer" id="id2-1">
    1
    <div class="round-pointer-left"></div>
  </div>
</div>
like image 126
Mitul Avatar answered Oct 19 '22 23:10

Mitul


According to this answer, when you want to erase a line, you need to clear the entire canvas and then redraw all.

In my suggestion, you should have an array that contains the lines that are active and check it before drawing a line in order to draw or erase the line you're checking.

I suggest add an array lines, a function redrawAll and a function checkLine like I added into your snippet:

var lastSelection;
var lines = new Array();

// Add click listener for answer-container
function listenToClick() {
    var rows = document.querySelectorAll('.row'),
        row;
    var cols, col;

    for (row = 0; row < rows.length; row++) {
        cols = rows[row].children;

        for (col = 0; col < cols.length; col++) {
            // Bind information about which answer is this,
            // so we can prevent from connecting two answers on
            // same column.
            cols[col].addEventListener('click', selectAnswer.bind({
                row: row,
                col: col,
                element: cols[col]
            }));
        }
    }
}

function checkLine(p1, p2)
{
	var line;
	for (var i = 0; i < lines.length; i++)
    {
    	line = lines[i];
    	if (line.p1.x == p1.x && line.p1.y == p1.y
           && line.p2.x == p2.x && line.p2.y == p2.y)
        {
            //line exists, remove it from lines
            lines.splice(i, 1);
        	return true;
        }
        else if (line.p1.x == p2.x && line.p1.y == p2.y
           && line.p2.x == p1.x && line.p2.y == p1.y)
        {
            //line exists, remove it from lines
            lines.splice(i, 1);
        	return true;
        }
    }
    return false;
}

function redrawAll()
{
    for (var i = 0; i < lines.length; i++)
    {
        drawLine(lines[i].p1, lines[i].p2);
    }
}

// This is fired when a answer-container is clicked.
function selectAnswer(event) {
    if (lastSelection) {
       lastSelection.element.classList.remove('selected');
    }

    if (!lastSelection || lastSelection.col === this.col)
    {
        lastSelection = this;
        this.element.classList.add('selected');
    } 
    else 
    {
        if ( checkLine(getPoint(lastSelection.element), getPoint(this.element)) )
        {
            var canvas = document.getElementById("connection-canvas");
            var ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
            redrawAll();
        }
        else
        {
            var line = {
          	  'p1': getPoint(this.element), 
          	  'p2': getPoint(lastSelection.element)
        	};
        	drawLine(line.p1, line.p2);
            lines.push(line);
        }
        console.log(lines);
        lastSelection = null;
    }
}

function getPoint(answerElement) {
    var roundPointer = answerElement.lastElementChild;
    return {
        y: answerElement.offsetTop + roundPointer.offsetTop + roundPointer.offsetHeight / 2,
        x: answerElement.offsetLeft + roundPointer.offsetLeft + roundPointer.offsetWidth / 2
    };
}

function drawLine(p1, p2) {
    var canvas = document.getElementById("connection-canvas");
    var ctx = canvas.getContext("2d");

    ctx.beginPath();
    ctx.moveTo(p1.x, p1.y);
    ctx.lineTo(p2.x, p2.y);
    ctx.stroke();
}

function resizeCanvas() {
    var canvas = document.getElementById("connection-canvas");
    var ctx = canvas.getContext("2d");

    ctx.canvas.width  = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
}

listenToClick();
resizeCanvas();
.padding-answer-line-mapping
{
    padding-bottom:8px;
}

.answer-container
{
    width:40px;
    height:40px;
    background-color:#ccc;
    border:1px solid #ccc;
    margin:2px;
    float:left;
    text-align:center;
    padding-top:8px;
    cursor:pointer;
    position:relative;
}

.answer-container:hover, .answer-container:focus, .answer-container:active
{
    background-color: #0076e9;
    color: white;
    border: 1px solid #0076e9;
}

.round-pointer-right
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    right:0px;
    top:14px;
    margin-right:-20px;
}

.round-pointer-left
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    left:0px;
    top:14px;
    margin-left:-20px;
}

.selected {
    background-color: red;
}
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet"/>
Match the following items.

 <canvas id="connection-canvas" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></canvas>
<div class="row padding-answer-line-mapping">
    <div class="col answer-container">
        One
        <div class="round-pointer-right"></div>
    </div>
    <div class="col">
        
    </div>
    <div class="col answer-container">
        2
        <div class="round-pointer-left"></div>
    </div>
</div>
<div class="row padding-answer-line-mapping">
    <div class="col answer-container">
        Two
        <div class="round-pointer-right"></div>
    </div>
    <div class="col">
        
    </div>
    <div class="col answer-container">
        1
        <div class="round-pointer-left"></div>
    </div>
</div>
like image 37
dubafek Avatar answered Oct 19 '22 23:10

dubafek


I have used your existing code and made some change into it, please review this snippet and let me know, this is what you want?

var lastSelection;
    var p = 0;
// Add click listener for answer-container
    function listenToClick() {
        var rows = document.querySelectorAll('.row'),
                row;
        var cols, col;

        for (row = 0; row < rows.length; row++) {
            cols = rows[row].children;

            for (col = 0; col < cols.length; col++) {
                // Bind information about which answer is this,
                // so we can prevent from connecting two answers on
                // same column.
                cols[col].addEventListener('click', selectAnswer.bind({
                    row: row,
                    col: col,
                    element: cols[col]
                }));
            }
        }
    }

// This is fired when a answer-container is clicked.
    function selectAnswer(event) {
        
        if (lastSelection) {
            lastSelection.element.classList.remove('selected');
        }        
        
        if (!lastSelection || lastSelection.col === this.col) {
            lastSelection = this;
            this.element.classList.add('selected');
            
            if(p%2==0){
                resizeCanvas();
            }
            p++;
        } else {
           
            drawLine(getPoint(this.element), getPoint(lastSelection.element));
            lastSelection = null;
        }
        
    }

    function getPoint(answerElement) {
      //  console.log('getpoint : ' + JSON.stringify(answerElement));

        var roundPointer = answerElement.lastElementChild;
        //console.log('roundPointer : ' + JSON.stringify(roundPointer));

        return {
            y: answerElement.offsetTop + roundPointer.offsetTop + roundPointer.offsetHeight / 2,
            x: answerElement.offsetLeft + roundPointer.offsetLeft + roundPointer.offsetWidth / 2
        };
    }

    function drawLine(p1, p2) {


        var canvas = document.getElementById("connection-canvas");
        var ctx = canvas.getContext("2d");

        ctx.beginPath();
        ctx.moveTo(p1.x, p1.y);
        ctx.lineTo(p2.x, p2.y);
        ctx.stroke();
    }

    function resizeCanvas() {
        var canvas = document.getElementById("connection-canvas");
        var ctx = canvas.getContext("2d");

        ctx.canvas.width = window.innerWidth;
        ctx.canvas.height = window.innerHeight;
    }

    listenToClick();
    resizeCanvas();
.padding-answer-line-mapping
{
    padding-bottom:8px;
}

.answer-container
{
    width:40px;
    height:40px;
    background-color:#ccc;
    border:1px solid #ccc;
    margin:2px;
    float:left;
    text-align:center;
    padding-top:8px;
    cursor:pointer;
    position:relative;
}

.answer-container:hover, .answer-container:focus, .answer-container:active
{
    background-color: #0076e9;
    color: white;
    border: 1px solid #0076e9;
}

.round-pointer-right
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    right:0px;
    top:14px;
    margin-right:-20px;
}

.round-pointer-left
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    left:0px;
    top:14px;
    margin-left:-20px;
}

.selected {
    background-color: red;
}
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet"/>
Match the following items.

<canvas id="connection-canvas" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></canvas>
<div class="row padding-answer-line-mapping" id="id1">
    <div class="col answer-container" id="id1-One">
        One
        <div class="round-pointer-right"></div>
    </div>
    <div class="col" id="id1-cols">

    </div>
    <div class="col answer-container" id="id1-2">
        2
        <div class="round-pointer-left"></div>
    </div>
</div>
<div class="row padding-answer-line-mapping" id="id2">
    <div class="col answer-container" id="id2-two">
        Two
        <div class="round-pointer-right"></div>
    </div>
    <div class="col"  id="id2-cols">

    </div>
    <div class="col answer-container" id="id2-1">
        1
        <div class="round-pointer-left"></div>
    </div>
</div>
like image 37
Jigar7521 Avatar answered Oct 20 '22 01:10

Jigar7521