Unifiy hotspot scripts on hotspot.js - refs #7705

1.10.x
Angel Fernando Quiroz Campos 10 years ago
parent 3d2877ee2e
commit 3945697d83
  1. 5
      main/exercice/exercise.class.php
  2. 3
      main/exercice/exercise_result.php
  3. 13
      main/exercice/exercise_show.php
  4. 3
      main/exercice/exercise_submit.php
  5. 1
      main/exercice/hotspot_actionscript.as.php
  6. 1
      main/exercice/hotspot_actionscript_admin.as.php
  7. 5
      main/exercice/hotspot_admin.inc.php
  8. 3
      main/exercice/hotspot_answers.as.php
  9. 3
      main/exercice/result.php
  10. 5
      main/inc/lib/exercise.lib.php
  11. 410
      main/plugin/hotspot2/js/hotspot.js
  12. 231
      main/plugin/hotspot2/js/hotspot_solution.js
  13. 269
      main/plugin/hotspot2/js/hotspot_user.js

@ -4044,10 +4044,11 @@ class Exercise
<script>
$(document).on('ready', function () {
HotSpotSolution.init({
HotspotQuestion.init({
questionId: $questionId,
exerciseId: $exeId,
selector: '#hotspot-solution-$questionId'
selector: '#hotspot-solution-$questionId',
for: 'solution'
});
});
</script>

@ -75,7 +75,8 @@ $interbreadcrumb[] = array(
"name" => get_lang('Exercises'),
);
$htmlHeadXtra[] = '<script src="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/js/hotspot_solution.js"></script>';
$htmlHeadXtra[] = '<script src="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/js/hotspot.js"></script>';
$htmlHeadXtra[] = '<link rel="stylesheet" href="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/css/hotspot.css">';
if ($origin != 'learnpath') {
// So we are not in learnpath tool

@ -120,7 +120,8 @@ $interbreadcrumb[]= array("url" => "#","name" => get_lang('Result'));
$this_section = SECTION_COURSES;
$htmlHeadXtra[] = '<script src="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/js/hotspot_solution.js"></script>';
$htmlHeadXtra[] = '<link rel="stylesheet" href="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/css/hotspot.css">';
$htmlHeadXtra[] = '<script src="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/js/hotspot.js"></script>';
if ($origin != 'learnpath') {
Display::display_header('');
@ -376,10 +377,11 @@ foreach ($questionList as $questionId) {
<div id=\"hotspot-solution\"></div>
<script>
$(document).on('ready', function () {
HotSpotSolution.init({
HotspotQuestion.init({
questionId: $questionId,
exerciseId: $id,
selector: '#hotspot-solution'
selector: '#hotspot-solution',
for: 'solution'
});
});
</script>
@ -517,10 +519,11 @@ foreach ($questionList as $questionId) {
<div id=\"hotspot-solution\"></div>
<script>
$(document).on('ready', function () {
HotSpotSolution.init({
HotspotQuestion.init({
questionId: $questionId,
exerciseId: $id,
selector: '#hotspot-solution'
selector: '#hotspot-solution',
for: 'solution'
});
});
</script>

@ -60,7 +60,8 @@ $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epicloc
$htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.dateformat.min.js');
$htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.epiclock.min.js');
$htmlHeadXtra[] = api_get_js('epiclock/renderers/minute/epiclock.minute.js');
$htmlHeadXtra[] = '<script src="../plugin/hotspot2/js/hotspot_user.js"></script>';
$htmlHeadXtra[] = '<link rel="stylesheet" href="../plugin/hotspot2/css/hotspot.css">';
$htmlHeadXtra[] = '<script src="../plugin/hotspot2/js/hotspot.js"></script>';
$template = new Template();

@ -37,6 +37,7 @@ if ($answer_type==HOT_SPOT_DELINEATION) {
$result = Database::query($sql);
$data = [];
$data['type'] = 'user';
$data['lang'] = [
'Square' => get_lang('Square'),
'Circle' => get_lang('Circle'),

@ -22,6 +22,7 @@ $pictureWidth = $pictureSize[0];
$pictureHeight = $pictureSize[1];
$data = [];
$data['type'] = 'admin';
$data['lang'] = [
'Square' => get_lang('Square'),
'Circle' => get_lang('Circle'),

@ -1021,9 +1021,10 @@ if ($modifyAnswers) {
</form>
<script>
$(document).on('ready', function () {
HotSpotAdmin.init({
HotspotQuestion.init({
questionId: <?php echo $modifyAnswers ?>,
selector: '#hotspot-container'
selector: '#hotspot-container',
for: 'admin'
});
});
</script>

@ -37,6 +37,8 @@ if ($answer_type == HOT_SPOT_DELINEATION) {
}
$result = Database::query($sql);
// Init
$data = [];
$data['type'] = 'solution';
$data['lang'] = [
'Square' => get_lang('Square'),
'Circle' => get_lang('Circle'),
@ -63,6 +65,7 @@ $data['hotspots'] = [];
while ($hotspot = Database::fetch_array($result)) {
$hotSpot = [];
$hotSpot['id'] = $hotspot['id'];
$hotSpot['answer'] = $hotspot['answer'];
// Square or rectancle
if ($hotspot['hotspot_type'] == 'square' ) {

@ -53,7 +53,8 @@ if (!$is_allowedToEdit) {
}
}
$htmlHeadXtra[] = '<script src="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/js/hotspot_solution.js"></script>';
$htmlHeadXtra[] = '<link rel="stylesheet" href="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/css/hotspot.css">';
$htmlHeadXtra[] = '<script src="' . api_get_path(WEB_CODE_PATH) . 'plugin/hotspot2/js/hotspot.js"></script>';
if ($show_headers) {
$interbreadcrumb[] = array(

@ -1177,9 +1177,10 @@ HOTSPOT;
<div class="hotspot-image"></div>
<script>
$(document).on('ready', function () {
HotSpotUser.init({
HotspotQuestion.init({
questionId: $questionId,
selector: '#question_div_' + $questionId + ' .hotspot-image'
selector: '#question_div_' + $questionId + ' .hotspot-image',
for: 'user'
});
});
</script>

@ -1,4 +1,4 @@
var HotSpotAdmin = (function () {
var HotspotQuestion = (function () {
var HotspotModel = function (attributes) {
this.attributes = attributes;
this.id = 0;
@ -196,21 +196,22 @@ var HotSpotAdmin = (function () {
};
PolygonModel.decode = function (hotspotInfo) {
var pairedPoints = hotspotInfo.coord.split('|'),
points = [],
hotspot = new PolygonModel({
points: []
});
points = [];
$.each(pairedPoints, function (index, pair) {
var point = pair.split(';');
points.push([
point[0],
point[1]
parseInt(point[0]),
parseInt(point[1])
]);
});
hotspot.set('points', points);
var hotspot = new PolygonModel({
points: points
});
hotspot.id = hotspotInfo.id;
hotspot.name = hotspotInfo.answer;
return hotspot;
};
@ -226,6 +227,49 @@ var HotSpotAdmin = (function () {
return pairedPoints.join('|');
};
var AnswerModel = function (attributes) {
this.attributes = attributes;
this.changeEvent = null;
};
AnswerModel.prototype.set = function (key, value) {
this.attributes[key] = value;
if (this.changeEvent) {
this.changeEvent(this);
}
};
AnswerModel.prototype.get = function (key) {
return this.attributes[key];
};
AnswerModel.prototype.onChange = function (callback) {
this.changeEvent = callback;
};
AnswerModel.decode = function (answerInfo) {
var coords = answerInfo.split(';');
return new AnswerModel({
x: coords[0],
y: coords[1]
});
};
var AnswersCollection = function () {
this.models = [];
this.length = 0;
this.addEvent = null;
};
AnswersCollection.prototype.add = function (answerModel) {
this.models.push(answerModel);
this.length++;
if (this.addEvent) {
this.addEvent(answerModel);
}
};
AnswersCollection.prototype.onAdd = function (callback) {
this.addEvent = callback;
};
var HotspotsCollection = function () {
this.hotspots = [];
this.length = 0;
@ -431,7 +475,7 @@ var HotSpotAdmin = (function () {
$(this.el).css({left: x, top: y}).show();
};
var HotspotsSVG = function (hotspotsCollection, image) {
var AdminHotspotsSVG = function (hotspotsCollection, image) {
var self = this;
this.el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
@ -442,7 +486,7 @@ var HotSpotAdmin = (function () {
self.renderHotspot(hotspotModel);
});
};
HotspotsSVG.prototype.render = function () {
AdminHotspotsSVG.prototype.render = function () {
this.el.setAttribute('version', '1.1');
this.el.setAttribute('viewBox', '0 0 ' + this.image.width + ' ' + this.image.height);
@ -457,7 +501,7 @@ var HotSpotAdmin = (function () {
return this;
};
HotspotsSVG.prototype.renderHotspot = function (hotspot) {
AdminHotspotsSVG.prototype.renderHotspot = function (hotspot) {
var hotspotIndex = this.collection.length - 1,
hotspotSVG = new HotspotSVG(hotspot, hotspotIndex);
@ -471,27 +515,12 @@ var HotSpotAdmin = (function () {
hotspotSelect.render().el
);
};
HotspotsSVG.prototype.setEvents = function () {
AdminHotspotsSVG.prototype.setEvents = function () {
var self = this,
$el = $(this.el);
isDrawing = false;
var getPointOnImage = function (x, y) {
var pointerPosition = {
left: x + window.scrollX,
top: y + window.scrollY
},
canvasOffset = {
x: self.el.getBoundingClientRect().left + window.scrollX,
y: self.el.getBoundingClientRect().top + window.scrollY
};
return {
x: Math.round(pointerPosition.left - canvasOffset.x),
y: Math.round(pointerPosition.top - canvasOffset.y)
};
},
startPoint = {
var startPoint = {
x: 0,
y: 0
};
@ -516,7 +545,7 @@ var HotSpotAdmin = (function () {
return;
}
startPoint = getPointOnImage(e.clientX, e.clientY);
startPoint = getPointOnImage(self.el, e.clientX, e.clientY);
if (currentHotspot instanceof SquareModel) {
isDrawing = true;
@ -551,7 +580,7 @@ var HotSpotAdmin = (function () {
}
var currentHotspot = self.collection.get(selectedHotspotIndex),
currentPoint = getPointOnImage(e.clientX, e.clientY);
currentPoint = getPointOnImage(self.el, e.clientX, e.clientY);
if (!currentHotspot) {
return;
@ -645,7 +674,7 @@ var HotSpotAdmin = (function () {
e.preventDefault();
var currentHotspot = self.collection.get(selectedHotspotIndex),
currentPoint = getPointOnImage(e.clientX, e.clientY);
currentPoint = getPointOnImage(self.el, e.clientX, e.clientY);
if (!currentHotspot) {
return;
@ -670,7 +699,7 @@ var HotSpotAdmin = (function () {
.on('contextmenu', function (e) {
e.preventDefault();
var currentPoint = getPointOnImage(e.clientX, e.clientY),
var currentPoint = getPointOnImage(self.el, e.clientX, e.clientY),
currentHotspot = self.collection.get(selectedHotspotIndex),
hotspotTypeSelector = '[name="hotspot_type[' + (selectedHotspotIndex + 1) + ']"]',
hotspotCoordSelector = '[name="hotspot_coordinates[' + (selectedHotspotIndex + 1) + ']"]';
@ -694,15 +723,12 @@ var HotSpotAdmin = (function () {
var startHotspotsAdmin = function (questionInfo) {
var image = new Image();
image.onload = function () {
var hotspotsCollection = new HotspotsCollection();
var hotspotsSVG = new HotspotsSVG(hotspotsCollection, this);
var hotspotsCollection = new HotspotsCollection(),
hotspotsSVG = new AdminHotspotsSVG(hotspotsCollection, this);
$(config.selector)
.css('width', image.width)
.append(hotspotsSVG.render().el);
$(config.selector).css('width', this.width).append(hotspotsSVG.render().el);
$(config.selector).parent().append('<div class="row"></div>');
$(config.selector).parent().prepend('<div class="row"></div>');
contextMenu = new ContextMenu();
@ -736,6 +762,275 @@ var HotSpotAdmin = (function () {
lang = questionInfo.lang;
};
var UserHotspotsSVG = function (hotspotsCollection, image) {
var self = this;
this.el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this.hotspotsCollection = hotspotsCollection;
this.answersCollection = new AnswersCollection();
this.image = image;
this.answersCollection.onAdd(function (answerModel) {
self.renderAnswer(answerModel);
});
};
UserHotspotsSVG.prototype.render = function () {
this.el.setAttribute('version', '1.1');
this.el.setAttribute('viewBox', '0 0 ' + this.image.width + ' ' + this.image.height);
var imageSvg = document.createElementNS('http://www.w3.org/2000/svg', 'image');
imageSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', this.image.src);
imageSvg.setAttribute('width', this.image.width);
imageSvg.setAttribute('height', this.image.height);
this.el.appendChild(imageSvg);
this.setEvents();
return this;
};
UserHotspotsSVG.prototype.renderAnswer = function (answerModel) {
var pointSVG = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
pointSVG.setAttribute('cx', answerModel.get('x'));
pointSVG.setAttribute('cy', answerModel.get('y'));
pointSVG.setAttribute('r', 15);
pointSVG.setAttribute('fill', '#00677C');
var textSVG = document.createElementNS('http://www.w3.org/2000/svg', 'text');
textSVG.setAttribute('x', answerModel.get('x'));
textSVG.setAttribute('y', answerModel.get('y'));
textSVG.setAttribute('dy', 5);
textSVG.setAttribute('font-family', 'sans-serif');
textSVG.setAttribute('text-anchor', 'middle');
textSVG.setAttribute('fill', 'white');
textSVG.textContent = this.answersCollection.length;
this.el.appendChild(pointSVG);
this.el.appendChild(textSVG);
var hotspot = this.hotspotsCollection.get(this.answersCollection.length - 1),
x = answerModel.get('x'),
y = answerModel.get('y');
$('<input>', {
type: 'hidden',
name: 'hotspot[' + config.questionId + '][' + hotspot.id + ']'
}).val(function () {
return [x, y].join(';');
}).appendTo(this.el.parentNode);
$('<input>', {
type: 'hidden',
name: 'choice[' + config.questionId + '][' + hotspot.id + ']'
}).val(function () {
if (hotspot.checkPoint(x, y)) {
return 1;
}
return 0;
}).appendTo(this.el.parentNode);
};
UserHotspotsSVG.prototype.setEvents = function () {
var self = this,
$el = $(this.el);
$el
.on('dragstart', function (e) {
e.preventDefault();
})
.on('click', function (e) {
e.preventDefault();
if (self.answersCollection.length >= self.hotspotsCollection.length) {
return;
}
var point = getPointOnImage(self.el, e.clientX, e.clientY);
var answerModel = new AnswerModel({
x: point.x,
y: point.y
});
self.answersCollection.add(answerModel);
if (self.answersCollection.length === self.hotspotsCollection.length) {
$(config.selector).parent()
.find('#hotspot-messages-' + config.questionId).text(
lang.HotspotExerciseFinished
);
return;
}
$(config.selector).parent()
.find('#hotspot-messages-' + config.questionId).text(
lang.NextAnswer + ' ' + self.hotspotsCollection.get(
self.answersCollection.length
).name
);
});
};
var startHotspotsUser = function (questionInfo) {
var image = new Image();
image.onload = function () {
var hotspotsCollection = new HotspotsCollection(),
hotspotsSVG = new UserHotspotsSVG(hotspotsCollection, this);
$(config.selector).css('width', this.width).append(hotspotsSVG.render().el);
$(config.selector).parent().prepend('<div id="hotspot-messages-' + config.questionId + '"></div>');
$.each(questionInfo.hotspots, function (index, hotspotInfo) {
var hotspot = null;
switch (hotspotInfo.type) {
case 'square':
default:
hotspot = SquareModel.decode(hotspotInfo);
break;
case 'circle':
hotspot = EllipseModel.decode(hotspotInfo);
break;
case 'poly':
hotspot = PolygonModel.decode(hotspotInfo);
break;
}
hotspotsCollection.add(hotspot);
});
$(config.selector).parent().find('#hotspot-messages-' + config.questionId)
.text(
lang.NextAnswer + ' ' + hotspotsCollection.get(0).name
);
};
image.src = questionInfo.image;
lang = questionInfo.lang;
};
var SolutionHotspotsSVG = function (hotspotsCollection, answersCollection, image) {
this.hotspotsCollection = hotspotsCollection;
this.answersCollection = answersCollection;
this.image = image;
this.el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var self = this;
this.hotspotsCollection.onAdd(function (hotspotModel) {
self.renderHotspot(hotspotModel);
});
this.answersCollection.onAdd(function (answerModel) {
self.renderAnswer(answerModel);
});
};
SolutionHotspotsSVG.prototype.render = function () {
this.el.setAttribute('version', '1.1');
this.el.setAttribute('viewBox', '0 0 ' + this.image.width + ' ' + this.image.height);
var imageSvg = document.createElementNS('http://www.w3.org/2000/svg', 'image');
imageSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', this.image.src);
imageSvg.setAttribute('width', this.image.width);
imageSvg.setAttribute('height', this.image.height);
this.el.appendChild(imageSvg);
return this;
};
SolutionHotspotsSVG.prototype.renderHotspot = function (hotspotModel) {
var hotspotIndex = this.hotspotsCollection.length,
hotspotSVG = new HotspotSVG(hotspotModel, hotspotIndex);
this.el.appendChild(
hotspotSVG.render().el
);
return this;
};
SolutionHotspotsSVG.prototype.renderAnswer = function (answerModel) {
var pointSVG = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
pointSVG.setAttribute('cx', answerModel.get('x'));
pointSVG.setAttribute('cy', answerModel.get('y'));
pointSVG.setAttribute('r', 15);
pointSVG.setAttribute('fill', '#00677C');
var textSVG = document.createElementNS('http://www.w3.org/2000/svg', 'text');
textSVG.setAttribute('x', answerModel.get('x'));
textSVG.setAttribute('y', answerModel.get('y'));
textSVG.setAttribute('dy', 5);
textSVG.setAttribute('font-family', 'sans-serif');
textSVG.setAttribute('text-anchor', 'middle');
textSVG.setAttribute('fill', 'white');
textSVG.textContent = this.answersCollection.length;
this.el.appendChild(pointSVG);
this.el.appendChild(textSVG);
return this;
};
var startHotspotsSolution = function (questionInfo) {
var image = new Image();
image.onload = function () {
var hotspotsCollection = new HotspotsCollection(),
answersCollection = new AnswersCollection(),
hotspotsSVG = new SolutionHotspotsSVG(hotspotsCollection, answersCollection, this);
$(config.selector).css('width', this.width).append(hotspotsSVG.render().el);
$.each(questionInfo.hotspots, function (index, hotspotInfo) {
var hotspot = null;
switch (hotspotInfo.type) {
case 'square':
default:
hotspot = SquareModel.decode(hotspotInfo);
break;
case 'circle':
hotspot = EllipseModel.decode(hotspotInfo);
break;
case 'poly':
hotspot = PolygonModel.decode(hotspotInfo);
break;
}
hotspotsCollection.add(hotspot);
});
$.each(questionInfo.answers, function (index, answerInfo) {
var answer = AnswerModel.decode(answerInfo);
answersCollection.add(answer);
});
};
image.src = questionInfo.image;
lang = questionInfo.lang;
};
var getPointOnImage = function (referenceElement, x, y) {
var pointerPosition = {
left: x + window.scrollX,
top: y + window.scrollY
},
canvasOffset = {
x: referenceElement.getBoundingClientRect().left + window.scrollX,
y: referenceElement.getBoundingClientRect().top + window.scrollY
};
return {
x: Math.round(pointerPosition.left - canvasOffset.x),
y: Math.round(pointerPosition.top - canvasOffset.y)
};
};
var config, lang, selectedHotspotIndex = 0, contextMenu;
return {
@ -749,12 +1044,41 @@ var HotSpotAdmin = (function () {
return;
}
var xhrQuestion = $.getJSON('/main/exercice/hotspot_actionscript_admin.as.php', {
modifyAnswers: parseInt(config.questionId)
});
var xhrQuestion = null;
switch (config.for) {
case 'admin':
xhrQuestion = $.getJSON('/main/exercice/hotspot_actionscript_admin.as.php', {
modifyAnswers: parseInt(config.questionId)
});
break;
case 'user':
xhrQuestion = $.getJSON('/main/exercice/hotspot_actionscript.as.php', {
modifyAnswers: parseInt(config.questionId)
});
break;
case 'solution':
xhrQuestion = $.getJSON('/main/exercice/hotspot_answers.as.php', {
modifyAnswers: parseInt(config.questionId),
exe_id: parseInt(config.exerciseId)
});
}
$.when(xhrQuestion).done(function (questionInfo) {
startHotspotsAdmin(questionInfo);
switch (questionInfo.type) {
case 'admin':
startHotspotsAdmin(questionInfo);
break;
case 'user':
startHotspotsUser(questionInfo);
break;
case 'solution':
startHotspotsSolution(questionInfo);
}
});
}
};

@ -1,231 +0,0 @@
var HotSpotSolution = (function () {
var Answer = function () {
this.x = 0;
this.y = 0;
};
var HotSpot = function () {
this.id = 0;
this.name = '';
};
var Square = function () {
HotSpot.call(this);
this.x = 0,
this.y = 0,
this.width = 0,
this.height = 0;
};
Square.prototype = Object.create(HotSpot.prototype);
var Ellipse = function () {
HotSpot.call(this);
this.centerX = 0;
this.centerY = 0;
this.radiusX = 0;
this.radiusY = 0;
};
Ellipse.prototype = Object.create(HotSpot.prototype);
var Polygon = function () {
HotSpot.call(this);
this.points = [];
};
Polygon.prototype = Object.create(HotSpot.prototype);
var config, lang, hotSpots = [], answers = [];
var CanvasSVG = function (image) {
var imageSvg = document.createElementNS('http://www.w3.org/2000/svg', 'image');
imageSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', image.src);
imageSvg.setAttribute('width', image.width);
imageSvg.setAttribute('height', image.height);
this.el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this.el.setAttribute('version', '1.1');
this.el.setAttribute('viewBox', '0 0 ' + image.width + ' ' + image.height);
this.el.appendChild(imageSvg);
};
CanvasSVG.prototype.addHotSpot = function (hotSpot) {
var hotSpotSVG = null;
if (hotSpot instanceof Square) {
hotSpotSVG = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
hotSpotSVG.setAttribute('x', hotSpot.x);
hotSpotSVG.setAttribute('y', hotSpot.y);
hotSpotSVG.setAttribute('width', hotSpot.width);
hotSpotSVG.setAttribute('height', hotSpot.height);
} else if (hotSpot instanceof Ellipse) {
hotSpotSVG = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse');
hotSpotSVG.setAttribute('cx', hotSpot.centerX);
hotSpotSVG.setAttribute('cy', hotSpot.centerY);
hotSpotSVG.setAttribute('rx', hotSpot.radiusX);
hotSpotSVG.setAttribute('ry', hotSpot.radiusY);
} else if (hotSpot instanceof Polygon) {
var pointsPaired = [];
hotSpot.points.forEach(function (point) {
pointsPaired.push(point.join(','));
});
hotSpotSVG = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
hotSpotSVG.setAttribute(
'points',
pointsPaired.join(' ')
);
}
if (!hotSpotSVG) {
return;
}
var color = colors[hotSpots.length - 1];
hotSpotSVG.setAttribute('stroke-width', 2);
hotSpotSVG.setAttribute('stroke', 'rgb(' + color + ')');
hotSpotSVG.setAttribute('fill', 'rgba(' + color + ', 0.75)');
this.el.appendChild(hotSpotSVG);
};
CanvasSVG.prototype.addAnswer = function (answer) {
var pointSVG = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
pointSVG.setAttribute('cx', answer.x);
pointSVG.setAttribute('cy', answer.y);
pointSVG.setAttribute('r', 15);
pointSVG.setAttribute('fill', '#00677C');
var textSVG = document.createElementNS('http://www.w3.org/2000/svg', 'text');
textSVG.setAttribute('x', answer.x);
textSVG.setAttribute('y', answer.y);
textSVG.setAttribute('dy', 5);
textSVG.setAttribute('font-family', 'sans-serif');
textSVG.setAttribute('text-anchor', 'middle');
textSVG.setAttribute('fill', 'white');
textSVG.textContent = answers.length;
this.el.appendChild(pointSVG);
this.el.appendChild(textSVG);
};
var decodeHotSpot = function (hotSpotInfo) {
var hotSpot = null,
coords = hotSpotInfo.coord.split('|');
switch (hotSpotInfo.type) {
case 'square':
var position = coords[0].split(';');
hotSpot = new Square();
hotSpot.x = parseInt(position[0]);
hotSpot.y = parseInt(position[1]);
hotSpot.width = parseInt(coords[1]);
hotSpot.height = parseInt(coords[2]);
break;
case 'circle':
var center = coords[0].split(';');
hotSpot = new Ellipse();
hotSpot.centerX = parseInt(center[0]);
hotSpot.centerY = parseInt(center[1]);
hotSpot.radiusX = parseInt(coords[1]);
hotSpot.radiusY = parseInt(coords[2]);
break;
case 'poly':
hotSpot = new Polygon();
coords.forEach(function (pairedCoord) {
var coord = pairedCoord.split(';');
hotSpot.points.push([
parseInt(coord[0]),
parseInt(coord[1])
]);
});
break;
}
return hotSpot;
};
var decodeAnswer = function (answerInfo) {
var answer = null,
coords = answerInfo.split(';');
answer = new Answer();
answer.x = coords[0];
answer.y = coords[1];
return answer;
};
var colors = [
'66, 113, 181',
'254, 142, 22',
'69, 199, 240',
'188, 214, 49',
'214, 49, 115',
'215, 215, 215',
'144, 175, 221',
'174, 134, 64',
'79, 146, 66',
'244, 235, 36',
'237, 32, 36',
'59, 59, 59'
];
var startAnswer = function (hotSpotAnswerInfo) {
var image = new Image();
image.onload = function () {
var canvasSVG = new CanvasSVG(this);
hotSpotAnswerInfo.hotspots.forEach(function (hotSpotInfo) {
var hotSpot = decodeHotSpot(hotSpotInfo);
if (!hotSpot) {
return;
}
hotSpots.push(hotSpot);
canvasSVG.addHotSpot(hotSpot);
});
hotSpotAnswerInfo.answers.forEach(function (answerInfo) {
var answer = decodeAnswer(answerInfo);
answers.push(answer);
canvasSVG.addAnswer(answer);
});
$(config.selector)
.css('width', this.width)
.append(canvasSVG.el);
};
image.src = hotSpotAnswerInfo.image;
lang = hotSpotAnswerInfo.lang;
};
return {
init: function (settings) {
config = $.extend({
questionId: 0,
exerciseId: 0,
selector: ''
}, settings);
if (!config.questionId || !config.selector) {
return;
}
var xhrHotSpotAnswers = $.getJSON('/main/exercice/hotspot_answers.as.php', {
modifyAnswers: parseInt(config.questionId),
exe_id: parseInt(config.exerciseId)
});
$.when(xhrHotSpotAnswers).done(startAnswer);
}
};
})();

@ -1,269 +0,0 @@
var HotSpotUser = (function () {
var Answer = function () {
this.x = 0;
this.y = 0;
};
var HotSpot = function () {
this.id = 0;
this.name = '';
};
HotSpot.prototype.checkPoint = function (x, y) {
return false;
};
var Square = function () {
HotSpot.call(this);
this.x = 0,
this.y = 0,
this.width = 0,
this.height = 0;
};
Square.prototype = Object.create(HotSpot.prototype);
Square.prototype.checkPoint = function (x, y) {
var left = this.x,
right = this.x + this.width,
top = this.y,
bottom = this.y + this.height;
var xIsValid = x >= left && x <= right,
yIsValid = y >= top && y <= bottom;
return xIsValid && yIsValid;
};
var Ellipse = function () {
HotSpot.call(this);
this.centerX = 0;
this.centerY = 0;
this.radiusX = 0;
this.radiusY = 0;
};
Ellipse.prototype = Object.create(HotSpot.prototype);
Ellipse.prototype.checkPoint = function (x, y) {
var dX = x - this.centerX,
dY = y - this.centerY;
return Math.pow(dX, 2) / Math.pow(this.radiusX, 2) + Math.pow(dY, 2) / Math.pow(this.radiusY, 2) <= 1;
};
var Polygon = function () {
HotSpot.call(this);
this.points = [];
};
Polygon.prototype = Object.create(HotSpot.prototype);
Polygon.prototype.checkPoint = function (x, y) {
var isInside = false;
for (var i = 0, j = this.points.length - 1; i < this.points.length; j = i++) {
var xi = this.points[i][0],
yi = this.points[i][1],
xj = this.points[j][0],
yj = this.points[j][1];
var intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) {
isInside = !isInside;
}
}
return isInside;
};
var CanvasSVG = function (image) {
var imageSvg = document.createElementNS('http://www.w3.org/2000/svg', 'image');
imageSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', image.src);
imageSvg.setAttribute('width', image.width);
imageSvg.setAttribute('height', image.height);
this.el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this.el.setAttribute('version', '1.1');
this.el.setAttribute('viewBox', '0 0 ' + image.width + ' ' + image.height);
this.el.appendChild(imageSvg);
this.messagesEl = document.createElement('div');
};
CanvasSVG.prototype.setEvents = function () {
var self = this;
var getPointOnImage = function (x, y) {
var pointerPosition = {
left: x + window.scrollX,
top: y + window.scrollY
},
canvasOffset = {
x: self.el.getBoundingClientRect().left + window.scrollX,
y: self.el.getBoundingClientRect().top + window.scrollY
};
return {
x: Math.round(pointerPosition.left - canvasOffset.x),
y: Math.round(pointerPosition.top - canvasOffset.y)
};
};
this.el.addEventListener('dragstart', function (e) {
e.preventDefault();
}, false);
this.el.addEventListener('click', function (e) {
e.preventDefault();
if (answers.length >= hotSpots.length) {
return;
}
var point = getPointOnImage(e.clientX, e.clientY);
var answer = new Answer();
answer.x = point.x;
answer.y = point.y;
answers.push(answer);
self.addAnswer(answer);
if (answers.length === hotSpots.length) {
self.messagesEl.textContent = lang.HotspotExerciseFinished;
return;
}
self.messagesEl.textContent = lang.NextAnswer + ' ' + hotSpots[answers.length].name;
});
};
CanvasSVG.prototype.addAnswer = function (answer) {
var pointSVG = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
pointSVG.setAttribute('cx', answer.x);
pointSVG.setAttribute('cy', answer.y);
pointSVG.setAttribute('r', 15);
pointSVG.setAttribute('fill', '#00677C');
var textSVG = document.createElementNS('http://www.w3.org/2000/svg', 'text');
textSVG.setAttribute('x', answer.x);
textSVG.setAttribute('y', answer.y);
textSVG.setAttribute('dy', 5);
textSVG.setAttribute('font-family', 'sans-serif');
textSVG.setAttribute('text-anchor', 'middle');
textSVG.setAttribute('fill', 'white');
textSVG.textContent = answers.length;
this.el.appendChild(pointSVG);
this.el.appendChild(textSVG);
var hotSpot = hotSpots[answers.length - 1];
var hotspotTxt = document.createElement('input');
hotspotTxt.type = 'hidden';
hotspotTxt.name = 'hotspot[' + config.questionId + '][' + hotSpot.id + ']';
hotspotTxt.value = [answer.x, answer.y].join(';');
var choiceTxt = document.createElement('input');
choiceTxt.type = 'hidden';
choiceTxt.name = 'choice[' + config.questionId + '][' + hotSpot.id + ']';
choiceTxt.value = hotSpot.checkPoint(answer.x, answer.y) ? 1 : 0;
this.el.parentNode.appendChild(hotspotTxt);
this.el.parentNode.appendChild(choiceTxt);
};
CanvasSVG.prototype.startMessagesPanel = function () {
this.messagesEl.textContent = lang.NextAnswer + ' ' + hotSpots[0].name;
this.el.parentNode.parentNode.appendChild(this.messagesEl);
};
var decodeHotSpot = function (hotSpotInfo) {
var hotSpot = null,
coords = hotSpotInfo.coord.split('|');
switch (hotSpotInfo.type) {
case 'square':
var position = coords[0].split(';');
hotSpot = new Square();
hotSpot.x = parseInt(position[0]);
hotSpot.y = parseInt(position[1]);
hotSpot.width = parseInt(coords[1]);
hotSpot.height = parseInt(coords[2]);
break;
case 'circle':
var center = coords[0].split(';');
hotSpot = new Ellipse();
hotSpot.centerX = parseInt(center[0]);
hotSpot.centerY = parseInt(center[1]);
hotSpot.radiusX = parseInt(coords[1]);
hotSpot.radiusY = parseInt(coords[2]);
break;
case 'poly':
hotSpot = new Polygon();
coords.forEach(function (pairedCoord) {
var coord = pairedCoord.split(';');
hotSpot.points.push([
parseInt(coord[0]),
parseInt(coord[1])
]);
});
break;
}
if (hotSpot) {
hotSpot.id = parseInt(hotSpotInfo.id);
hotSpot.name = hotSpotInfo.answer;
}
return hotSpot;
};
var config, lang, hotSpots = [], answers = [];
var startQuestion = function (hotSpotQuestionInfo) {
var image = new Image();
image.onload = function () {
var canvasSVG = new CanvasSVG(this);
hotSpotQuestionInfo.hotspots.forEach(function (hotSpotInfo) {
var hotSpot = decodeHotSpot(hotSpotInfo);
if (!hotSpot) {
return;
}
hotSpots.push(hotSpot);
});
$(config.selector)
.css('width', this.width)
.append(canvasSVG.el);
canvasSVG.setEvents();
canvasSVG.startMessagesPanel();
};
image.src = hotSpotQuestionInfo.image;
lang = hotSpotQuestionInfo.lang;
};
return {
init: function (settings) {
config = $.extend({
questionId: 0,
selector: ''
}, settings);
if (!config.questionId || !config.selector) {
return;
}
var xhrHotSpotQuestion = $.getJSON('/main/exercice/hotspot_actionscript.as.php', {
modifyAnswers: parseInt(config.questionId)
});
$.when(xhrHotSpotQuestion).done(startQuestion);
}
};
})();
Loading…
Cancel
Save