Permalink
Browse files

Allow changing the image

Added an event system to replace hardcoded functions
  • Loading branch information...
1 parent faa0351 commit 9eb65c98dd43f6bd69c28f8d0d214f95de57a1f1 @caleb committed May 29, 2014
Showing with 159 additions and 75 deletions.
  1. +35 −21 lib/crop-box.coffee
  2. +21 −11 lib/drawing.coffee
  3. +16 −0 lib/events.coffee
  4. +20 −18 lib/rodeo-crop.coffee
  5. BIN public/MondoCabin.jpg
  6. +67 −25 public/index.html
View
@@ -21,12 +21,14 @@ class CropBox extends drawing.Drawable
@cropWidth = options.cropWidth || @handleSize * 4
@cropHeight = options.cropHeight || @handleSize * 4
- @onCropFrameChanged = options.onCropFrameChanged || null
-
@dragging = null
@handles = {}
+ @image.on 'load', () =>
+ # reposition the frame when the image is loaded
+ @setCropFrameAndUpdateFrame @cropFrame()
+
frame: () ->
{
x: if @w < 0 then @x + @w else @x
@@ -43,46 +45,59 @@ class CropBox extends drawing.Drawable
height: @cropHeight
}
- updateCropAreaFromFrame: () ->
+ updateCropFrameFromFrame: () ->
frame = @frame()
naturalBounds = @image.naturalBounds()
imageBounds = @image.bounds()
- if imageBounds.w && imageBounds.h
+ if @image.loaded
@cropX = (naturalBounds.w * (frame.x / imageBounds.w))
@cropY = (naturalBounds.h * (frame.y / imageBounds.h))
@cropWidth = (naturalBounds.w * (frame.w / imageBounds.w))
@cropHeight = (naturalBounds.h * (frame.h / imageBounds.h))
- @onCropFrameChanged? @cropFrame()
+ @trigger 'change:cropFrame', @cropFrame()
setFrameAndUpdateCropArea: (frame) ->
@x = frame.x
@y = frame.y
@w = frame.w
@h = frame.h
- @updateCropAreaFromFrame()
+ @updateCropFrameFromFrame()
- updateFrameFromCropArea: () ->
+ updateFrameFromCropFrame: () ->
naturalBounds = @image.naturalBounds()
imageBounds = @image.bounds()
- if imageBounds.w && imageBounds.h
+ if @image.loaded
@x = (imageBounds.w * (@cropX / naturalBounds.w))
@y = (imageBounds.h * (@cropY / naturalBounds.h))
@w = (imageBounds.w * (@cropWidth / naturalBounds.w))
@h = (imageBounds.h * (@cropHeight / naturalBounds.h))
- setCropAreaAndUpdateFrame: (cropArea) ->
+ setCropFrameAndUpdateFrame: (cropArea) ->
naturalBounds = @image.naturalBounds()
- @cropX = Math.min(Math.max(cropArea.x, 0.0), naturalBounds.w)
- @cropY = Math.min(Math.max(cropArea.y, 0.0), naturalBounds.h)
- @cropWidth = Math.min(Math.max(cropArea.width, 0.0), naturalBounds.w - @cropX)
- @cropHeight = Math.min(Math.max(cropArea.height, 0.0), naturalBounds.h - @cropY)
-
- @updateFrameFromCropArea()
+ # if the image is loaded, constrain the crop frame to the natural
+ # image size
+ #
+ # Also update the drawn frame from the new crop frame
+ if @image.loaded
+ @cropX = Math.min(Math.max(cropArea.x, 0), naturalBounds.w)
+ @cropY = Math.min(Math.max(cropArea.y, 0), naturalBounds.h)
+ @cropWidth = Math.min(Math.max(cropArea.width, 0), naturalBounds.w - @cropX)
+ @cropHeight = Math.min(Math.max(cropArea.height, 0), naturalBounds.h - @cropY)
+
+ @updateFrameFromCropFrame()
+ else
+ # our image isn't loaded, so just set the crop area, and
+ # assume that we will update the frame and constrain it when
+ # it is loaded
+ @cropX = cropArea.x
+ @cropY = cropArea.y
+ @cropWidth = cropArea.width
+ @cropHeight = cropArea.height
bounds: () ->
{
@@ -92,10 +107,6 @@ class CropBox extends drawing.Drawable
h: Math.abs @h
}
- onCanvasSizeChange: () ->
- # move/size the crop area based on the image size
- @updateFrameFromCropArea()
-
containsCanvasPoint: (point) ->
local = @convertFromCanvas point
containsPoint = @containsPoint local
@@ -170,7 +181,7 @@ class CropBox extends drawing.Drawable
x: localPoint.x - @dragging.offsetX
y: localPoint.y - @dragging.offsetY
- @updateCropAreaFromFrame()
+ @updateCropFrameFromFrame()
else if @dragging?.resizeDirection
parentPoint = @parent.convertFromCanvas point
@@ -224,7 +235,7 @@ class CropBox extends drawing.Drawable
@x = @x
@y = @y
- @updateCropAreaFromFrame()
+ @updateCropFrameFromFrame()
onDragEnd: (point) ->
# reset our frame after a drag to fix negative widths/heights used during
@@ -235,6 +246,9 @@ class CropBox extends drawing.Drawable
@w = frame.w
@h = frame.h
+ # trigger our change event at the end of the change
+ @trigger 'change', @cropFrame()
+
onClick: (point) ->
moveTo: (point) ->
View
@@ -1,8 +1,9 @@
`import _ from "funderscore"`
+`import Events from "events"`
drawing = {}
-class Drawable
+class Drawable extends Events
constructor: (options) ->
@options = options
@@ -16,9 +17,6 @@ class Drawable
@children = options.children || []
@dragable = options.dragable || false
- onCanvasSizeChange: () ->
- @options.onCanvasSizeChange.call @ if _.isFunction @options.onCanvasSizeChange
-
set: (options) ->
for own key, value of options
@[key] = value
@@ -130,8 +128,20 @@ class CanvasImage extends Drawable
@source = options.source
@naturalWidth = options.naturalWidth
@naturalHeight = options.naturalHeight
- @onLoad = options.onLoad
+ @loaded = false
+
+ @loadImage()
+
+ clearImage: () ->
+ @loaded = false
+ @w = null
+ @h = null
+ @naturalWidth = null
+ @naturalHeight = null
+ setSource: (source) ->
+ @clearImage()
+ @source = source
@loadImage()
naturalBounds: () ->
@@ -156,27 +166,27 @@ class CanvasImage extends Drawable
@w = (@naturalWidth * @scale)|0
@h = (@naturalHeight * @scale)|0
+ @trigger 'resize', @frame()
+
centerOnParent: () ->
@x = ((@parent.frame().w / 2) - (@w / 2))|0
@y = ((@parent.frame().h / 2) - (@h / 2))|0
+ @trigger 'reposition', @frame()
+
draw: (ctx) ->
@isolateAndMoveToParent ctx, (ctx) ->
ctx.drawImage @img, 0, 0, @w, @h
@drawChildren ctx
- onCanvasSizeChange: ->
- super()
- for child in @children
- child.onCanvasSizeChange()
-
loadImage: ->
@img = document.createElement 'img'
@img.onload = =>
+ @loaded = true
@naturalWidth = @img.naturalWidth
@naturalHeight = @img.naturalHeight
- @onLoad.call @ if _.isFunction @onLoad
+ @trigger 'load', @
@img.src = @source
drawing.CanvasImage = CanvasImage
View
@@ -0,0 +1,16 @@
+class Events
+ on: (event, callback, context) ->
+ @events ||= {}
+ @events[event] ||= []
+ @events[event].push [callback, context]
+
+ trigger: (event) ->
+ tail = Array.prototype.slice.call arguments, 1
+ callbacks = @events[event] || []
+
+ for callbackStruct in callbacks
+ callback = callbackStruct[0]
+ context = callbackStruct[1] || @
+ callback.apply context, tail
+
+`export default Events`
View
@@ -1,5 +1,6 @@
`import _ from "funderscore"`
`import drawing from "drawing"`
+`import Events from "events"`
`import CropBox from "crop-box"`
RodeoCrop = {}
@@ -19,18 +20,13 @@ class Stage extends drawing.Drawable
bounds: ->
@frame()
- onCanvasSizeChange: () ->
- super()
- for child in @children
- child.onCanvasSizeChange()
-
draw: (ctx) ->
@drawChildren ctx
clear: (ctx) ->
ctx.clearRect 0, 0, @canvas.width, @canvas.height
-class Cropper
+class Cropper extends Events
constructor: (el, options) ->
@el = if _.isString el
document.querySelector el
@@ -78,16 +74,15 @@ class Cropper
@image = new drawing.CanvasImage
canvas: @canvas
source: @imageSource
- onLoad: () =>
- @valid = false
- @image.resizeToParent()
- @image.centerOnParent()
- @cropBox.updateFrameFromCropArea()
+ @image.on 'load', () =>
+ @valid = false
+ @image.resizeToParent()
+ @image.centerOnParent()
- onCanvasSizeChange: () =>
- @image.resizeToParent()
- @image.centerOnParent()
+ @stage.on 'resize', () =>
+ @image.resizeToParent()
+ @image.centerOnParent()
@stage.addChild @image
@@ -100,8 +95,11 @@ class Cropper
cropWidth: @options.cropWidth
cropHeight: @options.cropHeight
- onCropFrameChanged: (cropFrame) =>
- @options.onCropFrameChanged? cropFrame
+ @cropBox.on 'change', (cropFrame) =>
+ @trigger 'change', cropFrame
+
+ @image.on 'resize', () =>
+ @cropBox.updateFrameFromCropFrame()
@image.addChild @cropBox
@@ -162,8 +160,12 @@ class Cropper
@mouseOver.onMouseOut? pos
@mouseOver = null
+ setImageSource: (source) ->
+ @image.setSource source
+ @valid = false
+
setCropFrame: (frame) ->
- @cropBox.setCropAreaAndUpdateFrame frame
+ @cropBox.setCropFrameAndUpdateFrame frame
@valid = false
@cropBox.cropFrame()
@@ -188,7 +190,7 @@ class Cropper
unless @valid
@stage.clear @ctx
- @stage.onCanvasSizeChange() if canvasSizeChanged
+ @stage.trigger 'resize' if canvasSizeChanged
@stage.draw @ctx
@valid = true
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.

0 comments on commit 9eb65c9

Please sign in to comment.