Refactor image loading code into ImageLoader class

This commit is contained in:
Andrew Miner
2015-01-07 11:20:49 -08:00
parent 4a10a36e37
commit 9f79722378
5 changed files with 125 additions and 81 deletions
@@ -0,0 +1,81 @@
###
Crafting Guide - image_loader.coffee
Copyright (c) 2014 by Redwood Labs
All rights reserved.
###
{Duration} = require '../constants'
########################################################################################################################
module.exports = class ImageLoader
constructor: (options={})->
options.defaultUrl ?= ''
options.onLoading ?= -> @hide()
options.onLoad ?= -> @fadeIn Duration.fast
@defaultUrl = options.defaultUrl
@onLoading = options.onLoading
@onLoad = options.onLoad
@_images = {}
# Class Methods ################################################################################
@load: (imageUrl, $el, options={}) ->
loader = new ImageLoader options
loader.load $el, options
return loader
# Public Methods ###############################################################################
isLoaded: (imageUrl)->
data = @_images[imageUrl]
return false unless data?
return data.isLoaded
load: (imageUrl, $el)->
data = @preload imageUrl
return if $el.attr('src').indexOf(imageUrl) isnt -1
if @onLoading? then @onLoading.call $el
$el.data 'isLoading', true
$el.data 'isLoaded', false
if data.isLoaded?
@_loadImageIntoElement data.imageUrl, $el
else
if @defaultUrl? then $el.attr 'src', @defaultUrl
if data.elements.indexOf($el) is -1 then data.elements.push $el
return this
preload: (imageUrl)->
data = @_images[imageUrl]
if not data?
data = imageUrl:imageUrl, elements:[], image:new Image, isLoaded:false
@_images[imageUrl] = data
data.image = new Image
data.image.onload = => @_onImageLoaded data
data.image.src = imageUrl
return data
# Private Methods ##############################################################################
_onImageLoaded: (data)->
for $el in data.elements
@_loadImageIntoElement data.imageUrl, $el
data.elements = []
data.isLoaded = true
_loadImageIntoElement: (imageUrl, $el)->
$el.data 'isLoading', false
$el.data 'isLoaded', true
$el.attr 'src', imageUrl
if @onLoad? then @onLoad.call $el
@@ -8,6 +8,7 @@ All rights reserved.
BaseController = require './base_controller'
{Duration} = require '../constants'
{Key} = require '../constants'
ImageLoader = require './image_loader'
StackController = require './stack_controller'
########################################################################################################################
@@ -22,14 +23,17 @@ module.exports = class InventoryController extends BaseController
options.icon ?= '/images/chest_front.png'
options.editable ?= true
options.templateName = 'inventory'
options.imageLoader ?= new ImageLoader defaultUrl:'/images/unknown.png'
options.title ?= 'Inventory'
options.templateName = 'inventory'
super options
@editable = options.editable
@icon = options.icon
@modPack = options.modPack
@title = options.title
@editable = options.editable
@icon = options.icon
@imageLoader = options.imageLoader
@modPack = options.modPack
@title = options.title
@_stackControllers = []
@@ -114,9 +118,10 @@ module.exports = class InventoryController extends BaseController
@_stackControllers = []
@model.each (stack)=>
options =
model: stack
modPack: @modPack
onRemove: if not @editable then null else (stack)=> @_removeStack(stack)
imageLoader: @imageLoader
model: stack
modPack: @modPack
onRemove: if not @editable then null else (stack)=> @_removeStack(stack)
controller = new StackController options
controller.render()
@@ -7,6 +7,7 @@ All rights reserved.
BaseController = require './base_controller'
CraftingTableController = require './crafting_table_controller'
ImageLoader = require './image_loader'
InventoryController = require './inventory_controller'
ItemPage = require '../models/item_page'
ModPackController = require './mod_pack_controller'
@@ -17,6 +18,7 @@ module.exports = class ItemPageController extends BaseController
constructor: (options={})->
options.model ?= new ItemPage
options.imageLoader ?= new ImageLoader defaultUrl:'/images/unknown.png'
options.templateName = 'item_page'
super options
@@ -35,26 +37,29 @@ module.exports = class ItemPageController extends BaseController
onDidRender: ->
options =
editable: true,
model: @model.plan.have,
modPack: @model.modPack,
title: 'Items you have'
editable: true,
imageLoader: @imageLoader
model: @model.plan.have,
modPack: @model.modPack,
title: 'Items you have'
@haveController = @addChild InventoryController, '.have', options
options =
editable: true
icon: '/images/fishing_rod.png',
model: @model.plan.want,
modPack: @model.modPack,
title: 'Items you want'
editable: true
icon: '/images/fishing_rod.png',
imageLoader: @imageLoader
model: @model.plan.want,
modPack: @model.modPack,
title: 'Items you want'
@wantController = @addChild InventoryController, '.want', options
options =
editable: false
icon: '/images/boots.png',
model: @model.plan.need,
modPack: @model.modPack,
title: "Items you'll need"
editable: false
icon: '/images/boots.png',
imageLoader: @imageLoader
model: @model.plan.need,
modPack: @model.modPack,
title: "Items you'll need"
@needController = @addChild InventoryController, '.need', options
@modPackController = @addChild ModPackController, '.view__mod_pack', model:@model.modPack
@@ -6,7 +6,8 @@ All rights reserved.
###
BaseController = require './base_controller'
{ImageUrl} = require '../constants'
{ImageUrl} = require '../constants'
ImageLoader = require './image_loader'
########################################################################################################################
@@ -15,20 +16,12 @@ module.exports = class StackController extends BaseController
constructor: (options={})->
if not options.model? then throw new Error 'options.model is required'
if not options.modPack? then throw new Error 'options.modPack is required'
options.imageLoader ?= new ImageLoader defaultUrl:'/images/unknown.png'
options.templateName = 'stack'
super options
@modPack = options.modPack
@_loadImage()
# Event Methods ################################################################################
onImageLoaded: ->
return if @_image.loaded
logger.trace "#{@constructor.name}.onImageLoaded(#{@_image.src})"
@_image.loaded = true
@$image.attr 'src', @_image.src
@modPack = options.modPack
@_imageLoader = options.imageLoader
# BaseController Overrides #####################################################################
@@ -39,10 +32,12 @@ module.exports = class StackController extends BaseController
super
refresh: ->
{itemName} = @_gatherData()
{itemName, itemSlug, modSlug} = @_gatherData()
imageUrl = ImageUrl itemSlug:itemSlug, modSlug:modSlug
@$nameField.html itemName
@$quantityField.html @model.quantity
@$image.attr 'src', (if @_image?.loaded then @_image.src else '/images/unknown.png')
@_imageLoader.load imageUrl, @$image
super
# Private Methods ##############################################################################
@@ -58,14 +53,3 @@ module.exports = class StackController extends BaseController
modSlug = 'minecraft'
return itemName:itemName, itemSlug:itemSlug, modSlug:modSlug
_loadImage: ->
{itemSlug, modSlug} = @_gatherData()
url = ImageUrl(modSlug:modSlug, itemSlug:itemSlug)
return if @$image?.attr('src').indexOf(url) is -1
@_image = new Image()
@_image.loaded = false
@_image.onload = => @onImageLoaded()
@_image.src = url
logger.verbose "loading image: #{url}"
+3 -34
View File
@@ -15,42 +15,11 @@ Inventory = require './inventory'
module.exports = class CraftingTable extends BaseModel
constructor: (attributes={}, options={})->
if not attributes.modPack? then throw new Error "attributes.modPack is required"
attributes.name ?= null
attributes.quantity ?= 1
attributes.includingTools ?= false
attributes.have ?= new Inventory
attributes.plan ?= null
attributes.want ?= new Inventory
if not attributes.plan? then throw new Error "attributes.plan is required"
attributes.step ?= 0
super attributes, options
Object.defineProperty @prototype, 'need', -> @plan?.need
# Public Methods ###############################################################################
craft: ->
if not @modPack.hasRecipe @name
@plan = null
return
toolPhrase = if @includingTools then ' including tools' else ''
logger.verbose "calculating build plan for #{@quantity} #{@name}#{toolPhrase} with inventory: #{@have}"
@modPack.enableModsForItem @name
plan = new CraftingPlan @modPack, @includingTools
plan.includingTools = @includingTools
plan.craft @name, @quantity, @have
@plan = plan
# Object Overrides #############################################################################
toString: ->
return "#{@constructor.name} (#{@cid}) {
name:#{@name},
quantity:#{@quantity},
includingTools:#{@includingTools},
have:#{@have},
plan:#{@plan}
}"
return "#{@constructor.name} (#{@cid}) { plan:#{@plan}, step:#{@step} }"