Skip to content

Commit 2d79bff

Browse files
author
Greg MacWilliam
committed
Cleaning up drag-and-drop implementation and adding position constraints.
1 parent c2334b6 commit 2d79bff

File tree

2 files changed

+45
-46
lines changed

2 files changed

+45
-46
lines changed

source/javascripts/models/meme.js

+6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ MEME.MemeModel = Backbone.Model.extend({
5656
});
5757
},
5858

59+
// Specifies if the background image currently has data:
60+
hasBackground: function() {
61+
return this.background.width && this.background.height;
62+
},
63+
64+
// Loads a file stream into an image object:
5965
loadFileForImage: function(file, image) {
6066
var reader = new FileReader();
6167
reader.onload = function() { image.src = reader.result; };

source/javascripts/views/meme-canvas.js

+39-46
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ MEME.MemeCanvasView = Backbone.View.extend({
66

77
initialize: function() {
88
var canvas = document.createElement('canvas');
9-
var $container = $('#meme-canvas');
10-
var _this = this;
9+
var $container = MEME.$('#meme-canvas');
1110

1211
// Display canvas, if enabled:
1312
if (canvas && canvas.getContext) {
@@ -21,17 +20,6 @@ MEME.MemeCanvasView = Backbone.View.extend({
2120

2221
// Listen to model for changes, and re-render in response:
2322
this.listenTo(this.model, 'change', this.render);
24-
// Allow for moving the background image within the canvas
25-
$(this.canvas).on('mousedown', function(e) {
26-
_this.startDrag(e);
27-
});
28-
$(document).on('mouseup', function(e) {
29-
_this.stopDrag(e);
30-
});
31-
$(document).on('mousemove', function(e) {
32-
_this.moveDrag(e);
33-
});
34-
3523
},
3624

3725
setDownload: function() {
@@ -62,14 +50,12 @@ MEME.MemeCanvasView = Backbone.View.extend({
6250
var bw = m.background.width;
6351

6452
if (bh && bw) {
65-
var bp = m.get('backgroundPosition');
66-
6753
// Transformed height and width:
6854
// Set the base position if null
6955
var th = bh * d.imageScale;
7056
var tw = bw * d.imageScale;
71-
var cx = bp.x || d.width / 2;
72-
var cy = bp.y || d.height / 2;
57+
var cx = d.backgroundPosition.x || d.width / 2;
58+
var cy = d.backgroundPosition.y || d.height / 2;
7359

7460
ctx.drawImage(m.background, 0, 0, bw, bh, cx-(tw/2), cy-(th/2), tw, th);
7561
}
@@ -180,40 +166,47 @@ MEME.MemeCanvasView = Backbone.View.extend({
180166
'href': data,
181167
'download': (d.downloadName || 'share') + '.png'
182168
});
183-
},
184-
185-
startDrag: function(e) {
186169

187-
if (e.button != null && e.button != 0) {
188-
this._canMove = false;
189-
return true;
190-
}
191-
192-
this._canMove = true;
193-
$('body').addClass('noselect');
194-
195-
this._startBG = this.model.get('backgroundPosition');
196-
this._startPos = { x: e.clientX, y: e.clientY };
197-
this.canvas.style.cursor = 'move';
170+
// Enable drag cursor while canvas has artwork:
171+
this.canvas.style.cursor = this.model.background.width ? 'move' : 'default';
198172
},
199173

200-
stopDrag: function(e) {
201-
this._canMove = false;
202-
$('body').removeClass('noselect');
203-
this.canvas.style.cursor = 'default';
174+
events: {
175+
'mousedown canvas': 'onDrag'
204176
},
205177

206-
moveDrag: function(e) {
207-
if (typeof(this._canMove) !== "undefined" && this._canMove) {
208-
var origPos = this._startBG;
209-
210-
var position = {
211-
x: origPos.x - (this._startPos.x - e.clientX),
212-
y: origPos.y - (this._startPos.y - e.clientY)
213-
};
214-
215-
this.model.set('backgroundPosition', position);
216-
178+
// Performs drag-and-drop on the background image placement:
179+
onDrag: function(evt) {
180+
evt.preventDefault();
181+
182+
// Return early if there is no background image:
183+
if (!this.model.hasBackground()) return;
184+
185+
// Configure drag settings:
186+
var model = this.model;
187+
var d = model.toJSON();
188+
var iw = model.background.width * d.imageScale / 2;
189+
var ih = model.background.height * d.imageScale / 2;
190+
var origin = {x: evt.clientX, y: evt.clientY};
191+
var start = d.backgroundPosition;
192+
start.x = start.x || d.width / 2;
193+
start.y = start.y || d.height / 2;
194+
195+
// Create update function with draggable constraints:
196+
function update(evt) {
197+
evt.preventDefault();
198+
model.set('backgroundPosition', {
199+
x: Math.max(d.width-iw, Math.min(start.x - (origin.x - evt.clientX), iw)),
200+
y: Math.max(d.height-ih, Math.min(start.y - (origin.y - evt.clientY), ih))
201+
});
217202
}
203+
204+
// Perform drag sequence:
205+
var $doc = MEME.$(document)
206+
.on('mousemove.drag', update)
207+
.on('mouseup.drag', function(evt) {
208+
$doc.off('mouseup.drag mousemove.drag');
209+
update(evt);
210+
});
218211
}
219212
});

0 commit comments

Comments
 (0)