Add basic support for displaying multiblock steps

This commit is contained in:
Andrew Miner
2015-11-22 22:33:15 -08:00
parent 8cdd130064
commit 7dbfd25ef3
12 changed files with 342 additions and 42 deletions
-1
View File
@@ -76,7 +76,6 @@ module.exports = (grunt)->
node: true node: true
processName: (f)-> processName: (f)->
f = f.replace './src/jade/templates/', '' f = f.replace './src/jade/templates/', ''
f = f.replace '_view', ''
f = f.replace '.jade', '' f = f.replace '.jade', ''
f = f.replace /\//g, '_' f = f.replace /\//g, '_'
return f return f
+10 -16
View File
@@ -107,31 +107,25 @@ module.exports = class BaseController extends backbone.View
# Property Methods ############################################################################# # Property Methods #############################################################################
getModel: -> Object.defineProperties @prototype,
return @_model model:
get: -> @_model
setModel: (newModel)-> set: (newModel)->
return if @model is newModel return if @model is newModel
newModel = @onWillChangeModel @_model, newModel newModel = @onWillChangeModel @_model, newModel
@_model = newModel @_model = newModel
@tryRefresh() @tryRefresh()
isRendered: -> rendered:
return @_rendered get: -> @_rendered
getUser: -> user:
return @_user get: -> @_user
set: (newUser)->
setUser: (user)-> @_user = newUser
@_user = user
@tryRefresh() @tryRefresh()
Object.defineProperties @prototype,
model: {get:@prototype.getModel, set:@prototype.setModel}
rendered: {get:@prototype.isRendered }
user: {get:@prototype.getUser, set:@prototype.setUser}
# Backbone.View Overrides ###################################################################### # Backbone.View Overrides ######################################################################
events: -> events: ->
@@ -5,24 +5,25 @@ Copyright (c) 2015 by Redwood Labs
All rights reserved. All rights reserved.
### ###
_ = require 'underscore'
AdsenseController = require './adsense_controller' AdsenseController = require './adsense_controller'
{Duration} = require '../constants'
EditableFile = require '../models/editable_file' EditableFile = require '../models/editable_file'
{Event} = require '../constants'
FullRecipeController = require './full_recipe_controller' FullRecipeController = require './full_recipe_controller'
{GitHub} = require '../constants'
ImageLoader = require './image_loader' ImageLoader = require './image_loader'
Item = require '../models/item' Item = require '../models/item'
ItemGroupController = require './item_group_controller' ItemGroupController = require './item_group_controller'
ItemPage = require '../models/item_page' ItemPage = require '../models/item_page'
ItemSlug = require '../models/item_slug' ItemSlug = require '../models/item_slug'
MarkdownSectionController = require './markdown_section_controller' MarkdownSectionController = require './markdown_section_controller'
MultiblockViewerController = require './multiblock_viewer_controller'
PageController = require './page_controller' PageController = require './page_controller'
VideoController = require './video_controller'
_ = require 'underscore'
w = require 'when'
{Duration} = require '../constants'
{Event} = require '../constants'
{GitHub} = require '../constants'
{Text} = require '../constants' {Text} = require '../constants'
{Url} = require '../constants' {Url} = require '../constants'
VideoController = require './video_controller'
w = require 'when'
######################################################################################################################## ########################################################################################################################
@@ -77,6 +78,7 @@ module.exports = class ItemPageController extends PageController
@adsenseController = @addChild AdsenseController, '.view__adsense', model:'sidebar_skyscraper' @adsenseController = @addChild AdsenseController, '.view__adsense', model:'sidebar_skyscraper'
options = imageLoader:@imageLoader, modPack:@modPack, show:false options = imageLoader:@imageLoader, modPack:@modPack, show:false
@_multiblockController = @addChild MultiblockViewerController, '.view__multiblock_viewer', options
@_similarItemsController = @addChild ItemGroupController, '.view__item_group.similar', options @_similarItemsController = @addChild ItemGroupController, '.view__item_group.similar', options
@_usedAsToolToMakeController = @addChild ItemGroupController, '.view__item_group.usedAsToolToMake', options @_usedAsToolToMakeController = @addChild ItemGroupController, '.view__item_group.usedAsToolToMake', options
@_usedToMakeController = @addChild ItemGroupController, '.view__item_group.usedToMake', options @_usedToMakeController = @addChild ItemGroupController, '.view__item_group.usedToMake', options
@@ -91,6 +93,7 @@ module.exports = class ItemPageController extends PageController
@$byline = @$('.byline') @$byline = @$('.byline')
@$bylineLink = @$('.byline a') @$bylineLink = @$('.byline a')
@$descriptionSection = @$('.description') @$descriptionSection = @$('.description')
@$multiblockSection = @$('.multiblock.section')
@$name = @$('h1.name') @$name = @$('h1.name')
@$officialPageLink = @$('a.officialPage') @$officialPageLink = @$('a.officialPage')
@$recipeContainer = @$('.recipes .panel') @$recipeContainer = @$('.recipes .panel')
@@ -127,6 +130,7 @@ module.exports = class ItemPageController extends PageController
@_refreshByline() @_refreshByline()
@_refreshDescription() @_refreshDescription()
@_refreshMultiblock()
@_refreshRecipes() @_refreshRecipes()
@_refreshSimilarItems() @_refreshSimilarItems()
@_refreshUsedAsToolToMake() @_refreshUsedAsToolToMake()
@@ -217,6 +221,13 @@ module.exports = class ItemPageController extends PageController
@_descriptionController.model = @model.item.description @_descriptionController.model = @model.item.description
@_descriptionController.resetToDefaultState() @_descriptionController.resetToDefaultState()
_refreshMultiblock: ->
if @model.item?.multiblock?
@_multiblockController.model = @model.item.multiblock
@show @$multiblockSection
else
@hide @$multiblockSection
_refreshRecipes: -> _refreshRecipes: ->
@_recipeControllers ?= [] @_recipeControllers ?= []
index = 0 index = 0
@@ -0,0 +1,156 @@
###
Crafting Guide - multiblock_controller.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
$ = require 'jquery'
_ = require '../underscore_mixins'
BaseController = require './base_controller'
########################################################################################################################
module.exports = class MultiblockController extends BaseController
@::IMAGE_SIZE = 48 # px
@::X_LAYER_H_SHIFT = -24 # px
@::Z_LAYER_H_SHIFT = +24 # px
@::X_LAYER_V_SHIFT = -12 # px
@::Y_LAYER_V_SHIFT = -30 # px
@::Z_LAYER_V_SHIFT = -12 # px
@::MAX_DROP_DELAY = 250 # ms
constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.modPack? then throw new Error 'options.modPack is required'
options.templateName = 'multiblock'
super options
@_currentLayer = 0
@_blockCache = null
@_imageLoader = options.imageLoader
@_modPack = options.modPack
# Public Methods ###############################################################################
goBackLayer: ->
@_currentLayer = Math.max 0, @_currentLayer - 1
@_refreshAllBlocks()
goNextLayer: ->
@_currentLayer = Math.min @model.height - 1, @_currentLayer + 1
@_refreshAllBlocks()
hasBackLayer: ->
return false unless @model?
return @_currentLayer > 0
hasNextLayer: ->
return false unless @model?
return @_currentLayer < @model.height - 1
# BaseController Overrides #####################################################################
onDidRender: ->
# do nothing
refresh: ->
@$el.css 'min-height':@_computeMinHeight(), 'min-width':@_computeMinWidth()
@_refreshBlockCache()
@_refreshAllBlocks()
# Private Methods ##############################################################################
_computePosition: (x, y, z, options={})->
if not @model? then return left:0, top:-@IMAGE_SIZE, 'z-index':0, opacity:0.0
options.hideUpperLayers ?= false
pxWidth = @$el.width()
pxHeight = @$el.height()
left = ((pxWidth - @IMAGE_SIZE) / 2) + (x * @X_LAYER_H_SHIFT) + (z * @Z_LAYER_H_SHIFT)
if options.hideUpperLayers and y > @_currentLayer
top = 0
opacity = 0.0
else
top = (pxHeight - @IMAGE_SIZE) + (x * @X_LAYER_V_SHIFT) + (z * @Z_LAYER_V_SHIFT) + (y * @Y_LAYER_V_SHIFT)
opacity = 1.0
zindex = (@model.width - x) + (@model.depth - z) + ((@model.width * @model.depth) * y)
return left:left, top:top, 'z-index':zindex, opacity:opacity
_computeMinHeight: ->
return 0 unless @model?
minHeight = Math.max(Math.abs(@model.width * @X_LAYER_V_SHIFT), Math.abs(@model.depth * @Z_LAYER_V_SHIFT))
minHeight += Math.abs(@model.height * @Y_LAYER_V_SHIFT)
minHeight += 2 * @IMAGE_SIZE
return minHeight
_computeMinWidth: ->
return 0 unless @model?
leftPosition = @_computePosition @model.width, 0, 0
rightPosition = @_computePosition 0, 0, @model.depth
return rightPosition.left - leftPosition.left
_randomDropDelay: ->
return Math.random() * @MAX_DROP_DELAY
_refreshBlockCache: ->
@_blockCache = null
return unless @model?
@_blockCache = width:@model.width, height:@model.height, depth:@model.depth
for x in [0...@model.width]
@_blockCache[x] ?= {}
for y in [0...@model.height]
@_blockCache[x][y] ?= {}
for z in [0...@model.depth]
@_blockCache[x][y][z] ?= null
for el in @$('.block')
$el = $(el)
@_blockCache[$el.data('x')][$el.data('y')][$el.data('z')] = $el
_refreshBlock: (x, y, z)->
return unless @model?
stack = @model.getStackAt x, y, z
$block = @_blockCache[x][y][z]
position = @_computePosition x, y, z, hideUpperLayers:true
move = false
if stack?
itemDisplay = @_modPack.findItemDisplay stack.itemSlug
if not $block?
$block = $("<img alt='#{itemDisplay.itemName}' class='block' />")
$block.css position, top:-@IMAGE_SIZE, opacity:0.0
@_imageLoader.load itemDisplay.iconUrl, $block
@_blockCache[x][y][z] = $block
@$el.append $block
move = true
else
$block.attr 'src', itemDisplay.iconUrl
move = true
else if $block?
$block.attr 'src', ''
move = true
if move then _.delay (-> $block.css position), @_randomDropDelay()
_refreshAllBlocks: ->
return unless @model?
for x in [0...@model.width]
for y in [0...@model.height]
for z in [0...@model.depth]
@_refreshBlock(x, y, z)
@@ -0,0 +1,68 @@
###
Crafting Guide - multiblock_viewer_controller.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
_ = require '../underscore_mixins'
BaseController = require './base_controller'
MultiblockController = require './multiblock_controller'
########################################################################################################################
module.exports = class MultiblockViewerController extends BaseController
constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.modPack? then throw new Error 'options.modPack is required'
options.templateName = 'multiblock_viewer'
super options
@_imageLoader = options.imageLoader
@_modPack = options.modPack
# Event Methods ################################################################################
onBackClicked: ->
return if @backButton.hasClass 'disabled'
@multiblockController.goBackLayer()
@refresh()
onNextClicked: ->
return if @nextButton.hasClass 'disabled'
@multiblockController.goNextLayer()
@refresh()
# BaseController Overrides #####################################################################
onDidRender: ->
@multiblockController = @addChild MultiblockController, '.view__multiblock',
imageLoader: @_imageLoader
modPack: @_modPack
@backButton = @$('.button.back')
@nextButton = @$('.button.next')
super
refresh: ->
@multiblockController.model = @model
if @multiblockController.hasBackLayer()
@backButton.removeClass 'disabled'
else
@backButton.addClass 'disabled'
if @multiblockController.hasNextLayer()
@nextButton.removeClass 'disabled'
else
@nextButton.addClass 'disabled'
super
# Backbone.View Overrides ######################################################################
events: ->
_.extend super,
'click .button.back': 'onBackClicked'
'click .button.next': 'onNextClicked'
+4
View File
@@ -5,6 +5,7 @@ Copyright (c) 2014-2015 by Redwood Labs
All rights reserved. All rights reserved.
### ###
_ = require '../underscore_mixins'
BaseModel = require './base_model' BaseModel = require './base_model'
SimpleInventory = require './simple_inventory' SimpleInventory = require './simple_inventory'
@@ -36,6 +37,9 @@ module.exports = class Multiblock extends BaseModel
height: height:
get: -> @_height get: -> @_height
inventory:
get: -> @_inventory
width: width:
get: -> @_width get: -> @_width
+5
View File
@@ -22,6 +22,11 @@
h2 Recipes h2 Recipes
.panel .panel
.multiblock.section.hideable.hidden
h2 Multiblock Construction
.panel
.view__multiblock_viewer
.description.section .description.section
h2 Description h2 Description
.panel.markdown .panel.markdown
+8
View File
@@ -0,0 +1,8 @@
//-
//- Crafting Guide - multiblock.jade
//-
//- Copyright (c) 2015 by Redwood Labs
//- All rights reserved.
//-
.view__multiblock
+12
View File
@@ -0,0 +1,12 @@
//-
//- Crafting Guide - multiblock_viewer.jade
//-
//- Copyright (c) 2015 by Redwood Labs
//- All rights reserved.
//-
.view__multiblock_viewer
.view__multiblock
.buttons
.button.back: p back
.button.next: p next
+2
View File
@@ -23,6 +23,8 @@ All rights reserved.
@import 'markdown_image'; @import 'markdown_image';
@import 'markdown_image_list'; @import 'markdown_image_list';
@import 'markdown_section'; @import 'markdown_section';
@import 'multiblock';
@import 'multiblock_viewer';
@import 'minimal_recipe'; @import 'minimal_recipe';
@import 'mod'; @import 'mod';
@import 'mod_pack'; @import 'mod_pack';
+15
View File
@@ -0,0 +1,15 @@
/*
Crafting Guide - mod.scss
Copyright (C) 2015 by Redwood Labs
All rights reserved.
*/
.view__multiblock {
position: relative;
.block {
position: absolute;
transition: all $animate-slow cubic-bezier(0.615, -0.090, 0.010, 1.090);
}
}
+26
View File
@@ -0,0 +1,26 @@
/*
Crafting Guide - mod.scss
Copyright (C) 2015 by Redwood Labs
All rights reserved.
*/
.view__multiblock_viewer {
display: flex;
flex-direction: column;
.view__multiblock_viewer {
flex: 0 1 100%;
}
.buttons {
display: flex;
flex: 0 0 auto;
margin: 1em 25% 0 25%;
.button {
flex: 50%;
margin: 1em;
}
}
}