Compare commits

..

No commits in common. "f8984174e0948ff64cef7e54e827be54d36c5fe6" and "7f6ab572c7626f845194e60419c0a562e199bc72" have entirely different histories.

6 changed files with 543 additions and 742 deletions

View file

@ -5,36 +5,10 @@ import {
window.mapValue = mapValue; window.mapValue = mapValue;
const AudioMappingOptions = function() {
this.freq_min = 0.0;
this.freq_max = config.audio.fftBandsUsed;
this.min_out = 0.0;
this.max_out = 1.0;
this.smoothing = config.audio.defaultSmoothing;
this.sync = 'volume';
this.value = 0.0;
};
const Audio = function(tp, record) { const Audio = function(tp, record) {
const audioDom = document.querySelector('.audioWrapper'); const audioDom = document.querySelector('.audioWrapper');
let audioCtx = false;
const heading = audioDom.querySelector("h1"); const heading = audioDom.querySelector("h1");
heading.textContent = "CLICK HERE TO START"; heading.textContent = "CLICK HERE TO START";
// an array of possible sync options.
const audio_sync_options = ['volume', 'pitch', 'frequency'];
// could also be an enum
// like that
//const AudioSyncOptions = Object.freeze({
//RED: Symbol("volume"),
//BLUE: Symbol("pitch"),
//GREEN: Symbol("frequency"),
//toString: (e) => {
//return e.toString.match(/\(([\S\s]*)\)/)[1]
//},
//});
//document.body.addEventListener("click", init); //document.body.addEventListener("click", init);
let started = false; let started = false;
@ -42,66 +16,14 @@ const Audio = function(tp, record) {
const canvass = []; const canvass = [];
const canvasCtxs = []; const canvasCtxs = [];
const isMapped = (layer, propTitle) => {
if (!mapping.hasOwnProperty(layer.id())) {
return false;
}
if (!mapping[layer.id()].hasOwnProperty(propTitle)) {
return false;
}
return true;
};
const addAudioMapping = (layer, propTitle, options = new AudioMappingOptions()) => {
if (!mapping.hasOwnProperty(layer.id())) {
mapping[layer.id()] = {};
}
if (!mapping[layer.id()].hasOwnProperty(propTitle)) {
mapping[layer.id()][propTitle] = options;
return true;
} else {
// already there
return false;
}
};
const removeAudioMapping = (layer = false, propTitle = false) => {
if (!layer && !propTitle) {
Object.keys(mapping).forEach((layerID) => {
Object.keys(mapping[layerID]).forEach((propTitle) => {
delete mapping[layerID][propTitle];
});
delete mapping[layerID];
});
return true;
}
if (!mapping.hasOwnProperty(layer.id())) {
// no layer
return false;
}
if (!mapping[layer.id()].hasOwnProperty(propTitle)) {
// no propTitle
return false;
}
delete mapping[layer.id()][propTitle];
if (Object.keys(mapping[layer.id()]).length === 0) {
delete mapping[layer.id()];
}
return true;
}
const addAudioOptions = (layer, propTitle) => { const addAudioOptions = (layer, propTitle) => {
if (!started) {
// audioOptions need a started init
init();
}
const panelPropTitle = tp.getPanelPropTitle(propTitle); const panelPropTitle = tp.getPanelPropTitle(propTitle);
if (panelPropTitle === null) { if (panelPropTitle === null) {
console.log('Audio::addAudioOptions::error',`cannot find panelPropTitle "${propTitle}"`); console.log('Audio::addAudioOptions::error',`cannot find panelPropTitle "${propTitle}"`);
return; return;
} }
if (tp.getPanel().querySelector(`.audioOptions${propTitle}`) !== null) { if (tp.getPanel().querySelector(`.audioOptions${propTitle}`) !== null) {
//console.log('Audio::addAudioOptions::error',`audioOptions already exist for "${propTitle}"`); console.log('Audio::addAudioOptions::error',`audioOptions already exist for "${propTitle}"`);
return; return;
} }
const container = tp.getPanelPropContainer(panelPropTitle); const container = tp.getPanelPropContainer(panelPropTitle);
@ -116,6 +38,9 @@ const Audio = function(tp, record) {
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; audioOptions.style.order = parseInt(container.style.order) + 1;
mappingOptions.freq_min = 0;
mappingOptions.freq_max = config.audio.fftBandsUsed;
const updateMappingOptions = () => { const updateMappingOptions = () => {
mappingOptions.min_out = parseFloat(panel.querySelector(`#audio_min${propTitle}`).value); mappingOptions.min_out = parseFloat(panel.querySelector(`#audio_min${propTitle}`).value);
mappingOptions.max_out = parseFloat(panel.querySelector(`#audio_max${propTitle}`).value); mappingOptions.max_out = parseFloat(panel.querySelector(`#audio_max${propTitle}`).value);
@ -134,7 +59,7 @@ const Audio = function(tp, record) {
min_inputDom.type = 'number'; min_inputDom.type = 'number';
min_inputDom.name = `audio_min${propTitle}`; min_inputDom.name = `audio_min${propTitle}`;
min_inputDom.id = `audio_min${propTitle}`; min_inputDom.id = `audio_min${propTitle}`;
min_inputDom.value = `${mappingOptions.min_out}`; min_inputDom.value = '0';
const max_inputDom_label = document.createElement('label'); const max_inputDom_label = document.createElement('label');
max_inputDom_label.for = 'audio_max'; max_inputDom_label.for = 'audio_max';
max_inputDom_label.innerHTML = 'audio_max'; max_inputDom_label.innerHTML = 'audio_max';
@ -142,7 +67,7 @@ const Audio = function(tp, record) {
max_inputDom.type = 'number'; max_inputDom.type = 'number';
max_inputDom.name = `audio_max${propTitle}`; max_inputDom.name = `audio_max${propTitle}`;
max_inputDom.id = `audio_max${propTitle}`; max_inputDom.id = `audio_max${propTitle}`;
max_inputDom.value = `${mappingOptions.max_out}`; max_inputDom.value = '255';
const smoothing_inputDom_label = document.createElement('label'); const smoothing_inputDom_label = document.createElement('label');
smoothing_inputDom_label.for = 'audio_smoothing'; smoothing_inputDom_label.for = 'audio_smoothing';
smoothing_inputDom_label.innerHTML = 'audio_smoothing'; smoothing_inputDom_label.innerHTML = 'audio_smoothing';
@ -150,7 +75,7 @@ const Audio = function(tp, record) {
smoothing_inputDom.type = 'number'; smoothing_inputDom.type = 'number';
smoothing_inputDom.name = `audio_smoothing${propTitle}`; smoothing_inputDom.name = `audio_smoothing${propTitle}`;
smoothing_inputDom.id = `audio_smoothing${propTitle}`; smoothing_inputDom.id = `audio_smoothing${propTitle}`;
smoothing_inputDom.value = mappingOptions.smoothing; smoothing_inputDom.value = config.audio.defaultSmoothing;
smoothing_inputDom.min = 0; smoothing_inputDom.min = 0;
smoothing_inputDom.max = 1; smoothing_inputDom.max = 1;
smoothing_inputDom.step = 0.01; smoothing_inputDom.step = 0.01;
@ -167,7 +92,8 @@ const Audio = function(tp, record) {
sync_titleDom.innerHTML = 'sync with:'; sync_titleDom.innerHTML = 'sync with:';
sync_Dom.append(sync_titleDom); sync_Dom.append(sync_titleDom);
audio_sync_options.forEach((o, oi) => { const sync_options = ['volume', 'pitch', 'frequency'];
sync_options.forEach((o, oi) => {
const sync_inputDom_label = document.createElement('label'); const sync_inputDom_label = document.createElement('label');
sync_inputDom_label.for = `audio_sync${o}`; sync_inputDom_label.for = `audio_sync${o}`;
sync_inputDom_label.innerHTML = o; sync_inputDom_label.innerHTML = o;
@ -177,7 +103,7 @@ const Audio = function(tp, record) {
sync_inputDom.id = `audio_sync${propTitle}${o}`; sync_inputDom.id = `audio_sync${propTitle}${o}`;
sync_inputDom.value = o; sync_inputDom.value = o;
// default select first option // default select first option
if (o === mappingOptions.sync) { if (oi === 0) {
sync_inputDom.checked = '1'; sync_inputDom.checked = '1';
} }
sync_Dom.append(sync_inputDom_label); sync_Dom.append(sync_inputDom_label);
@ -232,40 +158,27 @@ const Audio = function(tp, record) {
//removeAudioOptions(); //removeAudioOptions();
container.after(audioOptions); container.after(audioOptions);
const audioButton = container.querySelector('.audioButton');
audioButton.classList.add('active');
canvass.push(fft_imgDom); canvass.push(fft_imgDom);
canvasCtxs.push(fft_imgDom.getContext("2d")); canvasCtxs.push(fft_imgDom.getContext("2d"));
updateMappingOptions(); updateMappingOptions();
mappingOptions.value = mappingOptions.min_out;
}; };
const removeAudioOptions = (layer = false, propTitle = false) => { const removeAudioOptions = (propTitle = '') => {
const panel = tp.getPanel(); const panel = tp.getPanel();
if (!layer && !propTitle) { if (propTitle === '') {
const allAudioOptions = panel.querySelectorAll('.audioOptions'); const otherAudioOptions = panel.querySelectorAll('.audioOptions');
if (allAudioOptions !== null) { if (otherAudioOptions !== null) {
for (let i = 0; i < allAudioOptions.length; i++) { for (let i = 0; i < otherAudioOptions.length; i++) {
allAudioOptions[i].remove(); otherAudioOptions[i].remove();
} }
} }
panel.querySelectorAll('.audioButton').forEach((button) => {
button.classList.remove('active');
});
} else { } else {
// only selected layers have options
// otherwise the ui is not there
if (layer.isSelected()) {
const audioOptions = panel.querySelector(`.audioOptions${propTitle}`); const audioOptions = panel.querySelector(`.audioOptions${propTitle}`);
if (audioOptions !== null) { if (audioOptions !== null) {
audioOptions.remove(); audioOptions.remove();
} }
const audioButton = panel.querySelector(`.audioButton${propTitle}`);
if (audioButton !== null) {
audioButton.classList.remove('active');
}
}
} }
}; };
@ -292,16 +205,24 @@ const Audio = function(tp, record) {
if (!started) { if (!started) {
init(); init();
} }
if (!isMapped(layer, propTitle)) { if (!mapping.hasOwnProperty(layer.id())) {
addAudioMapping(layer, propTitle); mapping[layer.id()] = {};
}
if (!mapping[layer.id()].hasOwnProperty(propTitle)) {
mapping[layer.id()][propTitle] = {};
button.classList.add('active');
addAudioOptions(layer, propTitle); addAudioOptions(layer, propTitle);
} else { } else {
removeAudioMapping(layer, propTitle); delete mapping[layer.id()][propTitle];
removeAudioOptions(layer, propTitle); if (Object.keys(mapping[layer.id()]).length === 0) {
delete mapping[layer.id()];
}
button.classList.remove('active');
removeAudioOptions(propTitle);
} }
}); });
if (isActive) { if (isActive) {
addAudioMapping(layer, propTitle); button.classList.add('active');
addAudioOptions(layer, propTitle); addAudioOptions(layer, propTitle);
} }
} }
@ -326,13 +247,8 @@ const Audio = function(tp, record) {
}); });
}; };
const init = () => { function init() {
if (!started) {
started = true; started = true;
if (audioCtx !== false && audioCtx.state === 'suspended') {
audioCtx.resume();
return;
}
heading.textContent = "Voice-change-O-matic"; heading.textContent = "Voice-change-O-matic";
//document.body.removeEventListener("click", init); //document.body.removeEventListener("click", init);
@ -369,7 +285,7 @@ const Audio = function(tp, record) {
// Set up forked web audio context, for multiple browsers // Set up forked web audio context, for multiple browsers
// window. is needed otherwise Safari explodes // window. is needed otherwise Safari explodes
audioCtx = new(window.AudioContext || window.webkitAudioContext)(); const audioCtx = new(window.AudioContext || window.webkitAudioContext)();
const voiceSelect = audioDom.querySelector("#voice"); const voiceSelect = audioDom.querySelector("#voice");
let source; let source;
let stream; let stream;
@ -576,7 +492,7 @@ const Audio = function(tp, record) {
if (mapping.hasOwnProperty(layer.id())) { if (mapping.hasOwnProperty(layer.id())) {
Object.keys(mapping[layer.id()]).forEach((propTitle) => { Object.keys(mapping[layer.id()]).forEach((propTitle) => {
const m = mapping[layer.id()][propTitle]; const m = mapping[layer.id()][propTitle];
switch (m.sync) { switch(m.sync) {
case 'volume': { case 'volume': {
let a = mapValue(max_v, 0, 255, m.min_out, m.max_out, true); let a = mapValue(max_v, 0, 255, m.min_out, m.max_out, true);
m.value = m.value * m.smoothing + (1.0 - m.smoothing) * a; m.value = m.value * m.smoothing + (1.0 - m.smoothing) * a;
@ -590,7 +506,7 @@ const Audio = function(tp, record) {
break; break;
} }
case 'pitch': { case 'pitch': {
let a = mapValue(max_i, 0, bufferLengthAlt - 1, m.min_out, m.max_out, true); let a = mapValue(max_i, 0, bufferLengthAlt-1, m.min_out, m.max_out, true);
m.value = m.value * m.smoothing + (1.0 - m.smoothing) * a; m.value = m.value * m.smoothing + (1.0 - m.smoothing) * a;
propsToSet.push({ propsToSet.push({
layer, layer,
@ -604,7 +520,8 @@ const Audio = function(tp, record) {
default: default:
break; break;
} }
if (m.sync === 'volume') {} if (m.sync === 'volume') {
}
}); });
} }
}); });
@ -629,21 +546,10 @@ const Audio = function(tp, record) {
} }
}; };
} }
let values = {};
propsToSet.forEach((p) => { propsToSet.forEach((p) => {
const newValues = { immediateUpdate(p.layer, {
[p.title]: p.value [p.title]: p.value
};
if (!values.hasOwnProperty(p.id)) {
values[p.id] = {};
}
values[p.id] = {
...values[p.id],
...newValues,
};
}); });
Object.keys(values).forEach((layerID) => {
immediateUpdate(getLayer(layerID), values[layerID]);
}); });
} }
} else { } else {
@ -777,28 +683,10 @@ const Audio = function(tp, record) {
} }
} }
} }
}
const deinit = () => {
if (started) {
if (audioCtx !== false) {
audioCtx.suspend();
}
started = false;
}
};
this.getContext = () => {
return audioCtx;
};
this.init = init; this.init = init;
this.deinit = deinit;
this.injectPanel = injectPanel; this.injectPanel = injectPanel;
this.mapping = mapping; this.mapping = mapping;
this.addAudioMapping = addAudioMapping;
this.removeAudioMapping = removeAudioMapping;
this.addAudioOptions = addAudioOptions;
this.removeAudioOptions = removeAudioOptions;
this.AudioMappingOptions = AudioMappingOptions;
}; };
export { export {

View file

@ -91,7 +91,6 @@ const config = {
}, },
record: { record: {
ignoreProps: ['fontVariationAxes','letterDelays','color'], ignoreProps: ['fontVariationAxes','letterDelays','color'],
recordMapped: true,
}, },
midi: { midi: {
touchTimeThreshold_s: 0.5, touchTimeThreshold_s: 0.5,

View file

@ -188,6 +188,7 @@ window.onload = () => {
alert('Sorry, Variable Time is a tool currently designed to be used on desktop!'); alert('Sorry, Variable Time is a tool currently designed to be used on desktop!');
} }
window.addEventListener('panelEvent', (e) => { window.addEventListener('panelEvent', (e) => {
console.log('debug panelEvent received', e);
clearTimeout(window.panelFinderTimeout); clearTimeout(window.panelFinderTimeout);
let target = false; let target = false;
if (e.detail.panelID === 'artboard') { if (e.detail.panelID === 'artboard') {
@ -203,6 +204,7 @@ window.onload = () => {
} }
}); });
window.addEventListener('sequenceEvent', (e) => { window.addEventListener('sequenceEvent', (e) => {
console.log('debug sequenceEvent received', e);
let target = false; let target = false;
if (e.detail.panelID === 'artboard') { if (e.detail.panelID === 'artboard') {
target = artboard; target = artboard;

View file

@ -137,7 +137,7 @@ const Record = function(tp) {
return hot.hasOwnProperty(layerID) return hot.hasOwnProperty(layerID)
&& hot[layerID].hasOwnProperty(propTitle); && hot[layerID].hasOwnProperty(propTitle);
}; };
const addHot = (layerID, propTitle) => { const makeHot = (layerID, propTitle) => {
if (!isHot(layerID, propTitle)) { if (!isHot(layerID, propTitle)) {
if (!hot.hasOwnProperty(layerID)) { if (!hot.hasOwnProperty(layerID)) {
hot[layerID] = {}; hot[layerID] = {};
@ -146,37 +146,12 @@ const Record = function(tp) {
recording: [], recording: [],
}; };
} }
buffy.register(layerID);
// handle UI only if layer is selected
if (getLayer(layerID).isSelected()) {
const button = tp const button = tp
.getPanelPropContainer(propTitle) .getPanelPropContainer(propTitle)
.querySelector('.recordButton'); .querySelector('.recordButton');
if (button !== null) { if (button !== null) {
button.classList.add('active'); button.classList.add('active');
} }
}
};
const removeHot = (layerID, propTitle) => {
if (isHot(layerID, propTitle)) {
delete hot[layerID][propTitle];
}
// what if it is the last prop in the layer
if (hot.hasOwnProperty(layerID)) {
if (Object.keys(hot[layerID]).length === 0) {
delete hot[layerID];
buffy.deregister(layerID);
}
}
// handle UI only if layer is selected
if (getLayer(layerID).isSelected()) {
const button = tp
.getPanelPropContainer(propTitle)
.querySelector('.recordButton');
if (button !== null) {
button.classList.remove('active');
}
}
}; };
//const makeNotHot = (layerID, propTitle) => { //const makeNotHot = (layerID, propTitle) => {
//if (isHot(layerID, propTitle)) { //if (isHot(layerID, propTitle)) {
@ -206,27 +181,21 @@ const Record = function(tp) {
if(isRecording) { if(isRecording) {
stopRecording(); stopRecording();
} else { } else {
if (config.record.recordMapped) {
// make all mapped props hot and
Object.keys(audio.mapping) Object.keys(audio.mapping)
.forEach((layerID) => { .forEach((layerID) => {
if (getLayer(layerID).isSelected()) { if (getLayer(layerID).isSelected()) {
Object.keys(audio.mapping[layerID]) Object.keys(audio.mapping[layerID])
.forEach((propTitle) => { .forEach((propTitle) => {
addHot(layerID, propTitle); makeHot(layerID, propTitle);
}); });
buffy.register(layerID);
} }
}); });
} else {
// only make this propTitle hot and
// register its layer for recording
addHot(layer.id(), propTitle);
}
startRecording(); startRecording();
} }
}); });
//console.log("Record::addRecordButton", console.log("Record::addRecordButton",
//`added a record button for ${propTitle}`); `added a record button for ${propTitle}`);
} }
} else { } else {
console.log("Record::addRecordButton", console.log("Record::addRecordButton",
@ -304,7 +273,6 @@ const Record = function(tp) {
}; };
const startRecording = () => { const startRecording = () => {
console.log('Record::startRecording');
tp.sheet.sequence.pause(); tp.sheet.sequence.pause();
const layerKeys = Object.keys(hot); const layerKeys = Object.keys(hot);
layerKeys.forEach((layerID) => { layerKeys.forEach((layerID) => {
@ -328,12 +296,11 @@ const Record = function(tp) {
[propTitle]: value, [propTitle]: value,
}; };
buffy.addValues(layerID, recording, position, lastPosition); buffy.addValues(layerID, recording, position, lastPosition);
const merged = buffy.getValues(layerID, position); liveUpdater.immediateUpdate(layer, recording);
liveUpdater.immediateUpdate(layer, merged);
lastPosition = position; lastPosition = position;
}); });
} else { } else {
console.log('Record::startRecording', `whoops input_clone for ${propTitle} is null`); console.log('whoops input_clone is null');
} }
}); });
tp.sheet.sequence.position = 0; tp.sheet.sequence.position = 0;
@ -343,7 +310,11 @@ const Record = function(tp) {
}; };
const stopRecording = () => { const stopRecording = () => {
return new Promise((resolve) => { return new Promise((resolve) => {
console.log('stoprecording');
const layerKeys = Object.keys(hot); const layerKeys = Object.keys(hot);
console.log('stopRecording', 'layerKeys', {
layerKeys
}, 'hot', JSON.stringify(hot));
const promises = []; const promises = [];
promises.push(() => { promises.push(() => {
return new Promise((subResolve) => { return new Promise((subResolve) => {
@ -358,19 +329,23 @@ const Record = function(tp) {
}); });
}); });
layerKeys.forEach((layerID) => { layerKeys.forEach((layerID) => {
console.log('stopRecording', layerID);
const layer = getLayer(layerID); const layer = getLayer(layerID);
const propTitles = Object.keys(hot[layerID]); const propTitles = Object.keys(hot[layerID]);
const keyframes = []; const keyframes = [];
propTitles.forEach((propTitle) => { propTitles.forEach((propTitle) => {
console.log('stopRecording', propTitle);
// NOTE: layerID is not actually used atm // NOTE: layerID is not actually used atm
// and should be the layer anyways // and should be the layer anyways
uncloneInput(layerID, propTitle); uncloneInput(layerID, propTitle);
console.log('stopRecording', 'should have uncloned input for ' + propTitle);
keyframes.push({ keyframes.push({
path: [propTitle], path: [propTitle],
keyframes: hot[layerID][propTitle].recording, keyframes: hot[layerID][propTitle].recording,
}); });
}); });
//setTimeout(() => { //setTimeout(() => {
console.log('stopRecording', 'adding the keyframes now because we wnat it to happen right now please', keyframes);
promises.push(() => { promises.push(() => {
return new Promise((subResolve) => { return new Promise((subResolve) => {
tp.setKeyframes(layer, keyframes).then(() => { tp.setKeyframes(layer, keyframes).then(() => {
@ -383,12 +358,17 @@ const Record = function(tp) {
}); });
sequencialPromises(promises, () => { sequencialPromises(promises, () => {
Object.keys(hot).forEach((layerID) => { Object.keys(hot).forEach((layerID) => {
Object.keys(hot[layerID]).forEach((propTitle) => {
removeHot(layerID, propTitle);
});
buffy.deregister(layerID); buffy.deregister(layerID);
Object.keys(hot[layerID]).forEach((propTitle) => {
delete hot[layerID][propTitle];
if (Object.keys(hot[layerID]).length === 0) {
delete hot[layerID];
}
const button = tp.getPanel().querySelector(`.recordButton${propTitle}`);
button.classList.remove('active');
}); });
console.log('Record::stopRecording', 'stopped recording'); });
console.log('stopRecording', 'absolutely stopped recording');
isRecording = false; isRecording = false;
resolve(); resolve();
}); });
@ -397,8 +377,6 @@ const Record = function(tp) {
// public // public
this.addRecordButton = addRecordButton; this.addRecordButton = addRecordButton;
this.addHot = addHot;
this.removeHot = removeHot;
this.getHot = () => { this.getHot = () => {
return hot; return hot;
}; };

View file

@ -135,53 +135,32 @@ const TheatrePlay = function(autoInit = false) {
return keyframes; return keyframes;
}; };
const getSequenceButton = (path) => { const getSequenceButton = (path) => {
let t = getPanelPropTitle(Array.isArray(path) ? path.join('.') : path); let t = getPanelPropTitle(path.join('.'));
if (t === null) { if (t === null) {
return null; return null;
} }
return t.parentElement.querySelector('[title="Sequence this prop"]'); return t.parentElement.querySelector('[title="Sequence this prop"]');
}; };
const isSequenced = (path) => {
return getSequenceButton(path) === null;
};
const setSequenced = (propTitle, sequenced, metaResolve = false) => { const setSequenced = (propTitle, sequenced) => {
const f = (resolve) => { return new Promise((resolve) => {
const propIsSequenced = isSequenced(propTitle);
const somethingToDo = sequenced !== propIsSequenced;
if (somethingToDo) {
const contextItem = sequenced ? 'sequence' : 'make static'; const contextItem = sequenced ? 'sequence' : 'make static';
const antiContextItem = sequenced ? 'make static' : 'sequence'; const antiContextItem = sequenced ? 'make static' : 'sequence';
const finishedSequencedEvent = (e) => { const finishedSequencedEvent = (e) => {
// only care about events from our prop tp.getPanel().removeEventListener('injected', finishedSequencedEvent);
if (propTitle === e.detail.prop.join('.')) { console.log('debug FINISHED SEQUENCED EVENT', e, propTitle);
// if we un-sequence, we listen to stateEditors' event
if (!sequenced && e.detail.origin === 'stateEditors.ts' && e.detail.sequenced === sequenced) {
window.removeEventListener('sequenceEvent', finishedSequencedEvent);
resolve(true); resolve(true);
// if we sequence, then we wait until the track is there
} else if (sequenced && e.detail.origin === 'BasicKeyframedTrack.tsx' && e.detail.sequenced === sequenced) {
window.removeEventListener('sequenceEvent', finishedSequencedEvent);
resolve(true);
} else {
console.log('TheatrePlayu::setSequenced', 'ignored event', e, e.detail);
}
}
}; };
let counter = 0; const clickContextMenu = () => {
const clickContextMenu = (e) => {
let done = false; let done = false;
if (e.target !== null) { tp.getPanelPropTitle(propTitle).removeEventListener('contextmenu', clickContextMenu);
e.target.removeEventListener('contextmenu', clickContextMenu);
}
tp.shadowRoot.querySelectorAll('ul li span').forEach((s) => { tp.shadowRoot.querySelectorAll('ul li span').forEach((s) => {
if (s.innerHTML.toLowerCase() === contextItem.toLowerCase()) { if (s.innerHTML.toLowerCase() === contextItem.toLowerCase()) {
window.addEventListener('sequenceEvent', finishedSequencedEvent); tp.getPanel().addEventListener('injected', finishedSequencedEvent);
s.click(); s.click();
console.log('debug click');
done = true; done = true;
} else if (s.innerHTML.toLowerCase() === antiContextItem.toLowerCase()) { } else if (s.innerHTML.toLowerCase() === antiContextItem.toLowerCase()) {
done = true; done = true;
@ -190,29 +169,14 @@ const TheatrePlay = function(autoInit = false) {
}); });
if (!done) { if (!done) {
setTimeout(() => { setTimeout(() => {
if (counter < 4) { clickContextMenu();
clickContextMenu(e);
counter++;
} else {
setSequenced(propTitle, sequenced, resolve);
}
}, 100); }, 100);
} }
}; };
getPanelPropTitle(propTitle).addEventListener('contextmenu', clickContextMenu); getPanelPropTitle(propTitle).addEventListener('contextmenu', clickContextMenu);
getPanelPropTitle(propTitle).dispatchEvent(new Event('contextmenu')); getPanelPropTitle(propTitle).dispatchEvent(new Event('contextmenu'));
} else {
resolve();
}
};
if (!metaResolve) {
return new Promise((resolve) => {
f(resolve);
}); });
} else {
f(metaResolve);
}
}; };
const addKeyframes = (layer, keyframes) => { const addKeyframes = (layer, keyframes) => {
@ -223,42 +187,37 @@ const TheatrePlay = function(autoInit = false) {
} }
const existingKeyframes = getKeyframes(layer); const existingKeyframes = getKeyframes(layer);
const promises = []; const promises = [];
const ms = 0; //config.tp.addKeyframesTimeout_s * 1000; const ms = 0;//config.tp.addKeyframesTimeout_s * 1000;
keyframes.forEach((k) => { keyframes.forEach((k) => {
let prop = layer.theatreObject.props; let prop = layer.theatreObject.props;
for (let i = 0; i < k.path.length; i++) { for (let i = 0; i < k.path.length; i++) {
prop = prop[k.path[i]]; prop = prop[k.path[i]];
} }
const position = tp.sheet.sequence.position; const position = tp.sheet.sequence.position;
promises.push(() => { // NOTE: can we sequence values without pretend clicking?
return new Promise((subResolve) => { const sequenceButton = getSequenceButton(k.path);
if (sequenceButton !== null) {
promises.push(() => { return new Promise((subResolve) => {
setTimeout(() => { setTimeout(() => {
if (layer.isSelected()) { sequenceButton.click();
setSequenced(k.path.join('.'), true) const detectSE = (e) => {
.then(() => { if (e.detail.panelID === layer.id()) {
subResolve(); window.removeEventListener('sequenceEvent',detectSE);
}); console.log('received sequenceEvent',e);
} else { const f = (e) => {
// we cannot select layers without pseudoclicking
// so let's wait for a happy 'injected' event that
// closes off the selection
//
// first, the listener callback
const f = () => {
tp.getPanel().removeEventListener('injected', f); tp.getPanel().removeEventListener('injected', f);
setSequenced(k.path.join('.'), true)
.then(() => {
subResolve(); subResolve();
});
}; };
// then add it
tp.getPanel().addEventListener('injected', f); tp.getPanel().addEventListener('injected', f);
// and fire the click
layer.select();
} }
}, ms); // * promises.length); };
}) window.addEventListener('sequenceEvent', detectSE);
}); }, ms);// * promises.length);
})});
} else {
//console.error(k.path, 'did not find sequence button');
// is (probably) already sequenced
}
let propHasKeyframesAt = -1; let propHasKeyframesAt = -1;
if (existingKeyframes !== null && if (existingKeyframes !== null &&
existingKeyframes !== false && existingKeyframes !== false &&
@ -281,8 +240,7 @@ const TheatrePlay = function(autoInit = false) {
}); });
} }
if (!alreadyThere) { if (!alreadyThere) {
promises.push(() => { promises.push(() => { return new Promise((subResolve) => {
return new Promise((subResolve) => {
setTimeout(() => { setTimeout(() => {
tp.sheet.sequence.position = keyframe.position; tp.sheet.sequence.position = keyframe.position;
this.studio.transaction(({ this.studio.transaction(({
@ -291,19 +249,16 @@ const TheatrePlay = function(autoInit = false) {
set(prop, keyframe.value); set(prop, keyframe.value);
subResolve(); subResolve();
}); });
}, ms); // * promises.length); }, ms);// * promises.length);
}) })});
});
} }
}); });
promises.push(() => { promises.push(() => { return new Promise((subResolve) => {
return new Promise((subResolve) => {
setTimeout(() => { setTimeout(() => {
tp.sheet.sequence.position = position; tp.sheet.sequence.position = position;
subResolve(); subResolve();
}, ms); // * promises.length); }, ms);// * promises.length);
}) })});
});
}); });
sequencialPromises(promises, resolve); sequencialPromises(promises, resolve);
//Promise.all(promises).then(() => { //Promise.all(promises).then(() => {
@ -318,27 +273,18 @@ const TheatrePlay = function(autoInit = false) {
return false; return false;
} }
const promises = []; const promises = [];
let waitify = false;
keyframes.forEach((k) => { keyframes.forEach((k) => {
promises.push(new Promise((subResolve) => {
const propTitle = k.path.join('.'); const propTitle = k.path.join('.');
if (isSequenced(propTitle)) {
waitify = true;
promises.push(() => {
return new Promise((subResolve) => {
setSequenced(propTitle, false) setSequenced(propTitle, false)
.then(subResolve);
}));
});
Promise
.all(promises)
.then(() => { .then(() => {
subResolve();
});
});
});
}
});
sequencialPromises(promises, () => {
const timeout_ms = waitify ? 1000 : 0;
setTimeout(() => {
addKeyframes(layer, keyframes) addKeyframes(layer, keyframes)
.then(resolve); .then(resolve);
}, timeout_ms);
}); });
}); });
}; };
@ -412,8 +358,6 @@ const TheatrePlay = function(autoInit = false) {
// remove object from objects list // remove object from objects list
delete theatreObjects[name]; delete theatreObjects[name];
}; };
this.isSequenced = isSequenced;
this.getSequenceButton = getSequenceButton;
this.getSequencePanelLeft = getSequencePanelLeft; this.getSequencePanelLeft = getSequencePanelLeft;
this.getPanel = getPanel; this.getPanel = getPanel;
this.getPanelPropTitle = getPanelPropTitle; this.getPanelPropTitle = getPanelPropTitle;

View file

@ -395,21 +395,11 @@ const isMobile = () => {
return false; return false;
}; };
// NOTE:
// promises must be delivered inside a function like:
//
// const promises = [];
//
// promises.push(() => { return new Promise((resolve) => { console.log('lalala ONE'); resolve() }); });
// promises.push(() => { return new Promise((resolve) => { console.log('lalala TWO'); resolve() }); });
// promises.push(() => { return new Promise((resolve) => { console.log('lalala THREE'); resolve() }); });
//
// sequencialPromises(promises, () => { console.log('i am done'); });
const sequencialPromises = async (iterable, callback = false) => { const sequencialPromises = async (iterable, callback = false) => {
for (const x of iterable) { for (const x of iterable) {
await x(); await x();
} }
if (typeof callback === 'function') { if (callback !== false) {
callback(); callback();
} }
}; };