Commit 80465114 by Braden MacDonald

Make zones proportional in Studio

parent 74a0e79a
...@@ -12,10 +12,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -12,10 +12,7 @@ function DragAndDropEditBlock(runtime, element, params) {
var dragAndDrop = (function($) { var dragAndDrop = (function($) {
var _fn = { var _fn = {
// Templates
// DOM Elements
$target: $('.target-img', element),
tpl: { tpl: {
init: function() { init: function() {
_fn.tpl = { _fn.tpl = {
...@@ -41,7 +38,8 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -41,7 +38,8 @@ function DragAndDropEditBlock(runtime, element, params) {
form: $('.drag-builder .items-form', element), form: $('.drag-builder .items-form', element),
tab: $('.drag-builder .items-tab', element) tab: $('.drag-builder .items-tab', element)
}, },
target: $('.drag-builder .target', element) targetImage: $('.drag-builder .target .target-img', element),
zonesPreview: $('.drag-builder .target .zones-preview', element),
}, },
init: function() { init: function() {
_fn.data = params.data; _fn.data = params.data;
...@@ -50,7 +48,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -50,7 +48,7 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.tpl.init(); _fn.tpl.init();
// Display target image // Display target image
_fn.$target.show(); _fn.build.$el.targetImage.show();
_fn.build.clickHandlers(); _fn.build.clickHandlers();
}, },
...@@ -71,9 +69,10 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -71,9 +69,10 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.build.form.zone.add(); _fn.build.form.zone.add();
} }
// Set the target image: // Set the target image and bind its event handler:
$('.target-image-form input', element).val(_fn.data.targetImg); $('.target-image-form input', element).val(_fn.data.targetImg);
$('.target-img', element).attr('src', params.target_img_expanded_url); _fn.build.$el.targetImage.load(_fn.build.form.zone.imageLoaded);
_fn.build.$el.targetImage.attr('src', params.target_img_expanded_url);
if (_fn.data.displayLabels) { if (_fn.data.displayLabels) {
$('.display-labels-form input', element).prop('checked', true); $('.display-labels-form input', element).prop('checked', true);
...@@ -88,7 +87,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -88,7 +87,7 @@ function DragAndDropEditBlock(runtime, element, params) {
$(this).one('click', function(e) { $(this).one('click', function(e) {
// $zoneTab -> $itemTab // $zoneTab -> $itemTab
e.preventDefault(); e.preventDefault();
_fn.build.form.zone.setAll();
for (var i = 0; i < _fn.data.items.length; i++) { for (var i = 0; i < _fn.data.items.length; i++) {
_fn.build.form.item.add(_fn.data.items[i]); _fn.build.form.item.add(_fn.data.items[i]);
} }
...@@ -119,6 +118,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -119,6 +118,7 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.build.form.zone.add(); _fn.build.form.zone.add();
}) })
.on('click', '.remove-zone', _fn.build.form.zone.remove) .on('click', '.remove-zone', _fn.build.form.zone.remove)
.on('input', '.zone-row input', _fn.build.form.zone.changedInputHandler)
.on('click', '.target-image-form button', function(e) { .on('click', '.target-image-form button', function(e) {
e.preventDefault(); e.preventDefault();
...@@ -128,7 +128,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -128,7 +128,7 @@ function DragAndDropEditBlock(runtime, element, params) {
// e.g. '/static/blah.png' becomes '/asset-v1:course+id/blah.png' // e.g. '/static/blah.png' becomes '/asset-v1:course+id/blah.png'
var handlerUrl = runtime.handlerUrl(element, 'expand_static_url'); var handlerUrl = runtime.handlerUrl(element, 'expand_static_url');
$.post(handlerUrl, JSON.stringify(new_img_url), function(result) { $.post(handlerUrl, JSON.stringify(new_img_url), function(result) {
_fn.$target.attr('src', result.url); _fn.build.$el.targetImage.attr('src', result.url);
}).error(function(a, b, c) { console.log(a, b, c); }); }).error(function(a, b, c) { console.log(a, b, c); });
// Placeholder shim for IE9 // Placeholder shim for IE9
...@@ -148,21 +148,18 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -148,21 +148,18 @@ function DragAndDropEditBlock(runtime, element, params) {
zone: { zone: {
count: 0, count: 0,
formCount: 0, formCount: 0,
list: [], zoneObjects: [],
obj: [],
getObjByIndex: function(num) { getObjByIndex: function(num) {
for (var i = 0; i < _fn.build.form.zone.obj.length; i++) { for (var i = 0; i < _fn.build.form.zone.zoneObjects.length; i++) {
if (_fn.build.form.zone.obj[i].index == num) if (_fn.build.form.zone.zoneObjects[i].index == num)
return _fn.build.form.zone.obj[i]; return _fn.build.form.zone.zoneObjects[i];
} }
}, },
add: function(oldZone) { add: function(oldZone) {
var inputTemplate = _fn.tpl.zoneInput, var inputTemplate = _fn.tpl.zoneInput,
zoneTemplate = _fn.tpl.zoneElement,
name = 'zone-', name = 'zone-',
$elements = _fn.build.$el, $elements = _fn.build.$el,
num, num;
zoneObj;
if (!oldZone) oldZone = {}; if (!oldZone) oldZone = {};
...@@ -172,17 +169,17 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -172,17 +169,17 @@ function DragAndDropEditBlock(runtime, element, params) {
name += num; name += num;
// Update zone obj // Update zone obj
zoneObj = { var zoneObj = {
title: oldZone.title || 'Zone ' + num, title: oldZone.title || 'Zone ' + num,
id: name, id: name,
index: num, index: num,
width: oldZone.width || 200, width: oldZone.width || 200,
height: oldZone.height || 100, height: oldZone.height || 100,
x: oldZone.x || 0, x: oldZone.x || 0,
y: oldZone.y || 0 y: oldZone.y || 0,
}; };
_fn.build.form.zone.obj.push(zoneObj); _fn.build.form.zone.zoneObjects.push(zoneObj);
// Add fields to zone position form // Add fields to zone position form
$zoneNode = $(inputTemplate(zoneObj)); $zoneNode = $(inputTemplate(zoneObj));
...@@ -191,10 +188,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -191,10 +188,7 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.build.form.zone.enableDelete(); _fn.build.form.zone.enableDelete();
// Add zone div to target // Add zone div to target
$elements.target.append(zoneTemplate(zoneObj)); _fn.build.form.zone.renderZonesPreview();
// Listen to changes in form to update zone div
_fn.build.form.zone.clickHandler(num);
// Placeholder shim for IE9 // Placeholder shim for IE9
$.placeholder.shim(); $.placeholder.shim();
...@@ -208,14 +202,14 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -208,14 +202,14 @@ function DragAndDropEditBlock(runtime, element, params) {
e.preventDefault(); e.preventDefault();
$el.detach(); $el.detach();
$('#' + id, element).detach();
// Find the index of the zone in the array and remove it. // Find the index of the zone in the array and remove it.
for (array_index = 0; array_index < _fn.build.form.zone.obj.length; for (array_index = 0; array_index < _fn.build.form.zone.zoneObjects.length;
array_index++) { array_index++) {
if (_fn.build.form.zone.obj[array_index].index == index) break; if (_fn.build.form.zone.zoneObjects[array_index].index == index) break;
} }
_fn.build.form.zone.obj.splice(array_index, 1); _fn.build.form.zone.zoneObjects.splice(array_index, 1);
_fn.build.form.zone.renderZonesPreview();
_fn.build.form.zone.formCount--; _fn.build.form.zone.formCount--;
_fn.build.form.zone.disableDelete(); _fn.build.form.zone.disableDelete();
...@@ -233,80 +227,68 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -233,80 +227,68 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.build.$el.zones.form.find('.remove-zone').addClass('hidden'); _fn.build.$el.zones.form.find('.remove-zone').addClass('hidden');
} }
}, },
setAll: function() { renderZonesPreview: function() {
var zones = [], // Refresh the div which shows a preview of the zones over top of
$form = _fn.build.$el.zones.form.find('.title'); // the background image.
_fn.build.$el.zonesPreview.html('');
var imgWidth = _fn.build.$el.targetImage[0].naturalWidth;
var imgHeight = _fn.build.$el.targetImage[0].naturalHeight;
this.zoneObjects.forEach(function(zoneObj) {
_fn.build.$el.zonesPreview.append(
_fn.tpl.zoneElement({
id: zoneObj.id,
title: zoneObj.title,
x_percent: (+zoneObj.x) / imgWidth * 100,
y_percent: (+zoneObj.y) / imgHeight * 100,
width_percent: (+zoneObj.width) / imgWidth * 100,
height_percent: (+zoneObj.height) / imgHeight * 100,
})
);
});
},
getZoneNames: function() {
var zoneNames = [];
var $form = _fn.build.$el.zones.form.find('.title');
$form.each(function(i, el) { $form.each(function(i, el) {
var val = $(el).val(); var val = $(el).val();
if (val.length > 0) { if (val.length > 0) {
zones.push(val); zoneNames.push(val);
} }
}); });
return zoneNames;
_fn.build.form.zone.list = zones;
},
clickHandler: function(num) {
var $div = $('#zone-' + num, element),
$form = _fn.build.$el.zones.form.find('.zone-row.zone-' + num);
// Listen to form changes and update zone div position
$form.on('keyup', '.title', function(e) {
var text = $(e.currentTarget).val(),
record = _fn.build.form.zone.getObjByIndex(num);
$div.find('p').html(text);
record.title = text;
}).on('keyup', '.width', function(e) {
var width = $(e.currentTarget).val(),
record = _fn.build.form.zone.getObjByIndex(num);
$div.css('width', width + 'px');
record.width = width;
}).on('keyup', '.height', function(e) {
var height = $(e.currentTarget).val(),
record = _fn.build.form.zone.getObjByIndex(num);
$div.css('height', height + 'px');
record.height = height;
}).on('keyup', '.x', function(e) {
var x = $(e.currentTarget).val(),
record = _fn.build.form.zone.getObjByIndex(num);
$div.css('left', x + 'px');
record.x = x;
}).on('keyup', '.y', function(e) {
var y = $(e.currentTarget).val(),
record = _fn.build.form.zone.getObjByIndex(num);
$div.css('top', y + 'px');
record.y = y;
});
}, },
cleanObject: function(arr) { changedInputHandler: function(ev) {
var clean = [], // Called when any of the inputs have changed.
i, var $changedInput = $(ev.currentTarget);
len = arr.length; var $row = $changedInput.closest('.zone-row');
var record = _fn.build.form.zone.getObjByIndex($row.data('index'));
for (i=0; i<len; i++) { if ($changedInput.hasClass('title')) {
clean.push(arr[i]); record.title = $changedInput.val();
} } else if ($changedInput.hasClass('width')) {
record.width = $changedInput.val();
return clean; } else if ($changedInput.hasClass('height')) {
record.height = $changedInput.val();
} else if ($changedInput.hasClass('x')) {
record.x = $changedInput.val();
} else if ($changedInput.hasClass('y')) {
record.y = $changedInput.val();
} }
_fn.build.form.zone.renderZonesPreview();
},
imageLoaded: function() {
// The target background image has loaded (or reloaded, if changed).
_fn.build.form.zone.renderZonesPreview();
},
}, },
createDropdown: function(selected) { createDropdown: function(selected) {
var tpl = _fn.tpl.zoneDropdown, var tpl = _fn.tpl.zoneDropdown,
i,
is_sel,
arr = _fn.build.form.zone.list,
dropdown = [], dropdown = [],
html, html,
dropdown_items = arr.concat('none'); dropdown_items = _fn.build.form.zone.getZoneNames().concat('none');
for (i=0; i<dropdown_items.length; i++) { for (var i=0; i<dropdown_items.length; i++) {
is_sel = (dropdown_items[i] == selected) ? 'selected' : ''; var is_sel = (dropdown_items[i] == selected) ? 'selected' : '';
dropdown.push(tpl({ value: dropdown_items[i], selected: is_sel })); dropdown.push(tpl({ value: dropdown_items[i], selected: is_sel }));
} }
...@@ -425,7 +407,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -425,7 +407,7 @@ function DragAndDropEditBlock(runtime, element, params) {
}); });
_fn.data.items = items; _fn.data.items = items;
_fn.data.zones = _fn.build.form.zone.cleanObject(_fn.build.form.zone.obj); _fn.data.zones = _fn.build.form.zone.zoneObjects;
var data = { var data = {
'display_name': $element.find('.display-name').val(), 'display_name': $element.find('.display-name').val(),
......
...@@ -60,6 +60,8 @@ ...@@ -60,6 +60,8 @@
</div> </div>
<div class="target"> <div class="target">
<img class="target-img"> <img class="target-img">
<div class="zones-preview">
</div>
</div> </div>
</div> </div>
</section> </section>
......
<script id="zone-element-tpl" type="text/html"> <script id="zone-element-tpl" type="text/html">
<div id="{{ id }}" class="zone" data-zone="{{ title }}" style=" <div id="{{ id }}" class="zone" data-zone="{{ title }}" style="
top:{{ y }}px; top:{{ y_percent }}%;
left:{{ x }}px; left:{{ x_percent }}%;
width:{{ width }}px; width:{{ width_percent }}%;
height:{{ height }}px;"> height:{{ height_percent }}%;">
<p>{{{ title }}}</p> <p>{{{ title }}}</p>
</div> </div>
</script> </script>
<script id="zone-input-tpl" type="text/html"> <script id="zone-input-tpl" type="text/html">
<div class="zone-row {{ id }}"> <div class="zone-row {{ id }}" data-index="{{index}}">
<label>{{i18n "Text"}}</label> <label>{{i18n "Text"}}</label>
<input type="text" class="title" value="{{ title }}" /> <input type="text" class="title" value="{{ title }}" />
<a href="#" class="remove-zone hidden"> <a href="#" class="remove-zone hidden">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment