From 30a5567f1e6ada89a40f5de1a3d386ee05a6010f Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 2 Apr 2012 20:19:14 -0600 Subject: [PATCH] Make fill objects selectable and draggable --- TODO.md | 2 - app/javascripts/common/util.coffee | 76 +++++-- app/javascripts/editor/core.coffee | 2 +- app/javascripts/editor/drag_object.coffee | 12 +- app/javascripts/editor/viewport.coffee | 117 +++++++++-- app/stylesheets/editor.scss | 31 ++- .../images/editor/selection-border-static.gif | Bin 0 -> 57 bytes .../editor/selection-border-static2.gif | Bin 0 -> 51 bytes public/javascripts/app/common/util.js | 186 +++++++++++------- public/javascripts/app/editor/core.js | 4 +- public/javascripts/app/editor/viewport.js | 130 ++++++++++-- public/stylesheets/app/editor.css | 22 ++- 12 files changed, 432 insertions(+), 150 deletions(-) create mode 100644 public/images/editor/selection-border-static.gif create mode 100644 public/images/editor/selection-border-static2.gif diff --git a/TODO.md b/TODO.md index bfa6d0c..18d63d9 100644 --- a/TODO.md +++ b/TODO.md @@ -29,8 +29,6 @@ ## Editor -* BUG: When switching layers sidebar never gets hidden - * FEATURE: Add ability to click on a fill object and delete it just like you can do with tiles -- or extract this into a common place diff --git a/app/javascripts/common/util.coffee b/app/javascripts/common/util.coffee index e0f520f..32298ee 100644 --- a/app/javascripts/common/util.coffee +++ b/app/javascripts/common/util.coffee @@ -18,7 +18,7 @@ define 'util', -> # # Returns a modified version of `target`. # - extend: (args...) -> + extend = (args...) -> if typeof args[0] is 'boolean' deep = args.shift() else @@ -29,7 +29,7 @@ define 'util', -> for obj in objects for own prop of obj if deep and ($.v.is.obj(obj[prop]) or $.v.is.arr(obj[prop])) - target[prop] = @clone obj[prop] + target[prop] = clone obj[prop] else target[prop] = obj[prop] @@ -41,11 +41,11 @@ define 'util', -> # # Returns an Object of the same type as the given Object. # - clone: (obj) -> + clone = (obj) -> if $.v.is.arr(obj) - @extend true, [], obj - else if @isPlainObject(obj) - @extend true, {}, obj + extend true, [], obj + else if isPlainObject(obj) + extend true, {}, obj else obj @@ -55,44 +55,82 @@ define 'util', -> # # Returns an Object of the same type as the given Object. # - dup: (obj) -> + dup = (obj) -> if $.v.is.arr(obj) - @extend false, [], obj - else if @isPlainObject(obj) - @extend false, {}, obj + extend false, [], obj + else if isPlainObject(obj) + extend false, {}, obj else obj - isPlainObject: (obj) -> + isPlainObject = (obj) -> $.v.is.obj(obj) and obj.constructor is Object - createFromProto: (obj) -> + # DEPRECATED (use Object.create() directly) + createFromProto = (obj) -> Object.create(obj) - randomItem: (arr) -> - arr[@randomInt(arr.length-1)] + randomItem = (arr) -> + arr[randomInt(arr.length-1)] - randomInt: (args...) -> + randomInt = (args...) -> if args.length is 1 [min, max] = [0, args[0]] else [min, max] = args Math.floor(Math.random() * (max - min + 1)) + min - capitalize: (str) -> + capitalize = (str) -> str[0].toUpperCase() + str[1..-1] - ensureArray: (arr) -> + ensureArray = (arr) -> arr = arr[0] if arr.length is 1 and $.is.arr(arr[0]) return arr - arrayDelete: (arr, item) -> + arrayDelete = (arr, item) -> arr.splice(item, 1) - cmp: (a, b) -> + cmp = (a, b) -> if a > b return 1 else if a < b return -1 else return 0 + + hashWithout = (hash, keys...) -> + hash2 = dup(hash) + delete hash2[key] for key in keys + return hash2 + + return { + extend: extend + clone: clone + dup: dup + cmp: cmp + + array: + delete: arrayDelete + wrap: ensureArray + random: randomItem + int: + random: randomInt + string: + capitalize: capitalize + is: + hash: isPlainObject + hash: + is: isPlainObject + without: hashWithout + + # DEPRECATED + isPlainObject: isPlainObject # use is.hash() / hash.is() + randomItem: randomItem # use array.random() + randomInt: randomInt # use int.random + capitalize: capitalize # use string.capitalize() + ensureArray: ensureArray # use array.wrap() + arrayDelete: arrayDelete # use array.delete() + + # DEPRECATED + createFromProto: createFromProto + } diff --git a/app/javascripts/editor/core.coffee b/app/javascripts/editor/core.coffee index fbb0543..2808efb 100644 --- a/app/javascripts/editor/core.coffee +++ b/app/javascripts/editor/core.coffee @@ -25,8 +25,8 @@ define 'editor.core', -> @_populateMapObjects() @_initLayers() @_initToolbox() - @_changeLayerTo(0) # currentTool is already set @viewport.loadMap() + @_changeLayerTo(0) # currentTool is already set # Block backspace from leaving the page $(window) diff --git a/app/javascripts/editor/drag_object.coffee b/app/javascripts/editor/drag_object.coffee index a135f7a..ec71a4d 100644 --- a/app/javascripts/editor/drag_object.coffee +++ b/app/javascripts/editor/drag_object.coffee @@ -10,6 +10,7 @@ define 'editor.DragObject', -> that = this @$elem = $(elem) + @$elem.addClass('editor-drag-object') @offset = @$elem.offset() @options = options @@ -17,7 +18,7 @@ define 'editor.DragObject', -> $dropTarget = $(options.dropTarget) @dropTarget = $dropTarget.data('dropTarget') if not @dropTarget - throw new Error "DragObject#init: Drop target does not exist" + throw new Error "DragObject#init: Drop target not defined. Either the drop target doesn't exist, or you need to call $(...).dropTarget() on it." @dragOffset = null @@ -37,7 +38,7 @@ define 'editor.DragObject', -> .bind "mousedragstart.#{EVT_NS}", (evt) => @_logEvent @$elem, 'elem mousedragstart' - $(document.body).addClass('editor-drag-active') + $(document.body).addClass('editor-drag-object-dragged') elemOffset = @$elem.offset() console.log "setting dragOffset on #{@$elem.data('node-uid')}" @dragOffset = @@ -56,7 +57,7 @@ define 'editor.DragObject', -> @$elem.one "mousedragend.#{EVT_NS}", (evt) => @_logEvent @$elem, 'elem mousedragend' - $(document.body).removeClass('editor-drag-active') + $(document.body).removeClass('editor-drag-object-dragged') @dragOffset = null if @dropTarget evt.relatedTarget = @$elem[0] @@ -69,8 +70,9 @@ define 'editor.DragObject', -> @_removeDragEventsWithoutHelper() destroy: -> - @$elem.unbind(".#{EVT_NS}") - $(window).unbind(".#{EVT_NS}") + @$elem.removeClass('editor-drag-object') + @$elem.unbind ".#{EVT_NS}" + $(window).unbind ".#{EVT_NS}" position: (evt) -> $elem = if @options.helper then @$helper else @$elem diff --git a/app/javascripts/editor/viewport.coffee b/app/javascripts/editor/viewport.coffee index d60bb03..f56eb95 100644 --- a/app/javascripts/editor/viewport.coffee +++ b/app/javascripts/editor/viewport.coffee @@ -1,5 +1,6 @@ define 'editor.viewport', -> + util = require('util') meta = require('meta') require('editor.DropTarget') @@ -25,8 +26,17 @@ define 'editor.viewport', -> getMapLayers: -> @$mapLayers + getElementForLayer: (layer) -> + @$mapLayers.find(".editor-layer[data-layer=#{layer}]") + + getElementForCurrentLayer: -> + @getElementForLayer(@core.getCurrentLayer()) + getContentForLayer: (layer) -> - @$mapLayers.find(".editor-layer[data-layer=#{layer}] .editor-layer-content") + @getElementForLayer(layer).find('.editor-layer-content') + + getContentForCurrentLayer: -> + @getContentForLayer(@core.getCurrentLayer()) setWidth: (width) -> @$elem.width(width) @@ -56,6 +66,7 @@ define 'editor.viewport', -> # TODO: Refactor # localStorage.removeItem('editor.map') if data = localStorage.getItem('editor.map') + console.log 'map data': data try layers = JSON.parse(data) for layer in ['tiles'] @@ -81,9 +92,7 @@ define 'editor.viewport', -> mapObjectsSel = "#{layerSel} .editor-map-object" @$elem - .dropTarget( - receptor: "#{layerSel} .editor-layer-content" - ) + .dropTarget(receptor: "#{layerSel} .editor-layer-content") .bind "mousedropwithin.#{evtns}", (evt) => console.log "#{evtns}: mousedropwithin" dragObject = evt.relatedObject @@ -102,6 +111,7 @@ define 'editor.viewport', -> @_addEventsToMapObjects $(mapObjectsSel) + # TODO: This is the same as fill @$map.bind "mouseup.#{evtns}", (evt) => console.log "#{evtns}: mouseup" @$map.find('.editor-map-object') @@ -201,6 +211,33 @@ define 'editor.viewport', -> @$elem.unbind(".#{evtns}") $(window).unbind(".#{evtns}") + activate_fill_normal_tool: -> + evtns = 'editor.viewport.layer-fill.tool-normal' + @$elem + .dropTarget(receptor: @getElementForCurrentLayer()) + .bind "mousedropwithin.#{evtns}", (evt) => + $draggee = $(evt.relatedTarget) + fill = $draggee.data('fill') + fill.position @_roundCoordsToGrid($draggee.position()) + @saveMap() + $boxes = @getContentForCurrentLayer().find('.editor-fill') + @_addEventsToSelectionBoxes($boxes) + # TODO: This is the same as tiles + @$elem.bind "mousedown.#{evtns}", (evt) => + console.log "#{evtns}: mousedown" + @$map.find('.editor-fill') + .removeClass('editor-selected') + @$map.find('.editor-fill[data-is-selected=yes]') + .addClass('editor-selected') + .removeAttr('data-is-selected') + + deactivate_fill_normal_tool: -> + evtns = 'editor.viewport.layer-fill.tool-normal' + @$elem.unbind ".#{evtns}" + @$elem.dropTarget('destroy') + $boxes = @getContentForCurrentLayer().find('.editor-fill') + @_removeEventsFromSelectionBoxes($boxes) + activate_fill_select_tool: -> evtns = 'editor.viewport.layer-fill.tool-select' @@ -251,7 +288,7 @@ define 'editor.viewport', -> evt.preventDefault() - addNewSelection = evt.altKey + appendingNewSelection = evt.altKey selectionStartedAt = @_roundCoordsToGrid( adjustCoords(x: evt.pageX, y: evt.pageY) ) @@ -262,13 +299,13 @@ define 'editor.viewport', -> # TODO: Can we use our dnd code to detect this? # Maybe define a 'dragSurface' plugin? unless dragStarted - clearActiveSelections() unless addNewSelection + dragStarted = true + clearActiveSelections() unless appendingNewSelection selectionEvents.remove() currentSelection = {} currentSelection.pos = selectionStartedAt - currentSelection.$box = $('
') + currentSelection.$box = $box = $('
') @$overlay.append(currentSelection.$box) - dragStarted = true mouse = @_roundCoordsToGrid( adjustCoords(x: evt.pageX, y: evt.pageY) @@ -337,12 +374,35 @@ define 'editor.viewport', -> if @keyboard.isKeyPressed(evt, 'F') # fill all of the selections $.v.each activeSelections, (sel) => - fill = {x: sel.x, y: sel.y, w: sel.w, h: sel.h, color: '#800000'} + fill = + x: sel.x, y: sel.y + w: sel.w, h: sel.h + color: '#800000' @_loadFill(fill) @saveMap() selectionEvents.add() + # TODO: This is the same as _addEventsToMapObjects() + _addEventsToSelectionBoxes: ($boxes) -> + evtns = 'editor.viewport.selection-box' + $boxes + .dragObject + dropTarget: @$elem + containWithinDropTarget: true + .bind "mousedown.#{evtns}", (evt) -> + console.log 'selection box mousedown (after creation)' + $draggee = $(this) + state = $draggee.attr('data-is-selected') + newstate = if state is 'no' or !state then 'yes' else 'no' + $draggee.attr('data-is-selected', newstate) + + _removeEventsFromSelectionBoxes: ($boxes) -> + evtns = 'editor.viewport.selection-box' + $boxes + .dragObject('destroy') + .unbind "mouseupnodrag.#{evtns}" + deactivate_fill_select_tool: -> evtns = 'editor.viewport.layer-fill.tool-select' @$elem.unbind(".#{evtns}") @@ -370,15 +430,48 @@ define 'editor.viewport', -> .position(fill) .size(fill) .css('background-color', fill.color) + .data('fill', fill) _addFill: (fill) -> @fills.push(fill) + # fill is a Hash: + # x - x coord of top-left corner + # y - y coord of top-left corner + # w - width + # h - height + # color - rgb hex string + # _loadFill: (fill) -> + fill = util.dup(fill) + fill.position = (pos) -> + if pos + @$elem.position(pos) + @x = pos.x + @y = pos.y + return this + else + return {@x, @y} + fill.size = (dim) -> + if dim + @$elem.size(dim) + @w = dim.w + @h = dim.h + return this + else + return {@w, @h} + $fill = @_createFill(fill) - @getContentForLayer('fill').append($fill) + $content = @getContentForLayer('fill') + if not $content.length + throw new Error "Can't add fill, couldn't find layer content element" + $content.append($fill) + fill.$elem = $fill + @_addFill(fill) + return fill + saveMap: -> console.log 'viewport: saving map...' layers = {} @@ -392,7 +485,8 @@ define 'editor.viewport', -> y: pos.y }) layers['fill'] = [] - for fill in @fills + $.v.each @fills, (fill) -> + fill = util.hash.without(fill, '$elem') layers['fill'].push(fill) localStorage.setItem('editor.map', JSON.stringify(layers)) @@ -421,6 +515,7 @@ define 'editor.viewport', -> offset.height ) + # TODO: This is the same as _addEventsToSelectionBoxes() _addEventsToMapObjects: ($draggees) -> evtns = 'editor.viewport.layer-tiles.tool-normal' $draggees.bind "mouseupnodrag.#{evtns}", (evt) -> diff --git a/app/stylesheets/editor.scss b/app/stylesheets/editor.scss index fa3d175..cac5256 100644 --- a/app/stylesheets/editor.scss +++ b/app/stylesheets/editor.scss @@ -7,6 +7,17 @@ height: 100%; } +@mixin border-image($url) { + -moz-border-image: url($url) 1 repeat; + -webkit-border-image: url($url) 1 repeat; + border-image: url($url) 1 repeat; +} + +@mixin transform($txn) { + -webkit-transform: $txn; + -moz-transform: $txn; +} + // prevent rubber-band effect in webkit browsers when scrolling // http://mir.aculo.us/2011/07/29/prevent-rubber-band-scrolling-for-single-page-apps-in-safari-5-1/ html, body { @@ -20,8 +31,8 @@ body { font-family: Helvetica Neue, Arial, sans-serif; } -.editor-tool-normal .editor-drag-active, -.editor-tool-normal .editor-map-object, +.editor-drag-object, +.editor-drag-object-dragged, #editor-sidebar div.img { cursor: move } @@ -113,12 +124,14 @@ $sidebar-width: 300px; position: absolute; z-index: 10; } +} - .editor-map-object.editor-selected { - border: 1px solid red; - -webkit-transform: translate(-1px, -1px); - -moz-transform: translate(-1px, -1px); - } +.editor-selected { + border: 1px dashed black; + @include border-image('/images/editor/selection-border-static2.gif'); + @include transform(translate(-1px, -1px)); + // box-shadow: 1px 1px 5px 1px rgba(0, 0, 0, 0.6); + // box-shadow: 4px 4px 3px 1px rgba(0,0,0,0.5); } #editor-map { @@ -182,7 +195,5 @@ $sidebar-width: 300px; z-index: 10; // background-color: rgba(255,255,255,0.15); border: 1px dashed black; - -moz-border-image: url(/images/editor/selection-border.gif) 1 repeat; - -webkit-border-image: url(/images/editor/selection-border.gif) 1 repeat; - border-image: url(/images/editor/selection-border.gif) 1 repeat; + @include border-image('/images/editor/selection-border.gif'); } diff --git a/public/images/editor/selection-border-static.gif b/public/images/editor/selection-border-static.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8c0fcc08dc86bd1a7eab314c680150c4ebb2b5e GIT binary patch literal 57 zcmZ?wbhEHb b) { + return 1; + } else if (a < b) { + return -1; + } else { + return 0; + } + }; + hashWithout = function() { + var hash, hash2, key, keys, _i, _len; + hash = arguments[0], keys = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + hash2 = dup(hash); + for (_i = 0, _len = keys.length; _i < _len; _i++) { + key = keys[_i]; + delete hash2[key]; + } + return hash2; + }; + return { + extend: extend, + clone: clone, + dup: dup, + cmp: cmp, + array: { + "delete": arrayDelete, + wrap: ensureArray, + random: randomItem }, - randomInt: function() { - var args, max, min, _ref; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - if (args.length === 1) { - _ref = [0, args[0]], min = _ref[0], max = _ref[1]; - } else { - min = args[0], max = args[1]; - } - return Math.floor(Math.random() * (max - min + 1)) + min; + int: { + random: randomInt }, - capitalize: function(str) { - return str[0].toUpperCase() + str.slice(1); + string: { + capitalize: capitalize }, - ensureArray: function(arr) { - if (arr.length === 1 && $.is.arr(arr[0])) arr = arr[0]; - return arr; + is: { + hash: isPlainObject }, - arrayDelete: function(arr, item) { - return arr.splice(item, 1); + hash: { + is: isPlainObject, + without: hashWithout }, - cmp: function(a, b) { - if (a > b) { - return 1; - } else if (a < b) { - return -1; - } else { - return 0; - } - } + isPlainObject: isPlainObject, + randomItem: randomItem, + randomInt: randomInt, + capitalize: capitalize, + ensureArray: ensureArray, + arrayDelete: arrayDelete, + createFromProto: createFromProto }; }); diff --git a/public/javascripts/app/editor/core.js b/public/javascripts/app/editor/core.js index b216202..9ec0ef7 100644 --- a/public/javascripts/app/editor/core.js +++ b/public/javascripts/app/editor/core.js @@ -23,8 +23,8 @@ _this._populateMapObjects(); _this._initLayers(); _this._initToolbox(); - _this._changeLayerTo(0); - return _this.viewport.loadMap(); + _this.viewport.loadMap(); + return _this._changeLayerTo(0); }); return $(window).bind("keydown.editor.core", function(evt) { if (_this.keyboard.isKeyPressed(evt, 'backspace')) { diff --git a/public/javascripts/app/editor/viewport.js b/public/javascripts/app/editor/viewport.js index 59471b5..555a320 100644 --- a/public/javascripts/app/editor/viewport.js +++ b/public/javascripts/app/editor/viewport.js @@ -2,7 +2,8 @@ var __hasProp = Object.prototype.hasOwnProperty; define('editor.viewport', function() { - var GRID_SIZE, meta; + var GRID_SIZE, meta, util; + util = require('util'); meta = require('meta'); require('editor.DropTarget'); GRID_SIZE = 16; @@ -31,8 +32,17 @@ getMapLayers: function() { return this.$mapLayers; }, + getElementForLayer: function(layer) { + return this.$mapLayers.find(".editor-layer[data-layer=" + layer + "]"); + }, + getElementForCurrentLayer: function() { + return this.getElementForLayer(this.core.getCurrentLayer()); + }, getContentForLayer: function(layer) { - return this.$mapLayers.find(".editor-layer[data-layer=" + layer + "] .editor-layer-content"); + return this.getElementForLayer(layer).find('.editor-layer-content'); + }, + getContentForCurrentLayer: function() { + return this.getContentForLayer(this.core.getCurrentLayer()); }, setWidth: function(width) { this.$elem.width(width); @@ -56,6 +66,9 @@ h: this.map.height }); if (data = localStorage.getItem('editor.map')) { + console.log({ + 'map data': data + }); try { layers = JSON.parse(data); _ref = ['tiles']; @@ -194,6 +207,35 @@ this.$elem.unbind("." + evtns); return $(window).unbind("." + evtns); }, + activate_fill_normal_tool: function() { + var $boxes, evtns, + _this = this; + evtns = 'editor.viewport.layer-fill.tool-normal'; + this.$elem.dropTarget({ + receptor: this.getElementForCurrentLayer() + }).bind("mousedropwithin." + evtns, function(evt) { + var $draggee, fill; + $draggee = $(evt.relatedTarget); + fill = $draggee.data('fill'); + fill.position(_this._roundCoordsToGrid($draggee.position())); + return _this.saveMap(); + }); + $boxes = this.getContentForCurrentLayer().find('.editor-fill'); + this._addEventsToSelectionBoxes($boxes); + return this.$elem.bind("mousedown." + evtns, function(evt) { + console.log("" + evtns + ": mousedown"); + _this.$map.find('.editor-fill').removeClass('editor-selected'); + return _this.$map.find('.editor-fill[data-is-selected=yes]').addClass('editor-selected').removeAttr('data-is-selected'); + }); + }, + deactivate_fill_normal_tool: function() { + var $boxes, evtns; + evtns = 'editor.viewport.layer-fill.tool-normal'; + this.$elem.unbind("." + evtns); + this.$elem.dropTarget('destroy'); + $boxes = this.getContentForCurrentLayer().find('.editor-fill'); + return this._removeEventsFromSelectionBoxes($boxes); + }, activate_fill_select_tool: function() { var activeSelections, adjustCoords, clearActiveSelections, currentSelection, dragStarted, evtns, mouseDownAt, selectionEvents, _this = this; @@ -238,25 +280,25 @@ this.$elem.bind("contextmenu." + evtns, function(evt) { return evt.preventDefault(); }).bind("mousedown." + evtns, function(evt) { - var addNewSelection, selectionStartedAt; + var appendingNewSelection, selectionStartedAt; if (evt.button === 2 || (evt.ctrlKey && evt.button === 0)) return; evt.preventDefault(); - addNewSelection = evt.altKey; + appendingNewSelection = evt.altKey; selectionStartedAt = _this._roundCoordsToGrid(adjustCoords({ x: evt.pageX, y: evt.pageY })); return _this.$elem.bind("mousemove." + evtns, function(evt) { - var h, mouse, w, x, y; + var $box, h, mouse, w, x, y; evt.preventDefault(); if (!dragStarted) { - if (!addNewSelection) clearActiveSelections(); + dragStarted = true; + if (!appendingNewSelection) clearActiveSelections(); selectionEvents.remove(); currentSelection = {}; currentSelection.pos = selectionStartedAt; - currentSelection.$box = $('
'); + currentSelection.$box = $box = $('
'); _this.$overlay.append(currentSelection.$box); - dragStarted = true; } mouse = _this._roundCoordsToGrid(adjustCoords({ x: evt.pageX, @@ -332,6 +374,26 @@ }); return selectionEvents.add(); }, + _addEventsToSelectionBoxes: function($boxes) { + var evtns; + evtns = 'editor.viewport.selection-box'; + return $boxes.dragObject({ + dropTarget: this.$elem, + containWithinDropTarget: true + }).bind("mousedown." + evtns, function(evt) { + var $draggee, newstate, state; + console.log('selection box mousedown (after creation)'); + $draggee = $(this); + state = $draggee.attr('data-is-selected'); + newstate = state === 'no' || !state ? 'yes' : 'no'; + return $draggee.attr('data-is-selected', newstate); + }); + }, + _removeEventsFromSelectionBoxes: function($boxes) { + var evtns; + evtns = 'editor.viewport.selection-box'; + return $boxes.dragObject('destroy').unbind("mouseupnodrag." + evtns); + }, deactivate_fill_select_tool: function() { var evtns; evtns = 'editor.viewport.layer-fill.tool-select'; @@ -364,19 +426,52 @@ }, _createFill: function(fill) { var $fill; - return $fill = $('
').position(fill).size(fill).css('background-color', fill.color); + return $fill = $('
').position(fill).size(fill).css('background-color', fill.color).data('fill', fill); }, _addFill: function(fill) { return this.fills.push(fill); }, _loadFill: function(fill) { - var $fill; + var $content, $fill; + fill = util.dup(fill); + fill.position = function(pos) { + if (pos) { + this.$elem.position(pos); + this.x = pos.x; + this.y = pos.y; + return this; + } else { + return { + x: this.x, + y: this.y + }; + } + }; + fill.size = function(dim) { + if (dim) { + this.$elem.size(dim); + this.w = dim.w; + this.h = dim.h; + return this; + } else { + return { + w: this.w, + h: this.h + }; + } + }; $fill = this._createFill(fill); - this.getContentForLayer('fill').append($fill); - return this._addFill(fill); + $content = this.getContentForLayer('fill'); + if (!$content.length) { + throw new Error("Can't add fill, couldn't find layer content element"); + } + $content.append($fill); + fill.$elem = $fill; + this._addFill(fill); + return fill; }, saveMap: function() { - var fill, id, layer, layers, object, pos, _i, _j, _len, _len2, _ref, _ref2, _ref3; + var id, layer, layers, object, pos, _i, _len, _ref, _ref2; console.log('viewport: saving map...'); layers = {}; _ref = ['tiles']; @@ -395,11 +490,10 @@ } } layers['fill'] = []; - _ref3 = this.fills; - for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) { - fill = _ref3[_j]; - layers['fill'].push(fill); - } + $.v.each(this.fills, function(fill) { + fill = util.hash.without(fill, '$elem'); + return layers['fill'].push(fill); + }); return localStorage.setItem('editor.map', JSON.stringify(layers)); }, _initMapGrid: function() { diff --git a/public/stylesheets/app/editor.css b/public/stylesheets/app/editor.css index 0b840e7..710a255 100644 --- a/public/stylesheets/app/editor.css +++ b/public/stylesheets/app/editor.css @@ -7,8 +7,8 @@ body { padding: 0; font-family: Helvetica Neue, Arial, sans-serif; } -.editor-tool-normal .editor-drag-active, -.editor-tool-normal .editor-map-object, +.editor-drag-object, +.editor-drag-object-dragged, #editor-sidebar div.img { cursor: move; } @@ -76,10 +76,14 @@ body { #editor-viewport .editor-dragged-image { position: absolute; z-index: 10; } - #editor-viewport .editor-map-object.editor-selected { - border: 1px solid red; - -webkit-transform: translate(-1px, -1px); - -moz-transform: translate(-1px, -1px); } + +.editor-selected { + border: 1px dashed black; + -moz-border-image: url("/images/editor/selection-border-static2.gif") 1 repeat; + -webkit-border-image: url("/images/editor/selection-border-static2.gif") 1 repeat; + border-image: url("/images/editor/selection-border-static2.gif") 1 repeat; + -webkit-transform: translate(-1px, -1px); + -moz-transform: translate(-1px, -1px); } #editor-map { background-color: white; @@ -130,6 +134,6 @@ body { position: absolute; z-index: 10; border: 1px dashed black; - -moz-border-image: url(/images/editor/selection-border.gif) 1 repeat; - -webkit-border-image: url(/images/editor/selection-border.gif) 1 repeat; - border-image: url(/images/editor/selection-border.gif) 1 repeat; } + -moz-border-image: url("/images/editor/selection-border.gif") 1 repeat; + -webkit-border-image: url("/images/editor/selection-border.gif") 1 repeat; + border-image: url("/images/editor/selection-border.gif") 1 repeat; }