admin管理员组

文章数量:1335349

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/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>

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./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>

Share Improve this question asked Oct 4, 2016 at 6:38 NereNere 4,0975 gold badges35 silver badges75 bronze badges 3
  • Didnt look too much into the code but in theory, just save a ref for each canvas and deleted in case the origin cell is the same.. – Roberto14 Commented Oct 14, 2016 at 9:10
  • If you can show me some codes then its better (^_^) – Nere Commented Oct 14, 2016 at 9:11
  • @Imran : I have made some change in your code and posted code snippet, please review it and let me know if you have some other expectation :) – Jigar7521 Commented Oct 18, 2016 at 9:34
Add a ment  | 

3 Answers 3

Reset to default 5 +50

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./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>

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./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>

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./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>

本文标签: javascriptRemove current line between 2 DIVs created if user want to change the answerStack Overflow