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>
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>
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>
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With