Created the VectorIconSetupModal, a quick way to get portraits aligned to a container.

This commit is contained in:
Scott Erickson 2014-11-12 14:06:30 -08:00
parent bd969c017e
commit 913dda65aa
8 changed files with 196 additions and 8 deletions

View file

@ -40,12 +40,17 @@ module.exports = class SpriteParser
if movieClips.length
# First movie clip is root, so do it last
movieClips = movieClips[1 ... movieClips.length].concat([movieClips[0]])
else if containers.length
# First container is root, so do it last
containers = containers[1 ... containers.length].concat([containers[0]])
# first container isn't necessarily root... actually the last one is root in blue-cart
# else if containers.length
# # First container is root, so do it last
# containers = containers[1 ... containers.length].concat([containers[0]])
mainClip = _.last(movieClips) ? _.last(containers)
@animationName = mainClip.name
for container in containers
for container, index in containers
if index is containers.length - 1 and not movieClips.length and container.bounds?.length
container.bounds[0] -= @width / 2
container.bounds[1] -= @height / 2
[shapeKeys, localShapes] = @getShapesFromBlock container, source
localContainers = @getContainersFromMovieClip container, source
addChildArgs = @getAddChildCallArguments container, source
@ -62,6 +67,7 @@ module.exports = class SpriteParser
if c.bn is bn
instructions.push {t: c.t, gn: c.gn}
break
continue unless container.bounds and instructions.length
@addContainer {c: instructions, b: container.bounds}, container.name
for movieClip, index in movieClips
if index is 0

View file

@ -240,7 +240,6 @@ module.exports = class ThangType extends CocoModel
return if _.isString spriteSheet
return unless spriteSheet
canvas = $("<canvas width='#{size}' height='#{size}'></canvas>")
console.log 'made canvas', canvas, 'with size', size unless canvas[0]
stage = new createjs.Stage(canvas[0])
sprite = new createjs.Sprite(spriteSheet)
pt = @actions.portrait?.positions?.registration
@ -261,6 +260,29 @@ module.exports = class ThangType extends CocoModel
createjs.Ticker.removeEventListener 'tick', @tick
@tick = null
stage
getVectorPortraitStage: (size=100) ->
return unless @actions
canvas = $("<canvas width='#{size}' height='#{size}'></canvas>")
stage = new createjs.Stage(canvas[0])
portrait = @actions.portrait
return unless portrait and (portrait.animation or portrait.container)
scale = portrait.scale or 1
vectorParser = new SpriteBuilder(@, {})
if portrait.animation
sprite = vectorParser.buildMovieClip portrait.animation
sprite.gotoAndStop(0)
else if portrait.container
sprite = vectorParser.buildContainerFromStore(portrait.container)
pt = portrait.positions?.registration
sprite.regX = pt?.x or 0
sprite.regY = pt?.y or 0
sprite.scaleX = sprite.scaleY = scale * size / 100
stage.addChild(sprite)
stage.update()
stage
uploadGenericPortrait: (callback, src) ->
src ?= @getPortraitSource()

View file

@ -130,6 +130,7 @@ _.extend ThangTypeSchema.properties,
positions: PositionsSchema
raster: {type: 'string', format: 'image-file', title: 'Raster Image'}
rasterIcon: { type: 'string', format: 'image-file', title: 'Raster Image Icon' }
containerIcon: { type: 'string' }
featureImage: { type: 'string', format: 'image-file', title: 'Feature Image' }
colorGroups: c.object
title: 'Color Groups'

View file

@ -0,0 +1,9 @@
#vector-icon-setup-modal
select
margin-bottom: 20px
canvas
background: lightblue
border: 3px solid black
margin: 20px auto
display: block

View file

@ -81,12 +81,15 @@ block outer_content
div#settings-col.well
img#portrait.img-thumbnail
div.file-controls
button(disabled=authorized === true ? undefined : "true").btn.btn-small.btn-info#upload-button
button(disabled=authorized === true ? undefined : "true").btn.btn-sm.btn-info#upload-button
span.glyphicon.glyphicon-upload
span.spl Upload Animation
button(disabled=authorized === true ? undefined : "true").btn.btn-small.btn-danger#clear-button
button(disabled=authorized === true ? undefined : "true").btn.btn-sm.btn-danger#clear-button
span.glyphicon.glyphicon-remove
span.spl Clear Data
button#set-vector-icon(disabled=authorized === true ? undefined : "true").btn.btn-sm
span.glyphicon.glyphicon-gbp
span.spl Vector Icon Setup
input#real-upload-button(type="file")
#thang-type-file-size= fileSizeString
div#thang-type-treema

View file

@ -0,0 +1,24 @@
extends /templates/modal/modal_base
block modal-header-content
h3 Choose Container for Vector Icon
block modal-body-content
if chosenContainer
form.form
.form-group
select#container-select.form-control
for container in containers
option(value=container, selected=container === chosenContainer)= container
canvas(width=demoSize height=demoSize)#resulting-icon
.alert.alert-info Arrow keys to move, Shift-Plus/Minus to scale.
else
div forgetting something?
block modal-footer-content
button.btn.pull-left.btn-info#center
span.glyphicon.glyphicon-cutlery
span.spl Center
button.btn.btn-primary#done-button Done

View file

@ -12,6 +12,7 @@ ThangTypeVersionsModal = require './ThangTypeVersionsModal'
ThangTypeColorsTabView = require './ThangTypeColorsTabView'
PatchesView = require 'views/editor/PatchesView'
ForkModal = require 'views/editor/ForkModal'
VectorIconSetupModal = require 'views/editor/thang/VectorIconSetupModal'
SaveVersionModal = require 'views/modal/SaveVersionModal'
template = require 'templates/editor/thang/thang-type-edit-view'
storage = require 'lib/storage'
@ -33,6 +34,7 @@ module.exports = class ThangTypeEditView extends RootView
events:
'click #clear-button': 'clearRawData'
'click #upload-button': -> @$el.find('input#real-upload-button').click()
'click #set-vector-icon': 'onClickSetVectorIcon'
'change #real-upload-button': 'animationFileChosen'
'change #animations-select': 'showAnimation'
'click #marker-button': 'toggleDots'
@ -47,6 +49,12 @@ module.exports = class ThangTypeEditView extends RootView
'keyup .play-with-level-input': 'onPlayLevelKeyUp'
'click #pop-level-i18n-button': 'onPopulateLevelI18N'
onClickSetVectorIcon: ->
modal = new VectorIconSetupModal({}, @thangType)
@openModalView modal
modal.once 'done', => @treema.set('/', @getThangData())
subscriptions:
'editor:thang-type-color-groups-changed': 'onColorGroupsChanged'
'editor:save-new-version': 'saveNewThangType'
@ -234,7 +242,7 @@ module.exports = class ThangTypeEditView extends RootView
# animation select
refreshAnimation: =>
@thangType.buildActions()
@thangType.resetSpriteSheetCache()
return @showRasterImage() if @thangType.get('raster')
options = @getLankOptions()
console.log 'refresh animation....'

View file

@ -0,0 +1,115 @@
ModalView = require 'views/kinds/ModalView'
template = require 'templates/editor/thang/vector-icon-setup-modal'
module.exports = class VectorIconSetupModal extends ModalView
id: "vector-icon-setup-modal"
template: template
demoSize: 400
plain: true
events:
'change #container-select': 'onChangeContainer'
'click #center': 'onClickCenter'
'click #zero-bounds': 'onClickZeroBounds'
'click #done-button': 'onClickDone'
shortcuts:
'shift+-': -> @incrScale(-0.02)
'shift+=': -> @incrScale(0.02)
'up': -> @incrRegY(1)
'down': -> @incrRegY(-1)
'left': -> @incrRegX(1)
'right': -> @incrRegX(-1)
constructor: (options, @thangType) ->
portrait = @thangType.get('actions')?.portrait
@containers = _.keys(@thangType.get('raw')?.containers or {})
@container = portrait?.container or _.last @containers
@scale = portrait?.scale or 1
@regX = portrait?.positions?.registration?.x or 0
@regY = portrait?.positions?.registration?.y or 0
@saveChanges()
super(options)
saveChanges: ->
actions = _.cloneDeep (@thangType.get('actions') ? {})
actions.portrait ?= {}
actions.portrait.scale = @scale
actions.portrait.positions ?= {}
actions.portrait.positions.registration = { x: @regX, y: @regY }
actions.portrait.container = @container
@thangType.set('actions', actions)
@thangType.buildActions()
getRenderData: ->
c = super()
c.containers = @containers
c.chosenContainer = @container
c.demoSize = @demoSize
c
afterRender: ->
@initStage()
super()
initStage: ->
return unless @containers and @container
@stage = @thangType.getVectorPortraitStage(@demoSize)
@sprite = @stage.children[0]
canvas = $(@stage.canvas)
canvas.attr('id', 'resulting-icon')
@$el.find('#resulting-icon').replaceWith(canvas)
@updateSpriteProperties()
onChangeContainer: (e) ->
@container = $(e.target).val()
@saveChanges()
@initStage()
refreshSprite: ->
return unless @stage
stage = @thangType.getVectorPortraitStage(@demoSize)
@stage.removeAllChildren()
@stage.addChild(@sprite = stage.children[0])
@updateSpriteProperties()
@stage.update()
updateSpriteProperties: ->
@sprite.scaleX = @sprite.scaleY = @scale * @demoSize / 100
@sprite.regX = @regX
@sprite.regY = @regY
console.log 'set to', @scale, @regX, @regY
onClickCenter: ->
containerInfo = @thangType.get('raw').containers[@container]
b = containerInfo.b
@regX = b[0]
@regY = b[1]
maxDimension = Math.max(b[2], b[3])
@scale = 100 / maxDimension
if b[2] > b[3]
@regY += (b[3] - b[2]) / 2
else
@regX += (b[2] - b[3]) / 2
@updateSpriteProperties()
@stage.update()
incrScale: (amount) ->
@scale += amount
@updateSpriteProperties()
@stage.update()
incrRegX: (amount) ->
@regX += amount
@updateSpriteProperties()
@stage.update()
incrRegY: (amount) ->
@regY += amount
@updateSpriteProperties()
@stage.update()
onClickDone: ->
@saveChanges()
@trigger 'done'
@hide()