Draw audio layers
This commit is contained in:
parent
e12622c7bf
commit
32e6549b99
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-volume-mute" viewBox="0 0 16 16">
|
||||||
|
<path d="M6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06M6 5.04 4.312 6.39A.5.5 0 0 1 4 6.5H2v3h2a.5.5 0 0 1 .312.11L6 10.96zm7.854.606a.5.5 0 0 1 0 .708L12.207 8l1.647 1.646a.5.5 0 0 1-.708.708L11.5 8.707l-1.646 1.647a.5.5 0 0 1-.708-.708L10.793 8 9.146 6.354a.5.5 0 1 1 .708-.708L11.5 7.293l1.646-1.647a.5.5 0 0 1 .708 0"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 551 B |
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-volume-up-fill" viewBox="0 0 16 16">
|
||||||
|
<path d="M11.536 14.01A8.47 8.47 0 0 0 14.026 8a8.47 8.47 0 0 0-2.49-6.01l-.708.707A7.48 7.48 0 0 1 13.025 8c0 2.071-.84 3.946-2.197 5.303z"/>
|
||||||
|
<path d="M10.121 12.596A6.48 6.48 0 0 0 12.025 8a6.48 6.48 0 0 0-1.904-4.596l-.707.707A5.48 5.48 0 0 1 11.025 8a5.48 5.48 0 0 1-1.61 3.89z"/>
|
||||||
|
<path d="M8.707 11.182A4.5 4.5 0 0 0 10.025 8a4.5 4.5 0 0 0-1.318-3.182L8 5.525A3.5 3.5 0 0 1 9.025 8 3.5 3.5 0 0 1 8 10.475zM6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 693 B |
89
src/main.js
89
src/main.js
|
|
@ -1601,6 +1601,7 @@ class Layer {
|
||||||
this.name = "Layer"
|
this.name = "Layer"
|
||||||
this.frames = [new Frame("keyframe", this.idx+"-F1")]
|
this.frames = [new Frame("keyframe", this.idx+"-F1")]
|
||||||
this.visible = true
|
this.visible = true
|
||||||
|
this.audible = true
|
||||||
pointerList[this.idx] = this
|
pointerList[this.idx] = this
|
||||||
}
|
}
|
||||||
getFrame(num) {
|
getFrame(num) {
|
||||||
|
|
@ -1827,6 +1828,7 @@ class AudioLayer {
|
||||||
} else {
|
} else {
|
||||||
this.name = name
|
this.name = name
|
||||||
}
|
}
|
||||||
|
this.audible = true
|
||||||
}
|
}
|
||||||
copy(idx) {
|
copy(idx) {
|
||||||
let newAudioLayer = new AudioLayer(idx.slice(0,8)+this.idx.slice(8), this.name)
|
let newAudioLayer = new AudioLayer(idx.slice(0,8)+this.idx.slice(8), this.name)
|
||||||
|
|
@ -2280,6 +2282,9 @@ class GraphicsObject {
|
||||||
get children() {
|
get children() {
|
||||||
return this.activeLayer.children
|
return this.activeLayer.children
|
||||||
}
|
}
|
||||||
|
get allLayers() {
|
||||||
|
return [...this.audioLayers, ...this.layers]
|
||||||
|
}
|
||||||
get currentFrame() {
|
get currentFrame() {
|
||||||
return this.getFrame(this.currentFrameNum)
|
return this.getFrame(this.currentFrameNum)
|
||||||
}
|
}
|
||||||
|
|
@ -4083,6 +4088,8 @@ function timeline() {
|
||||||
|
|
||||||
// Load icons for show/hide layer
|
// Load icons for show/hide layer
|
||||||
timeline_cvs.icons = {}
|
timeline_cvs.icons = {}
|
||||||
|
timeline_cvs.icons.volume_up_fill = new Icon('assets/volume-up-fill.svg');
|
||||||
|
timeline_cvs.icons.volume_mute = new Icon('assets/volume-mute.svg');
|
||||||
timeline_cvs.icons.eye_fill = new Icon('assets/eye-fill.svg');
|
timeline_cvs.icons.eye_fill = new Icon('assets/eye-fill.svg');
|
||||||
timeline_cvs.icons.eye_slash = new Icon('assets/eye-slash.svg');
|
timeline_cvs.icons.eye_slash = new Icon('assets/eye-slash.svg');
|
||||||
|
|
||||||
|
|
@ -4215,8 +4222,8 @@ function timeline() {
|
||||||
} else {
|
} else {
|
||||||
mouse.y -= gutterHeight
|
mouse.y -= gutterHeight
|
||||||
let l = Math.floor(mouse.y / layerHeight)
|
let l = Math.floor(mouse.y / layerHeight)
|
||||||
if (l < context.activeObject.layers.length) {
|
if (l < context.activeObject.allLayers.length) {
|
||||||
let i = context.activeObject.layers.length - (l+1)
|
let i = context.activeObject.allLayers.length - (l+1)
|
||||||
mouse.y -= l*layerHeight
|
mouse.y -= l*layerHeight
|
||||||
if (
|
if (
|
||||||
mouse.x > layerWidth - iconSize - 5 &&
|
mouse.x > layerWidth - iconSize - 5 &&
|
||||||
|
|
@ -4224,7 +4231,16 @@ function timeline() {
|
||||||
mouse.y > 0.5 * (layerHeight - iconSize) &&
|
mouse.y > 0.5 * (layerHeight - iconSize) &&
|
||||||
mouse.y < 0.5 * (layerHeight + iconSize)
|
mouse.y < 0.5 * (layerHeight + iconSize)
|
||||||
) {
|
) {
|
||||||
context.activeObject.layers[i].visible = !context.activeObject.layers[i].visible
|
context.activeObject.allLayers[i].visible = !context.activeObject.allLayers[i].visible
|
||||||
|
updateUI()
|
||||||
|
updateMenu()
|
||||||
|
} else if (
|
||||||
|
mouse.x > layerWidth - iconSize*2 - 10 &&
|
||||||
|
mouse.x < layerWidth - iconSize - 5 &&
|
||||||
|
mouse.y > 0.5 * (layerHeight - iconSize) &&
|
||||||
|
mouse.y < 0.5 * (layerHeight + iconSize)
|
||||||
|
) {
|
||||||
|
context.activeObject.allLayers[i].audible = !context.activeObject.allLayers[i].audible
|
||||||
updateUI()
|
updateUI()
|
||||||
updateMenu()
|
updateMenu()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4722,8 +4738,8 @@ function updateLayers() {
|
||||||
ctx.translate(0, -offsetY)
|
ctx.translate(0, -offsetY)
|
||||||
// Draw layer headers
|
// Draw layer headers
|
||||||
let i=0;
|
let i=0;
|
||||||
for (let k = context.activeObject.layers.length - 1; k >= 0; k--) {
|
for (let k = context.activeObject.allLayers.length - 1; k >= 0; k--) {
|
||||||
let layer = context.activeObject.layers[k];
|
let layer = context.activeObject.allLayers[k];
|
||||||
if (context.activeObject.activeLayer == layer) {
|
if (context.activeObject.activeLayer == layer) {
|
||||||
ctx.fillStyle = darkMode ? "#444" : "#ccc"
|
ctx.fillStyle = darkMode ? "#444" : "#ccc"
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4733,8 +4749,10 @@ function updateLayers() {
|
||||||
ctx.fillStyle = darkMode ? "white": "black"
|
ctx.fillStyle = darkMode ? "white": "black"
|
||||||
drawHorizontallyCenteredText(ctx, layer.name, 5, (i+0.5)*layerHeight, layerHeight*0.4)
|
drawHorizontallyCenteredText(ctx, layer.name, 5, (i+0.5)*layerHeight, layerHeight*0.4)
|
||||||
ctx.save()
|
ctx.save()
|
||||||
const visibilityIcon = layer.visible ? canvas.icons.eye_fill : canvas.icons.eye_slash
|
const visibilityIcon = layer.visible ? canvas.icons.eye_fill : canvas.icons.eye_slash
|
||||||
visibilityIcon.render(ctx, layerWidth - iconSize - 5, (i+0.5)*layerHeight - iconSize*0.5, iconSize, iconSize, labelColor)
|
visibilityIcon.render(ctx, layerWidth - iconSize - 5, (i+0.5)*layerHeight - iconSize*0.5, iconSize, iconSize, labelColor)
|
||||||
|
const audibilityIcon = layer.audible ? canvas.icons.volume_up_fill : canvas.icons.volume_mute
|
||||||
|
audibilityIcon.render(ctx, layerWidth - iconSize*2 - 10, (i+0.5)*layerHeight - iconSize*0.5, iconSize, iconSize, labelColor)
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
ctx.save()
|
ctx.save()
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
|
|
@ -4747,31 +4765,40 @@ function updateLayers() {
|
||||||
drawBorderedRect(ctx, j*frameWidth, 0, frameWidth, layerHeight, shadow, highlight, shadow, shadow)
|
drawBorderedRect(ctx, j*frameWidth, 0, frameWidth, layerHeight, shadow, highlight, shadow, shadow)
|
||||||
}
|
}
|
||||||
// Draw existing frames
|
// Draw existing frames
|
||||||
layer.frames.forEach((frame, j) => {
|
if (layer instanceof Layer) {
|
||||||
if (!frame) return;
|
layer.frames.forEach((frame, j) => {
|
||||||
switch (frame.frameType) {
|
if (!frame) return;
|
||||||
case "keyframe":
|
switch (frame.frameType) {
|
||||||
ctx.fillStyle = foregroundColor
|
case "keyframe":
|
||||||
drawBorderedRect(ctx, j*frameWidth, 0, frameWidth, layerHeight, highlight, shadow, shadow, shadow)
|
ctx.fillStyle = foregroundColor
|
||||||
ctx.fillStyle = "#111"
|
drawBorderedRect(ctx, j*frameWidth, 0, frameWidth, layerHeight, highlight, shadow, shadow, shadow)
|
||||||
ctx.beginPath()
|
ctx.fillStyle = "#111"
|
||||||
ctx.arc((j+0.5)*frameWidth, layerHeight*0.75, frameWidth*0.25, 0, 2*Math.PI)
|
ctx.beginPath()
|
||||||
ctx.fill()
|
ctx.arc((j+0.5)*frameWidth, layerHeight*0.75, frameWidth*0.25, 0, 2*Math.PI)
|
||||||
break;
|
ctx.fill()
|
||||||
case "normal":
|
break;
|
||||||
ctx.fillStyle = foregroundColor
|
case "normal":
|
||||||
drawBorderedRect(ctx, j*frameWidth, 0, frameWidth, layerHeight, highlight, shadow, backgroundColor, backgroundColor)
|
ctx.fillStyle = foregroundColor
|
||||||
break;
|
drawBorderedRect(ctx, j*frameWidth, 0, frameWidth, layerHeight, highlight, shadow, backgroundColor, backgroundColor)
|
||||||
case "motion":
|
break;
|
||||||
ctx.fillStyle = "#7a00b3"
|
case "motion":
|
||||||
ctx.fillRect(j*frameWidth, 0, frameWidth, layerHeight)
|
ctx.fillStyle = "#7a00b3"
|
||||||
break;
|
ctx.fillRect(j*frameWidth, 0, frameWidth, layerHeight)
|
||||||
case "shape":
|
break;
|
||||||
ctx.fillStyle = "#9bff9b"
|
case "shape":
|
||||||
ctx.fillRect(j*frameWidth, 0, frameWidth, layerHeight)
|
ctx.fillStyle = "#9bff9b"
|
||||||
break;
|
ctx.fillRect(j*frameWidth, 0, frameWidth, layerHeight)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (layer instanceof AudioLayer) {
|
||||||
|
// TODO: split waveform into chunks
|
||||||
|
for (let i in layer.sounds) {
|
||||||
|
let sound = layer.sounds[i]
|
||||||
|
// layerTrack.appendChild(sound.img)
|
||||||
|
ctx.drawImage(sound.img, 0,0)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
// if (context.activeObject.currentFrameNum)
|
// if (context.activeObject.currentFrameNum)
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
i++;
|
i++;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue