@behance/helicropter
Advanced tools
Comparing version 15.4.0 to 15.5.0
{ | ||
"name": "@behance/helicropter", | ||
"version": "15.4.0", | ||
"version": "15.5.0", | ||
"description": "My helicropter goes \"whosh whosh whosh\"", | ||
@@ -5,0 +5,0 @@ "main": "src/js/index.js", |
@@ -132,2 +132,18 @@ import View from '@behance/beff/View'; | ||
disable() { | ||
this._canvas.selection = false; | ||
this._canvas.forEachObject(function(object) { | ||
object.selectable = false; | ||
}); | ||
this._canvas.hoverCursor = 'default'; | ||
}, | ||
enable() { | ||
this._canvas.selection = true; | ||
this._canvas.forEachObject(function(object) { | ||
object.selectable = true; | ||
}); | ||
this._canvas.hoverCursor = 'move'; | ||
}, | ||
getCropData() { | ||
@@ -134,0 +150,0 @@ if (!this._image) { return; } |
@@ -8,3 +8,3 @@ import extend from '@behance/nbd/util/extend'; | ||
import CroppingArea from './CroppingArea'; | ||
import ZoomSlider from './ZoomSlider'; | ||
import { ZoomSlider } from './ZoomSlider'; | ||
import RatioLock from './RatioLock'; | ||
@@ -263,2 +263,10 @@ import SuggestionArea from './SuggestionArea'; | ||
this._zoomSlider.on('image-non-scalable', () => { | ||
this._pauseControls(); | ||
}); | ||
this._zoomSlider.on('image-scalable', () => { | ||
this._resumeControls(); | ||
}); | ||
this.on('remove-image', () => { | ||
@@ -327,2 +335,24 @@ this._uploadArea.trigger('image-upload-complete'); | ||
_pauseControls() { | ||
this._zoomSlider.disable(); | ||
this.$view.find('.js-crop-controls').hide(); | ||
this._croppingArea.disable(); | ||
this.trigger('controls:paused'); | ||
this.isControlPaused = true; | ||
}, | ||
_resumeControls() { | ||
if (!this.isControlPaused) { | ||
return; | ||
} | ||
this._zoomSlider.enable(); | ||
this.$view.find('.js-crop-controls').show(); | ||
this._croppingArea.enable(); | ||
this.trigger('controls:resumed'); | ||
this.isControlPaused = false; | ||
}, | ||
destroy() { | ||
@@ -364,3 +394,3 @@ window.removeEventListener('resize', () => this._calculateViewScale()); | ||
this._super(extend({}, this._defaults, model)); | ||
this.relay(this._view, 'controls:enabled controls:disabled image:uploading image:uploaded image:loaded error:upload image:cancelled'); | ||
this.relay(this._view, 'controls:enabled controls:disabled controls:paused controls:resumed image:uploading image:uploaded image:loaded error:upload image:cancelled'); | ||
}, | ||
@@ -367,0 +397,0 @@ |
@@ -8,3 +8,5 @@ import View from '@behance/beff/View'; | ||
export default View.extend({ | ||
export const maxScale = MAX_SCALE; | ||
export const ZoomSlider = View.extend({ | ||
mustache: template, | ||
@@ -20,2 +22,3 @@ | ||
this._calculateScaleStep(scale); | ||
this._evaluateScalability(); | ||
}, | ||
@@ -29,2 +32,3 @@ | ||
this.trigger('scale', this._currentScale()); | ||
this._evaluateScalability(); | ||
}, | ||
@@ -48,2 +52,11 @@ }); | ||
_evaluateScalability() { | ||
if (MAX_SCALE === this._scaleMin) { | ||
this.trigger('image-non-scalable'); | ||
return; | ||
} | ||
this.trigger('image-scalable'); | ||
}, | ||
_calculateScaleStep(initialScale = 0) { | ||
@@ -50,0 +63,0 @@ const initialValue = Math.max(initialScale - this._scaleMin, 0); |
@@ -72,2 +72,42 @@ import CroppingArea from 'CroppingArea'; | ||
describe('#disable', function() { | ||
beforeEach(function() { | ||
this.croppingArea.disable(); | ||
}); | ||
it('makes canvas unselectable', function() { | ||
expect(this.croppingArea._canvas.selection).toBe(false); | ||
}); | ||
it('makes objects inside canvas el unselectable', function() { | ||
this.croppingArea._canvas.forEachObject(function(object) { | ||
expect(object.selectable).toBe(false); | ||
}); | ||
}); | ||
it('sets canvas hover cursor to default', function() { | ||
expect(this.croppingArea._canvas.hoverCursor).toEqual('default'); | ||
}); | ||
}); | ||
describe('#enable', function() { | ||
beforeEach(function() { | ||
this.croppingArea.enable(); | ||
}); | ||
it('makes canvas selectable', function() { | ||
expect(this.croppingArea._canvas.selection).toBe(true); | ||
}); | ||
it('makes objects inside canvas el selectable', function() { | ||
this.croppingArea._canvas.forEachObject(function(object) { | ||
expect(object.selectable).toBe(true); | ||
}); | ||
}); | ||
it('sets canvas hover cursor to move', function() { | ||
expect(this.croppingArea._canvas.hoverCursor).toEqual('move'); | ||
}); | ||
}); | ||
describe('#getCropData', function() { | ||
@@ -74,0 +114,0 @@ it('returns undefined if no image is defined', function() { |
@@ -46,2 +46,4 @@ import $ from 'jquery'; | ||
}; | ||
this.triggerImageNonScalable = () => this.helicropter._view._zoomSlider.trigger('image-non-scalable'); | ||
}); | ||
@@ -451,2 +453,78 @@ | ||
}); | ||
describe('when a user uploads a min size image', function() { | ||
beforeEach(function() { | ||
this.helicropter = this._createWithInitialImage(); | ||
}); | ||
it('disables the slider', function() { | ||
this.triggerImageNonScalable(); | ||
expect(this.helicropter._view._zoomSlider.$view).toHaveClass('disabled'); | ||
expect(this.helicropter._view._zoomSlider._$slider).toHaveAttr('disabled'); | ||
}); | ||
it('hides .js-crop-controls', function() { | ||
this.triggerImageNonScalable(); | ||
expect($('.js-crop-controls')).not.toBeVisible(); | ||
}); | ||
it('disables the cropper', function() { | ||
const cropperCanvas = this.helicropter._view._croppingArea._canvas; | ||
this.triggerImageNonScalable(); | ||
expect(cropperCanvas.selection).toBe(false); | ||
cropperCanvas.forEachObject(function(object) { | ||
expect(object.selectable).toBe(false); | ||
}); | ||
expect(cropperCanvas.hoverCursor).toEqual('default'); | ||
}); | ||
it('emits controls:paused', function(done) { | ||
this.helicropter.on('controls:paused', done); | ||
this.triggerImageNonScalable(); | ||
}); | ||
}); | ||
describe('when a user reuploads with an image bigger than the min size', function() { | ||
beforeEach(function() { | ||
this.helicropter = this._createWithInitialImage(); | ||
this.triggerImageScalable = () => this.helicropter._view._zoomSlider.trigger('image-scalable'); | ||
}); | ||
it('enables the slider', function() { | ||
this.triggerImageNonScalable(); | ||
this.triggerImageScalable(); | ||
expect(this.helicropter._view._zoomSlider.$view).not.toHaveClass('disabled'); | ||
expect(this.helicropter._view._zoomSlider._$slider).not.toHaveAttr('disabled'); | ||
}); | ||
it('shows .js-crop-controls', function() { | ||
this.triggerImageNonScalable(); | ||
this.triggerImageScalable(); | ||
expect($('.js-crop-controls')).toBeVisible(); | ||
}); | ||
it('enables the cropper', function() { | ||
const cropperCanvas = this.helicropter._view._croppingArea._canvas; | ||
this.triggerImageNonScalable(); | ||
this.triggerImageScalable(); | ||
expect(cropperCanvas.selection).toBe(true); | ||
cropperCanvas.forEachObject(function(object) { | ||
expect(object.selectable).toBe(true); | ||
}); | ||
expect(cropperCanvas.hoverCursor).toEqual('move'); | ||
}); | ||
it('emits controls:resumed', function(done) { | ||
this.helicropter.on('controls:resumed', done); | ||
this.triggerImageNonScalable(); | ||
this.triggerImageScalable(); | ||
}); | ||
}); | ||
}); |
@@ -1,2 +0,2 @@ | ||
import ZoomSlider from 'ZoomSlider'; | ||
import { maxScale, ZoomSlider } from 'ZoomSlider'; | ||
@@ -71,2 +71,48 @@ describe('ZoomSlider', function() { | ||
describe('events', function() { | ||
describe('#image-non-scalable', function() { | ||
beforeEach(function() { | ||
this.minScale = maxScale; | ||
}); | ||
it('is emitted when image is loaded with "minScale" being the same as "MAX_SCALE"', function(done) { | ||
this.zoomSlider.on('image-non-scalable', done); | ||
this.zoomSlider.trigger('image-loaded', { | ||
scale: 'foo', | ||
minScale: this.minScale, | ||
}); | ||
}); | ||
it('is emitted when image is setting crop size with "minScale" being the same as "MAX_SCALE"', function(done) { | ||
this.zoomSlider.on('image-non-scalable', done); | ||
this.zoomSlider.trigger('set-crop-size', { | ||
minScale: this.minScale, | ||
}); | ||
}); | ||
}); | ||
describe('#image-scalable', function() { | ||
beforeEach(function() { | ||
this.minScale = maxScale / 2; | ||
}); | ||
it('is emitted when image is loaded with "minScale" being less than "MAX_SCALE"', function(done) { | ||
this.zoomSlider.on('image-scalable', done); | ||
this.zoomSlider.trigger('image-loaded', { | ||
scale: 'foo', | ||
minScale: this.minScale, | ||
}); | ||
}); | ||
it('is emitted when image is setting crop size with "minScale" being less than "MAX_SCALE"', function(done) { | ||
this.zoomSlider.on('image-scalable', done); | ||
this.zoomSlider.trigger('set-crop-size', { | ||
minScale: this.minScale, | ||
}); | ||
}); | ||
}); | ||
describe('#image-loaded', function() { | ||
@@ -73,0 +119,0 @@ describe('when only triggered with a minScale', function() { |
8684360
4590