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