Go to frame in clip
This commit is contained in:
parent
d9a06e417a
commit
c7c2cd3744
140
src/main.js
140
src/main.js
|
|
@ -76,7 +76,51 @@ let clipboard = []
|
||||||
let tools = {
|
let tools = {
|
||||||
select: {
|
select: {
|
||||||
icon: "/assets/select.svg",
|
icon: "/assets/select.svg",
|
||||||
properties: {}
|
properties: {
|
||||||
|
"selectedObjects": {
|
||||||
|
type: "text",
|
||||||
|
label: "Selected Object",
|
||||||
|
enabled: () => context.selection.length==1,
|
||||||
|
value: {
|
||||||
|
get: () => {
|
||||||
|
if (context.selection.length==1) {
|
||||||
|
return context.selection[0].name
|
||||||
|
} else if (context.selection.length==0) {
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
return "<multiple>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: (val) => {
|
||||||
|
if (context.selection.length==1) {
|
||||||
|
actions.setName.create(context.selection[0], val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"goToFrame": {
|
||||||
|
type: "number",
|
||||||
|
label: "Go To Frame",
|
||||||
|
enabled: () => context.selection.length==1,
|
||||||
|
value: {
|
||||||
|
get: () => {
|
||||||
|
if (context.selection.length != 1) return undefined
|
||||||
|
const selectedObject = context.selection[0]
|
||||||
|
return context.activeObject.currentFrame.keys[selectedObject.idx].goToFrame
|
||||||
|
},
|
||||||
|
set: (val) => {
|
||||||
|
if (context.selection.length != 1) return undefined
|
||||||
|
const selectedObject = context.selection[0]
|
||||||
|
context.activeObject.currentFrame.keys[selectedObject.idx].goToFrame = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"play": {
|
||||||
|
type: "boolean",
|
||||||
|
label: "Play",
|
||||||
|
enabled: () => context.selection.length==1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
transform: {
|
transform: {
|
||||||
|
|
@ -842,6 +886,7 @@ let actions = {
|
||||||
context.selection.push(group)
|
context.selection.push(group)
|
||||||
}
|
}
|
||||||
updateUI()
|
updateUI()
|
||||||
|
updateInfopanel()
|
||||||
},
|
},
|
||||||
rollback: (action) => {
|
rollback: (action) => {
|
||||||
let group = pointerList[action.groupUuid]
|
let group = pointerList[action.groupUuid]
|
||||||
|
|
@ -858,6 +903,7 @@ let actions = {
|
||||||
}
|
}
|
||||||
parent.removeChild(group)
|
parent.removeChild(group)
|
||||||
updateUI()
|
updateUI()
|
||||||
|
updateInfopanel()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sendToBack: {
|
sendToBack: {
|
||||||
|
|
@ -972,6 +1018,29 @@ let actions = {
|
||||||
updateUI()
|
updateUI()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setName: {
|
||||||
|
create: (object, name) => {
|
||||||
|
redoStack.length = 0
|
||||||
|
let action = {
|
||||||
|
object: object.idx,
|
||||||
|
newName: name,
|
||||||
|
oldName: object.name
|
||||||
|
}
|
||||||
|
undoStack.push({name: 'setName', action: action})
|
||||||
|
actions.setName.execute(action)
|
||||||
|
updateMenu()
|
||||||
|
},
|
||||||
|
execute: (action) => {
|
||||||
|
let object = pointerList[action.object]
|
||||||
|
object.name = action.newName
|
||||||
|
updateInfopanel()
|
||||||
|
},
|
||||||
|
rollback: (action) => {
|
||||||
|
let object = pointerList[action.object]
|
||||||
|
object.name = action.oldName
|
||||||
|
updateInfopanel()
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
function uuidv4() {
|
function uuidv4() {
|
||||||
|
|
@ -1805,9 +1874,26 @@ class GraphicsObject {
|
||||||
get maxFrame() {
|
get maxFrame() {
|
||||||
return Math.max(this.layers.map((layer)=>{return layer.frames.length}))
|
return Math.max(this.layers.map((layer)=>{return layer.frames.length}))
|
||||||
}
|
}
|
||||||
|
advanceFrame() {
|
||||||
|
this.setFrameNum(this.currentFrameNum + 1)
|
||||||
|
}
|
||||||
|
decrementFrame() {
|
||||||
|
this.setFrameNum(this.currentFrameNum - 1)
|
||||||
|
}
|
||||||
getFrame(num) {
|
getFrame(num) {
|
||||||
return this.activeLayer.getFrame(num)
|
return this.activeLayer.getFrame(num)
|
||||||
}
|
}
|
||||||
|
setFrameNum(num) {
|
||||||
|
this.currentFrameNum = Math.max(0, Math.min(this.maxFrame, num))
|
||||||
|
if (this.currentFrame.frameType=="keyframe") {
|
||||||
|
for (let child of this.children) {
|
||||||
|
if (this.currentFrame.keys[child.idx].goToFrame != undefined) {
|
||||||
|
// Frames are 1-indexed
|
||||||
|
child.setFrameNum(this.currentFrame.keys[child.idx].goToFrame - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
bbox() {
|
bbox() {
|
||||||
let bbox;
|
let bbox;
|
||||||
for (let layer of this.layers) {
|
for (let layer of this.layers) {
|
||||||
|
|
@ -2004,6 +2090,7 @@ class GraphicsObject {
|
||||||
rotation: 0,
|
rotation: 0,
|
||||||
scale_x: 1,
|
scale_x: 1,
|
||||||
scale_y: 1,
|
scale_y: 1,
|
||||||
|
goToFrame: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeShape(shape) {
|
removeShape(shape) {
|
||||||
|
|
@ -2243,7 +2330,7 @@ function playPause() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function advanceFrame() {
|
function advanceFrame() {
|
||||||
context.activeObject.currentFrameNum += 1
|
context.activeObject.advanceFrame()
|
||||||
updateLayers()
|
updateLayers()
|
||||||
updateMenu()
|
updateMenu()
|
||||||
updateUI()
|
updateUI()
|
||||||
|
|
@ -2263,12 +2350,10 @@ function advanceFrame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function decrementFrame() {
|
function decrementFrame() {
|
||||||
if (context.activeObject.currentFrameNum > 0) {
|
context.activeObject.decrementFrame()
|
||||||
context.activeObject.currentFrameNum -= 1
|
|
||||||
updateLayers()
|
updateLayers()
|
||||||
updateMenu()
|
updateMenu()
|
||||||
updateUI()
|
updateUI()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _newFile(width, height, fps) {
|
function _newFile(width, height, fps) {
|
||||||
|
|
@ -2911,6 +2996,7 @@ function stage() {
|
||||||
}
|
}
|
||||||
context.lastMouse = mouse
|
context.lastMouse = mouse
|
||||||
updateUI()
|
updateUI()
|
||||||
|
updateInfopanel()
|
||||||
})
|
})
|
||||||
stage.addEventListener("mouseup", (e) => {
|
stage.addEventListener("mouseup", (e) => {
|
||||||
context.mouseDown = false
|
context.mouseDown = false
|
||||||
|
|
@ -2970,6 +3056,7 @@ function stage() {
|
||||||
context.activeCurve = undefined
|
context.activeCurve = undefined
|
||||||
updateUI()
|
updateUI()
|
||||||
updateMenu()
|
updateMenu()
|
||||||
|
updateInfopanel()
|
||||||
})
|
})
|
||||||
stage.addEventListener("mousemove", (e) => {
|
stage.addEventListener("mousemove", (e) => {
|
||||||
let mouse = getMousePos(stage, e)
|
let mouse = getMousePos(stage, e)
|
||||||
|
|
@ -3805,7 +3892,7 @@ function updateLayers() {
|
||||||
layerTrack.addEventListener("click", (e) => {
|
layerTrack.addEventListener("click", (e) => {
|
||||||
let mouse = getMousePos(layerTrack, e)
|
let mouse = getMousePos(layerTrack, e)
|
||||||
let frameNum = parseInt(mouse.x/25)
|
let frameNum = parseInt(mouse.x/25)
|
||||||
context.activeObject.currentFrameNum = frameNum
|
context.activeObject.setFrameNum(frameNum)
|
||||||
updateLayers()
|
updateLayers()
|
||||||
updateMenu()
|
updateMenu()
|
||||||
updateUI()
|
updateUI()
|
||||||
|
|
@ -3926,7 +4013,12 @@ function updateInfopanel() {
|
||||||
input = document.createElement("input")
|
input = document.createElement("input")
|
||||||
input.className = "infopanel-input"
|
input.className = "infopanel-input"
|
||||||
input.type = "number"
|
input.type = "number"
|
||||||
|
input.disabled = prop.enabled==undefined ? false : !prop.enabled()
|
||||||
|
if (prop.value) {
|
||||||
|
input.value = prop.value.get()
|
||||||
|
} else {
|
||||||
input.value = getProperty(context, property)
|
input.value = getProperty(context, property)
|
||||||
|
}
|
||||||
if (prop.min) {
|
if (prop.min) {
|
||||||
input.min = prop.min
|
input.min = prop.min
|
||||||
}
|
}
|
||||||
|
|
@ -3937,6 +4029,7 @@ function updateInfopanel() {
|
||||||
case "enum":
|
case "enum":
|
||||||
input = document.createElement("select")
|
input = document.createElement("select")
|
||||||
input.className = "infopanel-input"
|
input.className = "infopanel-input"
|
||||||
|
input.disabled = prop.enabled==undefined ? false : !prop.enabled()
|
||||||
let optionEl;
|
let optionEl;
|
||||||
for (let option of prop.options) {
|
for (let option of prop.options) {
|
||||||
optionEl = document.createElement("option")
|
optionEl = document.createElement("option")
|
||||||
|
|
@ -3944,21 +4037,44 @@ function updateInfopanel() {
|
||||||
optionEl.innerText = option
|
optionEl.innerText = option
|
||||||
input.appendChild(optionEl)
|
input.appendChild(optionEl)
|
||||||
}
|
}
|
||||||
|
if (prop.value) {
|
||||||
|
input.value = prop.value.get()
|
||||||
|
} else {
|
||||||
input.value = getProperty(context, property)
|
input.value = getProperty(context, property)
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "boolean":
|
case "boolean":
|
||||||
input = document.createElement("input")
|
input = document.createElement("input")
|
||||||
input.className = "infopanel-input"
|
input.className = "infopanel-input"
|
||||||
input.type = "checkbox"
|
input.type = "checkbox"
|
||||||
|
input.disabled = prop.enabled==undefined ? false : !prop.enabled()
|
||||||
|
if (prop.value) {
|
||||||
|
input.checked = prop.value.get()
|
||||||
|
} else {
|
||||||
input.checked = getProperty(context, property)
|
input.checked = getProperty(context, property)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "text":
|
||||||
|
input = document.createElement("input")
|
||||||
|
input.className = "infopanel-input"
|
||||||
|
input.disabled = prop.enabled==undefined ? false : !prop.enabled()
|
||||||
|
if (prop.value) {
|
||||||
|
input.value = prop.value.get()
|
||||||
|
} else {
|
||||||
|
input.value = getProperty(context, property)
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
input.addEventListener("input", (e) => {
|
input.addEventListener("input", (e) => {
|
||||||
switch (prop.type) {
|
switch (prop.type) {
|
||||||
case "number":
|
case "number":
|
||||||
if (!isNaN(e.target.value) && e.target.value > 0) {
|
if (!isNaN(e.target.value) && e.target.value > 0) {
|
||||||
|
if (prop.value) {
|
||||||
|
prop.value.set(parseInt(e.target.value))
|
||||||
|
} else {
|
||||||
setProperty(context, property, parseInt(e.target.value))
|
setProperty(context, property, parseInt(e.target.value))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "enum":
|
case "enum":
|
||||||
if (prop.options.indexOf(e.target.value) >= 0) {
|
if (prop.options.indexOf(e.target.value) >= 0) {
|
||||||
|
|
@ -3966,8 +4082,20 @@ function updateInfopanel() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "boolean":
|
case "boolean":
|
||||||
|
if (prop.value) {
|
||||||
|
prop.value.set(e.target.value)
|
||||||
|
} else {
|
||||||
setProperty(context, property, e.target.checked)
|
setProperty(context, property, e.target.checked)
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case "text":
|
||||||
|
if (prop.value) {
|
||||||
|
prop.value.set(e.target.value)
|
||||||
|
} else {
|
||||||
|
setProperty(context, property, parseInt(e.target.value))
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
label.appendChild(span)
|
label.appendChild(span)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue