draw transform handles again
This commit is contained in:
parent
9c89d131d8
commit
b94d73c976
113
src/main.js
113
src/main.js
|
|
@ -3,7 +3,7 @@ import * as fitCurve from '/fit-curve.js';
|
||||||
import { Bezier } from "/bezier.js";
|
import { Bezier } from "/bezier.js";
|
||||||
import { Quadtree } from './quadtree.js';
|
import { Quadtree } from './quadtree.js';
|
||||||
import { createNewFileDialog, showNewFileDialog, closeDialog } from './newfile.js';
|
import { createNewFileDialog, showNewFileDialog, closeDialog } from './newfile.js';
|
||||||
import { titleCase, getMousePositionFraction, getKeyframesSurrounding, invertPixels, lerpColor, lerp, camelToWords, generateWaveform, floodFillRegion, getShapeAtPoint, hslToRgb, drawCheckerboardBackground, hexToHsl, hsvToRgb, hexToHsv, rgbToHex, clamp, drawBorderedRect, drawCenteredText, drawHorizontallyCenteredText, deepMerge } from './utils.js';
|
import { titleCase, getMousePositionFraction, getKeyframesSurrounding, invertPixels, lerpColor, lerp, camelToWords, generateWaveform, floodFillRegion, getShapeAtPoint, hslToRgb, drawCheckerboardBackground, hexToHsl, hsvToRgb, hexToHsv, rgbToHex, clamp, drawBorderedRect, drawCenteredText, drawHorizontallyCenteredText, deepMerge, getPointNearBox } from './utils.js';
|
||||||
import { backgroundColor, darkMode, foregroundColor, frameWidth, gutterHeight, highlight, iconSize, labelColor, layerHeight, layerWidth, scrubberColor, shade, shadow } from './styles.js';
|
import { backgroundColor, darkMode, foregroundColor, frameWidth, gutterHeight, highlight, iconSize, labelColor, layerHeight, layerWidth, scrubberColor, shade, shadow } from './styles.js';
|
||||||
import { Icon } from './icon.js';
|
import { Icon } from './icon.js';
|
||||||
const { writeTextFile: writeTextFile, readTextFile: readTextFile, writeFile: writeFile, readFile: readFile }= window.__TAURI__.fs;
|
const { writeTextFile: writeTextFile, readTextFile: readTextFile, writeFile: writeFile, readFile: readFile }= window.__TAURI__.fs;
|
||||||
|
|
@ -2165,31 +2165,31 @@ class GraphicsObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bbox != undefined) {
|
if (bbox != undefined) {
|
||||||
// ctx.save()
|
ctx.save()
|
||||||
// ctx.strokeStyle = "#00ffff"
|
ctx.strokeStyle = "#00ffff"
|
||||||
// ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
// ctx.beginPath()
|
ctx.beginPath()
|
||||||
// let xdiff = bbox.x.max - bbox.x.min
|
let xdiff = bbox.x.max - bbox.x.min
|
||||||
// let ydiff = bbox.y.max - bbox.y.min
|
let ydiff = bbox.y.max - bbox.y.min
|
||||||
// ctx.rect(
|
ctx.rect(
|
||||||
// bbox.x.min, bbox.y.min,
|
bbox.x.min, bbox.y.min,
|
||||||
// xdiff,
|
xdiff,
|
||||||
// ydiff
|
ydiff
|
||||||
// )
|
)
|
||||||
// ctx.stroke()
|
ctx.stroke()
|
||||||
// ctx.fillStyle = "#000000"
|
ctx.fillStyle = "#000000"
|
||||||
// let rectRadius = 5
|
let rectRadius = 5
|
||||||
// for (let i of [[0,0],[0.5,0],[1,0],[1,0.5],[1,1],[0.5,1],[0,1],[0,0.5]]) {
|
for (let i of [[0,0],[0.5,0],[1,0],[1,0.5],[1,1],[0.5,1],[0,1],[0,0.5]]) {
|
||||||
// ctx.beginPath()
|
ctx.beginPath()
|
||||||
// ctx.rect(
|
ctx.rect(
|
||||||
// bbox.x.min + xdiff * i[0] - rectRadius,
|
bbox.x.min + xdiff * i[0] - rectRadius,
|
||||||
// bbox.y.min + ydiff * i[1] - rectRadius,
|
bbox.y.min + ydiff * i[1] - rectRadius,
|
||||||
// rectRadius*2, rectRadius*2
|
rectRadius*2, rectRadius*2
|
||||||
// )
|
)
|
||||||
// ctx.fill()
|
ctx.fill()
|
||||||
// }
|
}
|
||||||
|
|
||||||
// ctx.restore()
|
ctx.restore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2989,6 +2989,7 @@ function stage() {
|
||||||
stage.addEventListener("mousedown", (e) => {
|
stage.addEventListener("mousedown", (e) => {
|
||||||
let mouse = getMousePos(stage, e)
|
let mouse = getMousePos(stage, e)
|
||||||
mouse = context.activeObject.transformMouse(mouse)
|
mouse = context.activeObject.transformMouse(mouse)
|
||||||
|
let selection;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "rectangle":
|
case "rectangle":
|
||||||
case "ellipse":
|
case "ellipse":
|
||||||
|
|
@ -2999,7 +3000,7 @@ function stage() {
|
||||||
break;
|
break;
|
||||||
case "select":
|
case "select":
|
||||||
if (context.activeObject.currentFrame.frameType != "keyframe") break;
|
if (context.activeObject.currentFrame.frameType != "keyframe") break;
|
||||||
let selection = selectVertex(context, mouse)
|
selection = selectVertex(context, mouse)
|
||||||
if (selection) {
|
if (selection) {
|
||||||
context.dragging = true
|
context.dragging = true
|
||||||
context.activeCurve = undefined
|
context.activeCurve = undefined
|
||||||
|
|
@ -3070,6 +3071,42 @@ function stage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "transform":
|
||||||
|
let bbox = undefined;
|
||||||
|
selection = {}
|
||||||
|
for (let item of context.selection) {
|
||||||
|
if (bbox==undefined) {
|
||||||
|
bbox = structuredClone(item.bbox())
|
||||||
|
} else {
|
||||||
|
growBoundingBox(bbox, item.bbox())
|
||||||
|
}
|
||||||
|
selection[item.idx] = {x: item.x, y: item.y, scale_x: item.scale_x, scale_y: item.scale_y}
|
||||||
|
}
|
||||||
|
let transformPoint = getPointNearBox(bbox, mouse, 10)
|
||||||
|
if (transformPoint) {
|
||||||
|
context.dragDirection = transformPoint
|
||||||
|
context.activeTransform = {
|
||||||
|
initial: {
|
||||||
|
x: {min: bbox.x.min, max: bbox.x.max},
|
||||||
|
y: {min: bbox.y.min, max: bbox.y.max},
|
||||||
|
selection: selection
|
||||||
|
},
|
||||||
|
current: {
|
||||||
|
x: {min: bbox.x.min, max: bbox.x.max},
|
||||||
|
y: {min: bbox.y.min, max: bbox.y.max},
|
||||||
|
selection: structuredClone(selection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.activeObject.currentFrame.saveState()
|
||||||
|
} else {
|
||||||
|
transformPoint = getPointNearBox(bbox, mouse, 30, false)
|
||||||
|
if (transformPoint) {
|
||||||
|
stage.style.cursor = `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='currentColor' class='bi bi-arrow-counterclockwise' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2z'/%3E%3Cpath d='M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466'/%3E%3C/svg%3E") 12 12, auto`
|
||||||
|
} else {
|
||||||
|
stage.style.cursor = "default"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "paint_bucket":
|
case "paint_bucket":
|
||||||
let line = {p1: mouse, p2: {x: mouse.x + 3000, y: mouse.y}}
|
let line = {p1: mouse, p2: {x: mouse.x + 3000, y: mouse.y}}
|
||||||
debugCurves = []
|
debugCurves = []
|
||||||
|
|
@ -3217,6 +3254,7 @@ function stage() {
|
||||||
}
|
}
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "draw":
|
case "draw":
|
||||||
|
stage.style.cursor = "default"
|
||||||
context.activeCurve = undefined
|
context.activeCurve = undefined
|
||||||
if (context.activeShape) {
|
if (context.activeShape) {
|
||||||
if (vectorDist(mouse, context.lastMouse) > minSegmentSize) {
|
if (vectorDist(mouse, context.lastMouse) > minSegmentSize) {
|
||||||
|
|
@ -3226,6 +3264,7 @@ function stage() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "rectangle":
|
case "rectangle":
|
||||||
|
stage.style.cursor = "default"
|
||||||
context.activeCurve = undefined
|
context.activeCurve = undefined
|
||||||
if (context.activeShape) {
|
if (context.activeShape) {
|
||||||
context.activeShape.clear()
|
context.activeShape.clear()
|
||||||
|
|
@ -3237,6 +3276,7 @@ function stage() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "ellipse":
|
case "ellipse":
|
||||||
|
stage.style.cursor = "default"
|
||||||
context.activeCurve = undefined
|
context.activeCurve = undefined
|
||||||
if (context.activeShape) {
|
if (context.activeShape) {
|
||||||
let midX = (mouse.x + context.activeShape.startx) / 2
|
let midX = (mouse.x + context.activeShape.startx) / 2
|
||||||
|
|
@ -3272,6 +3312,7 @@ function stage() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "select":
|
case "select":
|
||||||
|
stage.style.cursor = "default"
|
||||||
if (context.dragging) {
|
if (context.dragging) {
|
||||||
if (context.activeVertex) {
|
if (context.activeVertex) {
|
||||||
let vert = context.activeVertex
|
let vert = context.activeVertex
|
||||||
|
|
@ -3353,6 +3394,26 @@ function stage() {
|
||||||
context.lastMouse = mouse
|
context.lastMouse = mouse
|
||||||
break;
|
break;
|
||||||
case "transform":
|
case "transform":
|
||||||
|
// stage.style.cursor = "nw-resize"
|
||||||
|
let bbox = undefined;
|
||||||
|
for (let item of context.selection) {
|
||||||
|
if (bbox==undefined) {
|
||||||
|
bbox = structuredClone(item.bbox())
|
||||||
|
} else {
|
||||||
|
growBoundingBox(bbox, item.bbox())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let point = getPointNearBox(bbox, mouse, 10)
|
||||||
|
if (point) {
|
||||||
|
stage.style.cursor = `${point}-resize`
|
||||||
|
} else {
|
||||||
|
point = getPointNearBox(bbox, mouse, 30, false)
|
||||||
|
if (point) {
|
||||||
|
stage.style.cursor = `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='currentColor' class='bi bi-arrow-counterclockwise' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2z'/%3E%3Cpath d='M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466'/%3E%3C/svg%3E") 12 12, auto`
|
||||||
|
} else {
|
||||||
|
stage.style.cursor = "default"
|
||||||
|
}
|
||||||
|
}
|
||||||
if (context.dragDirection) {
|
if (context.dragDirection) {
|
||||||
let initial = context.activeTransform.initial
|
let initial = context.activeTransform.initial
|
||||||
let current = context.activeTransform.current
|
let current = context.activeTransform.current
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue