diff --git a/editor/js/Editor.js b/editor/js/Editor.js index b758710..3d46c12 100755 --- a/editor/js/Editor.js +++ b/editor/js/Editor.js @@ -318,6 +318,39 @@ Editor.prototype = { this.signals.animationSelected.dispatch( animation ); }, + + duplicateAnimation: function(animation) { + + if (animation === undefined) { + + animation = this.selected; + if (animation === null) return; + + } + + var offset = animation.end - animation.start; + + var copy = new FRAME.Animation( + animation.name, + animation.start + offset, + animation.end + offset, + animation.layer, + animation.effect + ); + + var overlap = this.getOverlappingAnimation(copy); + while (overlap) { + + copy.end = overlap.end + (copy.end - copy.start); + copy.start = overlap.end; + overlap = this.getOverlappingAnimation(copy); + + } + + this.addAnimation(copy); + this.selectAnimation(copy); + + }, removeAnimation: function ( animation ) { @@ -325,6 +358,20 @@ Editor.prototype = { this.signals.animationRemoved.dispatch( animation ); }, + + getOverlappingAnimation: function (animation) { + + for (let anim of this.timeline.animations) { + + if (anim.layer !== animation.layer || anim.id == animation.id) continue; + if ((anim.start <= animation.start && anim.end > animation.start) || + (anim.start < animation.end && anim.end > animation.end)) return anim; + + } + + return undefined; + + }, addCurve: function ( curve ) { diff --git a/editor/js/Menubar.Edit.js b/editor/js/Menubar.Edit.js index f69d8e9..a30c735 100755 --- a/editor/js/Menubar.Edit.js +++ b/editor/js/Menubar.Edit.js @@ -25,22 +25,7 @@ Menubar.Edit = function ( editor ) { option.setTextContent( 'Duplicate' ); option.onClick( function () { - if ( editor.selected === null ) return; - - var selected = editor.selected; - - var offset = selected.end - selected.start; - - var animation = new FRAME.Animation( - selected.name, - selected.start + offset, - selected.end + offset, - selected.layer, - selected.effect - ); - - editor.addAnimation( animation ); - editor.selectAnimation( animation ); + editor.duplicateAnimation(); } ); options.add( option ); diff --git a/editor/js/Timeline.Animations.js b/editor/js/Timeline.Animations.js index f3a3677..fe5c2aa 100755 --- a/editor/js/Timeline.Animations.js +++ b/editor/js/Timeline.Animations.js @@ -34,33 +34,40 @@ Timeline.Animations = function ( editor ) { movementX = event.movementX | event.webkitMovementX | event.mozMovementX | 0; - animation.start += movementX / scale; - animation.end += movementX / scale; + var pos = animation.getPosition(); + pos.start += movementX / scale; + pos.end += movementX / scale; - if ( animation.start < 0 ) { - - var offset = - animation.start; - - animation.start += offset; - animation.end += offset; + if (pos.start < 0) { + + var offset = -animation.start; + pos.start += offset; + pos.end += offset; + } movementY += event.movementY | event.webkitMovementY | event.mozMovementY | 0; - if ( movementY >= 30 ) { - - animation.layer = animation.layer + 1; + if (movementY >= 30) { + + pos.layer += 1; movementY = 0; - + } - if ( movementY <= -30 ) { - - animation.layer = Math.max( 0, animation.layer - 1 ); + if (movementY <= -30) { + + pos.layer = Math.max(0, pos.layer - 1); movementY = 0; - + } + + if (editor.getOverlappingAnimation(pos)) return false; + + animation.start = pos.start; + animation.end = pos.end; + animation.layer = pos.layer; signals.animationModified.dispatch( animation ); @@ -78,44 +85,56 @@ Timeline.Animations = function ( editor ) { }, false ); - var resizeLeft = document.createElement( 'div' ); - resizeLeft.style.position = 'absolute'; - resizeLeft.style.width = '6px'; - resizeLeft.style.height = '30px'; - resizeLeft.style.cursor = 'w-resize'; - resizeLeft.addEventListener( 'mousedown', function ( event ) { - + var resizeOnMouseDown = function (event, left) { + event.stopPropagation(); var movementX = 0; - function onMouseMove( event ) { - + function onMouseMove(event) { + movementX = event.movementX | event.webkitMovementX | event.mozMovementX | 0; - - animation.start += movementX / scale; - - signals.animationModified.dispatch( animation ); - - } - - function onMouseUp( event ) { - - if ( Math.abs( movementX ) < 2 ) { - - editor.selectAnimation( animation ); - + + let pos = animation.getPosition(); + + if (left) { + pos.start += movementX / scale; + if (pos.start > pos.end - 0.1) return; + } + else { + pos.end += movementX / scale; + } + + // If the animation would overlap any other on the same layer, don't increase the size. + if (editor.getOverlappingAnimation(pos)) return; + + if (left) { + animation.start = pos.start; + } + else { + animation.end = pos.end; } - document.removeEventListener( 'mousemove', onMouseMove ); - document.removeEventListener( 'mouseup', onMouseUp ); - + signals.animationModified.dispatch(animation); } + + function onMouseUp(event) { + if (Math.abs(movementX) < 2) editor.selectAnimation(animation); - document.addEventListener( 'mousemove', onMouseMove, false ); - document.addEventListener( 'mouseup', onMouseUp, false ); + document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('mouseup', onMouseUp); + } - }, false ); + document.addEventListener('mousemove', onMouseMove, false); + document.addEventListener('mouseup', onMouseUp, false); + } + + var resizeLeft = document.createElement( 'div' ); + resizeLeft.style.position = 'absolute'; + resizeLeft.style.width = '6px'; + resizeLeft.style.height = '30px'; + resizeLeft.style.cursor = 'w-resize'; + resizeLeft.addEventListener( 'mousedown', (event) => resizeOnMouseDown(event, true), false ); dom.appendChild( resizeLeft ); var name = document.createElement( 'div' ); @@ -129,39 +148,7 @@ Timeline.Animations = function ( editor ) { resizeRight.style.width = '6px'; resizeRight.style.height = '30px'; resizeRight.style.cursor = 'e-resize'; - resizeRight.addEventListener( 'mousedown', function ( event ) { - - event.stopPropagation(); - - var movementX = 0; - - function onMouseMove( event ) { - - movementX = event.movementX | event.webkitMovementX | event.mozMovementX | 0; - - animation.end += movementX / scale; - - signals.animationModified.dispatch( animation ); - - } - - function onMouseUp( event ) { - - if ( Math.abs( movementX ) < 2 ) { - - editor.selectAnimation( animation ); - - } - - document.removeEventListener( 'mousemove', onMouseMove ); - document.removeEventListener( 'mouseup', onMouseUp ); - - } - - document.addEventListener( 'mousemove', onMouseMove, false ); - document.addEventListener( 'mouseup', onMouseUp, false ); - - }, false ); + resizeRight.addEventListener( 'mousedown', (event) => resizeOnMouseDown(event, false), false ); dom.appendChild( resizeRight ); // diff --git a/src/Frame.js b/src/Frame.js index 37d35f6..83068ec 100755 --- a/src/Frame.js +++ b/src/Frame.js @@ -250,6 +250,17 @@ var FRAME = { this.layer = layer; this.effect = effect; this.enabled = enabled; + + this.getPosition = function() { + + return { + start: this.start, + end: this.end, + layer: this.layer, + id: this.id + }; + + }; };