Recipe component can show multiblock recipes

This commit is contained in:
Andrew Miner
2017-07-16 13:07:49 -04:00
parent 3ca0dcceed
commit 0e6d75ec9b
15 changed files with 199 additions and 197 deletions
+1 -6
View File
@@ -24,11 +24,6 @@
section.description.view__markdown_section
section.multiblock
h2 Multiblock Construction
.panel
.view__multiblock_viewer
section.recipes
h2 Recipes
.panel
@@ -43,4 +38,4 @@
section.view__item_group.usedAsToolToMake
section.view__item_group.similar
section.view__item_group.similar
@@ -11,9 +11,9 @@ ItemDisplay = require "../../models/site/item_display"
ItemGroupController = require "../common/item_group/item_group_controller"
ItemPage = require "../../models/site/item_page"
MarkdownSectionController = require "../common/markdown_section/markdown_section_controller"
MultiblockViewerController = require "./multiblock_viewer/multiblock_viewer_controller"
PageController = require "../page_controller"
RecipeDetailController = require "./recipe_detail/recipe_detail_controller"
RecipeController = require "../common/recipe/recipe_controller"
RecipeDisplay = require "../../models/site/recipe_display"
VideoController = require "../common/video/video_controller"
w = require "when"
@@ -79,7 +79,6 @@ module.exports = class ItemPageController extends PageController
onDidRender: ->
options = imageLoader:@_imageLoader, modPack:@_modPack, router:@_router, show:false
@_multiblockController = @addChild MultiblockViewerController, '.view__multiblock_viewer', options
@_similarItemsController = @addChild ItemGroupController, '.view__item_group.similar', options
@_usedAsToolToMakeController = @addChild ItemGroupController, '.view__item_group.usedAsToolToMake ', options
@_usedToMakeController = @addChild ItemGroupController, '.view__item_group.usedToMake', options
@@ -140,7 +139,6 @@ module.exports = class ItemPageController extends PageController
@_refreshSourceMod()
@_refreshDescription()
@_refreshMultiblock()
@_refreshRecipes()
@_refreshSimilarItems()
@_refreshUsedAsToolToMake()
@@ -221,13 +219,6 @@ module.exports = class ItemPageController extends PageController
@_descriptionController.model = @model.item.detail.description
@_descriptionController.resetToDefaultState()
_refreshMultiblock: ->
if @model.item.isMultiblock
@_multiblockController.model = @model.item.getMultiblockRecipe()
@show @$multiblockSection
else
@hide @$multiblockSection
_refreshRecipes: ->
@_recipeControllers ?= []
index = 0
@@ -239,16 +230,16 @@ module.exports = class ItemPageController extends PageController
for recipe in recipes
controller = @_recipeControllers[index]
if not controller?
controller = new RecipeDetailController
controller = new RecipeController
imageLoader: @_imageLoader
modPack: @_modPack
model: recipe
model: new RecipeDisplay recipe:recipe
router: @_router
@_recipeControllers.push controller
@$recipeContainer.append controller.$el
controller.render()
else
controller.model = recipe
controller.model = new RecipeDisplay recipe:recipe
index++
@show @$recipesSection
@@ -1,9 +0,0 @@
//-
//- Crafting Guide - multiblock.jade
//-
//- Copyright (c) 2015 by Redwood Labs
//- All rights reserved.
//-
.view__multiblock
img.outline(src="/images/outline.png")
@@ -1,24 +0,0 @@
//
// Crafting Guide - multiblock.scss
//
// Copyright © 2014-2017 by Redwood Labs
// All rights reserved.
//
$animate-slow: 400ms;
$animate-fast: 100ms;
.view__multiblock {
position: relative;
.block {
position: absolute;
transition: all $animate-slow cubic-bezier(0.615, -0.090, 0.010, 1.090);
}
.outline {
position: absolute;
opacity: 0.0;
transition: opacity $animate-fast;
}
}
@@ -1,187 +0,0 @@
#
# Crafting Guide - multiblock_controller.coffee
#
# Copyright (c) 2014-2017 by Redwood Labs
# All rights reserved.
#
BaseController = require "../../../base_controller"
ItemDisplay = require "../../../../models/site/item_display"
########################################################################################################################
module.exports = class MultiblockController extends BaseController
@::HOVER_TIMEOUT = 5000 # ms
@::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 = "item_page/multiblock_viewer/multiblock"
super options
@_currentLayer = 0
@_blockCache = null
@_imageLoader = options.imageLoader
@_modPack = options.modPack
@_onHovering = options.onHovering ?= (itemDisplay)-> # do nothing
# 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
# Property Methods #############################################################################
Object.defineProperties @prototype,
currentLayer:
get: -> return @_currentLayer
# BaseController Overrides #####################################################################
onDidRender: ->
@$outline = @$(".outline")
super
refresh: ->
@$el.css "height":@_computeMinHeight(), "width":@_computeMinWidth()
@_refreshBlockCache()
@_refreshAllBlocks()
super
# 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)) * 2
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
_endHovering: ->
@$outline.css opacity:0.0
@_hoverTimer = null
@_onHovering null
_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.getInputAt x, y, z
$block = @_blockCache[x][y][z]
position = @_computePosition x, y, z, hideUpperLayers:true
move = false
if stack?
itemDisplay = new ItemDisplay stack.item
if not $block?
$block = $("<img alt=\"#{itemDisplay.itemName}\" class=\"block\" />")
$block.css position, top:-@IMAGE_SIZE, opacity:0.0
@_registerHoverHandlers $block, y, itemDisplay
@_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?
if @_endHovering? then @_endHovering()
for x in [0...@model.width]
for y in [0...@model.height]
for z in [0...@model.depth]
@_refreshBlock(x, y, z)
_registerHoverHandlers: ($el, y, itemDisplay)->
startHovering = =>
return unless y is @_currentLayer
zIndex = parseInt($el.css("z-index")) + 1
zIndex = if _.isNaN(zIndex) then 0 else zIndex
@$outline.css opacity:1.0, top:$el.css("top"), left:$el.css("left"), "z-index":zIndex
@_onHovering itemDisplay
if @_hoverTimer? then clearTimeout @_hoverTimer
@_hoverTimer = setTimeout (=> @_endHovering()), @HOVER_TIMEOUT
$el.hover startHovering, (->)
@@ -1,22 +0,0 @@
//-
//- Crafting Guide - multiblock_viewer.jade
//-
//- Copyright (c) 2015 by Redwood Labs
//- All rights reserved.
//-
.view__multiblock_viewer
.left
h3 Complete Materials
.view__inventory.complete
h3 Current Layer
.view__inventory.layer
.right
.buttons
.button.back: .bezel: p back
.button.next: .bezel: p next
.view__multiblock
.caption
img
p &nbsp;
@@ -1,94 +0,0 @@
//
// Crafting Guide - multiblock_viewer.scss
//
// Copyright © 2014-2017 by Redwood Labs
// All rights reserved.
//
.view__multiblock_viewer {
display: flex;
align-items: stretch;
h3 {
margin-bottom: $size-margin-small;
margin-left: 0;
&:not(:first-child) {
margin-top: $size-margin-large;
}
}
.left {
border-right: 1px solid $color-gray-light;
flex: 1 0 40%;
.view__inventory {
margin-left: $size-margin-medium;
}
}
.right {
flex: 0 1 60%;
display: flex;
flex-direction: column;
.buttons {
flex: 0 0 auto;
margin-bottom: $size-margin-medium;
display: flex;
justify-content: space-between;
.button {
flex: 1 1 50%;
margin-left: $size-margin-medium;
}
}
.view__multiblock {
flex: 0 0 auto;
align-self: center;
}
.caption {
flex: 0 0 auto;
margin-top: $size-margin-medium;
display: flex;
justify-content: center;
align-items: center;
img {
margin-right : $size-margin-medium;
height : $size-minecraft-block;
width : $size-minecraft-block;
border : none;
}
p {
font-family: $font-family-text;
font-size: $font-size-medium;
}
}
}
}
@include screen-size(mobile) {
.view__multiblock_viewer {
flex-direction: column-reverse;
.left {
flex: 0 0 auto;
border: 0;
}
.right {
flex: 0 0 auto;
margin-bottom: $size-margin-large;
}
}
}
@@ -1,104 +0,0 @@
#
# Crafting Guide - multiblock_viewer_controller.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
BaseController = require "../../base_controller"
InventoryController = require "../../common/inventory/inventory_controller"
MultiblockController = require "./multiblock/multiblock_controller"
MultiblockDisplay = require "../../../models/site/multiblock_display"
########################################################################################################################
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"
if not options.router? then throw new Error "options.router is required"
options.templateName = "item_page/multiblock_viewer"
super options
@_imageLoader = options.imageLoader
@_modPack = options.modPack
@_hoverTimer = null
@_router = options.router
# Event Methods ################################################################################
onBackClicked: ->
return if @$backButton.hasClass "disabled"
tracker.trackEvent c.tracking.category.multiblock, "back"
@multiblockController.goBackLayer()
@refresh()
onNextClicked: ->
return if @$nextButton.hasClass "disabled"
tracker.trackEvent c.tracking.category.multiblock, "next"
@multiblockController.goNextLayer()
@refresh()
onBlockHovered: (itemDisplay)->
if itemDisplay?
@$captionText.html itemDisplay.name
@_imageLoader.load itemDisplay.iconUrl, @$captionIcon
else
@$captionText.html "&nbsp;"
@$captionIcon.attr "src", "/images/empty.png"
# BaseController Overrides #####################################################################
onDidRender: ->
@completeInventoryController = @addChild InventoryController, ".view__inventory.complete",
editable: false
imageLoader: @_imageLoader
modPack: @_modPack
router: @_router
@layerInventoryController = @addChild InventoryController, ".view__inventory.layer",
editable: false
imageLoader: @_imageLoader
modPack: @_modPack
router: @_router
@multiblockController = @addChild MultiblockController, ".view__multiblock",
imageLoader: @_imageLoader
modPack: @_modPack
onHovering: (itemDisplay)=> @onBlockHovered(itemDisplay)
@$backButton = @$(".button.back")
@$nextButton = @$(".button.next")
@$captionText = @$(".caption p")
@$captionIcon = @$(".caption img")
super
onWillChangeModel: (oldModel, newModel)->
@_display = new MultiblockDisplay newModel
super oldModel, newModel
refresh: ->
if @model? and @_display?
@completeInventoryController.model = @_display.getInventory()
@layerInventoryController.model = @_display.getInventory @multiblockController.currentLayer
@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"