From a4731d4af2ba57220dc667932f9bf9c3dbb2f831 Mon Sep 17 00:00:00 2001 From: Naomi Date: Fri, 26 Apr 2013 15:57:02 -0400 Subject: [PATCH] CC-2301 : automatically updating the fadein/fadeout for a track in the fadein/fadeout states. Can enable states on a per track basis. --- .../application/layouts/scripts/layout.phtml | 14 -- airtime_mvc/public/js/airtime/library/spl.js | 10 +- .../public/js/waveformplaylist/config.js | 9 + .../public/js/waveformplaylist/playlist.js | 5 +- .../public/js/waveformplaylist/track.js | 231 ++++++++++-------- .../js/waveformplaylist/track_render.js | 16 ++ 6 files changed, 162 insertions(+), 123 deletions(-) diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index 1cb0da978..b72305687 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -72,20 +72,6 @@ Fade Out Shift -
- - -
diff --git a/airtime_mvc/public/js/airtime/library/spl.js b/airtime_mvc/public/js/airtime/library/spl.js index a34ac500b..9c8f38b22 100644 --- a/airtime_mvc/public/js/airtime/library/spl.js +++ b/airtime_mvc/public/js/airtime/library/spl.js @@ -1126,7 +1126,10 @@ var AIRTIME = (function(AIRTIME){ type: "FadeOut", end: $fadeOut.data("cueout") - $fadeOut.data("cuein"), start: $fadeOut.data("cueout") - $fadeOut.data("cuein") - $fadeOut.data("length") - }] + }], + states: { + 'fadein': false + } }, { src: $fadeIn.data("fadein"), @@ -1138,7 +1141,10 @@ var AIRTIME = (function(AIRTIME){ type: "FadeIn", end: $fadeIn.data("length"), start: 0 - }] + }], + states: { + 'fadeout': false + } } ], dim = AIRTIME.utilities.findViewportDimensions(), diff --git a/airtime_mvc/public/js/waveformplaylist/config.js b/airtime_mvc/public/js/waveformplaylist/config.js index 0aec0b339..7b0ae3ecf 100644 --- a/airtime_mvc/public/js/waveformplaylist/config.js +++ b/airtime_mvc/public/js/waveformplaylist/config.js @@ -15,6 +15,7 @@ var Config = function(params) { resolution: 4096, //resolution - samples per pixel to draw. timeFormat: 'hh:mm:ss.uuu', mono: true, //whether to draw multiple channels or combine them. + fadeType: 'logarithmic', timescale: false, //whether or not to include the time measure. @@ -64,6 +65,10 @@ var Config = function(params) { return params.timescale; }; + that.getFadeType = function getFadeType() { + return params.fadeType; + }; + that.isDisplayMono = function isDisplayMono() { return params.mono; }; @@ -141,6 +146,10 @@ var Config = function(params) { params.timeFormat = format; }; + that.setFadeType = function setFadeType(type) { + params.fadeType = type; + }; + that.setDisplayMono = function setDisplayMono(bool) { params.mono = bool; }; diff --git a/airtime_mvc/public/js/waveformplaylist/playlist.js b/airtime_mvc/public/js/waveformplaylist/playlist.js index 0fa3a5284..ff47e8e75 100644 --- a/airtime_mvc/public/js/waveformplaylist/playlist.js +++ b/airtime_mvc/public/js/waveformplaylist/playlist.js @@ -49,7 +49,6 @@ PlaylistEditor.prototype.init = function(tracks) { this.trackEditors.push(trackEditor); fragment.appendChild(trackElem); - audioControls.on("changestate", "onStateChange", trackEditor); audioControls.on("trackedit", "onTrackEdit", trackEditor); audioControls.on("changeresolution", "onResolutionChange", trackEditor); @@ -127,10 +126,12 @@ PlaylistEditor.prototype.onStateChange = function() { editors = this.trackEditors, i, len, - editor; + editor, + state = this.config.getState(); for(i = 0, len = editors.length; i < len; i++) { editors[i].deactivate(); + editors[i].setState(state); } }; diff --git a/airtime_mvc/public/js/waveformplaylist/track.js b/airtime_mvc/public/js/waveformplaylist/track.js index 66f0ee644..1c6d898e1 100644 --- a/airtime_mvc/public/js/waveformplaylist/track.js +++ b/airtime_mvc/public/js/waveformplaylist/track.js @@ -4,55 +4,55 @@ var TrackEditor = function() { }; -TrackEditor.prototype.states = { - cursor: { - events: { - mousedown: "selectCursorPos" - }, +TrackEditor.prototype.classes = { + "cursor": [ + "state-select" + ], - classes: [ - "state-select" - ] + "select": [ + "state-select" + ], + + "fadein": [ + "state-select" + ], + + "fadeout": [ + "state-select" + ], + + "shift": [ + "state-shift" + ], + + "active": [ + "active" + ], + + "disabled": [ + "disabled" + ] +}; + +TrackEditor.prototype.events = { + "cursor": { + "mousedown": "selectCursorPos" }, - select: { - events: { - mousedown: "selectStart" - }, - - classes: [ - "state-select" - ] + "select": { + "mousedown": "selectStart" }, - fadein: { - events: { - mousedown: "selectFadeIn" - }, - - classes: [ - "state-select" - ] + "fadein": { + "mousedown": "selectFadeIn" }, - fadeout: { - events: { - mousedown: "selectFadeOut" - }, - - classes: [ - "state-select" - ] + "fadeout": { + "mousedown": "selectFadeOut" }, - - shift: { - events: { - mousedown: "timeShift" - }, - classes: [ - "state-shift" - ] + "shift": { + "mousedown": "timeShift" } }; @@ -64,7 +64,22 @@ TrackEditor.prototype.setWidth = function(width) { this.width = width; }; -TrackEditor.prototype.init = function(src, start, end, fades, cues, moveable) { +TrackEditor.prototype.init = function(src, start, end, fades, cues, stateConfig) { + + var statesEnabled = { + 'cursor': true, + 'fadein': true, + 'fadeout': true, + 'select': true, + 'shift': true + }; + + //extend enabled states config. + Object.keys(statesEnabled).forEach(function (key) { + statesEnabled[key] = (key in stateConfig) ? stateConfig[key] : statesEnabled[key]; + }); + + this.enabledStates = statesEnabled; makePublisher(this); @@ -103,8 +118,7 @@ TrackEditor.prototype.init = function(src, start, end, fades, cues, moveable) { this.selectedArea = undefined; //selected area of track stored as inclusive buffer indices to the audio buffer. this.active = false; - this.canShift = moveable !== undefined ? moveable : true; - + this.container.classList.add("channel-wrapper"); this.container.style.left = this.leftOffset; @@ -140,7 +154,7 @@ TrackEditor.prototype.loadTrack = function(track) { cuein: track.cuein, cueout: track.cueout }, - track.moveable + track.states ); this.loadBuffer(track.src); @@ -244,7 +258,6 @@ TrackEditor.prototype.deactivate = function() { this.active = false; this.selectedArea = undefined; this.container.classList.remove("active"); - //this.drawer.draw(-1, this.getPixelOffset()); this.updateEditor(-1, undefined, undefined, true); }; @@ -261,10 +274,6 @@ TrackEditor.prototype.timeShift = function(e) { scroll = this.config.getTrackScroll(), scrollX = scroll.left; - if (this.canShift === false) { - return; //setting the 'left' css property has no effect, but don't want internal variable leftOffset to update. - } - origX = editor.leftOffset / res; //dynamically put an event on the element. @@ -530,12 +539,10 @@ TrackEditor.prototype.selectCursorPos = function(e) { }; TrackEditor.prototype.selectFadeIn = function(e) { - var editor = this, - startX = e.layerX || e.offsetX, //relative to e.target (want the canvas). - offset = this.leftOffset, - startTime, - endTime, - layerOffset; + var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas). + layerOffset, + FADETYPE = "FadeIn", + shape = this.config.getFadeType(); layerOffset = this.findLayerOffset(e); if (layerOffset < 0) { @@ -543,23 +550,16 @@ TrackEditor.prototype.selectFadeIn = function(e) { } startX = startX + layerOffset; - editor.setSelectedArea(undefined, startX); - startTime = editor.samplesToSeconds(offset + editor.selectedArea.start); - endTime = editor.samplesToSeconds(offset + editor.selectedArea.end); - - editor.updateEditor(-1, undefined, undefined, true); - editor.notifySelectUpdate(startTime, endTime); - - editor.activateAudioSelection(); + this.setSelectedArea(undefined, startX); + this.removeFadeType(FADETYPE); + this.createFade(FADETYPE, shape); }; TrackEditor.prototype.selectFadeOut = function(e) { - var editor = this, - startX = e.layerX || e.offsetX, //relative to e.target (want the canvas). - offset = this.leftOffset, - startTime, - endTime, - layerOffset; + var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas). + layerOffset, + FADETYPE = "FadeOut", + shape = this.config.getFadeType(); layerOffset = this.findLayerOffset(e); if (layerOffset < 0) { @@ -567,14 +567,9 @@ TrackEditor.prototype.selectFadeOut = function(e) { } startX = startX + layerOffset; - editor.setSelectedArea(startX, undefined); - startTime = editor.samplesToSeconds(offset + editor.selectedArea.start); - endTime = editor.samplesToSeconds(offset + editor.selectedArea.end); - - editor.updateEditor(-1, undefined, undefined, true); - editor.notifySelectUpdate(startTime, endTime); - - editor.activateAudioSelection(); + this.setSelectedArea(startX, undefined); + this.removeFadeType(FADETYPE); + this.createFade(FADETYPE, shape); }; /* end of state methods */ @@ -594,6 +589,21 @@ TrackEditor.prototype.saveFade = function(id, type, shape, start, end) { TrackEditor.prototype.removeFade = function(id) { delete this.fades[id]; + this.drawer.removeFade(id); +}; + +TrackEditor.prototype.removeFadeType = function(type) { + var id, + fades = this.fades, + fade; + + for (id in fades) { + fade = fades[id]; + + if (fade.type === type) { + this.removeFade(id); + } + } }; /* @@ -645,9 +655,8 @@ TrackEditor.prototype.onTrackEdit = function(event) { } }; -TrackEditor.prototype.onCreateFade = function(args) { +TrackEditor.prototype.createFade = function(type, shape) { var selected = this.selectedArea, - pixelOffset = this.getPixelOffset(), start = this.samplesToPixels(selected.start), end = this.samplesToPixels(selected.end), startTime = this.samplesToSeconds(selected.start), @@ -655,10 +664,13 @@ TrackEditor.prototype.onCreateFade = function(args) { id = this.getFadeId(); this.resetCursor(); - this.saveFade(id, args.type, args.shape, startTime, endTime); - this.drawer.draw(-1, pixelOffset); - this.drawer.drawFade(id, args.type, args.shape, start, end); + this.saveFade(id, type, shape, startTime, endTime); + this.updateEditor(-1, undefined, undefined, true); + this.drawer.drawFade(id, type, shape, start, end); +}; +TrackEditor.prototype.onCreateFade = function(args) { + this.createFade(args.type, args.shape); this.deactivateAudioSelection(); }; @@ -692,8 +704,10 @@ TrackEditor.prototype.onRemoveAudio = function() { TrackEditor.prototype.setState = function(state) { var that = this, - stateEvents = this.states[state].events, - stateClasses = this.states[state].classes, + stateEvents = this.events[state], + stateClasses = this.classes[state], + disabledClasses = this.classes['disabled'], + enabledStates = this.enabledStates, container = this.container, prevState = this.currentState, prevStateClasses, @@ -702,38 +716,45 @@ TrackEditor.prototype.setState = function(state) { i, len; if (prevState) { - prevStateClasses = this.states[prevState].classes; + prevStateClasses = this.classes[prevState]; - for (event in prevStateEvents) { - container.removeEventListener(event, prevStateEvents[event]); - } - this.prevStateEvents = {}; + if (enabledStates[prevState] === true) { + for (event in prevStateEvents) { + container.removeEventListener(event, prevStateEvents[event]); + } + this.prevStateEvents = {}; - for (i = 0, len = prevStateClasses.length; i < len; i++) { - container.classList.remove(prevStateClasses[i]); + for (i = 0, len = prevStateClasses.length; i < len; i++) { + container.classList.remove(prevStateClasses[i]); + } } + else { + for (i = 0, len = disabledClasses.length; i < len; i++) { + container.classList.remove(disabledClasses[i]); + } + } } - for (event in stateEvents) { - - func = that[stateEvents[event]].bind(that); - //need to keep track of the added events for later removal since a new function is returned after using "bind" - this.prevStateEvents[event] = func; - container.addEventListener(event, func); - } - for (i = 0, len = stateClasses.length; i < len; i++) { + if (enabledStates[state] === true) { + for (event in stateEvents) { + func = that[stateEvents[event]].bind(that); + //need to keep track of the added events for later removal since a new function is returned after using "bind" + this.prevStateEvents[event] = func; + container.addEventListener(event, func); + } + for (i = 0, len = stateClasses.length; i < len; i++) { container.classList.add(stateClasses[i]); } + } + else { + for (i = 0, len = disabledClasses.length; i < len; i++) { + container.classList.add(disabledClasses[i]); + } + } this.currentState = state; }; -TrackEditor.prototype.onStateChange = function() { - var state = this.config.getState(); - - this.setState(state); -}; - TrackEditor.prototype.onResolutionChange = function(res) { var selected = this.selectedArea; diff --git a/airtime_mvc/public/js/waveformplaylist/track_render.js b/airtime_mvc/public/js/waveformplaylist/track_render.js index 611dfcbc0..70736dab2 100644 --- a/airtime_mvc/public/js/waveformplaylist/track_render.js +++ b/airtime_mvc/public/js/waveformplaylist/track_render.js @@ -367,6 +367,22 @@ WaveformDrawer.prototype.drawFadeCurve = function(ctx, shape, type, width) { ctx.stroke(); }; +WaveformDrawer.prototype.removeFade = function(id) { + var fadeClass = "playlist-fade-"+id, + el, els, + i,len; + + els = this.container.getElementsByClassName(fadeClass); + len = els.length; + + //DOM NodeList is live, use a decrementing counter. + if (len > 0) { + for (i = len-1; i >= 0; i--) { + el = els[i]; + el.parentNode.removeChild(el); + } + } +}; WaveformDrawer.prototype.drawFade = function(id, type, shape, start, end) { var div,