mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 17:06:53 +02:00
MDL-51914 qtype_ddmarker: precise grading round the edges of zones
There was a previous change to the CSS (7px -> 3px) to make things look prettier, which acutally broke the grading by a few pixes. I fixed this by: * Changing the offset of the cross hairs back to the correct value, and adding a comment to point out the imporance of not changing that CSS. * Achieved the nice layout of the label relative to the cross-hairs in a different way. * Added a similar clafirying comment in the JavaScript. * Improved how the grid on the editing form is aligned with the background image. * Added rounding to the grading code, to cope better now that browsers do sub-pixel positioning.
This commit is contained in:
parent
9382ac38d6
commit
2d391d1b10
9 changed files with 15 additions and 7 deletions
|
@ -214,6 +214,8 @@ class qtype_ddmarker_question extends qtype_ddtoimage_question_base {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$pointxy = explode(',', $coord);
|
$pointxy = explode(',', $coord);
|
||||||
|
$pointxy[0] = round($pointxy[0]);
|
||||||
|
$pointxy[1] = round($pointxy[1]);
|
||||||
if ($place->drop_hit($pointxy)) {
|
if ($place->drop_hit($pointxy)) {
|
||||||
if (!isset($hits[$placeno])) {
|
if (!isset($hits[$placeno])) {
|
||||||
$hits[$placeno] = array();
|
$hits[$placeno] = array();
|
||||||
|
|
|
@ -40,7 +40,7 @@ form.mform fieldset#id_previewareaheader div.draghome, form.mform fieldset#id_pr
|
||||||
.que.ddmarker div.dragitems span.markertext,
|
.que.ddmarker div.dragitems span.markertext,
|
||||||
.que.ddmarker div.markertexts span.markertext,
|
.que.ddmarker div.markertexts span.markertext,
|
||||||
form.mform fieldset#id_previewareaheader div.markertexts span.markertext {
|
form.mform fieldset#id_previewareaheader div.markertexts span.markertext {
|
||||||
margin: 5px;
|
margin: 0 5px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 2px solid black;
|
border: 2px solid black;
|
||||||
|
@ -70,8 +70,8 @@ form.mform fieldset#id_previewareaheader div.markertexts span.markertext {
|
||||||
}
|
}
|
||||||
.que.ddmarker div.dragitems img.target {
|
.que.ddmarker div.dragitems img.target {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -7px;
|
left: -7px; /* This must be half the size of the target image, minus 0.5. */
|
||||||
top: -3px;
|
top: -7px; /* In other words, this works for a 15x15 cross-hair. */
|
||||||
}
|
}
|
||||||
.que.ddmarker div.dragitems div.draghome img.target {
|
.que.ddmarker div.dragitems div.draghome img.target {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -133,6 +133,8 @@ Y.extend(DDMARKER_DD, Y.Base, {
|
||||||
return colour;
|
return colour;
|
||||||
},
|
},
|
||||||
convert_to_window_xy : function (bgimgxy) {
|
convert_to_window_xy : function (bgimgxy) {
|
||||||
|
// The +1 seems rather odd, but seems to give the best results in
|
||||||
|
// the three main browsers at a range of zoom levels.
|
||||||
return [Number(bgimgxy[0]) + this.doc.bg_img().getX() + 1,
|
return [Number(bgimgxy[0]) + this.doc.bg_img().getX() + 1,
|
||||||
Number(bgimgxy[1]) + this.doc.bg_img().getY() + 1];
|
Number(bgimgxy[1]) + this.doc.bg_img().getY() + 1];
|
||||||
},
|
},
|
||||||
|
|
|
@ -133,6 +133,8 @@ Y.extend(DDMARKER_DD, Y.Base, {
|
||||||
return colour;
|
return colour;
|
||||||
},
|
},
|
||||||
convert_to_window_xy : function (bgimgxy) {
|
convert_to_window_xy : function (bgimgxy) {
|
||||||
|
// The +1 seems rather odd, but seems to give the best results in
|
||||||
|
// the three main browsers at a range of zoom levels.
|
||||||
return [Number(bgimgxy[0]) + this.doc.bg_img().getX() + 1,
|
return [Number(bgimgxy[0]) + this.doc.bg_img().getX() + 1,
|
||||||
Number(bgimgxy[1]) + this.doc.bg_img().getY() + 1];
|
Number(bgimgxy[1]) + this.doc.bg_img().getY() + 1];
|
||||||
},
|
},
|
||||||
|
|
|
@ -98,7 +98,7 @@ Y.extend(DDMARKER_FORM, M.qtype_ddmarker.dd_base_class, {
|
||||||
}
|
}
|
||||||
if (this.doc.bg_img()) {
|
if (this.doc.bg_img()) {
|
||||||
Y.one('div.ddarea .grid')
|
Y.one('div.ddarea .grid')
|
||||||
.setXY(this.doc.bg_img().getXY())
|
.setXY(this.convert_to_window_xy([0, 0]))
|
||||||
.setStyle('width', this.doc.bg_img().get('width'))
|
.setStyle('width', this.doc.bg_img().get('width'))
|
||||||
.setStyle('height', this.doc.bg_img().get('height'));
|
.setStyle('height', this.doc.bg_img().get('height'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
YUI.add("moodle-qtype_ddmarker-form",function(e,t){var n="moodle-qtype_ddmarker-form",r=function(){r.superclass.constructor.apply(this,arguments)};e.extend(r,M.qtype_ddmarker.dd_base_class,{fp:null,initializer:function(){var t="qtype_ddmarker-form-"+Math.random().toString(36).slice(2);M.util.js_pending(t),this.fp=this.file_pickers();var n=e.one(this.get("topnode"));n.one("div.fcontainer").append('<div class="ddarea"><div class="markertexts"></div><div class="droparea"></div><div class="dropzones"></div><div class="grid"></div></div>'),this.doc=this.doc_structure(this),this.stop_selector_events(),this.set_options_for_drag_item_selectors(),this.setup_form_events(),e.later(500,this,this.update_drop_zones,[t],!0),e.after(this.load_bg_image,M.form_filepicker,"callback",this),this.load_bg_image()},load_bg_image:function(){var t=this.fp.file("bgimage").href;if(t!==null){this.doc.load_bg_img(t);var n=new e.DD.Drop({node:this.doc.bg_img()});n.on("drop:hit",function(e){e.drag.get("node").setData("gooddrop",!0)}),this.afterimageloaddone=!1,this.doc.bg_img().on("load",this.constrain_image_size,this)}},constrain_image_size:function(e){var t=this.get("maxsizes").bgimage,n=Math.max(e.target.get("width")/t.width,e.target.get("height")/t.height);n>1&&e.target.set("width",Math.floor(e.target.get("width")/n)),e.target.addClass("constrained"),e.target.detach("load",this.constrain_image_size)},update_drop_zones:function(t){this.graphics!==null&&this.graphics.destroy(),this.restart_colours(),this.graphics=new e.Graphic({render:"div.ddarea div.dropzones"});var n=this.form.get_form_value("nodropzone",[]);for(var r=0;r<n;r++){var i=this.form.get_form_value("drops",[r,"choice"]),s=this.get_marker_text(i),o=this.form.get_form_value("drops",[r,"shape"]),u=this.get_coords(r),a=this.get_next_colour();e.one("input#id_drops_"+r+"_coords").setStyle("background-color",a),this.draw_drop_zone(r,s,o,u,a,!1)}this.doc.bg_img()&&e.one("div.ddarea .grid").setXY(this.doc.bg_img().getXY()).setStyle("width",this.doc.bg_img().get("width")).setStyle("height",this.doc.bg_img().get("height")),M.util.js_complete(t)},get_coords:function(e){var t=this.form.get_form_value("drops",[e,"coords"]);return t.replace(new RegExp("\\s*","g"),"")},get_marker_text:function(e){if(Number(e)!==0){var t=this.form.get_form_value("drags",[e-1,"label"]);return t.replace(new RegExp("^\\s*(.*)\\s*$"),"$1")}return""},set_options_for_drag_item_selectors:function(){var t={0:""};for(var n=1;n<=this.form.get_form_value("noitems",[]);n++){var r=this.get_marker_text(n);r!==""&&(t[n]=e.Escape.html(r))}var i=[],s;for(n=0;n<this.form.get_form_value("nodropzone",[]);n++)s=e.one("#id_drops_"+n+"_choice"),i[n]=Number(s.get("value"));for(n=0;n<this.form.get_form_value("nodropzone",[]);n++){s=e.one("#id_drops_"+n+"_choice"),s.all("option").remove(!0);for(var o in t){o=Number(o);var u='<option value="'+o+'">'+t[o]+"</option>";s.append(u);var a=s.one('option[value="'+o+'"]');if(o===i[n])a.set("selected",!0);else if(o!==0){var f=this.form.get_form_value("drags",[o-1,"noofdrags"]);if(Number(f)!==0)for(var l in i)if(Number(i[l])===o){if(Number(f)===1){a.set("disabled",!0);break}f--}}}}},stop_selector_events:function(){e.all("fieldset#id_dropzoneheader select").detachAll()},setup_form_events:function(){e.all("fieldset#id_draggableitemheader input").on("change",function(){this.set_options_for_drag_item_selectors()},this),e.all("fieldset#id_draggableitemheader select").on("change",function(){this.set_options_for_drag_item_selectors()},this),e.all("fieldset#id_dropzoneheader select").on("change",function(){this.set_options_for_drag_item_selectors()},this)},form:{to_name_with_index:function(e,t){var n=e;for(var r=0;r<t.length;r++)n=n+"["+t[r]+"]";return n},get_el:function(e,t){var n=document.getElementById("mform1");return n.elements[this.to_name_with_index(e,t)]},get_form_value:function(e,t){var n=this.get_el(e,t);return n.type==="checkbox"?n.checked:n.value},set_form_value:function(e,t,n){var r=this.get_el(e,t);r.type==="checkbox"?r.checked=n:r.value=n},from_name_with_index:function(e){var t={};t.indexes=[];var n=e.indexOf("[");t.name=e.substring(0,n);while(n!==-1){var r=e.indexOf("]",n+1);t.indexes.push(e.substring(n+1,r)),n=e.indexOf("[",r+1)}return t}},file_pickers:function(){var t,n;if(t===undefined){t={},n={};var r=e.all("form.mform input.filepickerhidden");r.each(function(e){t[e.get("value")]=e.get("name"),n[e.get("name")]=e.get("parentNode")},this)}var i={file:function(e){var t=n[e],r=t.one("div.filepicker-filelist a");return r?{href:r.get("href"),name:r.get("innerHTML")}:{href:null,name:null}},name:function(e){return t[e]}};return i}},{NAME:n,ATTRS:{maxsizes:{value:null}}}),M.qtype_ddmarker=M.qtype_ddmarker||{},M.qtype_ddmarker.init_form=function(e){return new r(e)}},"@VERSION@",{requires:["moodle-qtype_ddmarker-dd","form_filepicker","graphics","escape"]});
|
YUI.add("moodle-qtype_ddmarker-form",function(e,t){var n="moodle-qtype_ddmarker-form",r=function(){r.superclass.constructor.apply(this,arguments)};e.extend(r,M.qtype_ddmarker.dd_base_class,{fp:null,initializer:function(){var t="qtype_ddmarker-form-"+Math.random().toString(36).slice(2);M.util.js_pending(t),this.fp=this.file_pickers();var n=e.one(this.get("topnode"));n.one("div.fcontainer").append('<div class="ddarea"><div class="markertexts"></div><div class="droparea"></div><div class="dropzones"></div><div class="grid"></div></div>'),this.doc=this.doc_structure(this),this.stop_selector_events(),this.set_options_for_drag_item_selectors(),this.setup_form_events(),e.later(500,this,this.update_drop_zones,[t],!0),e.after(this.load_bg_image,M.form_filepicker,"callback",this),this.load_bg_image()},load_bg_image:function(){var t=this.fp.file("bgimage").href;if(t!==null){this.doc.load_bg_img(t);var n=new e.DD.Drop({node:this.doc.bg_img()});n.on("drop:hit",function(e){e.drag.get("node").setData("gooddrop",!0)}),this.afterimageloaddone=!1,this.doc.bg_img().on("load",this.constrain_image_size,this)}},constrain_image_size:function(e){var t=this.get("maxsizes").bgimage,n=Math.max(e.target.get("width")/t.width,e.target.get("height")/t.height);n>1&&e.target.set("width",Math.floor(e.target.get("width")/n)),e.target.addClass("constrained"),e.target.detach("load",this.constrain_image_size)},update_drop_zones:function(t){this.graphics!==null&&this.graphics.destroy(),this.restart_colours(),this.graphics=new e.Graphic({render:"div.ddarea div.dropzones"});var n=this.form.get_form_value("nodropzone",[]);for(var r=0;r<n;r++){var i=this.form.get_form_value("drops",[r,"choice"]),s=this.get_marker_text(i),o=this.form.get_form_value("drops",[r,"shape"]),u=this.get_coords(r),a=this.get_next_colour();e.one("input#id_drops_"+r+"_coords").setStyle("background-color",a),this.draw_drop_zone(r,s,o,u,a,!1)}this.doc.bg_img()&&e.one("div.ddarea .grid").setXY(this.convert_to_window_xy([0,0])).setStyle("width",this.doc.bg_img().get("width")).setStyle("height",this.doc.bg_img().get("height")),M.util.js_complete(t)},get_coords:function(e){var t=this.form.get_form_value("drops",[e,"coords"]);return t.replace(new RegExp("\\s*","g"),"")},get_marker_text:function(e){if(Number(e)!==0){var t=this.form.get_form_value("drags",[e-1,"label"]);return t.replace(new RegExp("^\\s*(.*)\\s*$"),"$1")}return""},set_options_for_drag_item_selectors:function(){var t={0:""};for(var n=1;n<=this.form.get_form_value("noitems",[]);n++){var r=this.get_marker_text(n);r!==""&&(t[n]=e.Escape.html(r))}var i=[],s;for(n=0;n<this.form.get_form_value("nodropzone",[]);n++)s=e.one("#id_drops_"+n+"_choice"),i[n]=Number(s.get("value"));for(n=0;n<this.form.get_form_value("nodropzone",[]);n++){s=e.one("#id_drops_"+n+"_choice"),s.all("option").remove(!0);for(var o in t){o=Number(o);var u='<option value="'+o+'">'+t[o]+"</option>";s.append(u);var a=s.one('option[value="'+o+'"]');if(o===i[n])a.set("selected",!0);else if(o!==0){var f=this.form.get_form_value("drags",[o-1,"noofdrags"]);if(Number(f)!==0)for(var l in i)if(Number(i[l])===o){if(Number(f)===1){a.set("disabled",!0);break}f--}}}}},stop_selector_events:function(){e.all("fieldset#id_dropzoneheader select").detachAll()},setup_form_events:function(){e.all("fieldset#id_draggableitemheader input").on("change",function(){this.set_options_for_drag_item_selectors()},this),e.all("fieldset#id_draggableitemheader select").on("change",function(){this.set_options_for_drag_item_selectors()},this),e.all("fieldset#id_dropzoneheader select").on("change",function(){this.set_options_for_drag_item_selectors()},this)},form:{to_name_with_index:function(e,t){var n=e;for(var r=0;r<t.length;r++)n=n+"["+t[r]+"]";return n},get_el:function(e,t){var n=document.getElementById("mform1");return n.elements[this.to_name_with_index(e,t)]},get_form_value:function(e,t){var n=this.get_el(e,t);return n.type==="checkbox"?n.checked:n.value},set_form_value:function(e,t,n){var r=this.get_el(e,t);r.type==="checkbox"?r.checked=n:r.value=n},from_name_with_index:function(e){var t={};t.indexes=[];var n=e.indexOf("[");t.name=e.substring(0,n);while(n!==-1){var r=e.indexOf("]",n+1);t.indexes.push(e.substring(n+1,r)),n=e.indexOf("[",r+1)}return t}},file_pickers:function(){var t,n;if(t===undefined){t={},n={};var r=e.all("form.mform input.filepickerhidden");r.each(function(e){t[e.get("value")]=e.get("name"),n[e.get("name")]=e.get("parentNode")},this)}var i={file:function(e){var t=n[e],r=t.one("div.filepicker-filelist a");return r?{href:r.get("href"),name:r.get("innerHTML")}:{href:null,name:null}},name:function(e){return t[e]}};return i}},{NAME:n,ATTRS:{maxsizes:{value:null}}}),M.qtype_ddmarker=M.qtype_ddmarker||{},M.qtype_ddmarker.init_form=function(e){return new r(e)}},"@VERSION@",{requires:["moodle-qtype_ddmarker-dd","form_filepicker","graphics","escape"]});
|
||||||
|
|
|
@ -98,7 +98,7 @@ Y.extend(DDMARKER_FORM, M.qtype_ddmarker.dd_base_class, {
|
||||||
}
|
}
|
||||||
if (this.doc.bg_img()) {
|
if (this.doc.bg_img()) {
|
||||||
Y.one('div.ddarea .grid')
|
Y.one('div.ddarea .grid')
|
||||||
.setXY(this.doc.bg_img().getXY())
|
.setXY(this.convert_to_window_xy([0, 0]))
|
||||||
.setStyle('width', this.doc.bg_img().get('width'))
|
.setStyle('width', this.doc.bg_img().get('width'))
|
||||||
.setStyle('height', this.doc.bg_img().get('height'));
|
.setStyle('height', this.doc.bg_img().get('height'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,8 @@ Y.extend(DDMARKER_DD, Y.Base, {
|
||||||
return colour;
|
return colour;
|
||||||
},
|
},
|
||||||
convert_to_window_xy : function (bgimgxy) {
|
convert_to_window_xy : function (bgimgxy) {
|
||||||
|
// The +1 seems rather odd, but seems to give the best results in
|
||||||
|
// the three main browsers at a range of zoom levels.
|
||||||
return [Number(bgimgxy[0]) + this.doc.bg_img().getX() + 1,
|
return [Number(bgimgxy[0]) + this.doc.bg_img().getX() + 1,
|
||||||
Number(bgimgxy[1]) + this.doc.bg_img().getY() + 1];
|
Number(bgimgxy[1]) + this.doc.bg_img().getY() + 1];
|
||||||
},
|
},
|
||||||
|
|
|
@ -96,7 +96,7 @@ Y.extend(DDMARKER_FORM, M.qtype_ddmarker.dd_base_class, {
|
||||||
}
|
}
|
||||||
if (this.doc.bg_img()) {
|
if (this.doc.bg_img()) {
|
||||||
Y.one('div.ddarea .grid')
|
Y.one('div.ddarea .grid')
|
||||||
.setXY(this.doc.bg_img().getXY())
|
.setXY(this.convert_to_window_xy([0, 0]))
|
||||||
.setStyle('width', this.doc.bg_img().get('width'))
|
.setStyle('width', this.doc.bg_img().get('width'))
|
||||||
.setStyle('height', this.doc.bg_img().get('height'));
|
.setStyle('height', this.doc.bg_img().get('height'));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue