Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

dimensions and performance improvements

  • Loading branch information...
commit b72ed372757fc881d7607b6f834e82ae050da628 1 parent 0784f19
@maccman authored
Showing with 263 additions and 149 deletions.
  1. +3 −3 Gemfile.lock
  2. +3 −1 README.md
  3. +17 −8 assets/javascripts/app/controllers/element.module.coffee
  4. +3 −3 assets/javascripts/app/controllers/element/resizing.module.coffee
  5. +13 −3 assets/javascripts/app/controllers/inspector/dimensions.module.coffee
  6. +4 −4 assets/javascripts/app/controllers/stage.module.coffee
  7. +2 −2 assets/javascripts/app/controllers/stage/clipboard.module.coffee
  8. +3 −2 assets/javascripts/app/controllers/stage/dragging.module.coffee
  9. +4 −4 assets/javascripts/app/controllers/stage/key_bindings.module.coffee
  10. +2 −2 assets/javascripts/app/controllers/stage/resizing.module.coffee
  11. +8 −5 assets/javascripts/app/controllers/stage/select_area.module.coffee
  12. +15 −5 assets/javascripts/app/controllers/stage/selection.module.coffee
  13. +2 −2 assets/javascripts/app/controllers/stage/snapping.module.coffee
  14. +12 −0 assets/javascripts/app/views/inspector/dimensions.jst.eco
  15. +5 −1 assets/stylesheets/app/inspector/dimensions.css.styl
  16. +20 −10 public/assets/app/controllers/element.module.js
  17. +3 −3 public/assets/app/controllers/element/resizing.module.js
  18. +14 −4 public/assets/app/controllers/inspector/dimensions.module.js
  19. +4 −4 public/assets/app/controllers/stage.module.js
  20. +2 −2 public/assets/app/controllers/stage/clipboard.module.js
  21. +3 −2 public/assets/app/controllers/stage/dragging.module.js
  22. +4 −4 public/assets/app/controllers/stage/key_bindings.module.js
  23. +2 −2 public/assets/app/controllers/stage/resizing.module.js
  24. +5 −3 public/assets/app/controllers/stage/select_area.module.js
  25. +22 −15 public/assets/app/controllers/stage/selection.module.js
  26. +2 −2 public/assets/app/controllers/stage/snapping.module.js
  27. +4 −1 public/assets/application.css
  28. +82 −52 public/assets/application.js
View
6 Gemfile.lock
@@ -8,7 +8,7 @@ GIT
GIT
remote: git://github.com/maccman/sprockets-commonjs.git
- revision: 76520f2bdf805d308220f7fd56cab78afbe01892
+ revision: 36d8e9ff61653afbc3782d098c18075e7c3ce906
specs:
sprockets-commonjs (0.0.2)
sprockets (~> 2.4.0)
@@ -21,7 +21,7 @@ GEM
coffee-script (2.2.0)
coffee-script-source
execjs
- coffee-script-source (1.2.0)
+ coffee-script-source (1.3.1)
columnize (0.3.6)
daemons (1.1.8)
eco (1.0.0)
@@ -47,7 +47,7 @@ GEM
rack
rack-test (0.6.1)
rack (>= 1.0)
- rb-fsevent (0.9.0)
+ rb-fsevent (0.9.1)
ruby-debug-base19 (0.11.25)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
View
4 README.md
@@ -5,7 +5,8 @@ A Photoshop replacement. Inspired by Keynote. Democratizing design.
Background image
Background gradient rotation
Color inspector movable window
-Selection not working with scroll
+Dragging right and up doesn't select elements - offset by the header
+We want the resize to be around the selection
Phase 1:
@@ -25,6 +26,7 @@ Phase 1:
* Rotation
* ✓ Opacity
* content editable
+ * context menu
Phase 2:
View
25 assets/javascripts/app/controllers/element.module.coffee
@@ -38,7 +38,8 @@ class Element extends Spine.Controller
set: (key, value) ->
if typeof key is 'object'
- @set(k, v) for k, v of key
+ for k, v of key
+ @[k]?(v) or @properties[k] = v
else
@[key]?(value) or @properties[key] = value
@@ -47,14 +48,11 @@ class Element extends Spine.Controller
paint: ->
@el.css(@properties)
- toValue: ->
- @properties
-
# Manipulating elements
resize: (area) ->
@set(area)
- @el.trigger('resized', [this])
+ @el.trigger('element:resize', [this])
moveBy: (toPosition) ->
area = @area()
@@ -62,7 +60,7 @@ class Element extends Spine.Controller
area.top += toPosition.top
@set(area)
- @el.trigger('moved', [this])
+ @el.trigger('move.element', [this])
order: (i) ->
@set('zIndex', i + 100)
@@ -74,9 +72,9 @@ class Element extends Spine.Controller
select: (e) ->
if @selected()
- @el.trigger('deselect', [this, e?.shiftKey])
+ @el.trigger('deselect.element', [this, e?.shiftKey])
else
- @el.trigger('select', [this, e?.shiftKey])
+ @el.trigger('select.element', [this, e?.shiftKey])
selected: (bool) =>
if bool?
@@ -142,4 +140,15 @@ class Element extends Spine.Controller
styles = ("\t#{k}: #{v};" for k, v of styles).join("\n")
".#{@className} {\n#{styles}\n}"
+ toValue: ->
+ @properties
+
+ # Events
+
+ change: (func) ->
+ if typeof func is 'function'
+ @el.bind('change.element', func)
+ else
+ @el.trigger('change.element', arguments...)
+
module.exports = Element
View
6 assets/javascripts/app/controllers/element/resizing.module.coffee
@@ -22,10 +22,10 @@ class Thumb extends Spine.Controller
top: e.pageY - @dragPosition.top
@dragPosition = {left: e.pageX, top: e.pageY}
- @el.trigger('resize.start', [@type, difference, e.shiftKey])
+ @el.trigger('start.resize', [@type, difference, e.shiftKey])
drop: (e) =>
- @el.trigger('resize.end')
+ @el.trigger('end.resize')
$(document).unbind('mousemove', @drag)
$(document).unbind('mouseup', @drop)
@@ -34,7 +34,7 @@ class Resizing extends Spine.Controller
className: 'resizing'
events:
- 'resize.start': 'resize'
+ 'start.resize': 'resize'
constructor: (@element) ->
super(el: @element.el)
View
16 assets/javascripts/app/controllers/inspector/dimensions.module.coffee
@@ -8,14 +8,17 @@ class Dimensions extends Spine.Controller
'input': '$inputs'
'input[name=width]': '$width'
'input[name=height]': '$height'
+ 'input[name=x]': '$x'
+ 'input[name=y]': '$y'
constructor: ->
super
throw 'stage required' unless @stage
+ $(document).bind 'resize.element move.element', @update
@render()
render: =>
- @disabled = not @stage.selection.isAny()
+ @disabled = not @stage.selection.isSingle()
@html JST['app/views/inspector/dimensions'](this)
@update()
@@ -23,12 +26,19 @@ class Dimensions extends Spine.Controller
@el.toggleClass('disabled', @disabled)
@$inputs.attr('disabled', @disabled)
- update: ->
+ update: =>
+ @disabled = not @stage.selection.isSingle()
+ return if @disabled
+
@$width.val(@stage.selection.get('width'))
- @$height.val(@stage.selection.get('width'))
+ @$height.val(@stage.selection.get('height'))
+ @$x.val(@stage.selection.get('left'))
+ @$y.val(@stage.selection.get('top'))
change: (e) ->
@stage.selection.set('width', parseInt(@$width.val(), 10))
@stage.selection.set('height', parseInt(@$height.val(), 10))
+ @stage.selection.set('left', parseInt(@$x.val(), 10))
+ @stage.selection.set('top', parseInt(@$y.val(), 10))
module.exports = Dimensions
View
8 assets/javascripts/app/controllers/stage.module.coffee
@@ -18,11 +18,11 @@ class Stage extends Spine.Controller
className: 'stage'
events:
- 'select': 'select'
- 'deselect': 'deselect'
+ 'select.element': 'select'
+ 'deselect.element': 'deselect'
'mousedown': 'deselectAll'
- 'resize.start': 'resizeStart'
- 'resize.end': 'resizeEnd'
+ 'start.resize': 'resizeStart'
+ 'end.resize': 'resizeEnd'
constructor: ->
super
View
4 assets/javascripts/app/controllers/stage/clipboard.module.coffee
@@ -43,7 +43,7 @@ class Clipboard
@stage.add(el) for el in elements
@stage.selection.refresh(elements)
- @stage.selection.set('moveBy', left: 10, top: 10)
+ @stage.selection.moveBy(left: 10, top: 10)
data: null
@@ -59,7 +59,7 @@ class Clipboard
@stage.add(el) for el in @data
@stage.selection.refresh(@data)
- @stage.selection.set('moveBy', left: 10, top: 10)
+ @stage.selection.moveBy(left: 10, top: 10)
# Re-clone the elements
@copyInternal()
View
5 assets/javascripts/app/controllers/stage/dragging.module.coffee
@@ -48,12 +48,13 @@ class Dragging extends Spine.Controller
# Setup CoordTitle
@moveCoordTitle(e)
- @stage.selection.set('moveBy', difference)
+ @stage.selection.moveBy(difference)
+ @el.trigger('move.dragging')
drop: (e) =>
$(document).unbind('mousemove', @drag)
$(document).unbind('mouseup', @drop)
- @el.trigger('dragging.end')
+ @el.trigger('end.dragging')
# Reset coordTitle
@coordTitle?.remove()
View
8 assets/javascripts/app/controllers/stage/key_bindings.module.coffee
@@ -32,25 +32,25 @@ class KeyBindings extends Spine.Module
e.preventDefault()
amount = -1
amount *= 5 if e.shiftKey
- @stage.selection.set('moveBy', left: amount, top: 0)
+ @stage.selection.moveBy(left: amount, top: 0)
upArrow: (e) ->
e.preventDefault()
amount = -1
amount *= 5 if e.shiftKey
- @stage.selection.set('moveBy', left: 0, top: amount)
+ @stage.selection.moveBy(left: 0, top: amount)
rightArrow: (e) ->
e.preventDefault()
amount = 1
amount *= 5 if e.shiftKey
- @stage.selection.set('moveBy', left: amount, top: 0)
+ @stage.selection.moveBy(left: amount, top: 0)
downArrow: (e) ->
e.preventDefault()
amount = 1
amount *= 5 if e.shiftKey
- @stage.selection.set('moveBy', left: 0, top: amount)
+ @stage.selection.moveBy(left: 0, top: amount)
aKey: (e) ->
return unless e.metaKey
View
4 assets/javascripts/app/controllers/stage/resizing.module.coffee
@@ -12,8 +12,8 @@ class AreaTitle extends Spine.Controller
class Resizing extends Spine.Controller
events:
- 'resized': 'resized'
- 'resize.end': 'resizeEnd'
+ 'resize.element': 'resized'
+ 'end.resize': 'resizeEnd'
constructor: (@stage) ->
super(el: @stage.el)
View
13 assets/javascripts/app/controllers/stage/select_area.module.coffee
@@ -43,8 +43,11 @@ class SelectArea extends Spine.Controller
e.preventDefault()
- @selectArea?.remove()
@offset = @el.offset()
+ @offset.left -= @el.scrollLeft()
+ @offset.top -= @el.scrollTop()
+
+ @selectArea?.remove()
$(document).mousemove(@drag)
$(document).mouseup(@drop)
@@ -54,15 +57,15 @@ class SelectArea extends Spine.Controller
# mess up click events
unless @selectArea
@selectArea = new Area(
- e.clientX - @offset.left + 1,
- e.clientY - @offset.top + 1
+ e.pageX - @offset.left + 1,
+ e.pageY - @offset.top + 1
)
@append(@selectArea)
@selectArea.resize(
- e.clientX - @offset.left,
- e.clientY - @offset.top
+ e.pageX - @offset.left,
+ e.pageY - @offset.top
)
area = @selectArea.area()
View
20 assets/javascripts/app/controllers/stage/selection.module.coffee
@@ -14,11 +14,13 @@ class Selection extends Spine.Module
# Returns a property for an element selection.
# Returns null unless all of the elements have the same value.
get: (key) ->
- result = (el.get(key) for el in @elements)
- first = result.shift()
- for value in result when value isnt first
- return null
- return first
+ return null unless @isAny()
+
+ first = @elements[0]?.get(key)
+ for el in @elements
+ if el.get(key) isnt first
+ return null
+ first
# Sets a property on all elements
set: (key, value) ->
@@ -27,6 +29,9 @@ class Selection extends Spine.Module
isMultiple: ->
@elements.length > 1
+ isSingle: ->
+ @elements.length is 1
+
isAny: ->
@elements.length > 0
@@ -84,4 +89,9 @@ class Selection extends Spine.Module
area
+ moveBy: (toPosition) ->
+ # Shortcut to reduce calls on set() and paint()
+ el.moveBy(toPosition) for el in @elements
+
+
module.exports = Selection
View
4 assets/javascripts/app/controllers/stage/snapping.module.coffee
@@ -219,9 +219,9 @@ class VerticalElementSnap extends Snap
class Snapping extends Spine.Controller
events:
- 'resized': 'remove'
+ 'resize.element': 'remove'
'selection.change': 'remove'
- 'dragging.end': 'remove'
+ 'end.dragging': 'remove'
constructor: (@stage) ->
super(el: @stage.el)
View
12 assets/javascripts/app/views/inspector/dimensions.jst.eco
@@ -8,8 +8,20 @@
</label>
<label>
+ <span>X</span>
+ <input type="number" name="x" placeholder="0px">
+ </label>
+ </div>
+
+ <div class="hbox">
+ <label>
<span>Height</span>
<input type="number" name="height" placeholder="0px">
</label>
+
+ <label>
+ <span>Y</span>
+ <input type="number" name="y" placeholder="0px">
+ </label>
</div>
</article>
View
6 assets/stylesheets/app/inspector/dimensions.css.styl
@@ -2,7 +2,7 @@
#app .inspector .dimensions {
label {
- margin-right: 3px
+ margin-right: 10px
span {
width: 38px
@@ -11,5 +11,9 @@
input {
width: 45px
}
+
+ &:last-child span {
+ width: 15px
+ }
}
}
View
30 public/assets/app/controllers/element.module.js
@@ -63,7 +63,8 @@ this.require.define({"app/controllers/element":function(exports, require, module
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = Object.prototype.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
- __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+ __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
+ __slice = Array.prototype.slice;
Resizing = require('./element/resizing');
@@ -124,7 +125,7 @@ this.require.define({"app/controllers/element":function(exports, require, module
if (typeof key === 'object') {
for (k in key) {
v = key[k];
- this.set(k, v);
+ (typeof this[k] === "function" ? this[k](v) : void 0) || (this.properties[k] = v);
}
} else {
(typeof this[key] === "function" ? this[key](value) : void 0) || (this.properties[key] = value);
@@ -136,13 +137,9 @@ this.require.define({"app/controllers/element":function(exports, require, module
return this.el.css(this.properties);
};
- Element.prototype.toValue = function() {
- return this.properties;
- };
-
Element.prototype.resize = function(area) {
this.set(area);
- return this.el.trigger('resized', [this]);
+ return this.el.trigger('element:resize', [this]);
};
Element.prototype.moveBy = function(toPosition) {
@@ -151,7 +148,7 @@ this.require.define({"app/controllers/element":function(exports, require, module
area.left += toPosition.left;
area.top += toPosition.top;
this.set(area);
- return this.el.trigger('moved', [this]);
+ return this.el.trigger('move.element', [this]);
};
Element.prototype.order = function(i) {
@@ -164,9 +161,9 @@ this.require.define({"app/controllers/element":function(exports, require, module
Element.prototype.select = function(e) {
if (this.selected()) {
- return this.el.trigger('deselect', [this, e != null ? e.shiftKey : void 0]);
+ return this.el.trigger('deselect.element', [this, e != null ? e.shiftKey : void 0]);
} else {
- return this.el.trigger('select', [this, e != null ? e.shiftKey : void 0]);
+ return this.el.trigger('select.element', [this, e != null ? e.shiftKey : void 0]);
}
};
@@ -230,6 +227,19 @@ this.require.define({"app/controllers/element":function(exports, require, module
return "." + this.className + " {\n" + styles + "\n}";
};
+ Element.prototype.toValue = function() {
+ return this.properties;
+ };
+
+ Element.prototype.change = function(func) {
+ var _ref;
+ if (typeof func === 'function') {
+ return this.el.bind('change.element', func);
+ } else {
+ return (_ref = this.el).trigger.apply(_ref, ['change.element'].concat(__slice.call(arguments)));
+ }
+ };
+
return Element;
})(Spine.Controller);
View
6 public/assets/app/controllers/element/resizing.module.js
@@ -104,11 +104,11 @@ this.require.define({"app/controllers/element/resizing":function(exports, requir
left: e.pageX,
top: e.pageY
};
- return this.el.trigger('resize.start', [this.type, difference, e.shiftKey]);
+ return this.el.trigger('start.resize', [this.type, difference, e.shiftKey]);
};
Thumb.prototype.drop = function(e) {
- this.el.trigger('resize.end');
+ this.el.trigger('end.resize');
$(document).unbind('mousemove', this.drag);
return $(document).unbind('mouseup', this.drop);
};
@@ -124,7 +124,7 @@ this.require.define({"app/controllers/element/resizing":function(exports, requir
Resizing.prototype.className = 'resizing';
Resizing.prototype.events = {
- 'resize.start': 'resize'
+ 'start.resize': 'resize'
};
function Resizing(element) {
View
18 public/assets/app/controllers/inspector/dimensions.module.js
@@ -77,17 +77,21 @@ this.require.define({"app/controllers/inspector/dimensions":function(exports, re
Dimensions.prototype.elements = {
'input': '$inputs',
'input[name=width]': '$width',
- 'input[name=height]': '$height'
+ 'input[name=height]': '$height',
+ 'input[name=x]': '$x',
+ 'input[name=y]': '$y'
};
function Dimensions() {
+ this.update = __bind(this.update, this);
this.render = __bind(this.render, this); Dimensions.__super__.constructor.apply(this, arguments);
if (!this.stage) throw 'stage required';
+ $(document).bind('resize.element move.element', this.update);
this.render();
}
Dimensions.prototype.render = function() {
- this.disabled = !this.stage.selection.isAny();
+ this.disabled = !this.stage.selection.isSingle();
this.html(JST['app/views/inspector/dimensions'](this));
this.update();
this.el.toggleClass('disabled', this.disabled);
@@ -95,13 +99,19 @@ this.require.define({"app/controllers/inspector/dimensions":function(exports, re
};
Dimensions.prototype.update = function() {
+ this.disabled = !this.stage.selection.isSingle();
+ if (this.disabled) return;
this.$width.val(this.stage.selection.get('width'));
- return this.$height.val(this.stage.selection.get('width'));
+ this.$height.val(this.stage.selection.get('height'));
+ this.$x.val(this.stage.selection.get('left'));
+ return this.$y.val(this.stage.selection.get('top'));
};
Dimensions.prototype.change = function(e) {
this.stage.selection.set('width', parseInt(this.$width.val(), 10));
- return this.stage.selection.set('height', parseInt(this.$height.val(), 10));
+ this.stage.selection.set('height', parseInt(this.$height.val(), 10));
+ this.stage.selection.set('left', parseInt(this.$x.val(), 10));
+ return this.stage.selection.set('top', parseInt(this.$y.val(), 10));
};
return Dimensions;
View
8 public/assets/app/controllers/stage.module.js
@@ -97,11 +97,11 @@ this.require.define({"app/controllers/stage":function(exports, require, module){
Stage.prototype.className = 'stage';
Stage.prototype.events = {
- 'select': 'select',
- 'deselect': 'deselect',
+ 'select.element': 'select',
+ 'deselect.element': 'deselect',
'mousedown': 'deselectAll',
- 'resize.start': 'resizeStart',
- 'resize.end': 'resizeEnd'
+ 'start.resize': 'resizeStart',
+ 'end.resize': 'resizeEnd'
};
function Stage() {
View
4 public/assets/app/controllers/stage/clipboard.module.js
@@ -118,7 +118,7 @@ this.require.define({"app/controllers/stage/clipboard":function(exports, require
this.stage.add(el);
}
this.stage.selection.refresh(elements);
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: 10,
top: 10
});
@@ -151,7 +151,7 @@ this.require.define({"app/controllers/stage/clipboard":function(exports, require
this.stage.add(el);
}
this.stage.selection.refresh(this.data);
- this.stage.selection.set('moveBy', {
+ this.stage.selection.moveBy({
left: 10,
top: 10
});
View
5 public/assets/app/controllers/stage/dragging.module.js
@@ -144,14 +144,15 @@ this.require.define({"app/controllers/stage/dragging":function(exports, require,
difference = this.stage.snapping.snap(this.selectionArea, difference);
}
this.moveCoordTitle(e);
- return this.stage.selection.set('moveBy', difference);
+ this.stage.selection.moveBy(difference);
+ return this.el.trigger('move.dragging');
};
Dragging.prototype.drop = function(e) {
var _ref;
$(document).unbind('mousemove', this.drag);
$(document).unbind('mouseup', this.drop);
- this.el.trigger('dragging.end');
+ this.el.trigger('end.dragging');
if ((_ref = this.coordTitle) != null) _ref.remove();
return this.coordTitle = null;
};
View
8 public/assets/app/controllers/stage/key_bindings.module.js
@@ -108,7 +108,7 @@ this.require.define({"app/controllers/stage/key_bindings":function(exports, requ
e.preventDefault();
amount = -1;
if (e.shiftKey) amount *= 5;
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: amount,
top: 0
});
@@ -119,7 +119,7 @@ this.require.define({"app/controllers/stage/key_bindings":function(exports, requ
e.preventDefault();
amount = -1;
if (e.shiftKey) amount *= 5;
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: 0,
top: amount
});
@@ -130,7 +130,7 @@ this.require.define({"app/controllers/stage/key_bindings":function(exports, requ
e.preventDefault();
amount = 1;
if (e.shiftKey) amount *= 5;
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: amount,
top: 0
});
@@ -141,7 +141,7 @@ this.require.define({"app/controllers/stage/key_bindings":function(exports, requ
e.preventDefault();
amount = 1;
if (e.shiftKey) amount *= 5;
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: 0,
top: amount
});
View
4 public/assets/app/controllers/stage/resizing.module.js
@@ -97,8 +97,8 @@ this.require.define({"app/controllers/stage/resizing":function(exports, require,
__extends(Resizing, _super);
Resizing.prototype.events = {
- 'resized': 'resized',
- 'resize.end': 'resizeEnd'
+ 'resize.element': 'resized',
+ 'end.resize': 'resizeEnd'
};
function Resizing(stage) {
View
8 public/assets/app/controllers/stage/select_area.module.js
@@ -135,8 +135,10 @@ this.require.define({"app/controllers/stage/select_area":function(exports, requi
var _ref;
if (e.target !== e.currentTarget) return;
e.preventDefault();
- if ((_ref = this.selectArea) != null) _ref.remove();
this.offset = this.el.offset();
+ this.offset.left -= this.el.scrollLeft();
+ this.offset.top -= this.el.scrollTop();
+ if ((_ref = this.selectArea) != null) _ref.remove();
$(document).mousemove(this.drag);
return $(document).mouseup(this.drop);
};
@@ -144,10 +146,10 @@ this.require.define({"app/controllers/stage/select_area":function(exports, requi
SelectArea.prototype.drag = function(e) {
var area, element, _i, _len, _ref, _results;
if (!this.selectArea) {
- this.selectArea = new Area(e.clientX - this.offset.left + 1, e.clientY - this.offset.top + 1);
+ this.selectArea = new Area(e.pageX - this.offset.left + 1, e.pageY - this.offset.top + 1);
this.append(this.selectArea);
}
- this.selectArea.resize(e.clientX - this.offset.left, e.clientY - this.offset.top);
+ this.selectArea.resize(e.pageX - this.offset.left, e.pageY - this.offset.top);
area = this.selectArea.area();
_ref = this.stage.elements;
_results = [];
View
37 public/assets/app/controllers/stage/selection.module.js
@@ -89,21 +89,13 @@ this.require.define({"app/controllers/stage/selection":function(exports, require
}
Selection.prototype.get = function(key) {
- var el, first, result, value, _i, _len;
- result = (function() {
- var _i, _len, _ref, _results;
- _ref = this.elements;
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- el = _ref[_i];
- _results.push(el.get(key));
- }
- return _results;
- }).call(this);
- first = result.shift();
- for (_i = 0, _len = result.length; _i < _len; _i++) {
- value = result[_i];
- if (value !== first) return null;
+ var el, first, _i, _len, _ref, _ref2;
+ if (!this.isAny()) return null;
+ first = (_ref = this.elements[0]) != null ? _ref.get(key) : void 0;
+ _ref2 = this.elements;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ el = _ref2[_i];
+ if (el.get(key) !== first) return null;
}
return first;
};
@@ -123,6 +115,10 @@ this.require.define({"app/controllers/stage/selection":function(exports, require
return this.elements.length > 1;
};
+ Selection.prototype.isSingle = function() {
+ return this.elements.length === 1;
+ };
+
Selection.prototype.isAny = function() {
return this.elements.length > 0;
};
@@ -187,6 +183,17 @@ this.require.define({"app/controllers/stage/selection":function(exports, require
return area;
};
+ Selection.prototype.moveBy = function(toPosition) {
+ var el, _i, _len, _ref, _results;
+ _ref = this.elements;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ el = _ref[_i];
+ _results.push(el.moveBy(toPosition));
+ }
+ return _results;
+ };
+
return Selection;
})(Spine.Module);
View
4 public/assets/app/controllers/stage/snapping.module.js
@@ -394,9 +394,9 @@ this.require.define({"app/controllers/stage/snapping":function(exports, require,
__extends(Snapping, _super);
Snapping.prototype.events = {
- 'resized': 'remove',
+ 'resize.element': 'remove',
'selection.change': 'remove',
- 'dragging.end': 'remove'
+ 'end.dragging': 'remove'
};
function Snapping(stage) {
View
5 public/assets/application.css
@@ -644,7 +644,7 @@ body {
opacity: 0.6;
}
#app .inspector .dimensions label {
- margin-right: 3px;
+ margin-right: 10px;
}
#app .inspector .dimensions label span {
width: 38px;
@@ -652,6 +652,9 @@ body {
#app .inspector .dimensions label input {
width: 45px;
}
+#app .inspector .dimensions label:last-child span {
+ width: 15px;
+}
#app .inspector .opacity label {
display: -webkit-box;
-webkit-box-orient: horizontal;
View
134 public/assets/application.js
@@ -12218,7 +12218,8 @@ this.require.define({"app/controllers/element":function(exports, require, module
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = Object.prototype.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
- __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+ __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
+ __slice = Array.prototype.slice;
Resizing = require('./element/resizing');
@@ -12279,7 +12280,7 @@ this.require.define({"app/controllers/element":function(exports, require, module
if (typeof key === 'object') {
for (k in key) {
v = key[k];
- this.set(k, v);
+ (typeof this[k] === "function" ? this[k](v) : void 0) || (this.properties[k] = v);
}
} else {
(typeof this[key] === "function" ? this[key](value) : void 0) || (this.properties[key] = value);
@@ -12291,13 +12292,9 @@ this.require.define({"app/controllers/element":function(exports, require, module
return this.el.css(this.properties);
};
- Element.prototype.toValue = function() {
- return this.properties;
- };
-
Element.prototype.resize = function(area) {
this.set(area);
- return this.el.trigger('resized', [this]);
+ return this.el.trigger('element:resize', [this]);
};
Element.prototype.moveBy = function(toPosition) {
@@ -12306,7 +12303,7 @@ this.require.define({"app/controllers/element":function(exports, require, module
area.left += toPosition.left;
area.top += toPosition.top;
this.set(area);
- return this.el.trigger('moved', [this]);
+ return this.el.trigger('move.element', [this]);
};
Element.prototype.order = function(i) {
@@ -12319,9 +12316,9 @@ this.require.define({"app/controllers/element":function(exports, require, module
Element.prototype.select = function(e) {
if (this.selected()) {
- return this.el.trigger('deselect', [this, e != null ? e.shiftKey : void 0]);
+ return this.el.trigger('deselect.element', [this, e != null ? e.shiftKey : void 0]);
} else {
- return this.el.trigger('select', [this, e != null ? e.shiftKey : void 0]);
+ return this.el.trigger('select.element', [this, e != null ? e.shiftKey : void 0]);
}
};
@@ -12385,6 +12382,19 @@ this.require.define({"app/controllers/element":function(exports, require, module
return "." + this.className + " {\n" + styles + "\n}";
};
+ Element.prototype.toValue = function() {
+ return this.properties;
+ };
+
+ Element.prototype.change = function(func) {
+ var _ref;
+ if (typeof func === 'function') {
+ return this.el.bind('change.element', func);
+ } else {
+ return (_ref = this.el).trigger.apply(_ref, ['change.element'].concat(__slice.call(arguments)));
+ }
+ };
+
return Element;
})(Spine.Controller);
@@ -12439,11 +12449,11 @@ this.require.define({"app/controllers/element/resizing":function(exports, requir
left: e.pageX,
top: e.pageY
};
- return this.el.trigger('resize.start', [this.type, difference, e.shiftKey]);
+ return this.el.trigger('start.resize', [this.type, difference, e.shiftKey]);
};
Thumb.prototype.drop = function(e) {
- this.el.trigger('resize.end');
+ this.el.trigger('end.resize');
$(document).unbind('mousemove', this.drag);
return $(document).unbind('mouseup', this.drop);
};
@@ -12459,7 +12469,7 @@ this.require.define({"app/controllers/element/resizing":function(exports, requir
Resizing.prototype.className = 'resizing';
Resizing.prototype.events = {
- 'resize.start': 'resize'
+ 'start.resize': 'resize'
};
function Resizing(element) {
@@ -13581,17 +13591,21 @@ this.require.define({"app/controllers/inspector/dimensions":function(exports, re
Dimensions.prototype.elements = {
'input': '$inputs',
'input[name=width]': '$width',
- 'input[name=height]': '$height'
+ 'input[name=height]': '$height',
+ 'input[name=x]': '$x',
+ 'input[name=y]': '$y'
};
function Dimensions() {
+ this.update = __bind(this.update, this);
this.render = __bind(this.render, this); Dimensions.__super__.constructor.apply(this, arguments);
if (!this.stage) throw 'stage required';
+ $(document).bind('resize.element move.element', this.update);
this.render();
}
Dimensions.prototype.render = function() {
- this.disabled = !this.stage.selection.isAny();
+ this.disabled = !this.stage.selection.isSingle();
this.html(JST['app/views/inspector/dimensions'](this));
this.update();
this.el.toggleClass('disabled', this.disabled);
@@ -13599,13 +13613,19 @@ this.require.define({"app/controllers/inspector/dimensions":function(exports, re
};
Dimensions.prototype.update = function() {
+ this.disabled = !this.stage.selection.isSingle();
+ if (this.disabled) return;
this.$width.val(this.stage.selection.get('width'));
- return this.$height.val(this.stage.selection.get('width'));
+ this.$height.val(this.stage.selection.get('height'));
+ this.$x.val(this.stage.selection.get('left'));
+ return this.$y.val(this.stage.selection.get('top'));
};
Dimensions.prototype.change = function(e) {
this.stage.selection.set('width', parseInt(this.$width.val(), 10));
- return this.stage.selection.set('height', parseInt(this.$height.val(), 10));
+ this.stage.selection.set('height', parseInt(this.$height.val(), 10));
+ this.stage.selection.set('left', parseInt(this.$x.val(), 10));
+ return this.stage.selection.set('top', parseInt(this.$y.val(), 10));
};
return Dimensions;
@@ -13807,11 +13827,11 @@ this.require.define({"app/controllers/stage":function(exports, require, module){
Stage.prototype.className = 'stage';
Stage.prototype.events = {
- 'select': 'select',
- 'deselect': 'deselect',
+ 'select.element': 'select',
+ 'deselect.element': 'deselect',
'mousedown': 'deselectAll',
- 'resize.start': 'resizeStart',
- 'resize.end': 'resizeEnd'
+ 'start.resize': 'resizeStart',
+ 'end.resize': 'resizeEnd'
};
function Stage() {
@@ -14078,7 +14098,7 @@ this.require.define({"app/controllers/stage/clipboard":function(exports, require
this.stage.add(el);
}
this.stage.selection.refresh(elements);
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: 10,
top: 10
});
@@ -14111,7 +14131,7 @@ this.require.define({"app/controllers/stage/clipboard":function(exports, require
this.stage.add(el);
}
this.stage.selection.refresh(this.data);
- this.stage.selection.set('moveBy', {
+ this.stage.selection.moveBy({
left: 10,
top: 10
});
@@ -14237,14 +14257,15 @@ this.require.define({"app/controllers/stage/dragging":function(exports, require,
difference = this.stage.snapping.snap(this.selectionArea, difference);
}
this.moveCoordTitle(e);
- return this.stage.selection.set('moveBy', difference);
+ this.stage.selection.moveBy(difference);
+ return this.el.trigger('move.dragging');
};
Dragging.prototype.drop = function(e) {
var _ref;
$(document).unbind('mousemove', this.drag);
$(document).unbind('mouseup', this.drop);
- this.el.trigger('dragging.end');
+ this.el.trigger('end.dragging');
if ((_ref = this.coordTitle) != null) _ref.remove();
return this.coordTitle = null;
};
@@ -14316,7 +14337,7 @@ this.require.define({"app/controllers/stage/key_bindings":function(exports, requ
e.preventDefault();
amount = -1;
if (e.shiftKey) amount *= 5;
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: amount,
top: 0
});
@@ -14327,7 +14348,7 @@ this.require.define({"app/controllers/stage/key_bindings":function(exports, requ
e.preventDefault();
amount = -1;
if (e.shiftKey) amount *= 5;
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: 0,
top: amount
});
@@ -14338,7 +14359,7 @@ this.require.define({"app/controllers/stage/key_bindings":function(exports, requ
e.preventDefault();
amount = 1;
if (e.shiftKey) amount *= 5;
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: amount,
top: 0
});
@@ -14349,7 +14370,7 @@ this.require.define({"app/controllers/stage/key_bindings":function(exports, requ
e.preventDefault();
amount = 1;
if (e.shiftKey) amount *= 5;
- return this.stage.selection.set('moveBy', {
+ return this.stage.selection.moveBy({
left: 0,
top: amount
});
@@ -14442,8 +14463,8 @@ this.require.define({"app/controllers/stage/resizing":function(exports, require,
__extends(Resizing, _super);
Resizing.prototype.events = {
- 'resized': 'resized',
- 'resize.end': 'resizeEnd'
+ 'resize.element': 'resized',
+ 'end.resize': 'resizeEnd'
};
function Resizing(stage) {
@@ -14555,8 +14576,10 @@ this.require.define({"app/controllers/stage/select_area":function(exports, requi
var _ref;
if (e.target !== e.currentTarget) return;
e.preventDefault();
- if ((_ref = this.selectArea) != null) _ref.remove();
this.offset = this.el.offset();
+ this.offset.left -= this.el.scrollLeft();
+ this.offset.top -= this.el.scrollTop();
+ if ((_ref = this.selectArea) != null) _ref.remove();
$(document).mousemove(this.drag);
return $(document).mouseup(this.drop);
};
@@ -14564,10 +14587,10 @@ this.require.define({"app/controllers/stage/select_area":function(exports, requi
SelectArea.prototype.drag = function(e) {
var area, element, _i, _len, _ref, _results;
if (!this.selectArea) {
- this.selectArea = new Area(e.clientX - this.offset.left + 1, e.clientY - this.offset.top + 1);
+ this.selectArea = new Area(e.pageX - this.offset.left + 1, e.pageY - this.offset.top + 1);
this.append(this.selectArea);
}
- this.selectArea.resize(e.clientX - this.offset.left, e.clientY - this.offset.top);
+ this.selectArea.resize(e.pageX - this.offset.left, e.pageY - this.offset.top);
area = this.selectArea.area();
_ref = this.stage.elements;
_results = [];
@@ -14629,21 +14652,13 @@ this.require.define({"app/controllers/stage/selection":function(exports, require
}
Selection.prototype.get = function(key) {
- var el, first, result, value, _i, _len;
- result = (function() {
- var _i, _len, _ref, _results;
- _ref = this.elements;
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- el = _ref[_i];
- _results.push(el.get(key));
- }
- return _results;
- }).call(this);
- first = result.shift();
- for (_i = 0, _len = result.length; _i < _len; _i++) {
- value = result[_i];
- if (value !== first) return null;
+ var el, first, _i, _len, _ref, _ref2;
+ if (!this.isAny()) return null;
+ first = (_ref = this.elements[0]) != null ? _ref.get(key) : void 0;
+ _ref2 = this.elements;
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ el = _ref2[_i];
+ if (el.get(key) !== first) return null;
}
return first;
};
@@ -14663,6 +14678,10 @@ this.require.define({"app/controllers/stage/selection":function(exports, require
return this.elements.length > 1;
};
+ Selection.prototype.isSingle = function() {
+ return this.elements.length === 1;
+ };
+
Selection.prototype.isAny = function() {
return this.elements.length > 0;
};
@@ -14727,6 +14746,17 @@ this.require.define({"app/controllers/stage/selection":function(exports, require
return area;
};
+ Selection.prototype.moveBy = function(toPosition) {
+ var el, _i, _len, _ref, _results;
+ _ref = this.elements;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ el = _ref[_i];
+ _results.push(el.moveBy(toPosition));
+ }
+ return _results;
+ };
+
return Selection;
})(Spine.Module);
@@ -15071,9 +15101,9 @@ this.require.define({"app/controllers/stage/snapping":function(exports, require,
__extends(Snapping, _super);
Snapping.prototype.events = {
- 'resized': 'remove',
+ 'resize.element': 'remove',
'selection.change': 'remove',
- 'dragging.end': 'remove'
+ 'end.dragging': 'remove'
};
function Snapping(stage) {
@@ -16206,7 +16236,7 @@ this.require.define({"app/models/undo":function(exports, require, module){(funct
(function() {
(function() {
- __out.push('<h3>Dimensions</h3>\n\n<article>\n <div class="hbox">\n <label>\n <span>Width</span>\n <input type="number" name="width" placeholder="0px">\n </label>\n\n <label>\n <span>Height</span>\n <input type="number" name="height" placeholder="0px">\n </label>\n </div>\n</article>\n');
+ __out.push('<h3>Dimensions</h3>\n\n<article>\n <div class="hbox">\n <label>\n <span>Width</span>\n <input type="number" name="width" placeholder="0px">\n </label>\n\n <label>\n <span>X</span>\n <input type="number" name="x" placeholder="0px">\n </label>\n </div>\n\n <div class="hbox">\n <label>\n <span>Height</span>\n <input type="number" name="height" placeholder="0px">\n </label>\n\n <label>\n <span>Y</span>\n <input type="number" name="y" placeholder="0px">\n </label>\n </div>\n</article>\n');
}).call(this);
Please sign in to comment.
Something went wrong with that request. Please try again.