@dawcore/components 0.0.20 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.mts +30 -24
- package/dist/index.d.ts +30 -24
- package/dist/index.js +711 -470
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +699 -458
- package/dist/index.mjs.map +1 -1
- package/package.json +24 -15
package/dist/index.js
CHANGED
|
@@ -1252,8 +1252,8 @@ DawStopButtonElement = __decorateClass([
|
|
|
1252
1252
|
], DawStopButtonElement);
|
|
1253
1253
|
|
|
1254
1254
|
// src/elements/daw-editor.ts
|
|
1255
|
-
var
|
|
1256
|
-
var
|
|
1255
|
+
var import_lit15 = require("lit");
|
|
1256
|
+
var import_decorators13 = require("lit/decorators.js");
|
|
1257
1257
|
|
|
1258
1258
|
// src/types.ts
|
|
1259
1259
|
function isDomClip(desc) {
|
|
@@ -1732,10 +1732,268 @@ var PeakPipeline = class {
|
|
|
1732
1732
|
}
|
|
1733
1733
|
};
|
|
1734
1734
|
|
|
1735
|
-
// src/elements/daw-
|
|
1735
|
+
// src/elements/daw-ruler.ts
|
|
1736
1736
|
var import_lit11 = require("lit");
|
|
1737
1737
|
var import_decorators10 = require("lit/decorators.js");
|
|
1738
|
-
|
|
1738
|
+
|
|
1739
|
+
// src/utils/time-format.ts
|
|
1740
|
+
function formatTime(milliseconds) {
|
|
1741
|
+
const seconds = Math.floor(milliseconds / 1e3);
|
|
1742
|
+
const s = seconds % 60;
|
|
1743
|
+
const m = (seconds - s) / 60;
|
|
1744
|
+
return `${m}:${String(s).padStart(2, "0")}`;
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
// src/utils/smart-scale.ts
|
|
1748
|
+
var timeinfo = /* @__PURE__ */ new Map([
|
|
1749
|
+
[700, { marker: 1e3, bigStep: 500, smallStep: 100 }],
|
|
1750
|
+
[1500, { marker: 2e3, bigStep: 1e3, smallStep: 200 }],
|
|
1751
|
+
[2500, { marker: 2e3, bigStep: 1e3, smallStep: 500 }],
|
|
1752
|
+
[5e3, { marker: 5e3, bigStep: 1e3, smallStep: 500 }],
|
|
1753
|
+
[1e4, { marker: 1e4, bigStep: 5e3, smallStep: 1e3 }],
|
|
1754
|
+
[12e3, { marker: 15e3, bigStep: 5e3, smallStep: 1e3 }],
|
|
1755
|
+
[Infinity, { marker: 3e4, bigStep: 1e4, smallStep: 5e3 }]
|
|
1756
|
+
]);
|
|
1757
|
+
function getScaleInfo(samplesPerPixel) {
|
|
1758
|
+
for (const [resolution, config] of timeinfo) {
|
|
1759
|
+
if (samplesPerPixel < resolution) {
|
|
1760
|
+
return config;
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
return { marker: 3e4, bigStep: 1e4, smallStep: 5e3 };
|
|
1764
|
+
}
|
|
1765
|
+
function computeTemporalTicks(samplesPerPixel, sampleRate, duration, rulerHeight) {
|
|
1766
|
+
const widthX = Math.ceil(duration * sampleRate / samplesPerPixel);
|
|
1767
|
+
const config = getScaleInfo(samplesPerPixel);
|
|
1768
|
+
const { marker, bigStep, smallStep } = config;
|
|
1769
|
+
const canvasInfo = /* @__PURE__ */ new Map();
|
|
1770
|
+
const labels = [];
|
|
1771
|
+
const pixPerSec = sampleRate / samplesPerPixel;
|
|
1772
|
+
for (let counter = 0; ; counter += smallStep) {
|
|
1773
|
+
const pix = Math.floor(counter / 1e3 * pixPerSec);
|
|
1774
|
+
if (pix >= widthX) break;
|
|
1775
|
+
if (counter % marker === 0) {
|
|
1776
|
+
canvasInfo.set(pix, rulerHeight);
|
|
1777
|
+
labels.push({ pix, text: formatTime(counter) });
|
|
1778
|
+
} else if (counter % bigStep === 0) {
|
|
1779
|
+
canvasInfo.set(pix, Math.floor(rulerHeight / 2));
|
|
1780
|
+
} else if (counter % smallStep === 0) {
|
|
1781
|
+
canvasInfo.set(pix, Math.floor(rulerHeight / 5));
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
return { widthX, canvasInfo, labels };
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
// src/utils/musical-tick-cache.ts
|
|
1788
|
+
var import_core = require("@waveform-playlist/core");
|
|
1789
|
+
var cachedParams = null;
|
|
1790
|
+
var cachedResult = null;
|
|
1791
|
+
function meterEntriesMatch(a, b) {
|
|
1792
|
+
if (a.length !== b.length) return false;
|
|
1793
|
+
for (let i = 0; i < a.length; i++) {
|
|
1794
|
+
if (a[i].tick !== b[i].tick || a[i].numerator !== b[i].numerator || a[i].denominator !== b[i].denominator)
|
|
1795
|
+
return false;
|
|
1796
|
+
}
|
|
1797
|
+
return true;
|
|
1798
|
+
}
|
|
1799
|
+
function paramsMatch(a, b) {
|
|
1800
|
+
return a.ticksPerPixel === b.ticksPerPixel && a.startPixel === b.startPixel && a.endPixel === b.endPixel && meterEntriesMatch(a.meterEntries, b.meterEntries) && (a.ppqn ?? 960) === (b.ppqn ?? 960);
|
|
1801
|
+
}
|
|
1802
|
+
function getCachedMusicalTicks(params) {
|
|
1803
|
+
if (cachedParams && cachedResult && paramsMatch(cachedParams, params)) {
|
|
1804
|
+
return cachedResult;
|
|
1805
|
+
}
|
|
1806
|
+
cachedResult = (0, import_core.computeMusicalTicks)(params);
|
|
1807
|
+
cachedParams = {
|
|
1808
|
+
...params,
|
|
1809
|
+
meterEntries: params.meterEntries.map((e) => ({ ...e }))
|
|
1810
|
+
};
|
|
1811
|
+
return cachedResult;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
// src/elements/daw-ruler.ts
|
|
1815
|
+
var MAX_CANVAS_WIDTH3 = 1e3;
|
|
1816
|
+
var DawRulerElement = class extends import_lit11.LitElement {
|
|
1817
|
+
constructor() {
|
|
1818
|
+
super(...arguments);
|
|
1819
|
+
this.samplesPerPixel = 1024;
|
|
1820
|
+
this.sampleRate = 48e3;
|
|
1821
|
+
this.duration = 0;
|
|
1822
|
+
this.rulerHeight = 30;
|
|
1823
|
+
this.scaleMode = "temporal";
|
|
1824
|
+
this.ticksPerPixel = 4;
|
|
1825
|
+
this.meterEntries = [
|
|
1826
|
+
{ tick: 0, numerator: 4, denominator: 4 }
|
|
1827
|
+
];
|
|
1828
|
+
this.ppqn = 960;
|
|
1829
|
+
this.totalWidth = 0;
|
|
1830
|
+
this._tickData = null;
|
|
1831
|
+
this._musicalTickData = null;
|
|
1832
|
+
}
|
|
1833
|
+
willUpdate() {
|
|
1834
|
+
if (this.scaleMode === "beats" && this.totalWidth > 0) {
|
|
1835
|
+
this._musicalTickData = getCachedMusicalTicks({
|
|
1836
|
+
meterEntries: this.meterEntries,
|
|
1837
|
+
ticksPerPixel: this.ticksPerPixel,
|
|
1838
|
+
startPixel: 0,
|
|
1839
|
+
endPixel: this.totalWidth,
|
|
1840
|
+
ppqn: this.ppqn
|
|
1841
|
+
});
|
|
1842
|
+
this._tickData = null;
|
|
1843
|
+
} else if (this.duration > 0 || this.totalWidth > 0) {
|
|
1844
|
+
const widthDerivedDuration = this.totalWidth * this.samplesPerPixel / this.sampleRate;
|
|
1845
|
+
const effectiveDuration = Math.max(this.duration, widthDerivedDuration);
|
|
1846
|
+
this._musicalTickData = null;
|
|
1847
|
+
this._tickData = computeTemporalTicks(
|
|
1848
|
+
this.samplesPerPixel,
|
|
1849
|
+
this.sampleRate,
|
|
1850
|
+
effectiveDuration,
|
|
1851
|
+
this.rulerHeight
|
|
1852
|
+
);
|
|
1853
|
+
} else {
|
|
1854
|
+
this._musicalTickData = null;
|
|
1855
|
+
this._tickData = null;
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
render() {
|
|
1859
|
+
const widthX = this.scaleMode === "beats" ? this.totalWidth : this._tickData?.widthX ?? 0;
|
|
1860
|
+
if (widthX <= 0) return import_lit11.html``;
|
|
1861
|
+
const totalChunks = Math.ceil(widthX / MAX_CANVAS_WIDTH3);
|
|
1862
|
+
const indices = Array.from({ length: totalChunks }, (_, i) => i);
|
|
1863
|
+
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
1864
|
+
const beatsLabels = this.scaleMode === "beats" ? this._musicalTickData?.ticks.filter((t) => t.label) ?? [] : [];
|
|
1865
|
+
const temporalLabels = this.scaleMode !== "beats" ? this._tickData?.labels ?? [] : [];
|
|
1866
|
+
return import_lit11.html`
|
|
1867
|
+
<div class="container" style="width: ${widthX}px; height: ${this.rulerHeight}px;">
|
|
1868
|
+
${indices.map((i) => {
|
|
1869
|
+
const width = Math.min(MAX_CANVAS_WIDTH3, widthX - i * MAX_CANVAS_WIDTH3);
|
|
1870
|
+
return import_lit11.html`
|
|
1871
|
+
<canvas
|
|
1872
|
+
data-index=${i}
|
|
1873
|
+
width=${width * dpr}
|
|
1874
|
+
height=${this.rulerHeight * dpr}
|
|
1875
|
+
style="left: ${i * MAX_CANVAS_WIDTH3}px; width: ${width}px; height: ${this.rulerHeight}px;"
|
|
1876
|
+
></canvas>
|
|
1877
|
+
`;
|
|
1878
|
+
})}
|
|
1879
|
+
${this.scaleMode === "beats" ? beatsLabels.map(
|
|
1880
|
+
(t) => import_lit11.html`<span
|
|
1881
|
+
class="label ${t.pixel > 0 ? "centered" : ""}"
|
|
1882
|
+
style="left: ${t.pixel > 0 ? t.pixel : t.pixel + 4}px;"
|
|
1883
|
+
>${t.label}</span
|
|
1884
|
+
>`
|
|
1885
|
+
) : temporalLabels.map(
|
|
1886
|
+
({ pix, text }) => import_lit11.html`<span class="label" style="left: ${pix + 4}px;">${text}</span>`
|
|
1887
|
+
)}
|
|
1888
|
+
</div>
|
|
1889
|
+
`;
|
|
1890
|
+
}
|
|
1891
|
+
updated() {
|
|
1892
|
+
this._drawTicks();
|
|
1893
|
+
}
|
|
1894
|
+
_drawTicks() {
|
|
1895
|
+
const canvases = this.shadowRoot?.querySelectorAll("canvas");
|
|
1896
|
+
if (!canvases) return;
|
|
1897
|
+
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
1898
|
+
const rulerColor = getComputedStyle(this).getPropertyValue("--daw-ruler-color").trim() || "#c49a6c";
|
|
1899
|
+
const widthX = this.scaleMode === "beats" ? this.totalWidth : this._tickData?.widthX ?? 0;
|
|
1900
|
+
for (const canvas of canvases) {
|
|
1901
|
+
const idx = Number(canvas.dataset.index);
|
|
1902
|
+
const ctx = canvas.getContext("2d");
|
|
1903
|
+
if (!ctx) continue;
|
|
1904
|
+
const canvasWidth = Math.min(MAX_CANVAS_WIDTH3, widthX - idx * MAX_CANVAS_WIDTH3);
|
|
1905
|
+
const globalOffset = idx * MAX_CANVAS_WIDTH3;
|
|
1906
|
+
ctx.resetTransform();
|
|
1907
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
1908
|
+
ctx.scale(dpr, dpr);
|
|
1909
|
+
ctx.strokeStyle = rulerColor;
|
|
1910
|
+
ctx.lineWidth = 1;
|
|
1911
|
+
if (this.scaleMode === "beats" && this._musicalTickData) {
|
|
1912
|
+
const h = this.rulerHeight;
|
|
1913
|
+
for (const tick of this._musicalTickData.ticks) {
|
|
1914
|
+
const localX = tick.pixel - globalOffset;
|
|
1915
|
+
if (localX < 0 || localX >= canvasWidth) continue;
|
|
1916
|
+
const tickH = tick.type === "major" ? h * 0.6 : tick.type === "minor" ? h * 0.35 : h * 0.15;
|
|
1917
|
+
ctx.globalAlpha = tick.type === "major" ? 1 : 0.5;
|
|
1918
|
+
ctx.beginPath();
|
|
1919
|
+
ctx.moveTo(localX + 0.5, h);
|
|
1920
|
+
ctx.lineTo(localX + 0.5, h - tickH);
|
|
1921
|
+
ctx.stroke();
|
|
1922
|
+
}
|
|
1923
|
+
ctx.globalAlpha = 1;
|
|
1924
|
+
} else if (this._tickData) {
|
|
1925
|
+
for (const [pix, height] of this._tickData.canvasInfo) {
|
|
1926
|
+
const localX = pix - globalOffset;
|
|
1927
|
+
if (localX < 0 || localX >= canvasWidth) continue;
|
|
1928
|
+
ctx.beginPath();
|
|
1929
|
+
ctx.moveTo(localX + 0.5, this.rulerHeight);
|
|
1930
|
+
ctx.lineTo(localX + 0.5, this.rulerHeight - height);
|
|
1931
|
+
ctx.stroke();
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
};
|
|
1937
|
+
DawRulerElement.styles = import_lit11.css`
|
|
1938
|
+
:host {
|
|
1939
|
+
display: block;
|
|
1940
|
+
position: relative;
|
|
1941
|
+
background: var(--daw-ruler-background, #0f0f1a);
|
|
1942
|
+
}
|
|
1943
|
+
.container {
|
|
1944
|
+
position: relative;
|
|
1945
|
+
}
|
|
1946
|
+
canvas {
|
|
1947
|
+
position: absolute;
|
|
1948
|
+
top: 0;
|
|
1949
|
+
}
|
|
1950
|
+
.label {
|
|
1951
|
+
position: absolute;
|
|
1952
|
+
font-size: 0.7rem;
|
|
1953
|
+
line-height: 1;
|
|
1954
|
+
white-space: nowrap;
|
|
1955
|
+
color: var(--daw-ruler-color, #c49a6c);
|
|
1956
|
+
top: 1px;
|
|
1957
|
+
}
|
|
1958
|
+
.label.centered {
|
|
1959
|
+
transform: translateX(-50%);
|
|
1960
|
+
}
|
|
1961
|
+
`;
|
|
1962
|
+
__decorateClass([
|
|
1963
|
+
(0, import_decorators10.property)({ type: Number, attribute: false })
|
|
1964
|
+
], DawRulerElement.prototype, "samplesPerPixel", 2);
|
|
1965
|
+
__decorateClass([
|
|
1966
|
+
(0, import_decorators10.property)({ type: Number, attribute: false })
|
|
1967
|
+
], DawRulerElement.prototype, "sampleRate", 2);
|
|
1968
|
+
__decorateClass([
|
|
1969
|
+
(0, import_decorators10.property)({ type: Number, attribute: false })
|
|
1970
|
+
], DawRulerElement.prototype, "duration", 2);
|
|
1971
|
+
__decorateClass([
|
|
1972
|
+
(0, import_decorators10.property)({ type: Number, attribute: false })
|
|
1973
|
+
], DawRulerElement.prototype, "rulerHeight", 2);
|
|
1974
|
+
__decorateClass([
|
|
1975
|
+
(0, import_decorators10.property)({ type: String, attribute: false })
|
|
1976
|
+
], DawRulerElement.prototype, "scaleMode", 2);
|
|
1977
|
+
__decorateClass([
|
|
1978
|
+
(0, import_decorators10.property)({ type: Number, attribute: false })
|
|
1979
|
+
], DawRulerElement.prototype, "ticksPerPixel", 2);
|
|
1980
|
+
__decorateClass([
|
|
1981
|
+
(0, import_decorators10.property)({ attribute: false })
|
|
1982
|
+
], DawRulerElement.prototype, "meterEntries", 2);
|
|
1983
|
+
__decorateClass([
|
|
1984
|
+
(0, import_decorators10.property)({ type: Number, attribute: false })
|
|
1985
|
+
], DawRulerElement.prototype, "ppqn", 2);
|
|
1986
|
+
__decorateClass([
|
|
1987
|
+
(0, import_decorators10.property)({ type: Number, attribute: false })
|
|
1988
|
+
], DawRulerElement.prototype, "totalWidth", 2);
|
|
1989
|
+
DawRulerElement = __decorateClass([
|
|
1990
|
+
(0, import_decorators10.customElement)("daw-ruler")
|
|
1991
|
+
], DawRulerElement);
|
|
1992
|
+
|
|
1993
|
+
// src/elements/daw-track-controls.ts
|
|
1994
|
+
var import_lit12 = require("lit");
|
|
1995
|
+
var import_decorators11 = require("lit/decorators.js");
|
|
1996
|
+
var DawTrackControlsElement = class extends import_lit12.LitElement {
|
|
1739
1997
|
constructor() {
|
|
1740
1998
|
super(...arguments);
|
|
1741
1999
|
this.trackId = null;
|
|
@@ -1769,11 +2027,22 @@ var DawTrackControlsElement = class extends import_lit11.LitElement {
|
|
|
1769
2027
|
);
|
|
1770
2028
|
};
|
|
1771
2029
|
}
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
2030
|
+
firstUpdated() {
|
|
2031
|
+
requestAnimationFrame(() => {
|
|
2032
|
+
if (!this.isConnected) return;
|
|
2033
|
+
const rect = this.getBoundingClientRect();
|
|
2034
|
+
if (rect.width > 0 && rect.height === 0) {
|
|
2035
|
+
console.warn(
|
|
2036
|
+
"[dawcore] <daw-track-controls> has zero height: container-type: size requires an explicit height on the element (the editor sets one automatically; standalone usage must too). The controls are currently invisible."
|
|
2037
|
+
);
|
|
2038
|
+
}
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
_dispatchControl(prop, value) {
|
|
2042
|
+
if (!this.trackId) return;
|
|
2043
|
+
this.dispatchEvent(
|
|
2044
|
+
new CustomEvent("daw-track-control", {
|
|
2045
|
+
bubbles: true,
|
|
1777
2046
|
composed: true,
|
|
1778
2047
|
detail: { trackId: this.trackId, prop, value }
|
|
1779
2048
|
})
|
|
@@ -1783,7 +2052,7 @@ var DawTrackControlsElement = class extends import_lit11.LitElement {
|
|
|
1783
2052
|
const volPercent = Math.round(this.volume * 100);
|
|
1784
2053
|
const panPercent = Math.round(Math.abs(this.pan) * 100);
|
|
1785
2054
|
const panDisplay = this.pan === 0 ? "C" : (this.pan > 0 ? "R" : "L") + panPercent;
|
|
1786
|
-
return
|
|
2055
|
+
return import_lit12.html`
|
|
1787
2056
|
<div class="header">
|
|
1788
2057
|
<span class="name" title=${this.trackName}>${this.trackName || "Untitled"}</span>
|
|
1789
2058
|
<button class="remove-btn" @click=${this._onRemoveClick} title="Remove track">
|
|
@@ -1802,7 +2071,7 @@ var DawTrackControlsElement = class extends import_lit11.LitElement {
|
|
|
1802
2071
|
S
|
|
1803
2072
|
</button>
|
|
1804
2073
|
</div>
|
|
1805
|
-
<div class="slider-row">
|
|
2074
|
+
<div class="slider-row vol-row">
|
|
1806
2075
|
<span class="slider-label">
|
|
1807
2076
|
<span class="slider-label-name">Vol</span>
|
|
1808
2077
|
<span class="slider-label-value">${volPercent}%</span>
|
|
@@ -1816,7 +2085,7 @@ var DawTrackControlsElement = class extends import_lit11.LitElement {
|
|
|
1816
2085
|
@input=${this._onVolumeInput}
|
|
1817
2086
|
/>
|
|
1818
2087
|
</div>
|
|
1819
|
-
<div class="slider-row">
|
|
2088
|
+
<div class="slider-row pan-row">
|
|
1820
2089
|
<span class="slider-label">
|
|
1821
2090
|
<span class="slider-label-name">Pan</span>
|
|
1822
2091
|
<span class="slider-label-value">${panDisplay}</span>
|
|
@@ -1833,7 +2102,7 @@ var DawTrackControlsElement = class extends import_lit11.LitElement {
|
|
|
1833
2102
|
`;
|
|
1834
2103
|
}
|
|
1835
2104
|
};
|
|
1836
|
-
DawTrackControlsElement.styles =
|
|
2105
|
+
DawTrackControlsElement.styles = import_lit12.css`
|
|
1837
2106
|
:host {
|
|
1838
2107
|
display: flex;
|
|
1839
2108
|
flex-direction: column;
|
|
@@ -1846,6 +2115,7 @@ DawTrackControlsElement.styles = import_lit11.css`
|
|
|
1846
2115
|
font-family: system-ui, sans-serif;
|
|
1847
2116
|
font-size: 11px;
|
|
1848
2117
|
overflow: hidden;
|
|
2118
|
+
container-type: size;
|
|
1849
2119
|
}
|
|
1850
2120
|
.header {
|
|
1851
2121
|
display: flex;
|
|
@@ -1965,64 +2235,52 @@ DawTrackControlsElement.styles = import_lit11.css`
|
|
|
1965
2235
|
border: none;
|
|
1966
2236
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
|
|
1967
2237
|
}
|
|
2238
|
+
/* Compact modes: drop sliders when the row is too short for the full
|
|
2239
|
+
stack. Thresholds are CONTENT-BOX heights — the host is border-box
|
|
2240
|
+
with 12px vertical padding + 1px border, so an editor-given height H
|
|
2241
|
+
enters compact mode at H <= 89px (Pan hidden) and H <= 73px (Vol also
|
|
2242
|
+
hidden). NOTE: container-type: size requires an explicit height on
|
|
2243
|
+
the host — the editor always provides one; standalone consumers must
|
|
2244
|
+
too (see the firstUpdated guard). */
|
|
2245
|
+
@container (max-height: 76px) {
|
|
2246
|
+
.pan-row {
|
|
2247
|
+
display: none;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
@container (max-height: 60px) {
|
|
2251
|
+
.vol-row {
|
|
2252
|
+
display: none;
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
1968
2255
|
`;
|
|
1969
2256
|
__decorateClass([
|
|
1970
|
-
(0,
|
|
2257
|
+
(0, import_decorators11.property)({ attribute: false })
|
|
1971
2258
|
], DawTrackControlsElement.prototype, "trackId", 2);
|
|
1972
2259
|
__decorateClass([
|
|
1973
|
-
(0,
|
|
2260
|
+
(0, import_decorators11.property)({ attribute: false })
|
|
1974
2261
|
], DawTrackControlsElement.prototype, "trackName", 2);
|
|
1975
2262
|
__decorateClass([
|
|
1976
|
-
(0,
|
|
2263
|
+
(0, import_decorators11.property)({ type: Number, attribute: false })
|
|
1977
2264
|
], DawTrackControlsElement.prototype, "volume", 2);
|
|
1978
2265
|
__decorateClass([
|
|
1979
|
-
(0,
|
|
2266
|
+
(0, import_decorators11.property)({ type: Number, attribute: false })
|
|
1980
2267
|
], DawTrackControlsElement.prototype, "pan", 2);
|
|
1981
2268
|
__decorateClass([
|
|
1982
|
-
(0,
|
|
2269
|
+
(0, import_decorators11.property)({ type: Boolean, attribute: false })
|
|
1983
2270
|
], DawTrackControlsElement.prototype, "muted", 2);
|
|
1984
2271
|
__decorateClass([
|
|
1985
|
-
(0,
|
|
2272
|
+
(0, import_decorators11.property)({ type: Boolean, attribute: false })
|
|
1986
2273
|
], DawTrackControlsElement.prototype, "soloed", 2);
|
|
1987
2274
|
DawTrackControlsElement = __decorateClass([
|
|
1988
|
-
(0,
|
|
2275
|
+
(0, import_decorators11.customElement)("daw-track-controls")
|
|
1989
2276
|
], DawTrackControlsElement);
|
|
1990
2277
|
|
|
1991
2278
|
// src/elements/daw-grid.ts
|
|
1992
|
-
var
|
|
1993
|
-
var
|
|
2279
|
+
var import_lit13 = require("lit");
|
|
2280
|
+
var import_decorators12 = require("lit/decorators.js");
|
|
1994
2281
|
var import_core2 = require("@waveform-playlist/core");
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
var import_core = require("@waveform-playlist/core");
|
|
1998
|
-
var cachedParams = null;
|
|
1999
|
-
var cachedResult = null;
|
|
2000
|
-
function meterEntriesMatch(a, b) {
|
|
2001
|
-
if (a.length !== b.length) return false;
|
|
2002
|
-
for (let i = 0; i < a.length; i++) {
|
|
2003
|
-
if (a[i].tick !== b[i].tick || a[i].numerator !== b[i].numerator || a[i].denominator !== b[i].denominator)
|
|
2004
|
-
return false;
|
|
2005
|
-
}
|
|
2006
|
-
return true;
|
|
2007
|
-
}
|
|
2008
|
-
function paramsMatch(a, b) {
|
|
2009
|
-
return a.ticksPerPixel === b.ticksPerPixel && a.startPixel === b.startPixel && a.endPixel === b.endPixel && meterEntriesMatch(a.meterEntries, b.meterEntries) && (a.ppqn ?? 960) === (b.ppqn ?? 960);
|
|
2010
|
-
}
|
|
2011
|
-
function getCachedMusicalTicks(params) {
|
|
2012
|
-
if (cachedParams && cachedResult && paramsMatch(cachedParams, params)) {
|
|
2013
|
-
return cachedResult;
|
|
2014
|
-
}
|
|
2015
|
-
cachedResult = (0, import_core.computeMusicalTicks)(params);
|
|
2016
|
-
cachedParams = {
|
|
2017
|
-
...params,
|
|
2018
|
-
meterEntries: params.meterEntries.map((e) => ({ ...e }))
|
|
2019
|
-
};
|
|
2020
|
-
return cachedResult;
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2023
|
-
// src/elements/daw-grid.ts
|
|
2024
|
-
var MAX_CANVAS_WIDTH3 = 1e3;
|
|
2025
|
-
var DawGridElement = class extends import_lit12.LitElement {
|
|
2282
|
+
var MAX_CANVAS_WIDTH4 = 1e3;
|
|
2283
|
+
var DawGridElement = class extends import_lit13.LitElement {
|
|
2026
2284
|
constructor() {
|
|
2027
2285
|
super(...arguments);
|
|
2028
2286
|
this.ticksPerPixel = 24;
|
|
@@ -2050,25 +2308,25 @@ var DawGridElement = class extends import_lit12.LitElement {
|
|
|
2050
2308
|
}
|
|
2051
2309
|
}
|
|
2052
2310
|
render() {
|
|
2053
|
-
if (!this._tickData) return
|
|
2311
|
+
if (!this._tickData) return import_lit13.html``;
|
|
2054
2312
|
const totalWidth = this.length;
|
|
2055
2313
|
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
2056
2314
|
const indices = getVisibleChunkIndices(
|
|
2057
2315
|
totalWidth,
|
|
2058
|
-
|
|
2316
|
+
MAX_CANVAS_WIDTH4,
|
|
2059
2317
|
this.visibleStart,
|
|
2060
2318
|
this.visibleEnd
|
|
2061
2319
|
);
|
|
2062
|
-
return
|
|
2320
|
+
return import_lit13.html`
|
|
2063
2321
|
<div class="container" style="width: ${totalWidth}px; height: ${this.height}px;">
|
|
2064
2322
|
${indices.map((i) => {
|
|
2065
|
-
const width = Math.min(
|
|
2066
|
-
return
|
|
2323
|
+
const width = Math.min(MAX_CANVAS_WIDTH4, totalWidth - i * MAX_CANVAS_WIDTH4);
|
|
2324
|
+
return import_lit13.html`
|
|
2067
2325
|
<canvas
|
|
2068
2326
|
data-index=${i}
|
|
2069
2327
|
width=${width * dpr}
|
|
2070
2328
|
height=${this.height * dpr}
|
|
2071
|
-
style="left: ${i *
|
|
2329
|
+
style="left: ${i * MAX_CANVAS_WIDTH4}px; width: ${width}px; height: ${this.height}px;"
|
|
2072
2330
|
></canvas>
|
|
2073
2331
|
`;
|
|
2074
2332
|
})}
|
|
@@ -2092,8 +2350,8 @@ var DawGridElement = class extends import_lit12.LitElement {
|
|
|
2092
2350
|
const idx = Number(canvas.dataset.index);
|
|
2093
2351
|
const ctx = canvas.getContext("2d");
|
|
2094
2352
|
if (!ctx) continue;
|
|
2095
|
-
const chunkLeft = idx *
|
|
2096
|
-
const canvasWidth = Math.min(
|
|
2353
|
+
const chunkLeft = idx * MAX_CANVAS_WIDTH4;
|
|
2354
|
+
const canvasWidth = Math.min(MAX_CANVAS_WIDTH4, this.length - chunkLeft);
|
|
2097
2355
|
ctx.resetTransform();
|
|
2098
2356
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
2099
2357
|
ctx.scale(dpr, dpr);
|
|
@@ -2124,7 +2382,7 @@ var DawGridElement = class extends import_lit12.LitElement {
|
|
|
2124
2382
|
}
|
|
2125
2383
|
}
|
|
2126
2384
|
};
|
|
2127
|
-
DawGridElement.styles =
|
|
2385
|
+
DawGridElement.styles = import_lit13.css`
|
|
2128
2386
|
:host {
|
|
2129
2387
|
display: block;
|
|
2130
2388
|
position: absolute;
|
|
@@ -2142,33 +2400,33 @@ DawGridElement.styles = import_lit12.css`
|
|
|
2142
2400
|
}
|
|
2143
2401
|
`;
|
|
2144
2402
|
__decorateClass([
|
|
2145
|
-
(0,
|
|
2403
|
+
(0, import_decorators12.property)({ type: Number, attribute: false })
|
|
2146
2404
|
], DawGridElement.prototype, "ticksPerPixel", 2);
|
|
2147
2405
|
__decorateClass([
|
|
2148
|
-
(0,
|
|
2406
|
+
(0, import_decorators12.property)({ attribute: false })
|
|
2149
2407
|
], DawGridElement.prototype, "meterEntries", 2);
|
|
2150
2408
|
__decorateClass([
|
|
2151
|
-
(0,
|
|
2409
|
+
(0, import_decorators12.property)({ type: Number, attribute: false })
|
|
2152
2410
|
], DawGridElement.prototype, "ppqn", 2);
|
|
2153
2411
|
__decorateClass([
|
|
2154
|
-
(0,
|
|
2412
|
+
(0, import_decorators12.property)({ type: Number, attribute: false })
|
|
2155
2413
|
], DawGridElement.prototype, "visibleStart", 2);
|
|
2156
2414
|
__decorateClass([
|
|
2157
|
-
(0,
|
|
2415
|
+
(0, import_decorators12.property)({ type: Number, attribute: false })
|
|
2158
2416
|
], DawGridElement.prototype, "visibleEnd", 2);
|
|
2159
2417
|
__decorateClass([
|
|
2160
|
-
(0,
|
|
2418
|
+
(0, import_decorators12.property)({ type: Number, attribute: false })
|
|
2161
2419
|
], DawGridElement.prototype, "length", 2);
|
|
2162
2420
|
__decorateClass([
|
|
2163
|
-
(0,
|
|
2421
|
+
(0, import_decorators12.property)({ type: Number, attribute: false })
|
|
2164
2422
|
], DawGridElement.prototype, "height", 2);
|
|
2165
2423
|
DawGridElement = __decorateClass([
|
|
2166
|
-
(0,
|
|
2424
|
+
(0, import_decorators12.customElement)("daw-grid")
|
|
2167
2425
|
], DawGridElement);
|
|
2168
2426
|
|
|
2169
2427
|
// src/styles/theme.ts
|
|
2170
|
-
var
|
|
2171
|
-
var hostStyles =
|
|
2428
|
+
var import_lit14 = require("lit");
|
|
2429
|
+
var hostStyles = import_lit14.css`
|
|
2172
2430
|
:host {
|
|
2173
2431
|
--daw-wave-color: #c49a6c;
|
|
2174
2432
|
--daw-progress-color: #63c75f;
|
|
@@ -2184,7 +2442,7 @@ var hostStyles = import_lit13.css`
|
|
|
2184
2442
|
--daw-clip-header-text: #e0d4c8;
|
|
2185
2443
|
}
|
|
2186
2444
|
`;
|
|
2187
|
-
var clipStyles =
|
|
2445
|
+
var clipStyles = import_lit14.css`
|
|
2188
2446
|
.clip-container {
|
|
2189
2447
|
position: absolute;
|
|
2190
2448
|
overflow: hidden;
|
|
@@ -2931,7 +3189,11 @@ var PointerHandler = class {
|
|
|
2931
3189
|
e.preventDefault();
|
|
2932
3190
|
this._timeline = this._host.shadowRoot?.querySelector(".timeline");
|
|
2933
3191
|
if (this._timeline) {
|
|
2934
|
-
|
|
3192
|
+
try {
|
|
3193
|
+
this._timeline.setPointerCapture(e.pointerId);
|
|
3194
|
+
} catch (err) {
|
|
3195
|
+
console.warn("[dawcore] setPointerCapture failed: " + String(err));
|
|
3196
|
+
}
|
|
2935
3197
|
const onMove = (me) => clipHandler.onPointerMove(me);
|
|
2936
3198
|
const onUp = (ue) => {
|
|
2937
3199
|
clipHandler.onPointerUp(ue);
|
|
@@ -2953,11 +3215,20 @@ var PointerHandler = class {
|
|
|
2953
3215
|
}
|
|
2954
3216
|
}
|
|
2955
3217
|
this._timeline = this._host.shadowRoot?.querySelector(".timeline");
|
|
2956
|
-
if (!this._timeline)
|
|
3218
|
+
if (!this._timeline) {
|
|
3219
|
+
console.warn(
|
|
3220
|
+
"[dawcore] PointerHandler: .timeline not found in shadow root \u2014 seek/selection ignored"
|
|
3221
|
+
);
|
|
3222
|
+
return;
|
|
3223
|
+
}
|
|
2957
3224
|
this._timelineRect = this._timeline.getBoundingClientRect();
|
|
2958
3225
|
this._dragStartPx = this._pxFromPointer(e);
|
|
2959
3226
|
this._isDragging = false;
|
|
2960
|
-
|
|
3227
|
+
try {
|
|
3228
|
+
this._timeline.setPointerCapture(e.pointerId);
|
|
3229
|
+
} catch (err) {
|
|
3230
|
+
console.warn("[dawcore] setPointerCapture failed: " + String(err));
|
|
3231
|
+
}
|
|
2961
3232
|
this._timeline.addEventListener("pointermove", this._onPointerMove);
|
|
2962
3233
|
this._timeline.addEventListener("pointerup", this._onPointerUp);
|
|
2963
3234
|
};
|
|
@@ -3889,10 +4160,144 @@ async function loadWaveformDataFromUrl(src) {
|
|
|
3889
4160
|
}
|
|
3890
4161
|
}
|
|
3891
4162
|
|
|
4163
|
+
// src/controllers/scroll-sync-controller.ts
|
|
4164
|
+
var LINE_HEIGHT_PX = 16;
|
|
4165
|
+
var ScrollSyncController = class {
|
|
4166
|
+
constructor(host) {
|
|
4167
|
+
this._scrollContainer = null;
|
|
4168
|
+
this._wheelTargets = /* @__PURE__ */ new Set();
|
|
4169
|
+
this._warnedX = false;
|
|
4170
|
+
this._warnedY = false;
|
|
4171
|
+
/** Selector (in host shadow DOM) for the scroll container. */
|
|
4172
|
+
this.scrollSelector = "";
|
|
4173
|
+
/** Selector for the element receiving translate3d(-scrollLeft, 0, 0). */
|
|
4174
|
+
this.xTargetSelector = "";
|
|
4175
|
+
/** Selector for the element receiving translate3d(0, -scrollTop, 0). */
|
|
4176
|
+
this.yTargetSelector = "";
|
|
4177
|
+
/**
|
|
4178
|
+
* Selector (or comma-separated selectors) for elements whose wheel events
|
|
4179
|
+
* forward to the scroll container. All matching elements receive listeners.
|
|
4180
|
+
*/
|
|
4181
|
+
this.wheelForwardSelector = "";
|
|
4182
|
+
this._onScroll = () => {
|
|
4183
|
+
this._apply();
|
|
4184
|
+
};
|
|
4185
|
+
this._onWheel = (e) => {
|
|
4186
|
+
const sc = this._scrollContainer;
|
|
4187
|
+
if (!sc) return;
|
|
4188
|
+
const scale = e.deltaMode === WheelEvent.DOM_DELTA_LINE ? LINE_HEIGHT_PX : e.deltaMode === WheelEvent.DOM_DELTA_PAGE ? sc.clientHeight : 1;
|
|
4189
|
+
const scaleX = e.deltaMode === WheelEvent.DOM_DELTA_PAGE ? sc.clientWidth : scale;
|
|
4190
|
+
const beforeLeft = sc.scrollLeft;
|
|
4191
|
+
const beforeTop = sc.scrollTop;
|
|
4192
|
+
sc.scrollLeft += e.deltaX * scaleX;
|
|
4193
|
+
sc.scrollTop += e.deltaY * scale;
|
|
4194
|
+
if (sc.scrollLeft !== beforeLeft || sc.scrollTop !== beforeTop) {
|
|
4195
|
+
e.preventDefault();
|
|
4196
|
+
}
|
|
4197
|
+
};
|
|
4198
|
+
this._host = host;
|
|
4199
|
+
host.addController(this);
|
|
4200
|
+
}
|
|
4201
|
+
hostConnected() {
|
|
4202
|
+
requestAnimationFrame(() => {
|
|
4203
|
+
if (!this._host.isConnected) return;
|
|
4204
|
+
this._attach();
|
|
4205
|
+
if (!this._scrollContainer && this.scrollSelector) {
|
|
4206
|
+
console.warn(
|
|
4207
|
+
'[dawcore] ScrollSyncController: scroll container not found for "' + this.scrollSelector + '"'
|
|
4208
|
+
);
|
|
4209
|
+
}
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
hostDisconnected() {
|
|
4213
|
+
this._scrollContainer?.removeEventListener("scroll", this._onScroll);
|
|
4214
|
+
this._scrollContainer = null;
|
|
4215
|
+
for (const target of this._wheelTargets) {
|
|
4216
|
+
target.removeEventListener("wheel", this._onWheel);
|
|
4217
|
+
}
|
|
4218
|
+
this._wheelTargets.clear();
|
|
4219
|
+
}
|
|
4220
|
+
/**
|
|
4221
|
+
* Re-attach and re-apply transforms from the current scroll position.
|
|
4222
|
+
* Called from the host's updated() so elements created by a re-render
|
|
4223
|
+
* (e.g. the ruler appearing when the first track loads) pick up the
|
|
4224
|
+
* current offset and listeners.
|
|
4225
|
+
*/
|
|
4226
|
+
sync() {
|
|
4227
|
+
this._attach();
|
|
4228
|
+
}
|
|
4229
|
+
_query(selector) {
|
|
4230
|
+
return selector ? this._host.shadowRoot?.querySelector(selector) : null;
|
|
4231
|
+
}
|
|
4232
|
+
_queryAll(selector) {
|
|
4233
|
+
if (!selector) return [];
|
|
4234
|
+
return Array.from(this._host.shadowRoot?.querySelectorAll(selector) ?? []);
|
|
4235
|
+
}
|
|
4236
|
+
_attach() {
|
|
4237
|
+
const container = this._query(this.scrollSelector);
|
|
4238
|
+
if (!container) {
|
|
4239
|
+
if (this._scrollContainer && !this._scrollContainer.isConnected) {
|
|
4240
|
+
console.warn(
|
|
4241
|
+
'[dawcore] ScrollSyncController: scroll container "' + this.scrollSelector + '" was removed from the DOM \u2014 detaching listeners until it reappears.'
|
|
4242
|
+
);
|
|
4243
|
+
this._scrollContainer.removeEventListener("scroll", this._onScroll);
|
|
4244
|
+
this._scrollContainer = null;
|
|
4245
|
+
for (const t of this._wheelTargets) t.removeEventListener("wheel", this._onWheel);
|
|
4246
|
+
this._wheelTargets.clear();
|
|
4247
|
+
}
|
|
4248
|
+
return;
|
|
4249
|
+
}
|
|
4250
|
+
if (container !== this._scrollContainer) {
|
|
4251
|
+
this._scrollContainer?.removeEventListener("scroll", this._onScroll);
|
|
4252
|
+
this._scrollContainer = container;
|
|
4253
|
+
container.addEventListener("scroll", this._onScroll, { passive: true });
|
|
4254
|
+
}
|
|
4255
|
+
const nextTargets = new Set(this._queryAll(this.wheelForwardSelector));
|
|
4256
|
+
for (const old of this._wheelTargets) {
|
|
4257
|
+
if (!nextTargets.has(old)) {
|
|
4258
|
+
old.removeEventListener("wheel", this._onWheel);
|
|
4259
|
+
this._wheelTargets.delete(old);
|
|
4260
|
+
}
|
|
4261
|
+
}
|
|
4262
|
+
for (const next of nextTargets) {
|
|
4263
|
+
if (!this._wheelTargets.has(next)) {
|
|
4264
|
+
next.addEventListener("wheel", this._onWheel, { passive: false });
|
|
4265
|
+
this._wheelTargets.add(next);
|
|
4266
|
+
}
|
|
4267
|
+
}
|
|
4268
|
+
this._apply();
|
|
4269
|
+
}
|
|
4270
|
+
_apply() {
|
|
4271
|
+
const sc = this._scrollContainer;
|
|
4272
|
+
if (!sc) return;
|
|
4273
|
+
const xTarget = this._query(this.xTargetSelector);
|
|
4274
|
+
if (xTarget) {
|
|
4275
|
+
xTarget.style.transform = `translate3d(${-sc.scrollLeft}px, 0, 0)`;
|
|
4276
|
+
this._warnedX = false;
|
|
4277
|
+
} else if (this.xTargetSelector && sc.scrollLeft !== 0 && !this._warnedX) {
|
|
4278
|
+
this._warnedX = true;
|
|
4279
|
+
console.warn(
|
|
4280
|
+
'[dawcore] ScrollSyncController: x target "' + this.xTargetSelector + '" not found while scrolled \u2014 the synced pane will appear frozen. Check the selector, or clear it if the target is intentionally not rendered.'
|
|
4281
|
+
);
|
|
4282
|
+
}
|
|
4283
|
+
const yTarget = this._query(this.yTargetSelector);
|
|
4284
|
+
if (yTarget) {
|
|
4285
|
+
yTarget.style.transform = `translate3d(0, ${-sc.scrollTop}px, 0)`;
|
|
4286
|
+
this._warnedY = false;
|
|
4287
|
+
} else if (this.yTargetSelector && sc.scrollTop !== 0 && !this._warnedY) {
|
|
4288
|
+
this._warnedY = true;
|
|
4289
|
+
console.warn(
|
|
4290
|
+
'[dawcore] ScrollSyncController: y target "' + this.yTargetSelector + '" not found while scrolled \u2014 the synced pane will appear frozen. Check the selector, or clear it if the target is intentionally not rendered.'
|
|
4291
|
+
);
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
};
|
|
4295
|
+
|
|
3892
4296
|
// src/elements/daw-editor.ts
|
|
3893
4297
|
var import_meta = {};
|
|
4298
|
+
var RULER_HEIGHT = 30;
|
|
3894
4299
|
var NO_ADAPTER_ERROR = "No PlayoutAdapter set on <daw-editor>. Set editor.adapter before use.\n\n // Option 1: Native Web Audio (no Tone.js)\n npm install @dawcore/transport\n import { NativePlayoutAdapter } from '@dawcore/transport';\n editor.adapter = new NativePlayoutAdapter(new AudioContext());\n\n // Option 2: Tone.js (effects, MIDI synths)\n npm install @waveform-playlist/playout\n import { createToneAdapter } from '@waveform-playlist/playout';\n editor.adapter = createToneAdapter();";
|
|
3895
|
-
var DawEditorElement = class extends
|
|
4300
|
+
var DawEditorElement = class extends import_lit15.LitElement {
|
|
3896
4301
|
constructor() {
|
|
3897
4302
|
super(...arguments);
|
|
3898
4303
|
this._samplesPerPixel = 1024;
|
|
@@ -3951,6 +4356,11 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
3951
4356
|
v.scrollSelector = ".scroll-area";
|
|
3952
4357
|
return v;
|
|
3953
4358
|
})();
|
|
4359
|
+
this._scrollSync = (() => {
|
|
4360
|
+
const s = new ScrollSyncController(this);
|
|
4361
|
+
s.scrollSelector = ".scroll-area";
|
|
4362
|
+
return s;
|
|
4363
|
+
})();
|
|
3954
4364
|
/**
|
|
3955
4365
|
* Cache of the last ViewportState forwarded to the spectrogram controller.
|
|
3956
4366
|
* Lit's `updated()` fires on every reactive state change (`_isPlaying`,
|
|
@@ -4497,6 +4907,13 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
4497
4907
|
}
|
|
4498
4908
|
}
|
|
4499
4909
|
updated(_changed) {
|
|
4910
|
+
this._scrollSync.xTargetSelector = this._showRuler ? ".ruler-content" : "";
|
|
4911
|
+
this._scrollSync.yTargetSelector = this._showControls ? ".controls-column" : "";
|
|
4912
|
+
this._scrollSync.wheelForwardSelector = [
|
|
4913
|
+
this._showControls ? ".controls-viewport" : "",
|
|
4914
|
+
this._showRuler ? ".ruler-viewport" : ""
|
|
4915
|
+
].filter(Boolean).join(", ");
|
|
4916
|
+
this._scrollSync.sync();
|
|
4500
4917
|
if (this._spectrogramController) {
|
|
4501
4918
|
const vs = this._viewport.visibleStart;
|
|
4502
4919
|
const ve = this._viewport.visibleEnd;
|
|
@@ -5658,7 +6075,7 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5658
6075
|
const w = Math.floor(audibleSamples / renderSpp);
|
|
5659
6076
|
return rs.peaks.map((chPeaks, ch) => {
|
|
5660
6077
|
const slicedPeaks = latencyPixels > 0 ? chPeaks.slice(latencyPixels * 2) : chPeaks;
|
|
5661
|
-
return
|
|
6078
|
+
return import_lit15.html`
|
|
5662
6079
|
<daw-waveform
|
|
5663
6080
|
data-recording-track=${trackId}
|
|
5664
6081
|
data-recording-channel=${ch}
|
|
@@ -5714,6 +6131,14 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5714
6131
|
_getPlayhead() {
|
|
5715
6132
|
return this.shadowRoot?.querySelector("daw-playhead");
|
|
5716
6133
|
}
|
|
6134
|
+
/** True when the controls column should be rendered (and its selector is valid). */
|
|
6135
|
+
get _showControls() {
|
|
6136
|
+
return this._getOrderedTracks().length > 0 || this.indefinitePlayback;
|
|
6137
|
+
}
|
|
6138
|
+
/** True when the ruler header band should be rendered (and its selector is valid). */
|
|
6139
|
+
get _showRuler() {
|
|
6140
|
+
return (this._getOrderedTracks().length > 0 || this.scaleMode === "beats" || this.indefinitePlayback) && this.timescale;
|
|
6141
|
+
}
|
|
5717
6142
|
_getOrderedTracks() {
|
|
5718
6143
|
const domOrder = [...this.querySelectorAll("daw-track")].map(
|
|
5719
6144
|
(el) => el.trackId
|
|
@@ -5755,64 +6180,79 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5755
6180
|
trackHeight: this.waveHeight * numChannels + (this.clipHeaders ? this.clipHeaderHeight : 0)
|
|
5756
6181
|
};
|
|
5757
6182
|
});
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
style="height: ${t.trackHeight}px;"
|
|
5765
|
-
.trackId=${t.trackId}
|
|
5766
|
-
.trackName=${t.descriptor?.name ?? "Untitled"}
|
|
5767
|
-
.volume=${t.descriptor?.volume ?? 1}
|
|
5768
|
-
.pan=${t.descriptor?.pan ?? 0}
|
|
5769
|
-
.muted=${t.descriptor?.muted ?? false}
|
|
5770
|
-
.soloed=${t.descriptor?.soloed ?? false}
|
|
5771
|
-
></daw-track-controls>
|
|
5772
|
-
`
|
|
5773
|
-
)}
|
|
5774
|
-
</div>` : ""}
|
|
5775
|
-
<div class="scroll-area">
|
|
5776
|
-
<div
|
|
5777
|
-
class="timeline ${this._dragOver ? "drag-over" : ""}"
|
|
5778
|
-
style="width: ${this._totalWidth > 0 ? this._totalWidth + "px" : "100%"};"
|
|
5779
|
-
data-playing=${this._isPlaying}
|
|
5780
|
-
@pointerdown=${this._pointer.onPointerDown}
|
|
5781
|
-
@dragover=${this._onDragOver}
|
|
5782
|
-
@dragleave=${this._onDragLeave}
|
|
5783
|
-
@drop=${this._onDrop}
|
|
5784
|
-
>
|
|
5785
|
-
${(orderedTracks.length > 0 || this.scaleMode === "beats" || this.indefinitePlayback) && this.timescale ? import_lit14.html`<daw-ruler
|
|
5786
|
-
.samplesPerPixel=${spp}
|
|
5787
|
-
.sampleRate=${this.effectiveSampleRate}
|
|
5788
|
-
.duration=${this._duration}
|
|
5789
|
-
.scaleMode=${this.scaleMode}
|
|
5790
|
-
.ticksPerPixel=${this.ticksPerPixel}
|
|
5791
|
-
.meterEntries=${this._meterEntries}
|
|
5792
|
-
.ppqn=${this.ppqn}
|
|
5793
|
-
.totalWidth=${this._totalWidth}
|
|
5794
|
-
></daw-ruler>` : ""}
|
|
5795
|
-
${this.scaleMode === "beats" ? import_lit14.html`<daw-grid
|
|
5796
|
-
style="top: ${this.timescale ? 30 : 0}px;"
|
|
5797
|
-
.ticksPerPixel=${this.ticksPerPixel}
|
|
5798
|
-
.meterEntries=${this._meterEntries}
|
|
5799
|
-
.ppqn=${this.ppqn}
|
|
5800
|
-
.visibleStart=${this._viewport.visibleStart}
|
|
5801
|
-
.visibleEnd=${this._viewport.visibleEnd}
|
|
5802
|
-
.length=${this._totalWidth}
|
|
5803
|
-
.height=${orderedTracks.length > 0 ? orderedTracks.reduce((sum, t) => sum + t.trackHeight + 1, 0) : this._emptyGridHeight}
|
|
5804
|
-
></daw-grid>` : ""}
|
|
5805
|
-
${orderedTracks.length > 0 || this.scaleMode === "beats" || this.indefinitePlayback ? import_lit14.html`<daw-selection .startPx=${selStartPx} .endPx=${selEndPx}></daw-selection>
|
|
5806
|
-
<daw-playhead></daw-playhead>` : ""}
|
|
5807
|
-
${orderedTracks.map((t) => {
|
|
5808
|
-
const channelHeight = this.waveHeight;
|
|
5809
|
-
return import_lit14.html`
|
|
6183
|
+
const showControls = this._showControls;
|
|
6184
|
+
const showRuler = this._showRuler;
|
|
6185
|
+
return import_lit15.html`
|
|
6186
|
+
${showRuler ? import_lit15.html`<div class="header-row" style="height: ${RULER_HEIGHT}px;">
|
|
6187
|
+
${showControls ? import_lit15.html`<div class="ruler-gap"></div>` : ""}
|
|
6188
|
+
<div class="ruler-viewport" @pointerdown=${this._pointer.onPointerDown}>
|
|
5810
6189
|
<div
|
|
5811
|
-
class="
|
|
5812
|
-
style="
|
|
5813
|
-
data-track-id=${t.trackId}
|
|
6190
|
+
class="ruler-content"
|
|
6191
|
+
style="width: ${this._totalWidth > 0 ? this._totalWidth + "px" : "100%"};"
|
|
5814
6192
|
>
|
|
5815
|
-
|
|
6193
|
+
<daw-ruler
|
|
6194
|
+
.samplesPerPixel=${spp}
|
|
6195
|
+
.sampleRate=${this.effectiveSampleRate}
|
|
6196
|
+
.duration=${this._duration}
|
|
6197
|
+
.scaleMode=${this.scaleMode}
|
|
6198
|
+
.ticksPerPixel=${this.ticksPerPixel}
|
|
6199
|
+
.meterEntries=${this._meterEntries}
|
|
6200
|
+
.ppqn=${this.ppqn}
|
|
6201
|
+
.totalWidth=${this._totalWidth}
|
|
6202
|
+
.rulerHeight=${RULER_HEIGHT}
|
|
6203
|
+
></daw-ruler>
|
|
6204
|
+
</div>
|
|
6205
|
+
</div>
|
|
6206
|
+
</div>` : ""}
|
|
6207
|
+
<div class="body">
|
|
6208
|
+
${showControls ? import_lit15.html`<div class="controls-viewport">
|
|
6209
|
+
<div class="controls-column">
|
|
6210
|
+
${orderedTracks.map(
|
|
6211
|
+
(t) => import_lit15.html`
|
|
6212
|
+
<daw-track-controls
|
|
6213
|
+
style="height: ${t.trackHeight}px;"
|
|
6214
|
+
.trackId=${t.trackId}
|
|
6215
|
+
.trackName=${t.descriptor?.name ?? "Untitled"}
|
|
6216
|
+
.volume=${t.descriptor?.volume ?? 1}
|
|
6217
|
+
.pan=${t.descriptor?.pan ?? 0}
|
|
6218
|
+
.muted=${t.descriptor?.muted ?? false}
|
|
6219
|
+
.soloed=${t.descriptor?.soloed ?? false}
|
|
6220
|
+
></daw-track-controls>
|
|
6221
|
+
`
|
|
6222
|
+
)}
|
|
6223
|
+
</div>
|
|
6224
|
+
</div>` : ""}
|
|
6225
|
+
<div class="scroll-area">
|
|
6226
|
+
<div
|
|
6227
|
+
class="timeline ${this._dragOver ? "drag-over" : ""}"
|
|
6228
|
+
style="width: ${this._totalWidth > 0 ? this._totalWidth + "px" : "100%"};"
|
|
6229
|
+
data-playing=${this._isPlaying}
|
|
6230
|
+
@pointerdown=${this._pointer.onPointerDown}
|
|
6231
|
+
@dragover=${this._onDragOver}
|
|
6232
|
+
@dragleave=${this._onDragLeave}
|
|
6233
|
+
@drop=${this._onDrop}
|
|
6234
|
+
>
|
|
6235
|
+
${this.scaleMode === "beats" ? import_lit15.html`<daw-grid
|
|
6236
|
+
style="top: 0px;"
|
|
6237
|
+
.ticksPerPixel=${this.ticksPerPixel}
|
|
6238
|
+
.meterEntries=${this._meterEntries}
|
|
6239
|
+
.ppqn=${this.ppqn}
|
|
6240
|
+
.visibleStart=${this._viewport.visibleStart}
|
|
6241
|
+
.visibleEnd=${this._viewport.visibleEnd}
|
|
6242
|
+
.length=${this._totalWidth}
|
|
6243
|
+
.height=${orderedTracks.length > 0 ? orderedTracks.reduce((sum, t) => sum + t.trackHeight, 0) : this._emptyGridHeight}
|
|
6244
|
+
></daw-grid>` : ""}
|
|
6245
|
+
${orderedTracks.length > 0 || this.scaleMode === "beats" || this.indefinitePlayback ? import_lit15.html`<daw-selection .startPx=${selStartPx} .endPx=${selEndPx}></daw-selection>
|
|
6246
|
+
<daw-playhead></daw-playhead>` : ""}
|
|
6247
|
+
${orderedTracks.map((t) => {
|
|
6248
|
+
const channelHeight = this.waveHeight;
|
|
6249
|
+
return import_lit15.html`
|
|
6250
|
+
<div
|
|
6251
|
+
class="track-row ${t.trackId === this._selectedTrackId ? "selected" : ""}"
|
|
6252
|
+
style="height: ${t.trackHeight}px;"
|
|
6253
|
+
data-track-id=${t.trackId}
|
|
6254
|
+
>
|
|
6255
|
+
${t.track.clips.map((clip) => {
|
|
5816
6256
|
const peakData = this._peaksData.get(clip.id);
|
|
5817
6257
|
let clipLeft;
|
|
5818
6258
|
let width;
|
|
@@ -5855,7 +6295,10 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5855
6295
|
const segEndSample = Math.round(segEndAudioSec * sr);
|
|
5856
6296
|
const totalPeaks = clip.durationSamples / baseScale;
|
|
5857
6297
|
clipSegments.push({
|
|
5858
|
-
peakStart: Math.max(
|
|
6298
|
+
peakStart: Math.max(
|
|
6299
|
+
0,
|
|
6300
|
+
(segStartSample - clip.offsetSamples) / baseScale
|
|
6301
|
+
),
|
|
5859
6302
|
peakEnd: Math.min(
|
|
5860
6303
|
totalPeaks,
|
|
5861
6304
|
(segEndSample - clip.offsetSamples) / baseScale
|
|
@@ -5869,78 +6312,79 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5869
6312
|
const channels = segmentChannels ?? peakData?.data ?? [new Int16Array(0)];
|
|
5870
6313
|
const hdrH = this.clipHeaders ? this.clipHeaderHeight : 0;
|
|
5871
6314
|
const chH = this.waveHeight;
|
|
5872
|
-
return
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
data-clip-id=${clip.id}
|
|
5880
|
-
data-track-id=${t.trackId}
|
|
5881
|
-
?data-interactive=${this.interactiveClips}
|
|
5882
|
-
>
|
|
5883
|
-
<span>${clip.name || t.descriptor?.name || ""}</span>
|
|
5884
|
-
</div>` : ""}
|
|
5885
|
-
${t.descriptor?.renderMode === "piano-roll" ? import_lit14.html`<daw-piano-roll
|
|
5886
|
-
style="position:absolute;left:0;top:${hdrH}px;"
|
|
5887
|
-
.midiNotes=${clip.midiNotes ?? []}
|
|
5888
|
-
.length=${peakData?.length ?? width}
|
|
5889
|
-
.waveHeight=${chH * channels.length}
|
|
5890
|
-
.samplesPerPixel=${this._renderSpp}
|
|
5891
|
-
.sampleRate=${this.effectiveSampleRate}
|
|
5892
|
-
.clipOffsetSeconds=${(clip.offsetSamples ?? 0) / this.effectiveSampleRate}
|
|
5893
|
-
.visibleStart=${this._viewport.visibleStart}
|
|
5894
|
-
.visibleEnd=${this._viewport.visibleEnd}
|
|
5895
|
-
.originX=${clipLeft}
|
|
5896
|
-
?selected=${t.trackId === this._selectedTrackId}
|
|
5897
|
-
></daw-piano-roll>` : t.descriptor?.renderMode === "spectrogram" ? channels.map(
|
|
5898
|
-
(_chPeaks, chIdx) => import_lit14.html`<daw-spectrogram
|
|
5899
|
-
style="position:absolute;left:0;top:${hdrH + chIdx * chH}px;height:${chH}px;width:${peakData?.length ?? width}px;"
|
|
5900
|
-
.clipId=${clip.id}
|
|
5901
|
-
.trackId=${t.trackId}
|
|
5902
|
-
.channelIndex=${chIdx}
|
|
5903
|
-
.length=${peakData?.length ?? width}
|
|
5904
|
-
.waveHeight=${chH}
|
|
5905
|
-
.samplesPerPixel=${this._renderSpp}
|
|
5906
|
-
.sampleRate=${this.effectiveSampleRate}
|
|
5907
|
-
.clipOffsetSeconds=${(clip.offsetSamples ?? 0) / this.effectiveSampleRate}
|
|
5908
|
-
.visibleStart=${this._viewport.visibleStart}
|
|
5909
|
-
.visibleEnd=${this._viewport.visibleEnd}
|
|
5910
|
-
.originX=${clipLeft}
|
|
5911
|
-
></daw-spectrogram>`
|
|
5912
|
-
) : channels.map(
|
|
5913
|
-
(chPeaks, chIdx) => import_lit14.html` <daw-waveform
|
|
5914
|
-
style="position:absolute;left:0;top:${hdrH + chIdx * chH}px;"
|
|
5915
|
-
.peaks=${chPeaks}
|
|
5916
|
-
.length=${peakData?.length ?? width}
|
|
5917
|
-
.waveHeight=${chH}
|
|
5918
|
-
.barWidth=${this.barWidth}
|
|
5919
|
-
.barGap=${this.barGap}
|
|
5920
|
-
.visibleStart=${this._viewport.visibleStart}
|
|
5921
|
-
.visibleEnd=${this._viewport.visibleEnd}
|
|
5922
|
-
.originX=${clipLeft}
|
|
5923
|
-
.segments=${clipSegments}
|
|
5924
|
-
></daw-waveform>`
|
|
5925
|
-
)}
|
|
5926
|
-
${this.interactiveClips ? import_lit14.html` <div
|
|
5927
|
-
class="clip-boundary"
|
|
5928
|
-
data-boundary-edge="left"
|
|
5929
|
-
data-clip-id=${clip.id}
|
|
5930
|
-
data-track-id=${t.trackId}
|
|
5931
|
-
></div>
|
|
5932
|
-
<div
|
|
5933
|
-
class="clip-boundary"
|
|
5934
|
-
data-boundary-edge="right"
|
|
6315
|
+
return import_lit15.html` <div
|
|
6316
|
+
class="clip-container"
|
|
6317
|
+
style="left:${clipLeft}px;top:0;width:${width}px;height:${t.trackHeight}px;"
|
|
6318
|
+
data-clip-id=${clip.id}
|
|
6319
|
+
>
|
|
6320
|
+
${hdrH > 0 ? import_lit15.html`<div
|
|
6321
|
+
class="clip-header"
|
|
5935
6322
|
data-clip-id=${clip.id}
|
|
5936
6323
|
data-track-id=${t.trackId}
|
|
5937
|
-
|
|
5938
|
-
|
|
6324
|
+
?data-interactive=${this.interactiveClips}
|
|
6325
|
+
>
|
|
6326
|
+
<span>${clip.name || t.descriptor?.name || ""}</span>
|
|
6327
|
+
</div>` : ""}
|
|
6328
|
+
${t.descriptor?.renderMode === "piano-roll" ? import_lit15.html`<daw-piano-roll
|
|
6329
|
+
style="position:absolute;left:0;top:${hdrH}px;"
|
|
6330
|
+
.midiNotes=${clip.midiNotes ?? []}
|
|
6331
|
+
.length=${peakData?.length ?? width}
|
|
6332
|
+
.waveHeight=${chH * channels.length}
|
|
6333
|
+
.samplesPerPixel=${this._renderSpp}
|
|
6334
|
+
.sampleRate=${this.effectiveSampleRate}
|
|
6335
|
+
.clipOffsetSeconds=${(clip.offsetSamples ?? 0) / this.effectiveSampleRate}
|
|
6336
|
+
.visibleStart=${this._viewport.visibleStart}
|
|
6337
|
+
.visibleEnd=${this._viewport.visibleEnd}
|
|
6338
|
+
.originX=${clipLeft}
|
|
6339
|
+
?selected=${t.trackId === this._selectedTrackId}
|
|
6340
|
+
></daw-piano-roll>` : t.descriptor?.renderMode === "spectrogram" ? channels.map(
|
|
6341
|
+
(_chPeaks, chIdx) => import_lit15.html`<daw-spectrogram
|
|
6342
|
+
style="position:absolute;left:0;top:${hdrH + chIdx * chH}px;height:${chH}px;width:${peakData?.length ?? width}px;"
|
|
6343
|
+
.clipId=${clip.id}
|
|
6344
|
+
.trackId=${t.trackId}
|
|
6345
|
+
.channelIndex=${chIdx}
|
|
6346
|
+
.length=${peakData?.length ?? width}
|
|
6347
|
+
.waveHeight=${chH}
|
|
6348
|
+
.samplesPerPixel=${this._renderSpp}
|
|
6349
|
+
.sampleRate=${this.effectiveSampleRate}
|
|
6350
|
+
.clipOffsetSeconds=${(clip.offsetSamples ?? 0) / this.effectiveSampleRate}
|
|
6351
|
+
.visibleStart=${this._viewport.visibleStart}
|
|
6352
|
+
.visibleEnd=${this._viewport.visibleEnd}
|
|
6353
|
+
.originX=${clipLeft}
|
|
6354
|
+
></daw-spectrogram>`
|
|
6355
|
+
) : channels.map(
|
|
6356
|
+
(chPeaks, chIdx) => import_lit15.html` <daw-waveform
|
|
6357
|
+
style="position:absolute;left:0;top:${hdrH + chIdx * chH}px;"
|
|
6358
|
+
.peaks=${chPeaks}
|
|
6359
|
+
.length=${peakData?.length ?? width}
|
|
6360
|
+
.waveHeight=${chH}
|
|
6361
|
+
.barWidth=${this.barWidth}
|
|
6362
|
+
.barGap=${this.barGap}
|
|
6363
|
+
.visibleStart=${this._viewport.visibleStart}
|
|
6364
|
+
.visibleEnd=${this._viewport.visibleEnd}
|
|
6365
|
+
.originX=${clipLeft}
|
|
6366
|
+
.segments=${clipSegments}
|
|
6367
|
+
></daw-waveform>`
|
|
6368
|
+
)}
|
|
6369
|
+
${this.interactiveClips ? import_lit15.html` <div
|
|
6370
|
+
class="clip-boundary"
|
|
6371
|
+
data-boundary-edge="left"
|
|
6372
|
+
data-clip-id=${clip.id}
|
|
6373
|
+
data-track-id=${t.trackId}
|
|
6374
|
+
></div>
|
|
6375
|
+
<div
|
|
6376
|
+
class="clip-boundary"
|
|
6377
|
+
data-boundary-edge="right"
|
|
6378
|
+
data-clip-id=${clip.id}
|
|
6379
|
+
data-track-id=${t.trackId}
|
|
6380
|
+
></div>` : ""}
|
|
6381
|
+
</div>`;
|
|
5939
6382
|
})}
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
6383
|
+
${this._renderRecordingPreview(t.trackId, channelHeight)}
|
|
6384
|
+
</div>
|
|
6385
|
+
`;
|
|
5943
6386
|
})}
|
|
6387
|
+
</div>
|
|
5944
6388
|
</div>
|
|
5945
6389
|
</div>
|
|
5946
6390
|
<slot></slot>
|
|
@@ -5949,21 +6393,48 @@ var DawEditorElement = class extends import_lit14.LitElement {
|
|
|
5949
6393
|
};
|
|
5950
6394
|
DawEditorElement.styles = [
|
|
5951
6395
|
hostStyles,
|
|
5952
|
-
|
|
6396
|
+
import_lit15.css`
|
|
5953
6397
|
:host {
|
|
5954
6398
|
display: flex;
|
|
6399
|
+
flex-direction: column;
|
|
5955
6400
|
position: relative;
|
|
5956
6401
|
background: var(--daw-background, #1a1a2e);
|
|
5957
6402
|
overflow: hidden;
|
|
5958
6403
|
}
|
|
5959
|
-
.
|
|
6404
|
+
.header-row {
|
|
6405
|
+
display: flex;
|
|
6406
|
+
flex-shrink: 0;
|
|
6407
|
+
}
|
|
6408
|
+
.ruler-gap {
|
|
5960
6409
|
flex-shrink: 0;
|
|
5961
6410
|
width: var(--daw-controls-width, 180px);
|
|
5962
6411
|
}
|
|
6412
|
+
.ruler-viewport {
|
|
6413
|
+
flex: 1;
|
|
6414
|
+
position: relative;
|
|
6415
|
+
overflow: hidden;
|
|
6416
|
+
cursor: text;
|
|
6417
|
+
}
|
|
6418
|
+
.ruler-content {
|
|
6419
|
+
will-change: transform;
|
|
6420
|
+
}
|
|
6421
|
+
.body {
|
|
6422
|
+
flex: 1;
|
|
6423
|
+
min-height: 0;
|
|
6424
|
+
display: flex;
|
|
6425
|
+
}
|
|
6426
|
+
.controls-viewport {
|
|
6427
|
+
flex-shrink: 0;
|
|
6428
|
+
width: var(--daw-controls-width, 180px);
|
|
6429
|
+
overflow: hidden;
|
|
6430
|
+
}
|
|
6431
|
+
.controls-column {
|
|
6432
|
+
will-change: transform;
|
|
6433
|
+
}
|
|
5963
6434
|
.scroll-area {
|
|
5964
6435
|
flex: 1;
|
|
5965
|
-
overflow
|
|
5966
|
-
overflow-
|
|
6436
|
+
overflow: auto;
|
|
6437
|
+
overflow-anchor: none;
|
|
5967
6438
|
min-height: var(--daw-min-height, 200px);
|
|
5968
6439
|
}
|
|
5969
6440
|
.timeline {
|
|
@@ -5973,6 +6444,7 @@ DawEditorElement.styles = [
|
|
|
5973
6444
|
}
|
|
5974
6445
|
.track-row {
|
|
5975
6446
|
position: relative;
|
|
6447
|
+
box-sizing: border-box;
|
|
5976
6448
|
background: var(--daw-track-background, #16213e);
|
|
5977
6449
|
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
5978
6450
|
}
|
|
@@ -5997,333 +6469,102 @@ DawEditorElement.styles = [
|
|
|
5997
6469
|
];
|
|
5998
6470
|
DawEditorElement._CONTROL_PROPS = /* @__PURE__ */ new Set(["volume", "pan", "muted", "soloed"]);
|
|
5999
6471
|
__decorateClass([
|
|
6000
|
-
(0,
|
|
6472
|
+
(0, import_decorators13.property)({ type: Number, attribute: "samples-per-pixel", noAccessor: true })
|
|
6001
6473
|
], DawEditorElement.prototype, "samplesPerPixel", 1);
|
|
6002
6474
|
__decorateClass([
|
|
6003
|
-
(0,
|
|
6475
|
+
(0, import_decorators13.property)({ type: Number, attribute: "wave-height" })
|
|
6004
6476
|
], DawEditorElement.prototype, "waveHeight", 2);
|
|
6005
6477
|
__decorateClass([
|
|
6006
|
-
(0,
|
|
6478
|
+
(0, import_decorators13.property)({ type: Boolean })
|
|
6007
6479
|
], DawEditorElement.prototype, "timescale", 2);
|
|
6008
6480
|
__decorateClass([
|
|
6009
|
-
(0,
|
|
6481
|
+
(0, import_decorators13.property)({ type: Boolean })
|
|
6010
6482
|
], DawEditorElement.prototype, "mono", 2);
|
|
6011
6483
|
__decorateClass([
|
|
6012
|
-
(0,
|
|
6484
|
+
(0, import_decorators13.property)({ type: Number, attribute: "bar-width" })
|
|
6013
6485
|
], DawEditorElement.prototype, "barWidth", 2);
|
|
6014
6486
|
__decorateClass([
|
|
6015
|
-
(0,
|
|
6487
|
+
(0, import_decorators13.property)({ type: Number, attribute: "bar-gap" })
|
|
6016
6488
|
], DawEditorElement.prototype, "barGap", 2);
|
|
6017
6489
|
__decorateClass([
|
|
6018
|
-
(0,
|
|
6490
|
+
(0, import_decorators13.property)({ type: Boolean, attribute: "file-drop" })
|
|
6019
6491
|
], DawEditorElement.prototype, "fileDrop", 2);
|
|
6020
6492
|
__decorateClass([
|
|
6021
|
-
(0,
|
|
6493
|
+
(0, import_decorators13.property)({ type: Boolean, attribute: "clip-headers" })
|
|
6022
6494
|
], DawEditorElement.prototype, "clipHeaders", 2);
|
|
6023
6495
|
__decorateClass([
|
|
6024
|
-
(0,
|
|
6496
|
+
(0, import_decorators13.property)({ type: Number, attribute: "clip-header-height" })
|
|
6025
6497
|
], DawEditorElement.prototype, "clipHeaderHeight", 2);
|
|
6026
6498
|
__decorateClass([
|
|
6027
|
-
(0,
|
|
6499
|
+
(0, import_decorators13.property)({ type: Boolean, attribute: "interactive-clips" })
|
|
6028
6500
|
], DawEditorElement.prototype, "interactiveClips", 2);
|
|
6029
6501
|
__decorateClass([
|
|
6030
|
-
(0,
|
|
6502
|
+
(0, import_decorators13.property)({ type: Boolean, attribute: "indefinite-playback" })
|
|
6031
6503
|
], DawEditorElement.prototype, "indefinitePlayback", 2);
|
|
6032
6504
|
__decorateClass([
|
|
6033
|
-
(0,
|
|
6505
|
+
(0, import_decorators13.property)({ attribute: false, noAccessor: true })
|
|
6034
6506
|
], DawEditorElement.prototype, "spectrogramConfig", 1);
|
|
6035
6507
|
__decorateClass([
|
|
6036
|
-
(0,
|
|
6508
|
+
(0, import_decorators13.property)({ attribute: false, noAccessor: true })
|
|
6037
6509
|
], DawEditorElement.prototype, "spectrogramColorMap", 1);
|
|
6038
6510
|
__decorateClass([
|
|
6039
|
-
(0,
|
|
6511
|
+
(0, import_decorators13.property)({ type: String, attribute: "scale-mode" })
|
|
6040
6512
|
], DawEditorElement.prototype, "scaleMode", 2);
|
|
6041
6513
|
__decorateClass([
|
|
6042
|
-
(0,
|
|
6514
|
+
(0, import_decorators13.property)({ type: Number, attribute: "ticks-per-pixel", noAccessor: true })
|
|
6043
6515
|
], DawEditorElement.prototype, "ticksPerPixel", 1);
|
|
6044
6516
|
__decorateClass([
|
|
6045
|
-
(0,
|
|
6517
|
+
(0, import_decorators13.property)({ type: Number, noAccessor: true })
|
|
6046
6518
|
], DawEditorElement.prototype, "bpm", 1);
|
|
6047
6519
|
__decorateClass([
|
|
6048
|
-
(0,
|
|
6520
|
+
(0, import_decorators13.property)({ attribute: false })
|
|
6049
6521
|
], DawEditorElement.prototype, "timeSignature", 2);
|
|
6050
6522
|
__decorateClass([
|
|
6051
|
-
(0,
|
|
6523
|
+
(0, import_decorators13.property)({ attribute: false })
|
|
6052
6524
|
], DawEditorElement.prototype, "meterEntries", 2);
|
|
6053
6525
|
__decorateClass([
|
|
6054
|
-
(0,
|
|
6526
|
+
(0, import_decorators13.property)({ type: Number, noAccessor: true })
|
|
6055
6527
|
], DawEditorElement.prototype, "ppqn", 1);
|
|
6056
6528
|
__decorateClass([
|
|
6057
|
-
(0,
|
|
6529
|
+
(0, import_decorators13.property)({ type: String, attribute: "snap-to" })
|
|
6058
6530
|
], DawEditorElement.prototype, "snapTo", 2);
|
|
6059
6531
|
__decorateClass([
|
|
6060
|
-
(0,
|
|
6532
|
+
(0, import_decorators13.property)({ attribute: false })
|
|
6061
6533
|
], DawEditorElement.prototype, "secondsToTicks", 2);
|
|
6062
6534
|
__decorateClass([
|
|
6063
|
-
(0,
|
|
6535
|
+
(0, import_decorators13.property)({ attribute: false })
|
|
6064
6536
|
], DawEditorElement.prototype, "ticksToSeconds", 2);
|
|
6065
6537
|
__decorateClass([
|
|
6066
|
-
(0,
|
|
6538
|
+
(0, import_decorators13.state)()
|
|
6067
6539
|
], DawEditorElement.prototype, "_tracks", 2);
|
|
6068
6540
|
__decorateClass([
|
|
6069
|
-
(0,
|
|
6541
|
+
(0, import_decorators13.state)()
|
|
6070
6542
|
], DawEditorElement.prototype, "_engineTracks", 2);
|
|
6071
6543
|
__decorateClass([
|
|
6072
|
-
(0,
|
|
6544
|
+
(0, import_decorators13.state)()
|
|
6073
6545
|
], DawEditorElement.prototype, "_peaksData", 2);
|
|
6074
6546
|
__decorateClass([
|
|
6075
|
-
(0,
|
|
6547
|
+
(0, import_decorators13.state)()
|
|
6076
6548
|
], DawEditorElement.prototype, "_isPlaying", 2);
|
|
6077
6549
|
__decorateClass([
|
|
6078
|
-
(0,
|
|
6550
|
+
(0, import_decorators13.state)()
|
|
6079
6551
|
], DawEditorElement.prototype, "_duration", 2);
|
|
6080
6552
|
__decorateClass([
|
|
6081
|
-
(0,
|
|
6553
|
+
(0, import_decorators13.state)()
|
|
6082
6554
|
], DawEditorElement.prototype, "_selectedTrackId", 2);
|
|
6083
6555
|
__decorateClass([
|
|
6084
|
-
(0,
|
|
6556
|
+
(0, import_decorators13.state)()
|
|
6085
6557
|
], DawEditorElement.prototype, "_dragOver", 2);
|
|
6086
6558
|
__decorateClass([
|
|
6087
|
-
(0,
|
|
6559
|
+
(0, import_decorators13.property)({ attribute: false })
|
|
6088
6560
|
], DawEditorElement.prototype, "adapter", 1);
|
|
6089
6561
|
__decorateClass([
|
|
6090
|
-
(0,
|
|
6562
|
+
(0, import_decorators13.property)({ attribute: "eager-resume" })
|
|
6091
6563
|
], DawEditorElement.prototype, "eagerResume", 2);
|
|
6092
6564
|
DawEditorElement = __decorateClass([
|
|
6093
|
-
(0,
|
|
6565
|
+
(0, import_decorators13.customElement)("daw-editor")
|
|
6094
6566
|
], DawEditorElement);
|
|
6095
6567
|
|
|
6096
|
-
// src/elements/daw-ruler.ts
|
|
6097
|
-
var import_lit15 = require("lit");
|
|
6098
|
-
var import_decorators13 = require("lit/decorators.js");
|
|
6099
|
-
|
|
6100
|
-
// src/utils/time-format.ts
|
|
6101
|
-
function formatTime(milliseconds) {
|
|
6102
|
-
const seconds = Math.floor(milliseconds / 1e3);
|
|
6103
|
-
const s = seconds % 60;
|
|
6104
|
-
const m = (seconds - s) / 60;
|
|
6105
|
-
return `${m}:${String(s).padStart(2, "0")}`;
|
|
6106
|
-
}
|
|
6107
|
-
|
|
6108
|
-
// src/utils/smart-scale.ts
|
|
6109
|
-
var timeinfo = /* @__PURE__ */ new Map([
|
|
6110
|
-
[700, { marker: 1e3, bigStep: 500, smallStep: 100 }],
|
|
6111
|
-
[1500, { marker: 2e3, bigStep: 1e3, smallStep: 200 }],
|
|
6112
|
-
[2500, { marker: 2e3, bigStep: 1e3, smallStep: 500 }],
|
|
6113
|
-
[5e3, { marker: 5e3, bigStep: 1e3, smallStep: 500 }],
|
|
6114
|
-
[1e4, { marker: 1e4, bigStep: 5e3, smallStep: 1e3 }],
|
|
6115
|
-
[12e3, { marker: 15e3, bigStep: 5e3, smallStep: 1e3 }],
|
|
6116
|
-
[Infinity, { marker: 3e4, bigStep: 1e4, smallStep: 5e3 }]
|
|
6117
|
-
]);
|
|
6118
|
-
function getScaleInfo(samplesPerPixel) {
|
|
6119
|
-
for (const [resolution, config] of timeinfo) {
|
|
6120
|
-
if (samplesPerPixel < resolution) {
|
|
6121
|
-
return config;
|
|
6122
|
-
}
|
|
6123
|
-
}
|
|
6124
|
-
return { marker: 3e4, bigStep: 1e4, smallStep: 5e3 };
|
|
6125
|
-
}
|
|
6126
|
-
function computeTemporalTicks(samplesPerPixel, sampleRate, duration, rulerHeight) {
|
|
6127
|
-
const widthX = Math.ceil(duration * sampleRate / samplesPerPixel);
|
|
6128
|
-
const config = getScaleInfo(samplesPerPixel);
|
|
6129
|
-
const { marker, bigStep, smallStep } = config;
|
|
6130
|
-
const canvasInfo = /* @__PURE__ */ new Map();
|
|
6131
|
-
const labels = [];
|
|
6132
|
-
const pixPerSec = sampleRate / samplesPerPixel;
|
|
6133
|
-
for (let counter = 0; ; counter += smallStep) {
|
|
6134
|
-
const pix = Math.floor(counter / 1e3 * pixPerSec);
|
|
6135
|
-
if (pix >= widthX) break;
|
|
6136
|
-
if (counter % marker === 0) {
|
|
6137
|
-
canvasInfo.set(pix, rulerHeight);
|
|
6138
|
-
labels.push({ pix, text: formatTime(counter) });
|
|
6139
|
-
} else if (counter % bigStep === 0) {
|
|
6140
|
-
canvasInfo.set(pix, Math.floor(rulerHeight / 2));
|
|
6141
|
-
} else if (counter % smallStep === 0) {
|
|
6142
|
-
canvasInfo.set(pix, Math.floor(rulerHeight / 5));
|
|
6143
|
-
}
|
|
6144
|
-
}
|
|
6145
|
-
return { widthX, canvasInfo, labels };
|
|
6146
|
-
}
|
|
6147
|
-
|
|
6148
|
-
// src/elements/daw-ruler.ts
|
|
6149
|
-
var MAX_CANVAS_WIDTH4 = 1e3;
|
|
6150
|
-
var DawRulerElement = class extends import_lit15.LitElement {
|
|
6151
|
-
constructor() {
|
|
6152
|
-
super(...arguments);
|
|
6153
|
-
this.samplesPerPixel = 1024;
|
|
6154
|
-
this.sampleRate = 48e3;
|
|
6155
|
-
this.duration = 0;
|
|
6156
|
-
this.rulerHeight = 30;
|
|
6157
|
-
this.scaleMode = "temporal";
|
|
6158
|
-
this.ticksPerPixel = 4;
|
|
6159
|
-
this.meterEntries = [
|
|
6160
|
-
{ tick: 0, numerator: 4, denominator: 4 }
|
|
6161
|
-
];
|
|
6162
|
-
this.ppqn = 960;
|
|
6163
|
-
this.totalWidth = 0;
|
|
6164
|
-
this._tickData = null;
|
|
6165
|
-
this._musicalTickData = null;
|
|
6166
|
-
}
|
|
6167
|
-
willUpdate() {
|
|
6168
|
-
if (this.scaleMode === "beats" && this.totalWidth > 0) {
|
|
6169
|
-
this._musicalTickData = getCachedMusicalTicks({
|
|
6170
|
-
meterEntries: this.meterEntries,
|
|
6171
|
-
ticksPerPixel: this.ticksPerPixel,
|
|
6172
|
-
startPixel: 0,
|
|
6173
|
-
endPixel: this.totalWidth,
|
|
6174
|
-
ppqn: this.ppqn
|
|
6175
|
-
});
|
|
6176
|
-
this._tickData = null;
|
|
6177
|
-
} else if (this.duration > 0 || this.totalWidth > 0) {
|
|
6178
|
-
const widthDerivedDuration = this.totalWidth * this.samplesPerPixel / this.sampleRate;
|
|
6179
|
-
const effectiveDuration = Math.max(this.duration, widthDerivedDuration);
|
|
6180
|
-
this._musicalTickData = null;
|
|
6181
|
-
this._tickData = computeTemporalTicks(
|
|
6182
|
-
this.samplesPerPixel,
|
|
6183
|
-
this.sampleRate,
|
|
6184
|
-
effectiveDuration,
|
|
6185
|
-
this.rulerHeight
|
|
6186
|
-
);
|
|
6187
|
-
} else {
|
|
6188
|
-
this._musicalTickData = null;
|
|
6189
|
-
this._tickData = null;
|
|
6190
|
-
}
|
|
6191
|
-
}
|
|
6192
|
-
render() {
|
|
6193
|
-
const widthX = this.scaleMode === "beats" ? this.totalWidth : this._tickData?.widthX ?? 0;
|
|
6194
|
-
if (widthX <= 0) return import_lit15.html``;
|
|
6195
|
-
const totalChunks = Math.ceil(widthX / MAX_CANVAS_WIDTH4);
|
|
6196
|
-
const indices = Array.from({ length: totalChunks }, (_, i) => i);
|
|
6197
|
-
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
6198
|
-
const beatsLabels = this.scaleMode === "beats" ? this._musicalTickData?.ticks.filter((t) => t.label) ?? [] : [];
|
|
6199
|
-
const temporalLabels = this.scaleMode !== "beats" ? this._tickData?.labels ?? [] : [];
|
|
6200
|
-
return import_lit15.html`
|
|
6201
|
-
<div class="container" style="width: ${widthX}px; height: ${this.rulerHeight}px;">
|
|
6202
|
-
${indices.map((i) => {
|
|
6203
|
-
const width = Math.min(MAX_CANVAS_WIDTH4, widthX - i * MAX_CANVAS_WIDTH4);
|
|
6204
|
-
return import_lit15.html`
|
|
6205
|
-
<canvas
|
|
6206
|
-
data-index=${i}
|
|
6207
|
-
width=${width * dpr}
|
|
6208
|
-
height=${this.rulerHeight * dpr}
|
|
6209
|
-
style="left: ${i * MAX_CANVAS_WIDTH4}px; width: ${width}px; height: ${this.rulerHeight}px;"
|
|
6210
|
-
></canvas>
|
|
6211
|
-
`;
|
|
6212
|
-
})}
|
|
6213
|
-
${this.scaleMode === "beats" ? beatsLabels.map(
|
|
6214
|
-
(t) => import_lit15.html`<span
|
|
6215
|
-
class="label ${t.pixel > 0 ? "centered" : ""}"
|
|
6216
|
-
style="left: ${t.pixel > 0 ? t.pixel : t.pixel + 4}px;"
|
|
6217
|
-
>${t.label}</span
|
|
6218
|
-
>`
|
|
6219
|
-
) : temporalLabels.map(
|
|
6220
|
-
({ pix, text }) => import_lit15.html`<span class="label" style="left: ${pix + 4}px;">${text}</span>`
|
|
6221
|
-
)}
|
|
6222
|
-
</div>
|
|
6223
|
-
`;
|
|
6224
|
-
}
|
|
6225
|
-
updated() {
|
|
6226
|
-
this._drawTicks();
|
|
6227
|
-
}
|
|
6228
|
-
_drawTicks() {
|
|
6229
|
-
const canvases = this.shadowRoot?.querySelectorAll("canvas");
|
|
6230
|
-
if (!canvases) return;
|
|
6231
|
-
const dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio : 1;
|
|
6232
|
-
const rulerColor = getComputedStyle(this).getPropertyValue("--daw-ruler-color").trim() || "#c49a6c";
|
|
6233
|
-
const widthX = this.scaleMode === "beats" ? this.totalWidth : this._tickData?.widthX ?? 0;
|
|
6234
|
-
for (const canvas of canvases) {
|
|
6235
|
-
const idx = Number(canvas.dataset.index);
|
|
6236
|
-
const ctx = canvas.getContext("2d");
|
|
6237
|
-
if (!ctx) continue;
|
|
6238
|
-
const canvasWidth = Math.min(MAX_CANVAS_WIDTH4, widthX - idx * MAX_CANVAS_WIDTH4);
|
|
6239
|
-
const globalOffset = idx * MAX_CANVAS_WIDTH4;
|
|
6240
|
-
ctx.resetTransform();
|
|
6241
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
6242
|
-
ctx.scale(dpr, dpr);
|
|
6243
|
-
ctx.strokeStyle = rulerColor;
|
|
6244
|
-
ctx.lineWidth = 1;
|
|
6245
|
-
if (this.scaleMode === "beats" && this._musicalTickData) {
|
|
6246
|
-
const h = this.rulerHeight;
|
|
6247
|
-
for (const tick of this._musicalTickData.ticks) {
|
|
6248
|
-
const localX = tick.pixel - globalOffset;
|
|
6249
|
-
if (localX < 0 || localX >= canvasWidth) continue;
|
|
6250
|
-
const tickH = tick.type === "major" ? h * 0.6 : tick.type === "minor" ? h * 0.35 : h * 0.15;
|
|
6251
|
-
ctx.globalAlpha = tick.type === "major" ? 1 : 0.5;
|
|
6252
|
-
ctx.beginPath();
|
|
6253
|
-
ctx.moveTo(localX + 0.5, h);
|
|
6254
|
-
ctx.lineTo(localX + 0.5, h - tickH);
|
|
6255
|
-
ctx.stroke();
|
|
6256
|
-
}
|
|
6257
|
-
ctx.globalAlpha = 1;
|
|
6258
|
-
} else if (this._tickData) {
|
|
6259
|
-
for (const [pix, height] of this._tickData.canvasInfo) {
|
|
6260
|
-
const localX = pix - globalOffset;
|
|
6261
|
-
if (localX < 0 || localX >= canvasWidth) continue;
|
|
6262
|
-
ctx.beginPath();
|
|
6263
|
-
ctx.moveTo(localX + 0.5, this.rulerHeight);
|
|
6264
|
-
ctx.lineTo(localX + 0.5, this.rulerHeight - height);
|
|
6265
|
-
ctx.stroke();
|
|
6266
|
-
}
|
|
6267
|
-
}
|
|
6268
|
-
}
|
|
6269
|
-
}
|
|
6270
|
-
};
|
|
6271
|
-
DawRulerElement.styles = import_lit15.css`
|
|
6272
|
-
:host {
|
|
6273
|
-
display: block;
|
|
6274
|
-
position: relative;
|
|
6275
|
-
background: var(--daw-ruler-background, #0f0f1a);
|
|
6276
|
-
}
|
|
6277
|
-
.container {
|
|
6278
|
-
position: relative;
|
|
6279
|
-
}
|
|
6280
|
-
canvas {
|
|
6281
|
-
position: absolute;
|
|
6282
|
-
top: 0;
|
|
6283
|
-
}
|
|
6284
|
-
.label {
|
|
6285
|
-
position: absolute;
|
|
6286
|
-
font-size: 0.7rem;
|
|
6287
|
-
line-height: 1;
|
|
6288
|
-
white-space: nowrap;
|
|
6289
|
-
color: var(--daw-ruler-color, #c49a6c);
|
|
6290
|
-
top: 1px;
|
|
6291
|
-
}
|
|
6292
|
-
.label.centered {
|
|
6293
|
-
transform: translateX(-50%);
|
|
6294
|
-
}
|
|
6295
|
-
`;
|
|
6296
|
-
__decorateClass([
|
|
6297
|
-
(0, import_decorators13.property)({ type: Number, attribute: false })
|
|
6298
|
-
], DawRulerElement.prototype, "samplesPerPixel", 2);
|
|
6299
|
-
__decorateClass([
|
|
6300
|
-
(0, import_decorators13.property)({ type: Number, attribute: false })
|
|
6301
|
-
], DawRulerElement.prototype, "sampleRate", 2);
|
|
6302
|
-
__decorateClass([
|
|
6303
|
-
(0, import_decorators13.property)({ type: Number, attribute: false })
|
|
6304
|
-
], DawRulerElement.prototype, "duration", 2);
|
|
6305
|
-
__decorateClass([
|
|
6306
|
-
(0, import_decorators13.property)({ type: Number, attribute: false })
|
|
6307
|
-
], DawRulerElement.prototype, "rulerHeight", 2);
|
|
6308
|
-
__decorateClass([
|
|
6309
|
-
(0, import_decorators13.property)({ type: String, attribute: false })
|
|
6310
|
-
], DawRulerElement.prototype, "scaleMode", 2);
|
|
6311
|
-
__decorateClass([
|
|
6312
|
-
(0, import_decorators13.property)({ type: Number, attribute: false })
|
|
6313
|
-
], DawRulerElement.prototype, "ticksPerPixel", 2);
|
|
6314
|
-
__decorateClass([
|
|
6315
|
-
(0, import_decorators13.property)({ attribute: false })
|
|
6316
|
-
], DawRulerElement.prototype, "meterEntries", 2);
|
|
6317
|
-
__decorateClass([
|
|
6318
|
-
(0, import_decorators13.property)({ type: Number, attribute: false })
|
|
6319
|
-
], DawRulerElement.prototype, "ppqn", 2);
|
|
6320
|
-
__decorateClass([
|
|
6321
|
-
(0, import_decorators13.property)({ type: Number, attribute: false })
|
|
6322
|
-
], DawRulerElement.prototype, "totalWidth", 2);
|
|
6323
|
-
DawRulerElement = __decorateClass([
|
|
6324
|
-
(0, import_decorators13.customElement)("daw-ruler")
|
|
6325
|
-
], DawRulerElement);
|
|
6326
|
-
|
|
6327
6568
|
// src/elements/daw-selection.ts
|
|
6328
6569
|
var import_lit16 = require("lit");
|
|
6329
6570
|
var import_decorators14 = require("lit/decorators.js");
|