diff --git a/assets/template.html b/assets/template.html index 0869efc..1f6a2bc 100644 --- a/assets/template.html +++ b/assets/template.html @@ -296,6 +296,7 @@ + diff --git a/bin/em/variabletime/web/js/audio.js b/bin/em/variabletime/web/js/audio.js index dfebbb8..77557e2 100644 --- a/bin/em/variabletime/web/js/audio.js +++ b/bin/em/variabletime/web/js/audio.js @@ -329,6 +329,7 @@ const Audio = function(tp, record) { source_Dom.id = toCssClass(`audio_source${propTitle}`); const source_mic = document.createElement('option'); source_mic.value = 'microphone'; + source_mic.title = 'microphone'; source_mic.innerHTML = 'microphone'; source_Dom.append(source_mic); let selectedSource = 'microphone'; @@ -345,6 +346,7 @@ const Audio = function(tp, record) { source_file.setAttribute('selected','true'); } source_file.value = file; + source_file.title = file; if (file.length > config.audio.maxFilenameLength) { source_file.innerHTML = file.substr(0,6) + '..' + file.substr(file.length - 6, 6); } else { @@ -670,7 +672,6 @@ const Audio = function(tp, record) { } }; const addAudio = (layer, propTitle) => { - console.log('adding audio for', layer, propTitle); if (!started) { init(); } @@ -1160,11 +1161,23 @@ const Audio = function(tp, record) { //} } else { const position = tp.sheet.sequence.position; + let values = {}; propsToSet.forEach((p) => { const title = tp .getPanelPropTitle(p.title); const layer = getLayer(p.id); + const newValues = { + [p.title]: p.value + }; + if (!values.hasOwnProperty(p.id)) { + values[p.id] = {}; + } + values[p.id] = { + ...values[p.id], + ...newValues, + }; + if (title !== null) { const inputElement = title .parentNode.parentNode @@ -1175,14 +1188,21 @@ const Audio = function(tp, record) { inputElement.dispatchEvent(new Event('change')); } } - record.addValue(p.id, p.title, p.value, position); - if (p.title.indexOf('color') === 0) { - if (!config.audio.colorSeparateRGBA || p.title === 'color.a') { - record.liveUpdate(layer, position); - } - } else { - record.liveUpdate(layer, position); + if (record.isHot(p.id, p.title)) { + record.addValue(p.id, p.title, p.value, position); } + // NOTE: liveUpdate does not work if the layer is not registered + //if (p.title.indexOf('color') === 0) { + //if (!config.audio.colorSeparateRGBA || p.title === 'color.a') { + //record.liveUpdate(layer, position); + //} + //} else { + //record.liveUpdate(layer, position); + //} + }); + Object.keys(values).forEach((layerID) => { + deFlattenObject(values[layerID]); + record.liveUpdater.immediateUpdate(getLayer(layerID), values[layerID]); }); } } diff --git a/bin/em/variabletime/web/js/layer.js b/bin/em/variabletime/web/js/layer.js index 5df00d1..0825822 100644 --- a/bin/em/variabletime/web/js/layer.js +++ b/bin/em/variabletime/web/js/layer.js @@ -101,7 +101,6 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { let axes = fontsAndAxes[selectedFontIndex].axes; if (axes.length > 0) { let variationAxes = {}; - //let doThese = []; for (let a = 0; a < axes.length; a++) { const sanity_minMax = axes[a].minValue < axes[a].maxValue; const sanity_minDefault = axes[a].minValue <= axes[a].defaultValue; @@ -110,31 +109,11 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { variationAxes[axes[a].name] = tp.core.types.number(axes[a].defaultValue, { range: [axes[a].minValue, axes[a].maxValue], }); - //if (typeof audio === 'object' && - //typeof audio.getSavedMapping() === 'object' && - //typeof audio.getSavedMapping()[this.id()] === 'object' && - //typeof audio.getSavedMapping()[this.id()][`fontVariationAxes.${axes[a].name}`] === 'object' && - //typeof audio.getMapping() === 'object' && - //typeof audio.getMapping()[this.id()] === 'object' && - //typeof audio.getMapping()[this.id()][`fontVariationAxes.${axes[a].name}`] === 'object' && - //tp.getPanel() !== null) { - ////doThese.push(() => { - ////audio.removeAudioOptions(this, `fontVariationAxes.${axes[a].name}`); - ////audio.removeAudioMapping(this, `fontVariationAxes.${axes[a].name}`); - ////audio.getSavedMapping()[this.id()][`fontVariationAxes.${axes[a].name}`].min_out = axes[a].minValue; - ////audio.getSavedMapping()[this.id()][`fontVariationAxes.${axes[a].name}`].max_out = axes[a].maxValue; - ////audio.addAudioMapping(this, `fontVariationAxes.${axes[a].name}`); - ////audio.addAudioOptions(this, `fontVariationAxes.${axes[a].name}`); - ////}); - //} } else { console.log('js::layer::selectFont', 'this axis is insane, abort', axes[a]); } } props.fontVariationAxes = tp.core.types.compound(variationAxes); - //doThese.forEach((d) => { - //d(); - //}); } else { delete props.fontVariationAxes; } @@ -149,26 +128,21 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { return new Promise((resolve) => { // NOTE: stupid hack, seems that theatrejs tries to be too smart // detecting if reconfiguring the object is necessary. - // file bug report and test in future versions. + // file bug report and test in future versions? // // this overcomplicates some of our code though.. urgh.. // btw, we need a dummy property // this does not work //tp.changeObject(this.id(), {}); - //tp.changeObject(this.id(), {dummy:true}); - //updateTheatrePropsTimeout = setTimeout(() => { tp.changeObject(this.id(), {dummy: true}); setTimeout(() => { tp.changeObject(this.id(), props); setTimeout(() => { - //updateTheatrePropsTimeout = false; - //this.afterUpdateTheatrePropsCallback(); this.findInjectPanel(); resolve(); }, 100); }, 100); - //}, 100); }); }; const getDefaultFont = (selectableFonts) => { @@ -299,28 +273,19 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { const showBoundingBoxDiv = (boundingBox = false) => { const boundingBoxDivId = `boundingBox-${this.id()}`; - //const layerBoxDivId = `layerBox-${this.id()}`; if (document.querySelector(`#${boundingBoxDivId}`) === null) { if (boundingBox === false) { boundingBox = Module.getBoundingBox(this.id()); } const artboard = window.getArtboard(); const boundingBoxDiv = document.createElement('div'); - //const layerBoxDiv = document.createElement('div'); boundingBoxDiv.id = boundingBoxDivId; boundingBoxDiv.style.position = 'fixed'; boundingBoxDiv.style.background = 'transparent'; boundingBoxDiv.style.border = '1px dashed dimgrey'; boundingBoxDiv.style.boxSizing = 'border-box'; - //layerBoxDiv.id = layerBoxDivId; - //layerBoxDiv.style.position = 'fixed'; - //layerBoxDiv.style.background = 'transparent'; - //layerBoxDiv.style.border = '1px solid green'; - //layerBoxDiv.style.boxSizing = 'border-box'; - document.getElementById('body').append(boundingBoxDiv); - //document.getElementById('body').append(layerBoxDiv); clearInterval(boundingBoxInterval); boundingBoxInterval = setInterval(() => { updateBoundingBoxDiv(); @@ -335,7 +300,6 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { if (bb !== null) { bb.remove(); } - //document.getElementById(`layerBox-${this.id()}`).remove(); clearInterval(boundingBoxInterval); boundingBoxInterval = false; }; @@ -449,7 +413,6 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { mom.append(upButton); mom.append(downButton); mom.append(removeButton); - //window.layerOrder.add(this.id()); panel.addEventListener('mouseover', showBoundingBoxDiv); panel.addEventListener('mouseout', hideBoundingBoxDiv); @@ -715,8 +678,6 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { const alignButtonsHorizontal = panel.querySelector('.alignButtonsHorizontal'); const alignButtonsVertical = panel.querySelector('.alignButtonsVertical'); - //panelControlsWrapper.add(alignButtonsHorizontal); - //panelControlsWrapper.add(alignButtonsVertical); // first get previous textAlign buttons, // if they are already there @@ -774,23 +735,6 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { } togglePanelProp('width', this.theatreObject.value.width > 0, false); - let bottomButtonsContainer = panel.querySelector('.bottomButtonsContainer'); - if (bottomButtonsContainer === null) { - bottomButtonsContainer = document.createElement('div'); - bottomButtonsContainer.classList.add("bottomButtonsContainer"); - panel.append(bottomButtonsContainer); - } - if (bottomButtonsContainer.querySelector('.vte_button') === null) { - const addFontButton = document.createElement('div'); - addFontButton.classList.add('vte_button'); - addFontButton.style.cursor = 'pointer'; - addFontButton.innerHTML = "add Font"; - addFontButton.addEventListener('click', (clickEvent) => { - addUserFont(); - }); - bottomButtonsContainer.append(addFontButton); - } - doItAgain = false; clearTimeout(panelFinderTimeout); panelFinderTimeout = false; @@ -865,43 +809,6 @@ const Layer = function(tp, layerID, fontsAndAxes, autoInit = true) { } return letterDelays.hasOwnProperty(prop[0]); }; - const addUserFont = () => { - return new Promise((resolve, reject) => { - uploadFile('font') - .then((fontFile) => { - moduleFS - .save(fontFile) - .then(() => { - getFontsAndAxes() - .then((newFontsAndAxes) => { - // let's select the new uploaded font - if (newFontsAndAxes.length > 0) { - const path = newFontsAndAxes[0].fontPath; - this.selectFont(path); - // we need to update theatreprops - // a bit awkwardly twice - // - // first like this - this.updateTheatreProps() - .then(() => { - // and again with a transaction - const hash = props.fontFamily.default; - tp.studio.transaction(({ - set - }) => { - set(this.theatreObject.props.fontFamily, hash); - }); - this.findInjectPanel(); - resolve(); - }); - } else { - reject(); - } - }); - }); - }); - }); - }; this.handleSequenceEvent = (detail, updateTheatre = true) => { return new Promise((resolve) => { tp.friendlySequenceNames(); diff --git a/bin/em/variabletime/web/js/main.js b/bin/em/variabletime/web/js/main.js index 3f519a0..95d8617 100644 --- a/bin/em/variabletime/web/js/main.js +++ b/bin/em/variabletime/web/js/main.js @@ -186,6 +186,11 @@ const findInjectPanel = () => { bottomButtonsContainer.append(startNewButton); startNewButton.classList.add("main_panel_button"); } + const addFontButton = document.querySelector('#add_font'); + if (addFontButton !== null) { + bottomButtonsContainer.append(addFontButton); + addFontButton.classList.add("main_panel_button"); + } } else { setTimeout(() => { findInjectPanel(); @@ -600,4 +605,52 @@ const initPanels = () => { }); }); } + let addFontButton = document.querySelector('#add_font'); + if (addFontButton === null) { + addFontButton = tp.getPanel().querySelector('#add_font'); + } + if (addFontButton !== null) { + addFontButton.addEventListener('click', () => { + addUserFont(); + }); + } }; + +const addUserFont = () => { + uploadFile('font') + .then((fontFile) => { + moduleFS + .save(fontFile) + .then(() => { + getFontsAndAxes() + .then((newFontsAndAxes) => { + // let's select the new uploaded font + // if we have a layer selected + const layer = getLayer(); + if (layer.id().indexOf('layer-') === 0 && newFontsAndAxes.length > 0) { + const path = newFontsAndAxes[0].fontPath; + layer.selectFont(path); + // we need to update theatreprops + // a bit awkwardly twice + // + // first like this + layer.updateTheatreProps() + .then(() => { + // and again with a transaction + const hash = layer.props.fontFamily.default; + tp.studio.transaction(({ + set + }) => { + set(layer.theatreObject.props.fontFamily, hash); + }); + layer.findInjectPanel(); + resolve(); + }); + } else { + reject(); + } + }); + }); + }); +}; +window.addUserFont = addUserFont; diff --git a/bin/em/variabletime/web/js/record.js b/bin/em/variabletime/web/js/record.js index 8a601a5..924a538 100644 --- a/bin/em/variabletime/web/js/record.js +++ b/bin/em/variabletime/web/js/record.js @@ -177,8 +177,10 @@ const Record = function(tp) { }; const isHot = (layerID, propTitle) => { - return hot.hasOwnProperty(layerID) - && hot[layerID].hasOwnProperty(propTitle); + return typeof hot[layerID] === 'object' + && typeof hot[layerID][propTitle] === 'object'; + //return hot.hasOwnProperty(layerID) + //&& hot[layerID].hasOwnProperty(propTitle); }; const addHot = (layerID, propTitle) => { if (!isHot(layerID, propTitle)) { @@ -303,12 +305,13 @@ const Record = function(tp) { // only make these propTitles hot and // register their layer for recording propPaths.forEach((p) => { + if (typeof p === 'string') { + p = p.split('.'); + } if (Array.isArray(p)) { const layerID = p[0]; const propTitle = p.slice(1).join('.'); addHot(layerID, propTitle); - } else if (typeof p === 'string') { - console.error('not implemented yet, so sorry'); } }); } @@ -401,6 +404,7 @@ const Record = function(tp) { hot[layerID][propTitle].recording.push({ position, value, + type: 'linear', }); const recording = { [propTitle]: value, @@ -596,6 +600,7 @@ const Record = function(tp) { this.liveUpdate = liveUpdate; this.liveUpdater = liveUpdater; this.addRecordButton = addRecordButton; + this.isHot = isHot; this.addHot = addHot; this.removeHot = removeHot; this.getHot = () => { diff --git a/bin/em/variabletime/web/js/utils.js b/bin/em/variabletime/web/js/utils.js index de2bef2..f9f3424 100644 --- a/bin/em/variabletime/web/js/utils.js +++ b/bin/em/variabletime/web/js/utils.js @@ -115,14 +115,12 @@ function uploadFile(expectedType = 'application/json') { if (files.length == 0) return; const file = files[0]; - console.log('file', file); let reader = new FileReader(); if (expectedType === 'application/zip' || file.type === 'application/zip' || file.type.indexOf('audio') === 0) { reader.onload = (e) => { const f = e.target.result; - console.log(e, file.name, file.size, file.type, f); resolve({ name: file.name, size: file.size, @@ -136,7 +134,6 @@ function uploadFile(expectedType = 'application/json') { reader.readAsArrayBuffer(file); } else if (expectedType === 'application/json') { reader.onload = (e) => { - console.log(e); const f = e.target.result; // This is a regular expression to identify carriage @@ -156,12 +153,9 @@ function uploadFile(expectedType = 'application/json') { reader.readAsText(file); } else if (expectedType.indexOf('font') >= 0) { - console.log('expect font'); reader.onload = (e) => { - console.log(e); const f = e.target.result; if (file.type.indexOf('font') >= 0) { - console.log('is font'); //var uint8View = new Uint8Array(f); //console.log('trying to save the font file, file, uint8View', file, uint8View); //FS.createDataFile(config.fs.idbfsFontDir, file.name, uint8View, true, true); @@ -182,7 +176,6 @@ function uploadFile(expectedType = 'application/json') { type: file.type, arrayBuffer: f }; - console.log({outputFile}); resolve(outputFile); } else { reject('not a font'); diff --git a/lightclean.sh b/lightclean.sh index d0d7842..39d678a 100755 --- a/lightclean.sh +++ b/lightclean.sh @@ -7,7 +7,7 @@ cd $DIR project=$(basename $DIR) -rm -rf bin/$project* +rm -rf bin/em/$project/index.* rm -rf bin/data/ofxMsdfgen rm -rf bin/data/ofxGPUFont cp -r ../../../addons/ofxMsdfgen/data/ofxMsdfgen ./bin/data/ diff --git a/watch.sh b/watch.sh index 6992ea4..7ac35b0 100755 --- a/watch.sh +++ b/watch.sh @@ -5,6 +5,6 @@ PREVIOUS_DIR=$(pwd) cd $DIR -echo "$(git ls-files src && git ls-files bin/data)" | entr -d ./rebuild.sh +echo "$(git ls-files src && git ls-files bin/data && echo "assets/template.html")" | entr -d ./rebuild.sh cd $PREVIOUS_DIR