diff --git a/bin/web/js/audio.js b/bin/web/js/audio.js index cf102e4..60b332a 100644 --- a/bin/web/js/audio.js +++ b/bin/web/js/audio.js @@ -56,42 +56,7 @@ const Audio = function(tp, record) { return true; }; - const getAudioMappingOptions = (layer, propTitle) => { - if (propTitle === 'color') { - if (config.audio.colorSeparateRGBA) { - const r = new AudioMappingOptions(); - const g = new AudioMappingOptions(); - const b = new AudioMappingOptions(); - const a = new AudioMappingOptions(); - return [{r}, {g}, {b}, {a}]; - } else { - const rgba = new AudioMappingOptions(); - rgba.min_out = {r: 0, b: 0, g: 0, a: 0}; - rgba.max_out = {r: 1, b: 1, g: 1, a: 1}; - return rgba; - } - } else { - const o = new AudioMappingOptions(); - // TODO: get min_out, max_out from layer.props - // check for typeof layer.props[propTitle.split('.')[0]] blabla - return o; - } - }; - - // potentially recursive - const addAudioMapping = (layer, propTitle, options = false) => { - if (!options) { - options = getAudioMappingOptions(layer, propTitle); - if (Array.isArray(options)) { - let isGood = true; - options.forEach((o) => { - const subPropKey = Object.keys(o)[0]; - const subPropTitle = `${propTitle}.${subPropKey}`; - isGood = addAudioMapping(layer, subPropTitle, o[subPropKey]) ? isGood : false; - }); - return isGood; - } - } + const addAudioMapping = (layer, propTitle, options = new AudioMappingOptions()) => { if (!mapping.hasOwnProperty(layer.id())) { mapping[layer.id()] = {}; } @@ -120,15 +85,6 @@ const Audio = function(tp, record) { } if (!mapping[layer.id()].hasOwnProperty(propTitle)) { // no propTitle - // perhaps color? - if (config.audio.separateRGBA && propTitle === 'color') { - let isGood = true; - isGood = removeAudioMapping(layer, 'color.r'); - isGood = removeAudioMapping(layer, 'color.g'); - isGood = removeAudioMapping(layer, 'color.b'); - isGood = removeAudioMapping(layer, 'color.a'); - return isGood; - } return false; } delete mapping[layer.id()][propTitle]; @@ -138,7 +94,21 @@ const Audio = function(tp, record) { return true; } - const createAudioOptions = (layer, propTitle, container) => { + const addAudioOptions = (layer, propTitle) => { + if (!started) { + // audioOptions need a started init + init(); + } + const panelPropTitle = tp.getPanelPropTitle(propTitle); + if (panelPropTitle === null) { + console.log('Audio::addAudioOptions::error',`cannot find panelPropTitle "${propTitle}"`); + return; + } + if (tp.getPanel().querySelector(toCssClass(`audioOptions${propTitle}`, '.')) !== null) { + //console.log('Audio::addAudioOptions::error',`audioOptions already exist for "${propTitle}"`); + return; + } + const container = panelPropTitle.parentNode.parentNode; const mappingOptions = mapping[layer.id()][propTitle]; const panel = tp.getPanel(); const audioOptions = document.createElement('div'); @@ -147,28 +117,7 @@ const Audio = function(tp, record) { audioOptions.classList.add(toCssClass(`audioOptions${propTitle}`)); audioOptions.style.position = 'relative'; audioOptions.style.width = '100%'; - if (propTitle.split('.')[0] === 'color' && propTitle.split('.').length > 1) { - switch(propTitle.split('.')[1]) { - case 'r': { - audioOptions.style.background = 'rgba(255,0,0,0.2)'; - break; - } - case 'g': { - audioOptions.style.background = 'rgba(0,255,0,0.2)'; - break; - } - case 'b': { - audioOptions.style.background = 'rgba(0,0,255,0.2)'; - break; - } - case 'a': { - audioOptions.style.background = 'rgba(255,255,255,0.2)'; - break; - } - } - } else { - audioOptions.style.background = 'rgba(0,255,255,0.2)'; - } + audioOptions.style.background = 'rgba(0,255,255,0.2)'; audioOptions.style.order = parseInt(container.style.order) + 1; const updateMappingOptions = () => { @@ -222,7 +171,7 @@ const Audio = function(tp, record) { sync_titleDom.innerHTML = 'sync with:'; sync_Dom.append(sync_titleDom); - audio_sync_options.forEach((o) => { + audio_sync_options.forEach((o, oi) => { const sync_inputDom_label = document.createElement('label'); sync_inputDom_label.for = `audio_sync${o}`; sync_inputDom_label.innerHTML = o; @@ -284,42 +233,16 @@ const Audio = function(tp, record) { freq_down = mapValue(e.clientX, bb.x, bb.x + bb.width, 0, config.audio.fftBandsUsed, true); }); + //removeAudioOptions(); container.after(audioOptions); - canvass.push(fft_imgDom); - canvasCtxs.push(fft_imgDom.getContext("2d")); - updateMappingOptions(); - return audioOptions; - }; - - const addAudioOptions = (layer, propTitle) => { - if (!started) { - // audioOptions need a started init - init(); - } - const panelPropTitle = tp.getPanelPropTitle(propTitle); - if (panelPropTitle === null) { - console.log('Audio::addAudioOptions::error',`cannot find panelPropTitle "${propTitle}"`); - return; - } - if (tp.getPanel().querySelector(toCssClass(`audioOptions${propTitle}`, '.')) !== null) { - //console.log('Audio::addAudioOptions::error',`audioOptions already exist for "${propTitle}"`); - return; - } - const container = panelPropTitle.parentNode.parentNode; - - if (propTitle === 'color' && config.audio.colorSeparateRGBA) { - // NOTE: attach reversed, because container.after(audioOptions) - createAudioOptions(layer, `${propTitle}.a`, container).classList.add(toCssClass(`audioOptions${propTitle}`)); - createAudioOptions(layer, `${propTitle}.b`, container).classList.add(toCssClass(`audioOptions${propTitle}`)); - createAudioOptions(layer, `${propTitle}.g`, container).classList.add(toCssClass(`audioOptions${propTitle}`)); - createAudioOptions(layer, `${propTitle}.r`, container).classList.add(toCssClass(`audioOptions${propTitle}`)); - } else { - createAudioOptions(layer, propTitle, container); - } - const audioButton = container.querySelector('.audioButton'); audioButton.classList.add('active'); + + canvass.push(fft_imgDom); + canvasCtxs.push(fft_imgDom.getContext("2d")); + + updateMappingOptions(); }; const removeAudioOptions = (layer = false, propTitle = false) => { @@ -338,9 +261,9 @@ const Audio = function(tp, record) { // only selected layers have options // otherwise the ui is not there if (layer.isSelected()) { - const audioOptions = panel.querySelectorAll(toCssClass(`audioOptions${propTitle}`,'.')); - if (audioOptions.length > 0) { - audioOptions.forEach((e) => { e.remove(); }); + const audioOptions = panel.querySelector(toCssClass(`audioOptions${propTitle}`,'.')); + if (audioOptions !== null) { + audioOptions.remove(); } const audioButton = panel.querySelector(toCssClass(`audioButton${propTitle}`,'.')); if (audioButton !== null) { @@ -477,7 +400,7 @@ const Audio = function(tp, record) { // Distortion curve for the waveshaper, thanks to Kevin Ennis // http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion - const makeDistortionCurve = (amount) => { + function makeDistortionCurve(amount) { let k = typeof amount === "number" ? amount : 50, n_samples = 44100, curve = new Float32Array(n_samples), @@ -556,7 +479,7 @@ const Audio = function(tp, record) { console.log("getUserMedia not supported on your browser!"); } - const visualize = () => { + function visualize() { const WIDTH = canvas.width; const HEIGHT = canvas.height; @@ -709,21 +632,18 @@ const Audio = function(tp, record) { }; }); Object.keys(values).forEach((layerID) => { - window.debugPreValues = clone(values[layerID]); deFlattenObject(values[layerID]); - window.debugValues = clone(values[layerID]); record.liveUpdater.immediateUpdate(getLayer(layerID), values[layerID]); }); } } else { - const position = tp.sheet.sequence.position; propsToSet.forEach((p) => { const title = tp - .getPanelPropTitle(p.title); + .getPanelPropTitle(p.title) + .parentNode.parentNode; if (title !== null) { const inputElement = title - .parentNode.parentNode .querySelector('input.recording'); if (inputElement !== null) { @@ -731,10 +651,6 @@ const Audio = function(tp, record) { inputElement.dispatchEvent(new Event('change')); } } - record.addValue(p.id, p.title, p.value, position); - if (!config.audio.colorSeparateRGBA || p.title === 'color.a') { - record.liveUpdate(p.layer, position); - } }); } } @@ -756,7 +672,7 @@ const Audio = function(tp, record) { } } - const voiceChange = () => { + function voiceChange() { distortion.oversample = "4x"; biquadFilter.gain.setTargetAtTime(0, audioCtx.currentTime, 0); diff --git a/bin/web/js/config.js b/bin/web/js/config.js index 6694181..85834e4 100644 --- a/bin/web/js/config.js +++ b/bin/web/js/config.js @@ -88,7 +88,6 @@ const config = { fftBandsAnalysed: 256 * 8, fftBandsUsed: 256 * 8 / 2, fftHeight: 256 / 2, - colorSeparateRGBA: true, }, record: { ignoreProps: ['transformOrigin', 'fontFamily', 'text', 'mirror_x', 'mirror_y', 'mirror_xy'], diff --git a/bin/web/js/record.js b/bin/web/js/record.js index 5ba73bc..dc7511c 100644 --- a/bin/web/js/record.js +++ b/bin/web/js/record.js @@ -49,7 +49,7 @@ const LiveBuffer = function() { subValueBuffer.delete(value_time_s); break; } - } + }; } }); } @@ -73,7 +73,7 @@ const LiveBuffer = function() { let mergedValues = {}; let didMergeValues = {}; valueBuffer[id].forEach((value, value_time_s) => { - if (value_time_s <= time_s) { + if (value_time_s < time_s) { mergedValues = {...mergedValues, ...value}; } else { if (Object.keys(didMergeValues).length === 0) { @@ -116,20 +116,7 @@ const LiveUpdater = function(tp, buffy) { } }; this.immediateUpdate = (layer, values) => { - const cv = clone(values); - if (cv.hasOwnProperty('color.r')) { - cv['color'] = { - r: cv['color.r'], - g: cv['color.g'], - b: cv['color.b'], - a: cv['color.a'], - }; - delete cv['color.r']; - delete cv['color.g']; - delete cv['color.b']; - delete cv['color.a']; - } - const v = {...layer.theatreObject.value, ...cv}; + const v = {...layer.theatreObject.value, ...values}; const p = layer.values2cppProps(v); if (p !== false) { const id = layer.id(); @@ -165,13 +152,8 @@ const Record = function(tp) { buffy.register(layerID); // handle UI only if layer is selected if (getLayer(layerID).isSelected()) { - let cPropTitle = clone(propTitle); - // if colors are separate, there is still just one button - if (cPropTitle.indexOf('color.') === 0) { - cPropTitle = 'color'; - } const button = tp - .getPanelPropTitle(cPropTitle) + .getPanelPropTitle(propTitle) .parentNode.parentNode .querySelector('.recordButton'); if (button !== null) { @@ -192,13 +174,8 @@ const Record = function(tp) { } // handle UI only if layer is selected if (getLayer(layerID).isSelected()) { - let cPropTitle = clone(propTitle); - // if colors are separate, there is still just one button - if (cPropTitle.indexOf('color.') === 0) { - cPropTitle = 'color'; - } const button = tp - .getPanelPropTitle(cPropTitle) + .getPanelPropTitle(propTitle) .parentNode.parentNode .querySelector('.recordButton'); if (button !== null) { @@ -333,44 +310,8 @@ const Record = function(tp) { }); }; - let lastPositions = {}; - const addValue = (layerID, - propTitle, - value, - position = tp.sheet.sequence.position, - lastPosition = buffy.NO_TIME) => { - hot[layerID][propTitle].recording.push({ - position, - value, - }); - const recording = { - [propTitle]: value, - }; - if (!lastPositions.hasOwnProperty(layerID)) { - lastPositions[layerID] = {}; - } - if (lastPosition === buffy.NO_TIME) { - if (!lastPositions[layerID].hasOwnProperty(propTitle)) { - lastPositions[layerID][propTitle] = position; - } - } else { - lastPositions[layerID][propTitle] = lastPosition; - } - buffy.addValues(layerID, recording, position, lastPositions[layerID][propTitle]); - }; - const getValue = (layerID, position) => { - const merged = clone(buffy.getValues(layerID, position)); - deFlattenObject(merged); - return merged; - }; - const liveUpdate = (layer, position = tp.sheet.sequence.position) => { - const merged = getValue(layer.id(), position); - liveUpdater.immediateUpdate(layer, merged); - }; - const startRecording = () => { console.log('Record::startRecording'); - lastPositions = {}; tp.sheet.sequence.pause(); const layerKeys = Object.keys(hot); layerKeys.forEach((layerID) => { @@ -383,14 +324,22 @@ const Record = function(tp) { const input_clone = cloneInput(layerID, propTitle); let lastPosition = buffy.NO_TIME; if (input_clone !== null) { - //input_clone.addEventListener('change', () => { - //const position = tp.sheet.sequence.position; - //const value = parseFloat(input_clone.value); - //addValue(layerID, propTitle, value, position, lastPosition); - //const merged = getValue(layerID, position); - //liveUpdater.immediateUpdate(layer, merged); - //lastPosition = position; - //}); + input_clone.addEventListener('change', (e) => { + const position = tp.sheet.sequence.position; + const value = parseFloat(input_clone.value); + hot[layerID][propTitle].recording.push({ + position, + value, + }); + const recording = { + [propTitle]: value, + }; + buffy.addValues(layerID, recording, position, lastPosition); + const merged = clone(buffy.getValues(layerID, position)); + deFlattenObject(merged); + liveUpdater.immediateUpdate(layer, merged); + lastPosition = position; + }); } else { console.log('Record::startRecording', `whoops input_clone for ${propTitle} is null`); } @@ -424,39 +373,12 @@ const Record = function(tp) { // NOTE: layerID is not actually used atm // and should be the layer anyways uncloneInput(layerID, propTitle); - // special treatment if we have sperate RGBA for color - if (propTitle.indexOf('color.') === 0) { - if (propTitle === 'color.r') { - const recording = []; - hot[layerID]['color.r'].recording.forEach((rr, ri) => { - if (ri < hot[layerID]['color.r'].recording.length && - ri < hot[layerID]['color.g'].recording.length && - ri < hot[layerID]['color.b'].recording.length && - ri < hot[layerID]['color.a'].recording.length) { - const r = clone(rr); - r.value = { - r: hot[layerID]['color.r'].recording[ri].value, - g: hot[layerID]['color.g'].recording[ri].value, - b: hot[layerID]['color.b'].recording[ri].value, - a: hot[layerID]['color.a'].recording[ri].value, - }; - recording.push(r); - } - }); - keyframes.push({ - path: ['color'], - keyframes: recording, - }); - } - } else { - keyframes.push({ - path: propTitle.split('.'), - keyframes: hot[layerID][propTitle].recording, - }); - } + keyframes.push({ + path: propTitle.split('.'), + keyframes: hot[layerID][propTitle].recording, + }); }); //setTimeout(() => { - const kf = clone(keyframes); promises.push(() => { return new Promise((subResolve) => { tp.setKeyframes(layer, keyframes).then(() => { @@ -482,9 +404,6 @@ const Record = function(tp) { }; // public - this.addValue = addValue; - this.getValue = getValue; - this.liveUpdate = liveUpdate; this.liveUpdater = liveUpdater; this.addRecordButton = addRecordButton; this.addHot = addHot; diff --git a/bin/web/js/utils.js b/bin/web/js/utils.js index 958ce23..f7d04a6 100644 --- a/bin/web/js/utils.js +++ b/bin/web/js/utils.js @@ -347,7 +347,7 @@ function verifyVariableTimeProject(vt_project) { function clone(a) { return JSON.parse(JSON.stringify(a)); -} +}; function getParents(elem, until = null) { const parents = []; @@ -461,11 +461,7 @@ const deFlattenObject = (o, ignoreKeys = [], pathSymbol = '.') => { for (let i = ks.length - 1; i > 0; i--) { sos = {[ks[i]]: sos}; } - if (typeof o[ks[0]] === 'object') { - o[ks[0]] = {...o[ks[0]], ...sos}; - } else { - o[ks[0]] = sos; - } + o[ks[0]] = sos; delete o[k]; } }