Add layers
This commit is contained in:
parent
6b7e7eae16
commit
e1e48ede30
334
src/main.js
334
src/main.js
|
|
@ -349,6 +349,7 @@ let actions = {
|
||||||
let action = {
|
let action = {
|
||||||
audiosrc:audiosrc,
|
audiosrc:audiosrc,
|
||||||
uuid: uuidv4(),
|
uuid: uuidv4(),
|
||||||
|
layeruuid: uuidv4(),
|
||||||
frameNum: object.currentFrameNum,
|
frameNum: object.currentFrameNum,
|
||||||
object: object.idx
|
object: object.idx
|
||||||
}
|
}
|
||||||
|
|
@ -360,7 +361,7 @@ let actions = {
|
||||||
const player = new Tone.Player().toDestination();
|
const player = new Tone.Player().toDestination();
|
||||||
await player.load(action.audiosrc)
|
await player.load(action.audiosrc)
|
||||||
// player.autostart = true;
|
// player.autostart = true;
|
||||||
let newAudioLayer = new AudioLayer()
|
let newAudioLayer = new AudioLayer(action.layeruuid)
|
||||||
let object = pointerList[action.object]
|
let object = pointerList[action.object]
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.className = "audioWaveform"
|
img.className = "audioWaveform"
|
||||||
|
|
@ -379,7 +380,9 @@ let actions = {
|
||||||
updateLayers()
|
updateLayers()
|
||||||
},
|
},
|
||||||
rollback: (action) => {
|
rollback: (action) => {
|
||||||
// your code here
|
let object = pointerList[action.object]
|
||||||
|
let layer = pointerList[action.layeruuid]
|
||||||
|
object.audioLayers.splice(object.audioLayers.indexOf(layer),1)
|
||||||
updateLayers()
|
updateLayers()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -450,6 +453,59 @@ let actions = {
|
||||||
updateUI()
|
updateUI()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
addLayer: {
|
||||||
|
create: () => {
|
||||||
|
redoStack.length = 0
|
||||||
|
let action = {
|
||||||
|
object: context.activeObject.idx,
|
||||||
|
uuid: uuidv4()
|
||||||
|
}
|
||||||
|
undoStack.push({name: 'addLayer', action: action})
|
||||||
|
actions.addLayer.execute(action)
|
||||||
|
updateMenu()
|
||||||
|
},
|
||||||
|
execute: (action) => {
|
||||||
|
let object = pointerList[action.object]
|
||||||
|
let layer = new Layer(action.uuid)
|
||||||
|
layer.name = `Layer ${object.layers.length + 1}`
|
||||||
|
object.layers.push(layer)
|
||||||
|
updateLayers()
|
||||||
|
},
|
||||||
|
rollback: (action) => {
|
||||||
|
let object = pointerList[action.object]
|
||||||
|
let layer = pointerList[action.uuid]
|
||||||
|
object.layers.splice(object.layers.indexOf(layer),1)
|
||||||
|
updateLayers()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteLayer: {
|
||||||
|
create: (layer) => {
|
||||||
|
redoStack.length = 0
|
||||||
|
if (!(layer instanceof Layer)) {
|
||||||
|
layer = context.activeObject.activeLayer
|
||||||
|
}
|
||||||
|
let action = {
|
||||||
|
object: context.activeObject.idx,
|
||||||
|
layer: layer.idx,
|
||||||
|
index: context.activeObject.layers.indexOf(layer)
|
||||||
|
}
|
||||||
|
undoStack.push({name: 'deleteLayer', action: action})
|
||||||
|
actions.deleteLayer.execute(action)
|
||||||
|
updateMenu()
|
||||||
|
},
|
||||||
|
execute: (action) => {
|
||||||
|
let object = pointerList[action.object]
|
||||||
|
let layer = pointerList[action.layer]
|
||||||
|
object.layers.splice(object.layers.indexOf(layer),1)
|
||||||
|
updateLayers()
|
||||||
|
},
|
||||||
|
rollback: (action) => {
|
||||||
|
let object = pointerList[action.object]
|
||||||
|
let layer = pointerList[action.layer]
|
||||||
|
object.layers.splice(action.index,0,layer)
|
||||||
|
updateLayers()
|
||||||
|
}
|
||||||
|
},
|
||||||
editFrame: {
|
editFrame: {
|
||||||
create: (frame) => {
|
create: (frame) => {
|
||||||
redoStack.length = 0; // Clear redo stack
|
redoStack.length = 0; // Clear redo stack
|
||||||
|
|
@ -1060,9 +1116,102 @@ class Layer {
|
||||||
} else {
|
} else {
|
||||||
this.idx = uuid
|
this.idx = uuid
|
||||||
}
|
}
|
||||||
|
this.name = "Layer"
|
||||||
this.frames = [new Frame("keyframe", this.idx+"-F1")]
|
this.frames = [new Frame("keyframe", this.idx+"-F1")]
|
||||||
pointerList[this.idx] = this
|
pointerList[this.idx] = this
|
||||||
}
|
}
|
||||||
|
getFrame(num) {
|
||||||
|
if (this.frames[num]) {
|
||||||
|
if (this.frames[num].frameType == "keyframe") {
|
||||||
|
return this.frames[num]
|
||||||
|
} else if (this.frames[num].frameType == "motion") {
|
||||||
|
let frameKeys = {}
|
||||||
|
let prevFrame = this.frames[num].prev
|
||||||
|
let nextFrame = this.frames[num].next
|
||||||
|
const t = (num - this.frames[num].prevIndex) / (this.frames[num].nextIndex - this.frames[num].prevIndex);
|
||||||
|
for (let key in prevFrame.keys) {
|
||||||
|
frameKeys[key] = {}
|
||||||
|
let prevKeyDict = prevFrame.keys[key]
|
||||||
|
let nextKeyDict = nextFrame.keys[key]
|
||||||
|
for (let prop in prevKeyDict) {
|
||||||
|
frameKeys[key][prop] = (1 - t) * prevKeyDict[prop] + t * nextKeyDict[prop];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
let frame = new Frame("motion", "temp")
|
||||||
|
frame.keys = frameKeys
|
||||||
|
return frame
|
||||||
|
} else if (this.frames[num].frameType == "shape") {
|
||||||
|
let prevFrame = this.frames[num].prev
|
||||||
|
let nextFrame = this.frames[num].next
|
||||||
|
const t = (num - this.frames[num].prevIndex) / (this.frames[num].nextIndex - this.frames[num].prevIndex);
|
||||||
|
let shapes = []
|
||||||
|
for (let shape1 of prevFrame.shapes) {
|
||||||
|
if (shape1.curves.length == 0) continue;
|
||||||
|
let shape2 = undefined
|
||||||
|
for (let i of nextFrame.shapes) {
|
||||||
|
if (shape1.shapeId == i.shapeId) {
|
||||||
|
shape2 = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shape2 != undefined) {
|
||||||
|
let path1 = [{type: "M", x:shape1.curves[0].points[0].x, y:shape1.curves[0].points[0].y}]
|
||||||
|
for (let curve of shape1.curves) {
|
||||||
|
path1.push({type:"C", x1:curve.points[1].x, y1:curve.points[1].y,
|
||||||
|
x2: curve.points[2].x, y2: curve.points[2].y,
|
||||||
|
x: curve.points[3].x, y:curve.points[3].y
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let path2 = []
|
||||||
|
if (shape2.curves.length > 0) {
|
||||||
|
path2.push({type: "M", x:shape2.curves[0].points[0].x, y:shape2.curves[0].points[0].y})
|
||||||
|
for (let curve of shape2.curves) {
|
||||||
|
path2.push({type:"C", x1:curve.points[1].x, y1:curve.points[1].y,
|
||||||
|
x2: curve.points[2].x, y2: curve.points[2].y,
|
||||||
|
x: curve.points[3].x, y:curve.points[3].y
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const interpolator = d3.interpolatePathCommands(path1, path2)
|
||||||
|
let current = interpolator(t)
|
||||||
|
let curves = []
|
||||||
|
let start = current.shift()
|
||||||
|
let {x, y} = start
|
||||||
|
for (let curve of current) {
|
||||||
|
curves.push(new Bezier(x, y, curve.x1, curve.y1, curve.x2, curve.y2, curve.x, curve.y))
|
||||||
|
x = curve.x
|
||||||
|
y = curve.y
|
||||||
|
}
|
||||||
|
let lineWidth = lerp(shape1.lineWidth, shape2.lineWidth, t)
|
||||||
|
let strokeStyle = lerpColor(shape1.strokeStyle, shape2.strokeStyle, t)
|
||||||
|
let fillStyle;
|
||||||
|
if (!shape1.fillImage) {
|
||||||
|
fillStyle = lerpColor(shape1.fillStyle, shape2.fillStyle, t)
|
||||||
|
}
|
||||||
|
shapes.push(new TempShape(
|
||||||
|
start.x, start.y, curves, shape1.lineWidth,
|
||||||
|
shape1.stroked, shape1.filled, strokeStyle, fillStyle
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let frame = new Frame("shape", "temp")
|
||||||
|
frame.shapes = shapes
|
||||||
|
return frame
|
||||||
|
} else {
|
||||||
|
for (let i=Math.min(num, this.frames.length-1); i>=0; i--) {
|
||||||
|
if (this.frames[i].frameType == "keyframe") {
|
||||||
|
return this.frames[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (let i=Math.min(num, this.frames.length-1); i>=0; i--) {
|
||||||
|
if (this.frames[i].frameType == "keyframe") {
|
||||||
|
return this.frames[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
copy() {
|
copy() {
|
||||||
let newLayer = new Layer()
|
let newLayer = new Layer()
|
||||||
let idxMapping = {}
|
let idxMapping = {}
|
||||||
|
|
@ -1091,12 +1240,6 @@ class AudioLayer {
|
||||||
console.log(this.sounds[sound])
|
console.log(this.sounds[sound])
|
||||||
this.sounds[sound].player.start(time)
|
this.sounds[sound].player.start(time)
|
||||||
}))
|
}))
|
||||||
// const synth = new Tone.Synth().toDestination();
|
|
||||||
// this.track = new Tone.Part(((time, note) => {
|
|
||||||
// // the notes given as the second element in the array
|
|
||||||
// // will be passed in as the second argument
|
|
||||||
// synth.triggerAttackRelease(note, "8n", time);
|
|
||||||
// }), [[0, "C2"], ["0:2", "C3"], ["0:3:2", "G2"]]).start(0);
|
|
||||||
if (!uuid) {
|
if (!uuid) {
|
||||||
this.idx = uuidv4()
|
this.idx = uuidv4()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1546,103 +1689,7 @@ class GraphicsObject {
|
||||||
return Math.max(this.layers.map((layer)=>{return layer.frames.length}))
|
return Math.max(this.layers.map((layer)=>{return layer.frames.length}))
|
||||||
}
|
}
|
||||||
getFrame(num) {
|
getFrame(num) {
|
||||||
if (this.activeLayer.frames[num]) {
|
return this.activeLayer.getFrame(num)
|
||||||
if (this.activeLayer.frames[num].frameType == "keyframe") {
|
|
||||||
return this.activeLayer.frames[num]
|
|
||||||
} else if (this.activeLayer.frames[num].frameType == "motion") {
|
|
||||||
let frameKeys = {}
|
|
||||||
let prevFrame = this.activeLayer.frames[num].prev
|
|
||||||
let nextFrame = this.activeLayer.frames[num].next
|
|
||||||
const t = (num - this.activeLayer.frames[num].prevIndex) / (this.activeLayer.frames[num].nextIndex - this.activeLayer.frames[num].prevIndex);
|
|
||||||
for (let key in prevFrame.keys) {
|
|
||||||
frameKeys[key] = {}
|
|
||||||
let prevKeyDict = prevFrame.keys[key]
|
|
||||||
let nextKeyDict = nextFrame.keys[key]
|
|
||||||
for (let prop in prevKeyDict) {
|
|
||||||
frameKeys[key][prop] = (1 - t) * prevKeyDict[prop] + t * nextKeyDict[prop];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
let frame = new Frame("motion", "temp")
|
|
||||||
frame.keys = frameKeys
|
|
||||||
return frame
|
|
||||||
} else if (this.activeLayer.frames[num].frameType == "shape") {
|
|
||||||
let prevFrame = this.activeLayer.frames[num].prev
|
|
||||||
let nextFrame = this.activeLayer.frames[num].next
|
|
||||||
const t = (num - this.activeLayer.frames[num].prevIndex) / (this.activeLayer.frames[num].nextIndex - this.activeLayer.frames[num].prevIndex);
|
|
||||||
let shapes = []
|
|
||||||
for (let shape1 of prevFrame.shapes) {
|
|
||||||
if (shape1.curves.length == 0) continue;
|
|
||||||
let shape2 = undefined
|
|
||||||
for (let i of nextFrame.shapes) {
|
|
||||||
if (shape1.shapeId == i.shapeId) {
|
|
||||||
shape2 = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shape2 != undefined) {
|
|
||||||
let path1 = [{type: "M", x:shape1.curves[0].points[0].x, y:shape1.curves[0].points[0].y}]
|
|
||||||
for (let curve of shape1.curves) {
|
|
||||||
path1.push({type:"C", x1:curve.points[1].x, y1:curve.points[1].y,
|
|
||||||
x2: curve.points[2].x, y2: curve.points[2].y,
|
|
||||||
x: curve.points[3].x, y:curve.points[3].y
|
|
||||||
})
|
|
||||||
}
|
|
||||||
let path2 = []
|
|
||||||
if (shape2.curves.length > 0) {
|
|
||||||
path2.push({type: "M", x:shape2.curves[0].points[0].x, y:shape2.curves[0].points[0].y})
|
|
||||||
for (let curve of shape2.curves) {
|
|
||||||
path2.push({type:"C", x1:curve.points[1].x, y1:curve.points[1].y,
|
|
||||||
x2: curve.points[2].x, y2: curve.points[2].y,
|
|
||||||
x: curve.points[3].x, y:curve.points[3].y
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const interpolator = d3.interpolatePathCommands(path1, path2)
|
|
||||||
let current = interpolator(t)
|
|
||||||
let curves = []
|
|
||||||
let start = current.shift()
|
|
||||||
let {x, y} = start
|
|
||||||
for (let curve of current) {
|
|
||||||
curves.push(new Bezier(x, y, curve.x1, curve.y1, curve.x2, curve.y2, curve.x, curve.y))
|
|
||||||
x = curve.x
|
|
||||||
y = curve.y
|
|
||||||
}
|
|
||||||
let lineWidth = lerp(shape1.lineWidth, shape2.lineWidth, t)
|
|
||||||
let strokeStyle = lerpColor(shape1.strokeStyle, shape2.strokeStyle, t)
|
|
||||||
let fillStyle;
|
|
||||||
if (!shape1.fillImage) {
|
|
||||||
fillStyle = lerpColor(shape1.fillStyle, shape2.fillStyle, t)
|
|
||||||
}
|
|
||||||
shapes.push(new TempShape(
|
|
||||||
start.x, start.y, curves, shape1.lineWidth,
|
|
||||||
shape1.stroked, shape1.filled, strokeStyle, fillStyle
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let frame = new Frame("shape", "temp")
|
|
||||||
frame.shapes = shapes
|
|
||||||
return frame
|
|
||||||
} else {
|
|
||||||
for (let i=Math.min(num, this.activeLayer.frames.length-1); i>=0; i--) {
|
|
||||||
if (this.activeLayer.frames[i].frameType == "keyframe") {
|
|
||||||
return this.activeLayer.frames[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (let i=Math.min(num, this.activeLayer.frames.length-1); i>=0; i--) {
|
|
||||||
if (this.activeLayer.frames[i].frameType == "keyframe") {
|
|
||||||
return this.activeLayer.frames[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
get maxFrame() {
|
|
||||||
let maxFrames = []
|
|
||||||
for (let layer of this.layers) {
|
|
||||||
maxFrames.push(layer.frames.length)
|
|
||||||
}
|
|
||||||
return Math.max(maxFrames)
|
|
||||||
}
|
}
|
||||||
bbox() {
|
bbox() {
|
||||||
let bbox;
|
let bbox;
|
||||||
|
|
@ -1679,29 +1726,32 @@ class GraphicsObject {
|
||||||
// if (this.currentFrameNum>=this.maxFrame) {
|
// if (this.currentFrameNum>=this.maxFrame) {
|
||||||
// this.currentFrameNum = 0;
|
// this.currentFrameNum = 0;
|
||||||
// }
|
// }
|
||||||
for (let shape of this.currentFrame.shapes) {
|
for (let layer of this.layers) {
|
||||||
if (context.shapeselection.indexOf(shape) >= 0) {
|
let frame = layer.getFrame(this.currentFrameNum)
|
||||||
invertPixels(ctx, fileWidth, fileHeight)
|
for (let shape of frame.shapes) {
|
||||||
}
|
if (context.shapeselection.indexOf(shape) >= 0) {
|
||||||
shape.draw(context)
|
invertPixels(ctx, fileWidth, fileHeight)
|
||||||
if (context.shapeselection.indexOf(shape) >= 0) {
|
}
|
||||||
invertPixels(ctx, fileWidth, fileHeight)
|
shape.draw(context)
|
||||||
}
|
if (context.shapeselection.indexOf(shape) >= 0) {
|
||||||
}
|
invertPixels(ctx, fileWidth, fileHeight)
|
||||||
for (let child of this.children) {
|
}
|
||||||
let idx = child.idx
|
}
|
||||||
if (idx in this.currentFrame.keys) {
|
for (let child of layer.children) {
|
||||||
child.x = this.currentFrame.keys[idx].x;
|
let idx = child.idx
|
||||||
child.y = this.currentFrame.keys[idx].y;
|
if (idx in frame.keys) {
|
||||||
child.rotation = this.currentFrame.keys[idx].rotation;
|
child.x = frame.keys[idx].x;
|
||||||
child.scale_x = this.currentFrame.keys[idx].scale_x;
|
child.y = frame.keys[idx].y;
|
||||||
child.scale_y = this.currentFrame.keys[idx].scale_y;
|
child.rotation = frame.keys[idx].rotation;
|
||||||
ctx.save()
|
child.scale_x = frame.keys[idx].scale_x;
|
||||||
child.draw(context)
|
child.scale_y = frame.keys[idx].scale_y;
|
||||||
if (true) {
|
ctx.save()
|
||||||
|
child.draw(context)
|
||||||
|
if (true) {
|
||||||
|
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
}
|
}
|
||||||
ctx.restore()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this == context.activeObject) {
|
if (this == context.activeObject) {
|
||||||
|
|
@ -3117,7 +3167,19 @@ function updateLayers() {
|
||||||
for (let layer of context.activeObject.layers) {
|
for (let layer of context.activeObject.layers) {
|
||||||
let layerHeader = document.createElement("div")
|
let layerHeader = document.createElement("div")
|
||||||
layerHeader.className = "layer-header"
|
layerHeader.className = "layer-header"
|
||||||
|
if (context.activeObject.activeLayer == layer) {
|
||||||
|
layerHeader.classList.add("active")
|
||||||
|
}
|
||||||
layerspanel.appendChild(layerHeader)
|
layerspanel.appendChild(layerHeader)
|
||||||
|
let layerName = document.createElement("div")
|
||||||
|
layerName.className = "layer-name"
|
||||||
|
layerName.innerText = layer.name
|
||||||
|
layerHeader.appendChild(layerName)
|
||||||
|
layerHeader.addEventListener("click", (e) => {
|
||||||
|
context.activeObject.currentLayer = context.activeObject.layers.indexOf(layer)
|
||||||
|
updateLayers()
|
||||||
|
updateUI()
|
||||||
|
})
|
||||||
let layerTrack = document.createElement("div")
|
let layerTrack = document.createElement("div")
|
||||||
layerTrack.className = "layer-track"
|
layerTrack.className = "layer-track"
|
||||||
framescontainer.appendChild(layerTrack)
|
framescontainer.appendChild(layerTrack)
|
||||||
|
|
@ -3360,6 +3422,22 @@ async function updateMenu() {
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const layerSubmenu = await Submenu.new({
|
||||||
|
text: "Layer",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
text: "Add Layer",
|
||||||
|
enabled: true,
|
||||||
|
action: actions.addLayer.create
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Delete Layer",
|
||||||
|
enabled: context.activeObject.layers.length > 1,
|
||||||
|
action: actions.deleteLayer.create
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
newFrameMenuItem = {
|
newFrameMenuItem = {
|
||||||
text: "New Frame",
|
text: "New Frame",
|
||||||
enabled: !activeFrame,
|
enabled: !activeFrame,
|
||||||
|
|
@ -3440,7 +3518,7 @@ async function updateMenu() {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
let items = [fileSubmenu, editSubmenu, modifySubmenu, timelineSubmenu, viewSubmenu, helpSubmenu]
|
let items = [fileSubmenu, editSubmenu, modifySubmenu, layerSubmenu, timelineSubmenu, viewSubmenu, helpSubmenu]
|
||||||
if (macOS) {
|
if (macOS) {
|
||||||
items.unshift(appSubmenu)
|
items.unshift(appSubmenu)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -322,16 +322,23 @@ button {
|
||||||
.layer-header {
|
.layer-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc( 2 * var(--lineheight));
|
height: calc( 2 * var(--lineheight));
|
||||||
background-color: #ccc;
|
background-color: #bbb;
|
||||||
border-top: 1px solid #ddd;
|
border-top: 1px solid #ddd;
|
||||||
border-bottom: 1px solid #bbb;
|
border-bottom: 1px solid #aaa;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
.layer-header.active {
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
.layer-header.audio {
|
.layer-header.audio {
|
||||||
background-color: #8281cc;
|
background-color: #8281cc;
|
||||||
border-top: 1px solid #9a99db;
|
border-top: 1px solid #9a99db;
|
||||||
border-bottom: 1px solid #817db9;
|
border-bottom: 1px solid #817db9;
|
||||||
}
|
}
|
||||||
|
.layer-name {
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
.layer-track {
|
.layer-track {
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
height: calc( 2 * var(--lineheight));
|
height: calc( 2 * var(--lineheight));
|
||||||
|
|
@ -552,6 +559,9 @@ button {
|
||||||
border-top: 1px solid #4f4f4f;
|
border-top: 1px solid #4f4f4f;
|
||||||
border-bottom: 1px solid #222222;
|
border-bottom: 1px solid #222222;
|
||||||
}
|
}
|
||||||
|
.layer-header.active {
|
||||||
|
background-color: #444;
|
||||||
|
}
|
||||||
.layer-header.audio {
|
.layer-header.audio {
|
||||||
background-color: #23253b;
|
background-color: #23253b;
|
||||||
border-top: 1px solid #403f4e;
|
border-top: 1px solid #403f4e;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue