|
@@ -1,9 +1,14 @@
|
|
|
-import { SliceImage, SpecialTag, Track } from "@/types";
|
|
|
+import { SliceImage, SpecialTag, Track, Question, SplitConfig } from "@/types";
|
|
|
import { useMarkStore } from "@/store";
|
|
|
+import { randomCode } from "@/utils/utils";
|
|
|
|
|
|
export default function useMakeTrack() {
|
|
|
const markStore = useMarkStore();
|
|
|
|
|
|
+ function getTrackId(data: { mainNumber: number; subNumber: number }): string {
|
|
|
+ return `${data.mainNumber}-${data.subNumber}-${randomCode()}`;
|
|
|
+ }
|
|
|
+
|
|
|
// 标记分数轨迹
|
|
|
function makeScoreTrack(event: MouseEvent, item: SliceImage) {
|
|
|
if (
|
|
@@ -15,6 +20,10 @@ export default function useMakeTrack() {
|
|
|
|
|
|
const target = event.target as HTMLImageElement;
|
|
|
const track: Track = {
|
|
|
+ id: getTrackId({
|
|
|
+ mainNumber: markStore.currentQuestion?.mainNumber,
|
|
|
+ subNumber: markStore.currentQuestion?.subNumber,
|
|
|
+ }),
|
|
|
mainNumber: markStore.currentQuestion?.mainNumber,
|
|
|
subNumber: markStore.currentQuestion?.subNumber,
|
|
|
score: markStore.currentScore,
|
|
@@ -89,6 +98,10 @@ export default function useMakeTrack() {
|
|
|
|
|
|
const target = event.target as HTMLImageElement;
|
|
|
const track: SpecialTag = {
|
|
|
+ id: getTrackId({
|
|
|
+ mainNumber: markStore.currentQuestion?.mainNumber,
|
|
|
+ subNumber: markStore.currentQuestion?.subNumber,
|
|
|
+ }),
|
|
|
mainNumber: markStore.currentQuestion?.mainNumber,
|
|
|
subNumber: markStore.currentQuestion?.subNumber,
|
|
|
tagName: markStore.currentSpecialTag,
|
|
@@ -131,9 +144,104 @@ export default function useMakeTrack() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ function getRandomPosition(area: SplitConfig) {
|
|
|
+ const { x, y, w, h } = area;
|
|
|
+ return {
|
|
|
+ x: x + w / 4 + (Math.random() * w) / 2,
|
|
|
+ y: y + h / 4 + (Math.random() * h) / 2,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ function checkPointInArea(
|
|
|
+ point: { x: number; y: number },
|
|
|
+ area: { x: number; y: number; w: number; h: number }
|
|
|
+ ): boolean {
|
|
|
+ return (
|
|
|
+ point.x >= area.x &&
|
|
|
+ point.x <= area.x + area.w &&
|
|
|
+ point.y >= area.y &&
|
|
|
+ point.y <= area.y + area.h
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 标记普通模式轨迹
|
|
|
+ function makeCommonTrack(question: Question, score: number) {
|
|
|
+ if (!markStore.currentTask || question.problem) return;
|
|
|
+
|
|
|
+ markStore.currentQuestion = question;
|
|
|
+ const markResult = markStore.currentTaskEnsured.markResult;
|
|
|
+ markResult.scoreList[question.__index] = score;
|
|
|
+ const questionTrack = markResult.markerTrackList.find(
|
|
|
+ (t) =>
|
|
|
+ t.mainNumber === question.mainNumber &&
|
|
|
+ t.subNumber === question.subNumber
|
|
|
+ );
|
|
|
+ // 存在轨迹时直接使用已有的轨迹位置
|
|
|
+ if (questionTrack) {
|
|
|
+ questionTrack.score = score;
|
|
|
+ // 更新渲染轨迹中的分值
|
|
|
+ let viewTrack = null;
|
|
|
+ markStore.sliceImagesWithTrackList.forEach((item) => {
|
|
|
+ if (viewTrack || item.indexInSliceUrls !== questionTrack.offsetIndex)
|
|
|
+ return;
|
|
|
+ viewTrack = item.markerTrackList.find((t) => {
|
|
|
+ return t.id === questionTrack.id;
|
|
|
+ });
|
|
|
+ if (!viewTrack) return;
|
|
|
+ viewTrack.score = score;
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 通过题目设置的第一个评卷区,随机生成一个轨迹
|
|
|
+ const { picList } = question;
|
|
|
+ const area = picList[0] || null;
|
|
|
+ if (!area) return;
|
|
|
+
|
|
|
+ const imageSize = markStore.currentTaskSliceImages[area.i];
|
|
|
+ if (!imageSize) return;
|
|
|
+
|
|
|
+ // 不存在时,在第一个评卷区的中心50%的区域随机一个点
|
|
|
+ const { x, y } = getRandomPosition(area);
|
|
|
+ const track: Track = {
|
|
|
+ id: getTrackId({
|
|
|
+ mainNumber: question.mainNumber,
|
|
|
+ subNumber: question.subNumber,
|
|
|
+ }),
|
|
|
+ mainNumber: question.mainNumber,
|
|
|
+ subNumber: question.subNumber,
|
|
|
+ score,
|
|
|
+ unanswered: false,
|
|
|
+ offsetIndex: area.i,
|
|
|
+ offsetX: imageSize.width * x,
|
|
|
+ offsetY: imageSize.height * y,
|
|
|
+ number: -1,
|
|
|
+ };
|
|
|
+ markResult.markerTrackList.push(track);
|
|
|
+ // 将轨迹更新到渲染轨迹中
|
|
|
+ markStore.sliceImagesWithTrackList.forEach((item) => {
|
|
|
+ if (item.indexInSliceUrls !== area.i) return;
|
|
|
+
|
|
|
+ if (
|
|
|
+ checkPointInArea(
|
|
|
+ { x: track.offsetX, y: track.offsetY },
|
|
|
+ {
|
|
|
+ x: item.dx,
|
|
|
+ y: item.dy,
|
|
|
+ w: item.sliceImageWidth,
|
|
|
+ h: item.sliceImageHeight,
|
|
|
+ }
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ item.markerTrackList.push(track);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
return {
|
|
|
makeScoreTrack,
|
|
|
makeSpecialTagTrack,
|
|
|
makeTrack,
|
|
|
+ makeCommonTrack,
|
|
|
};
|
|
|
}
|