fix(paperjs): fix scale bug
This commit is contained in:
@@ -72,6 +72,8 @@ type Action =
|
|||||||
const initialState: LabelState = new Map()
|
const initialState: LabelState = new Map()
|
||||||
|
|
||||||
const operationTypeList = [101, 102, 103, 104]
|
const operationTypeList = [101, 102, 103, 104]
|
||||||
|
let latestProjectDetailRequestSeq = 0
|
||||||
|
let latestTaskDetailRequestSeq = 0
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
const getRectPoints = ([sx, sy, w, h]: number[]) => {
|
const getRectPoints = ([sx, sy, w, h]: number[]) => {
|
||||||
@@ -200,8 +202,17 @@ const LabelPage = ({
|
|||||||
|
|
||||||
const asyncGetProjectDetail = useCallback(async () => {
|
const asyncGetProjectDetail = useCallback(async () => {
|
||||||
if (projectId) {
|
if (projectId) {
|
||||||
|
const requestSeq = ++latestProjectDetailRequestSeq
|
||||||
try {
|
try {
|
||||||
const res = await getProjectDetail(projectId)
|
const res = await getProjectDetail(projectId)
|
||||||
|
if (requestSeq !== latestProjectDetailRequestSeq) {
|
||||||
|
console.warn("[LabelNossr] ignore stale project detail response", {
|
||||||
|
projectId,
|
||||||
|
requestSeq,
|
||||||
|
latestRequestSeq: latestProjectDetailRequestSeq,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
setProjectDetail(res)
|
setProjectDetail(res)
|
||||||
let operations: Project.LabelSchemaList[] = []
|
let operations: Project.LabelSchemaList[] = []
|
||||||
let textOperations: Project.LabelSchemaList[] = []
|
let textOperations: Project.LabelSchemaList[] = []
|
||||||
@@ -362,6 +373,7 @@ const LabelPage = ({
|
|||||||
|
|
||||||
const asyncGetTaskDetail = useCallback(async () => {
|
const asyncGetTaskDetail = useCallback(async () => {
|
||||||
if (taskId) {
|
if (taskId) {
|
||||||
|
const requestSeq = ++latestTaskDetailRequestSeq
|
||||||
try {
|
try {
|
||||||
usePaperStore.getState().setLoadingData(true)
|
usePaperStore.getState().setLoadingData(true)
|
||||||
// 获取当前任务全量数据
|
// 获取当前任务全量数据
|
||||||
@@ -371,8 +383,24 @@ const LabelPage = ({
|
|||||||
page_number: 1,
|
page_number: 1,
|
||||||
page_size: 1,
|
page_size: 1,
|
||||||
})
|
})
|
||||||
|
if (requestSeq !== latestTaskDetailRequestSeq) {
|
||||||
|
console.warn("[LabelNossr] ignore stale task list response", {
|
||||||
|
taskId,
|
||||||
|
requestSeq,
|
||||||
|
latestRequestSeq: latestTaskDetailRequestSeq,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
let detail = res.task_list[0]
|
let detail = res.task_list[0]
|
||||||
detail = await normalizeVideoTaskData(detail)
|
detail = await normalizeVideoTaskData(detail)
|
||||||
|
if (requestSeq !== latestTaskDetailRequestSeq) {
|
||||||
|
console.warn("[LabelNossr] ignore stale normalized task response", {
|
||||||
|
taskId,
|
||||||
|
requestSeq,
|
||||||
|
latestRequestSeq: latestTaskDetailRequestSeq,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
setTaskDetail(detail)
|
setTaskDetail(detail)
|
||||||
// 帧列表
|
// 帧列表
|
||||||
useBottomToolsStore
|
useBottomToolsStore
|
||||||
@@ -383,6 +411,14 @@ const LabelPage = ({
|
|||||||
let turn1time = 1
|
let turn1time = 1
|
||||||
let turn2time = 1
|
let turn2time = 1
|
||||||
const flowRes = await getTaskWorkFlow(taskId)
|
const flowRes = await getTaskWorkFlow(taskId)
|
||||||
|
if (requestSeq !== latestTaskDetailRequestSeq) {
|
||||||
|
console.warn("[LabelNossr] ignore stale workflow response", {
|
||||||
|
taskId,
|
||||||
|
requestSeq,
|
||||||
|
latestRequestSeq: latestTaskDetailRequestSeq,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
flowRes.forEach((item) => {
|
flowRes.forEach((item) => {
|
||||||
if (item.task_status_src !== 4 && item.task_status_dst === 4) {
|
if (item.task_status_src !== 4 && item.task_status_dst === 4) {
|
||||||
flowCommentArr.push({
|
flowCommentArr.push({
|
||||||
@@ -424,6 +460,14 @@ const LabelPage = ({
|
|||||||
})
|
})
|
||||||
// 获取并处理当前任务标注结果数据
|
// 获取并处理当前任务标注结果数据
|
||||||
const dataRes = await getLabelResult(taskId)
|
const dataRes = await getLabelResult(taskId)
|
||||||
|
if (requestSeq !== latestTaskDetailRequestSeq) {
|
||||||
|
console.warn("[LabelNossr] ignore stale label result response", {
|
||||||
|
taskId,
|
||||||
|
requestSeq,
|
||||||
|
latestRequestSeq: latestTaskDetailRequestSeq,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
const { results } = dataRes
|
const { results } = dataRes
|
||||||
const resultImageEntries = results.flatMap((item) =>
|
const resultImageEntries = results.flatMap((item) =>
|
||||||
expandLabelResultImages(item)
|
expandLabelResultImages(item)
|
||||||
@@ -714,6 +758,7 @@ const LabelPage = ({
|
|||||||
useDescToolsStore.getState().updateFlag(true)
|
useDescToolsStore.getState().updateFlag(true)
|
||||||
useRightToolsStore.getState().setPathGroupMap(pathGroupData)
|
useRightToolsStore.getState().setPathGroupMap(pathGroupData)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (requestSeq !== latestTaskDetailRequestSeq) return
|
||||||
console.log(err)
|
console.log(err)
|
||||||
setOldWorkLoad(null)
|
setOldWorkLoad(null)
|
||||||
setTaskDetail(undefined)
|
setTaskDetail(undefined)
|
||||||
@@ -729,7 +774,9 @@ const LabelPage = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
usePaperStore.getState().setLoadingData(false)
|
if (requestSeq === latestTaskDetailRequestSeq) {
|
||||||
|
usePaperStore.getState().setLoadingData(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
|
|||||||
@@ -633,6 +633,52 @@ const PaperContainer = (
|
|||||||
let operationSchema = getOperationSchema(operationId)
|
let operationSchema = getOperationSchema(operationId)
|
||||||
|
|
||||||
if (operationSchema && imageData) {
|
if (operationSchema && imageData) {
|
||||||
|
const toPaperPoint = (segment: any): paper.Point | null => {
|
||||||
|
if (segment instanceof paper.Point) return segment
|
||||||
|
if (segment instanceof paper.Segment) {
|
||||||
|
return new paper.Point(segment.point)
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Array.isArray(segment) &&
|
||||||
|
segment.length >= 2 &&
|
||||||
|
typeof segment[0] === "number" &&
|
||||||
|
typeof segment[1] === "number"
|
||||||
|
) {
|
||||||
|
return new paper.Point(segment[0], segment[1])
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Array.isArray(segment) &&
|
||||||
|
Array.isArray(segment[0]) &&
|
||||||
|
segment[0].length >= 2 &&
|
||||||
|
typeof segment[0][0] === "number" &&
|
||||||
|
typeof segment[0][1] === "number"
|
||||||
|
) {
|
||||||
|
return new paper.Point(segment[0][0], segment[0][1])
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
segment?.point &&
|
||||||
|
typeof segment.point.x === "number" &&
|
||||||
|
typeof segment.point.y === "number"
|
||||||
|
) {
|
||||||
|
return new paper.Point(segment.point.x, segment.point.y)
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
segment?.point &&
|
||||||
|
Array.isArray(segment.point) &&
|
||||||
|
segment.point.length >= 2 &&
|
||||||
|
typeof segment.point[0] === "number" &&
|
||||||
|
typeof segment.point[1] === "number"
|
||||||
|
) {
|
||||||
|
return new paper.Point(segment.point[0], segment.point[1])
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const toPaperPoints = (segments: any[]) => {
|
||||||
|
return segments
|
||||||
|
.map((segment) => toPaperPoint(segment))
|
||||||
|
.filter((point): point is paper.Point => point !== null)
|
||||||
|
}
|
||||||
|
|
||||||
let strokeColor = `rgb(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]})`
|
let strokeColor = `rgb(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]})`
|
||||||
let fillColor = `rgba(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]},0.3)`
|
let fillColor = `rgba(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]},0.3)`
|
||||||
let blankColor = `rgba(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]},0.01)`
|
let blankColor = `rgba(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]},0.01)`
|
||||||
@@ -646,69 +692,65 @@ const PaperContainer = (
|
|||||||
case "多边形":
|
case "多边形":
|
||||||
paths?.forEach((item) => {
|
paths?.forEach((item) => {
|
||||||
let outerPaths =
|
let outerPaths =
|
||||||
item[1]?.map((child) => {
|
item[1]
|
||||||
return addPolygon(
|
?.map((child) => {
|
||||||
renderPath,
|
const points = toPaperPoints(child)
|
||||||
child.map((segment: any) => {
|
if (!points.length) return null
|
||||||
if (segment instanceof paper.Point) {
|
return addPolygon(
|
||||||
return segment
|
renderPath,
|
||||||
} else {
|
points,
|
||||||
return new paper.Point(segment[0], segment[1])
|
{
|
||||||
|
strokeColor: strokeColor,
|
||||||
|
strokeWidth: 2,
|
||||||
|
// fillColor: fillColor,
|
||||||
|
fillColor: blankColor,
|
||||||
|
visible:
|
||||||
|
!paperPathStatus[activeImage + item[0]]?.["HIDE"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "polygon",
|
||||||
|
id: item[0],
|
||||||
|
imageId: activeImage,
|
||||||
|
operationId: operationId,
|
||||||
|
fillColor: fillColor,
|
||||||
|
blankColor: blankColor,
|
||||||
|
selected: paperSelectedPath[activeImage]?.includes(
|
||||||
|
item[0]
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}),
|
)
|
||||||
{
|
})
|
||||||
strokeColor: strokeColor,
|
.filter((path): path is paper.Path => !!path) || []
|
||||||
strokeWidth: 2,
|
|
||||||
// fillColor: fillColor,
|
|
||||||
fillColor: blankColor,
|
|
||||||
visible:
|
|
||||||
!paperPathStatus[activeImage + item[0]]?.["HIDE"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "polygon",
|
|
||||||
id: item[0],
|
|
||||||
imageId: activeImage,
|
|
||||||
operationId: operationId,
|
|
||||||
fillColor: fillColor,
|
|
||||||
blankColor: blankColor,
|
|
||||||
selected: paperSelectedPath[activeImage]?.includes(
|
|
||||||
item[0]
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}) || []
|
|
||||||
let innerPaths =
|
let innerPaths =
|
||||||
item[3]?.map((child) => {
|
item[3]
|
||||||
return addPolygon(
|
?.map((child) => {
|
||||||
renderPath,
|
const points = toPaperPoints(child)
|
||||||
child.map((segment: any) => {
|
if (!points.length) return null
|
||||||
if (segment instanceof paper.Point) {
|
return addPolygon(
|
||||||
return segment
|
renderPath,
|
||||||
} else {
|
points,
|
||||||
return new paper.Point(segment[0], segment[1])
|
{
|
||||||
|
strokeColor: strokeColor,
|
||||||
|
strokeWidth: 2,
|
||||||
|
fillColor: fillColor,
|
||||||
|
visible:
|
||||||
|
!paperPathStatus[activeImage + item[0]]?.["HIDE"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "polygon",
|
||||||
|
id: item[0],
|
||||||
|
imageId: activeImage,
|
||||||
|
operationId: operationId,
|
||||||
|
fillColor: fillColor,
|
||||||
|
blankColor: blankColor,
|
||||||
|
selected: paperSelectedPath[activeImage]?.includes(
|
||||||
|
item[0]
|
||||||
|
),
|
||||||
|
isHollowPolygon: true,
|
||||||
}
|
}
|
||||||
}),
|
)
|
||||||
{
|
})
|
||||||
strokeColor: strokeColor,
|
.filter((path): path is paper.Path => !!path) || []
|
||||||
strokeWidth: 2,
|
|
||||||
fillColor: fillColor,
|
|
||||||
visible:
|
|
||||||
!paperPathStatus[activeImage + item[0]]?.["HIDE"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "polygon",
|
|
||||||
id: item[0],
|
|
||||||
imageId: activeImage,
|
|
||||||
operationId: operationId,
|
|
||||||
fillColor: fillColor,
|
|
||||||
blankColor: blankColor,
|
|
||||||
selected: paperSelectedPath[activeImage]?.includes(
|
|
||||||
item[0]
|
|
||||||
),
|
|
||||||
isHollowPolygon: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}) || []
|
|
||||||
|
|
||||||
addCompoundPath(
|
addCompoundPath(
|
||||||
renderCompoundPath,
|
renderCompoundPath,
|
||||||
@@ -767,10 +809,8 @@ const PaperContainer = (
|
|||||||
item[1]?.forEach((child) => {
|
item[1]?.forEach((child) => {
|
||||||
// 保存前排好序
|
// 保存前排好序
|
||||||
child.forEach((segment: any, segmentIndex: number) => {
|
child.forEach((segment: any, segmentIndex: number) => {
|
||||||
let point =
|
let point = toPaperPoint(segment)
|
||||||
segment instanceof paper.Segment
|
if (!point) return
|
||||||
? new paper.Point(segment.point)
|
|
||||||
: new paper.Point(segment[0], segment[1])
|
|
||||||
addPoint(
|
addPoint(
|
||||||
renderCircle,
|
renderCircle,
|
||||||
point,
|
point,
|
||||||
@@ -788,15 +828,11 @@ const PaperContainer = (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
const points = toPaperPoints(child)
|
||||||
|
if (!points.length) return
|
||||||
addPointLine(
|
addPointLine(
|
||||||
renderPath,
|
renderPath,
|
||||||
child.map((segment: any) => {
|
points,
|
||||||
if (segment instanceof paper.Segment) {
|
|
||||||
return new paper.Point(segment.point)
|
|
||||||
} else {
|
|
||||||
return new paper.Point(segment[0], segment[1])
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
{
|
{
|
||||||
strokeColor: strokeColor,
|
strokeColor: strokeColor,
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
@@ -819,37 +855,35 @@ const PaperContainer = (
|
|||||||
case "多线段":
|
case "多线段":
|
||||||
paths?.forEach((item) => {
|
paths?.forEach((item) => {
|
||||||
let outerPaths =
|
let outerPaths =
|
||||||
item[1]?.map((child) => {
|
item[1]
|
||||||
return addBrush(
|
?.map((child) => {
|
||||||
renderPath,
|
const points = toPaperPoints(child)
|
||||||
child.map((segment: any) => {
|
if (!points.length) return null
|
||||||
if (segment instanceof paper.Point) {
|
return addBrush(
|
||||||
return segment
|
renderPath,
|
||||||
} else {
|
points,
|
||||||
return new paper.Point(segment[0], segment[1])
|
{
|
||||||
|
strokeColor: strokeColor,
|
||||||
|
strokeWidth: 2,
|
||||||
|
// fillColor: fillColor,
|
||||||
|
fillColor: blankColor,
|
||||||
|
visible:
|
||||||
|
!paperPathStatus[activeImage + item[0]]?.["HIDE"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "brush",
|
||||||
|
id: item[0],
|
||||||
|
imageId: activeImage,
|
||||||
|
operationId: operationId,
|
||||||
|
fillColor: fillColor,
|
||||||
|
blankColor: blankColor,
|
||||||
|
selected: paperSelectedPath[activeImage]?.includes(
|
||||||
|
item[0]
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}),
|
)
|
||||||
{
|
})
|
||||||
strokeColor: strokeColor,
|
.filter((path): path is paper.Path => !!path) || []
|
||||||
strokeWidth: 2,
|
|
||||||
// fillColor: fillColor,
|
|
||||||
fillColor: blankColor,
|
|
||||||
visible:
|
|
||||||
!paperPathStatus[activeImage + item[0]]?.["HIDE"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "brush",
|
|
||||||
id: item[0],
|
|
||||||
imageId: activeImage,
|
|
||||||
operationId: operationId,
|
|
||||||
fillColor: fillColor,
|
|
||||||
blankColor: blankColor,
|
|
||||||
selected: paperSelectedPath[activeImage]?.includes(
|
|
||||||
item[0]
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}) || []
|
|
||||||
|
|
||||||
addCompoundPath(
|
addCompoundPath(
|
||||||
renderCompoundPath,
|
renderCompoundPath,
|
||||||
@@ -876,13 +910,18 @@ const PaperContainer = (
|
|||||||
case "2D框":
|
case "2D框":
|
||||||
paths?.forEach((item) => {
|
paths?.forEach((item) => {
|
||||||
item[1].forEach((child) => {
|
item[1].forEach((child) => {
|
||||||
let flag = child[0] instanceof paper.Point
|
let p = toPaperPoint(child[1])
|
||||||
let p = flag
|
let dp = toPaperPoint(child[3])
|
||||||
? child[1]
|
if (!p || !dp) {
|
||||||
: new paper.Point(child[1][0], child[1][1])
|
console.warn(
|
||||||
let dp = flag
|
"[PaperContainer] skip invalid rectangle segment",
|
||||||
? child[3]
|
{
|
||||||
: new paper.Point(child[3][0], child[3][1])
|
id: item[0],
|
||||||
|
child,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
addRectangle(
|
addRectangle(
|
||||||
renderRectangle,
|
renderRectangle,
|
||||||
@@ -1216,6 +1255,7 @@ const PaperContainer = (
|
|||||||
}, [activeImage])
|
}, [activeImage])
|
||||||
|
|
||||||
const [rasterInited, setRasterInited] = useState<boolean>(false)
|
const [rasterInited, setRasterInited] = useState<boolean>(false)
|
||||||
|
const rasterLoadRequestIdRef = useRef(0)
|
||||||
|
|
||||||
const renderAndScaleRaster = useCallback(
|
const renderAndScaleRaster = useCallback(
|
||||||
async (paperGroup: paper.Group) => {
|
async (paperGroup: paper.Group) => {
|
||||||
@@ -1224,6 +1264,24 @@ const PaperContainer = (
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
if (activeImage && projectDetail?.id) {
|
if (activeImage && projectDetail?.id) {
|
||||||
|
const requestId = ++rasterLoadRequestIdRef.current
|
||||||
|
const requestImage = activeImage
|
||||||
|
const isStaleRasterRequest = () => {
|
||||||
|
const currentImage = useBottomToolsStore.getState().activeImage
|
||||||
|
const stale =
|
||||||
|
requestId !== rasterLoadRequestIdRef.current ||
|
||||||
|
currentImage !== requestImage
|
||||||
|
if (stale) {
|
||||||
|
console.warn("[PaperContainer] ignore stale raster callback", {
|
||||||
|
requestId,
|
||||||
|
latestRequestId: rasterLoadRequestIdRef.current,
|
||||||
|
requestImage,
|
||||||
|
currentImage,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return stale
|
||||||
|
}
|
||||||
|
|
||||||
console.log(usePaperStore.getState().paperScope)
|
console.log(usePaperStore.getState().paperScope)
|
||||||
// console.log(activeImage, projectDetail?.rpath);
|
// console.log(activeImage, projectDetail?.rpath);
|
||||||
notifications.show({
|
notifications.show({
|
||||||
@@ -1245,10 +1303,12 @@ const PaperContainer = (
|
|||||||
data_type: 0,
|
data_type: 0,
|
||||||
project_id: projectDetail?.id,
|
project_id: projectDetail?.id,
|
||||||
})
|
})
|
||||||
|
if (isStaleRasterRequest()) return
|
||||||
text = `data:image/jpeg;base64,${response}`
|
text = `data:image/jpeg;base64,${response}`
|
||||||
images.set(activeImage, text)
|
images.set(activeImage, text)
|
||||||
useImagesStore.getState().setImages(images)
|
useImagesStore.getState().setImages(images)
|
||||||
}
|
}
|
||||||
|
if (isStaleRasterRequest()) return
|
||||||
if (!text) return
|
if (!text) return
|
||||||
raster = renderRaster(paperGroup, {
|
raster = renderRaster(paperGroup, {
|
||||||
source: text,
|
source: text,
|
||||||
@@ -1259,9 +1319,29 @@ const PaperContainer = (
|
|||||||
if (!raster) return
|
if (!raster) return
|
||||||
|
|
||||||
raster.onLoad = function () {
|
raster.onLoad = function () {
|
||||||
|
if (isStaleRasterRequest()) {
|
||||||
|
raster.remove()
|
||||||
|
return
|
||||||
|
}
|
||||||
// Scale the raster to fit the canvas while maintaining aspect ratio
|
// Scale the raster to fit the canvas while maintaining aspect ratio
|
||||||
let canvasWidth = paperScope.current?.view.bounds.width
|
let canvasWidth =
|
||||||
let canvasHeight = paperScope.current?.view.bounds.height
|
imgSize?.clientWidth ?? paperScope.current?.view.bounds.width
|
||||||
|
let canvasHeight =
|
||||||
|
imgSize?.clientHeight ?? paperScope.current?.view.bounds.height
|
||||||
|
|
||||||
|
if (!canvasWidth || !canvasHeight) {
|
||||||
|
console.warn(
|
||||||
|
"[PaperContainer] skip raster scale: invalid canvas",
|
||||||
|
{
|
||||||
|
requestId,
|
||||||
|
requestImage,
|
||||||
|
canvasWidth,
|
||||||
|
canvasHeight,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
raster.remove()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let scaleX = canvasWidth! / raster.bounds.width
|
let scaleX = canvasWidth! / raster.bounds.width
|
||||||
let scaleY = canvasHeight! / raster.bounds.height
|
let scaleY = canvasHeight! / raster.bounds.height
|
||||||
@@ -1271,11 +1351,35 @@ const PaperContainer = (
|
|||||||
])
|
])
|
||||||
|
|
||||||
let scale = Math.min(scaleX, scaleY) // Maintain aspect ratio
|
let scale = Math.min(scaleX, scaleY) // Maintain aspect ratio
|
||||||
|
if (!Number.isFinite(scale) || scale <= 0) {
|
||||||
|
console.warn(
|
||||||
|
"[PaperContainer] skip raster scale: invalid scale",
|
||||||
|
{
|
||||||
|
requestId,
|
||||||
|
requestImage,
|
||||||
|
scale,
|
||||||
|
scaleX,
|
||||||
|
scaleY,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
raster.remove()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 将raster以(0,0)为中心点进行缩放
|
// 将raster以(0,0)为中心点进行缩放
|
||||||
raster.scale(scale, new paper.Point(0, 0))
|
raster.scale(scale, new paper.Point(0, 0))
|
||||||
const currentImgScale =
|
const currentImgScale =
|
||||||
usePaperStore.getState().rasterScale[activeImage]
|
usePaperStore.getState().rasterScale[activeImage]
|
||||||
|
console.debug("[PaperContainer] raster scale reconcile", {
|
||||||
|
image: activeImage,
|
||||||
|
currentImgScale,
|
||||||
|
nextScale: scale,
|
||||||
|
branch: !currentImgScale
|
||||||
|
? "init-scale"
|
||||||
|
: currentImgScale !== scale
|
||||||
|
? "rescale"
|
||||||
|
: "keep",
|
||||||
|
})
|
||||||
// 当前图片无缩放比例或缩放比例不等于上次记录比例时
|
// 当前图片无缩放比例或缩放比例不等于上次记录比例时
|
||||||
if (!currentImgScale) {
|
if (!currentImgScale) {
|
||||||
setRasterScale(activeImage, scale)
|
setRasterScale(activeImage, scale)
|
||||||
@@ -1338,6 +1442,8 @@ const PaperContainer = (
|
|||||||
},
|
},
|
||||||
[
|
[
|
||||||
activeImage,
|
activeImage,
|
||||||
|
imgSize?.clientHeight,
|
||||||
|
imgSize?.clientWidth,
|
||||||
|
|
||||||
projectDetail?.id,
|
projectDetail?.id,
|
||||||
setRasterPath,
|
setRasterPath,
|
||||||
@@ -1367,6 +1473,7 @@ const PaperContainer = (
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (loadingData) return
|
if (loadingData) return
|
||||||
|
if (!imgSize?.clientWidth || !imgSize?.clientHeight) return
|
||||||
const currentGroup = usePaperStore.getState().group
|
const currentGroup = usePaperStore.getState().group
|
||||||
if (currentGroup && projectDetail) {
|
if (currentGroup && projectDetail) {
|
||||||
if (!useTopToolsStore.getState().saveCurrentScale) {
|
if (!useTopToolsStore.getState().saveCurrentScale) {
|
||||||
@@ -1382,7 +1489,14 @@ const PaperContainer = (
|
|||||||
currentGroup
|
currentGroup
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, [activeImage, loadImageAndPolygons, loadingData, projectDetail])
|
}, [
|
||||||
|
activeImage,
|
||||||
|
imgSize?.clientHeight,
|
||||||
|
imgSize?.clientWidth,
|
||||||
|
loadImageAndPolygons,
|
||||||
|
loadingData,
|
||||||
|
projectDetail,
|
||||||
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (rasterInited) {
|
if (rasterInited) {
|
||||||
|
|||||||
@@ -1,5 +1,53 @@
|
|||||||
import paper from "paper"
|
import paper from "paper"
|
||||||
|
|
||||||
|
const scaleFlatPoint = (point: any, scale: number): [number, number] => {
|
||||||
|
return [point[0] * scale, point[1] * scale]
|
||||||
|
}
|
||||||
|
|
||||||
|
const scaleSegmentToPoint = (seg: any, scale: number): any => {
|
||||||
|
if (seg instanceof paper.Point) {
|
||||||
|
return [seg.x * scale, seg.y * scale]
|
||||||
|
}
|
||||||
|
if (seg instanceof paper.Segment) {
|
||||||
|
return [seg.point.x * scale, seg.point.y * scale]
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Array.isArray(seg) &&
|
||||||
|
seg.length >= 2 &&
|
||||||
|
typeof seg[0] === "number" &&
|
||||||
|
typeof seg[1] === "number"
|
||||||
|
) {
|
||||||
|
return scaleFlatPoint(seg, scale)
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
Array.isArray(seg) &&
|
||||||
|
Array.isArray(seg[0]) &&
|
||||||
|
seg[0].length >= 2 &&
|
||||||
|
typeof seg[0][0] === "number" &&
|
||||||
|
typeof seg[0][1] === "number"
|
||||||
|
) {
|
||||||
|
// Support paper JSON segment format: [[x,y], [handleInX, handleInY], [handleOutX, handleOutY]]
|
||||||
|
return scaleFlatPoint(seg[0], scale)
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
seg?.point &&
|
||||||
|
typeof seg.point.x === "number" &&
|
||||||
|
typeof seg.point.y === "number"
|
||||||
|
) {
|
||||||
|
return [seg.point.x * scale, seg.point.y * scale]
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
seg?.point &&
|
||||||
|
Array.isArray(seg.point) &&
|
||||||
|
seg.point.length >= 2 &&
|
||||||
|
typeof seg.point[0] === "number" &&
|
||||||
|
typeof seg.point[1] === "number"
|
||||||
|
) {
|
||||||
|
return [seg.point[0] * scale, seg.point[1] * scale]
|
||||||
|
}
|
||||||
|
return seg
|
||||||
|
}
|
||||||
|
|
||||||
// 调整原始比例点位到当前图片的缩放比例
|
// 调整原始比例点位到当前图片的缩放比例
|
||||||
export const adjustPoints: (
|
export const adjustPoints: (
|
||||||
id: string,
|
id: string,
|
||||||
@@ -34,25 +82,13 @@ export const adjustPoints: (
|
|||||||
|
|
||||||
let adjustedPoints = points.map((child) => {
|
let adjustedPoints = points.map((child) => {
|
||||||
return child.map((seg: any) => {
|
return child.map((seg: any) => {
|
||||||
if (seg instanceof paper.Point) {
|
return scaleSegmentToPoint(seg, scale)
|
||||||
return [seg.x * scale, seg.y * scale]
|
|
||||||
} else if (seg instanceof paper.Segment) {
|
|
||||||
return [seg.point.x * scale, seg.point.y * scale]
|
|
||||||
} else {
|
|
||||||
return seg.map((item: any) => item * scale)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
let adjustedHollowPoints = hollowPoints.map((child) => {
|
let adjustedHollowPoints = hollowPoints.map((child) => {
|
||||||
return child.map((seg: any) => {
|
return child.map((seg: any) => {
|
||||||
if (seg instanceof paper.Point) {
|
return scaleSegmentToPoint(seg, scale)
|
||||||
return [seg.x * scale, seg.y * scale]
|
|
||||||
} else if (seg instanceof paper.Segment) {
|
|
||||||
return [seg.point.x * scale, seg.point.y * scale]
|
|
||||||
} else {
|
|
||||||
return seg.map((item: any) => item * scale)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -103,25 +139,13 @@ export const adjustAllPoints: (
|
|||||||
|
|
||||||
let adjustedPoints = points.map((child) => {
|
let adjustedPoints = points.map((child) => {
|
||||||
return child.map((seg: any) => {
|
return child.map((seg: any) => {
|
||||||
if (seg instanceof paper.Point) {
|
return scaleSegmentToPoint(seg, scale)
|
||||||
return [seg.x * scale, seg.y * scale]
|
|
||||||
} else if (seg instanceof paper.Segment) {
|
|
||||||
return [seg.point.x * scale, seg.point.y * scale]
|
|
||||||
} else {
|
|
||||||
return seg.map((item: any) => item * scale)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
let adjustedHollowPoints = hollowPoints.map((child) => {
|
let adjustedHollowPoints = hollowPoints.map((child) => {
|
||||||
return child.map((seg: any) => {
|
return child.map((seg: any) => {
|
||||||
if (seg instanceof paper.Point) {
|
return scaleSegmentToPoint(seg, scale)
|
||||||
return [seg.x * scale, seg.y * scale]
|
|
||||||
} else if (seg instanceof paper.Segment) {
|
|
||||||
return [seg.point.x * scale, seg.point.y * scale]
|
|
||||||
} else {
|
|
||||||
return seg.map((item: any) => item * scale)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user