浏览代码

添加绘制相关类

bill 2 年之前
父节点
当前提交
12b3a62bab

文件差异内容过多而无法显示
+ 1 - 1
server/test/SS-t-P1d6CwREny2/attach/sceneStore


+ 2 - 0
src/graphic/CanvasStyle/default.js

@@ -28,6 +28,7 @@ const Magnifier = {
   radius: 10,
   target: {
     radius: 100,
+    realRadius: 30,
     strokeStyle: "#2F8FFF",
     lineWidth: 3
   }
@@ -51,6 +52,7 @@ const CurveLan = {
 const Text = {
   strokeStyle: "rgb(0,0,0,1)",
   fillStyle: "rgb(0,0,0,1)",
+  fontSize: 14,
   strokeStyle_adding: "rgba(243, 255, 0, 0.8)",
   fillStyle_adding: "rgba(243, 255, 0, 0.8)",
   lineWidth: 1,

+ 3 - 2
src/graphic/Geometry/Circle.js

@@ -2,14 +2,15 @@ import VectorType from "../enum/VectorType.js";
 import SelectState from "../enum/SelectState.js";
 import Geometry from "./Geometry";
 import Constant from "../Constant.js";
+import Style from '../CanvasStyle'
 
 //不靠墙
 export default class Circle extends Geometry {
   constructor(center, radius, vectorId) {
     super();
-    this.radius = 5;
+    this.radius = Style.Circle.radius;
     this.center = null;
-    this.color = "blue";
+    this.color = Style.Circle.strokeStyle;
     this.points = []; //包含圆的4个顶点,按照顺时针的方式存入数组中,第一个元素是左上角顶点
     this.geoType = VectorType.Circle;
     this.setId(vectorId);

+ 1 - 1
src/graphic/Geometry/Img.js

@@ -25,7 +25,7 @@ export default class Img extends Geometry {
   }
 
   setImageData() {
-    return Promise((resolve, reject) => {
+    return new Promise((resolve, reject) => {
       this.imageData = new Image();
       this.imageData.src = this.src;
       this.imageData.onload = function () {

+ 2 - 1
src/graphic/Geometry/Line.js

@@ -3,6 +3,7 @@ import VectorCategory from "../enum/VectorCategory.js";
 import SelectState from "../enum/SelectState.js";
 import Geometry from "./Geometry";
 import Constant from "../Constant.js";
+import Style from "@/graphic/CanvasStyle/index.js";
 
 export default class Line extends Geometry {
   constructor(startId, endId, vectorId) {
@@ -10,7 +11,7 @@ export default class Line extends Geometry {
     this.startId = startId;
     this.endId = endId;
     this.category = VectorCategory.Line.NormalLine;
-    this.arrowColor = null; //箭头类型会用到
+    this.arrowColor = Style.Arrow.strokeStyle; //箭头类型会用到
     this.geoType = VectorType.Line;
     this.setId(vectorId);
   }

+ 9 - 0
src/graphic/Geometry/Magnifier.js

@@ -10,6 +10,8 @@ export default class Magnifier extends Geometry {
   constructor(position, vectorId) {
     super();
     this.position = {};
+    this.photoUrl = null
+    this.photoImage = null
     this.popPosition = {};
     this.setPosition(position);
     this.geoType = VectorType.Magnifier;
@@ -49,4 +51,11 @@ export default class Magnifier extends Geometry {
       }
     }
   }
+
+  setPhotoUrl(url) {
+    this.photoUrl = url
+  }
+  setPhotoImage(img) {
+    this.photoImage = img
+  }
 }

+ 3 - 2
src/graphic/Geometry/Text.js

@@ -3,6 +3,7 @@ import Geometry from "./Geometry.js";
 import { mathUtil } from "../Util/MathUtil.js";
 import { coordinate } from "../Coordinate.js";
 import Constant from "../Constant.js";
+import Style from "@/graphic/CanvasStyle/index.js";
 
 //不靠墙
 export default class Text extends Geometry {
@@ -10,8 +11,8 @@ export default class Text extends Geometry {
     super();
     this.center = center;
     this.value = "固定点";
-    this.color = null;
-    this.fontSize = null;
+    this.color = Style.Text.fillStyle;
+    this.fontSize = Style.Text.fontSize;
     this.geoType = VectorType.Text;
     this.setId(vectorId);
   }

+ 50 - 42
src/graphic/Renderer/Draw.js

@@ -121,23 +121,19 @@ export default class Draw {
   }
 
   drawBackGroundImg(vector) {
-    help.getImage(vector.src)
-      .then(img => {
-        const width = help.getReal(img.width)
-        const height = help.getReal(img.height)
-        const center = coordinate.getScreenXY({x: 0, y: 0});
-        this.context.save();
-        this.context.drawImage(
-          img,
-          center.x - width / 2,
-          center.y - height / 2,
-          width,
-          height
-        )
-        this.context.restore();
-      })
-
-
+    const img = vector.imageData
+    const width = help.getReal(img.width)
+    const height = help.getReal(img.height)
+    const center = coordinate.getScreenXY(vector.center);
+    this.context.save();
+    this.context.drawImage(
+      img,
+      center.x - width / 2,
+      center.y - height / 2,
+      width,
+      height
+    )
+    this.context.restore();
   }
 
   drawGrid(startX, startY, w, h, step1, step2) {
@@ -396,7 +392,7 @@ export default class Draw {
     const ctx = this.context
 
     const ange = 30
-    const L = 8;
+    const L = 20;
     let a = Math.atan2((end.y - start.y), (end.x - start.x));
     let xC = end.x - L * Math.cos(a + ange * Math.PI/180); // θ=30
     let yC = end.y - L * Math.sin(a + ange * Math.PI/180);
@@ -462,29 +458,41 @@ export default class Draw {
       ctx.lineTo(targetPts[1].x, targetPts[1].y)
       ctx.stroke();
 
-      imgCache[Object.keys(imgCache)[0]].then(img => {
-        const size = help.getReal(style.target.radius);
-        ctx.save();
-        ctx.beginPath()
-        ctx.arc(target.x, target.y, size, 0, 2*Math.PI);
-        ctx.clip()
-        ctx.drawImage(
-          img,
-          vector.position.x - style.target.radius,
-          vector.position.y - style.target.radius,
-          style.target.radius*2,
-          style.target.radius*2,
-          target.x - size,
-          target.y - size,
-          size*2,
-          size*2
-        );
-        ctx.strokeStyle = style.target.strokeStyle
-        ctx.lineWidth = style.target.lineWidth
-        ctx.stroke()
-        ctx.restore();
-      })
-
+      let img, imgBound
+      if (vector.photoImage) {
+        img = vector.photoImage
+        imgBound = [0, 0, img.width, img.height]
+      } else {
+        const size = style.target.realRadius
+        const backImg = dataService.getBackgroundImg()
+        img = backImg.imageData
+        const imgCenter = coordinate.getScreenXY(backImg.center)
+        const start = {
+          x: imgCenter.x - img.width / 2,
+          y: imgCenter.y - img.height / 2
+        }
+        imgBound = [
+          pt.x - start.x - size,
+          pt.y - start.y - size,
+          size * 2,
+          size * 2
+        ]
+      }
+      const size = help.getReal(style.target.radius);
+      ctx.beginPath()
+      ctx.arc(target.x, target.y, size, 0, 2*Math.PI);
+      ctx.clip()
+      ctx.drawImage(
+        img,
+        ...imgBound,
+        target.x - size,
+        target.y - size,
+        size*2,
+        size*2
+      );
+      ctx.strokeStyle = style.target.strokeStyle
+      ctx.lineWidth = style.target.lineWidth
+      ctx.stroke()
     }
     ctx.restore();
   }
@@ -496,7 +504,7 @@ export default class Draw {
       ...element.center
     });
 
-    console.log(element)
+    element.points.forEach(point => this.drawPoint(point))
   }
 
   drawPoint(vector) {

+ 6 - 1
src/hook/useGraphic.ts

@@ -8,10 +8,15 @@ import {getStaticFile} from "@/dbo/main";
 
 export type UITypeT = typeof UIType
 export type VectorTypeT = typeof VectorType
+export type FocusVector = {
+  type: VectorTypeT[keyof VectorTypeT],
+  category?: VectorTypeT[keyof VectorTypeT],
+  vectorId: string
+}
 
 const newsletter = ref<{
   selectUI?: UITypeT[keyof UITypeT]
-  focusVector?: { type: VectorTypeT[keyof VectorTypeT], category?: VectorTypeT[keyof VectorTypeT], vectorId: string }
+  focusVector?: FocusVector
 }>({ selectUI: null, focusVector: null });
 
 export const graphicState = ref({

+ 17 - 4
src/views/graphic/geos/arrow.vue

@@ -16,12 +16,25 @@
 import GeoTeleport from "@/views/graphic/geos/geo-teleport.vue";
 import UiInput from "@/components/base/components/input/index.vue";
 import UiIcon from "@/components/base/components/icon/index.vue";
-import { uiType, UIType } from '@/hook/useGraphic'
-import {ref} from "vue";
-
-const props = defineProps<{geo: any}>()
+import {drawRef, FocusVector, uiType, UIType} from '@/hook/useGraphic'
+import {computed, ref, watch, watchEffect} from "vue";
+import {dataService} from "@/graphic/Service/DataService";
+import {debounce} from "@/utils";
 
+const props = defineProps<{geo: FocusVector}>()
+const vector = computed(() => dataService.getLine(props.geo.vectorId))
 const color = ref("#000000")
+watchEffect(() => {
+  color.value = vector.value.arrowColor
+})
+watch(
+  () => [color.value],
+  debounce(([color]) => {
+    vector.value.setArrowColor(color)
+    drawRef.value.renderer.autoRedraw()
+  }, 500)
+)
+
 const menus = [
   {
     key: 'color',

+ 16 - 3
src/views/graphic/geos/circle.vue

@@ -15,12 +15,25 @@
 import GeoTeleport from "@/views/graphic/geos/geo-teleport.vue";
 import UiInput from "@/components/base/components/input/index.vue";
 import UiIcon from "@/components/base/components/icon/index.vue";
-import { uiType, UIType } from '@/hook/useGraphic'
-import {ref} from "vue";
+import {drawRef, FocusVector, uiType, UIType} from '@/hook/useGraphic'
+import {computed, ref, watch, watchEffect} from "vue";
+import {dataService} from "@/graphic/Service/DataService";
+import {debounce} from "@/utils";
 
-const props = defineProps<{geo: any}>()
 
+const props = defineProps<{geo: FocusVector}>()
+const vector = computed(() => dataService.getCircle(props.geo.vectorId))
 const color = ref("#000000")
+watchEffect(() => {
+  color.value = vector.value.color
+})
+watch(
+  () => [color.value],
+  debounce(([color]) => {
+    vector.value.setColor(color)
+    drawRef.value.renderer.autoRedraw()
+  }, 500)
+)
 const menus = [
   {
     key: 'color',

+ 20 - 6
src/views/graphic/geos/magnifier.vue

@@ -15,10 +15,14 @@
 import GeoTeleport from "@/views/graphic/geos/geo-teleport.vue";
 import UiInput from "@/components/base/components/input/index.vue";
 import UiIcon from "@/components/base/components/icon/index.vue";
-import { uiType, UIType } from '@/hook/useGraphic'
-import {ref, watchEffect} from "vue";
+import {uploadImage} from '@/store/sync'
+import {drawRef, FocusVector, uiType, UIType} from '@/hook/useGraphic'
+import {computed, ref, watch} from "vue";
+import {dataService} from "@/graphic/Service/DataService";
+import {getStaticFile} from "@/dbo/main";
 
-const props = defineProps<{geo: any}>()
+const props = defineProps<{geo: FocusVector}>()
+const vector = computed(() => dataService.getMagnifier(props.geo.vectorId))
 const file = ref<Blob>()
 const menus = [
   {
@@ -34,9 +38,19 @@ const menus = [
   }
 ]
 
-watchEffect(() => {
-  console.log(file)
-})
+watch(
+  () => [file.value],
+  async ([blob]) => {
+    const url = getStaticFile(await uploadImage(blob))
+    const img = new Image()
+    img.src = url
+    img.onload = () => {
+      vector.value.setPhotoUrl(url)
+      vector.value.setPhotoImage(img)
+      drawRef.value.renderer.autoRedraw()
+    }
+  }
+)
 
 </script>
 

+ 24 - 7
src/views/graphic/geos/text.vue

@@ -27,19 +27,36 @@
 import GeoTeleport from "@/views/graphic/geos/geo-teleport.vue";
 import UiInput from "@/components/base/components/input/index.vue";
 import UiIcon from "@/components/base/components/icon/index.vue";
-import { uiType, UIType } from '@/hook/useGraphic'
-import {ref} from "vue";
+import {uiType, UIType, FocusVector, drawRef} from '@/hook/useGraphic'
+import {computed, ref, watch, watchEffect} from "vue";
+import {dataService} from "@/graphic/Service/DataService";
+import {debounce} from '@/utils/index'
 
-const props = defineProps<{geo: any}>()
+const props = defineProps<{geo: FocusVector}>()
+const vector = computed(() => dataService.getText(props.geo.vectorId))
+const text = ref("")
+const color = ref("#000000")
+const size = ref(18)
+
+watchEffect(() => {
+  color.value = vector.value.color
+  size.value = vector.value.fontSize
+  text.value = vector.value.value
+})
+watch(
+  () => [text.value, size.value, color.value],
+  debounce(([text, size, color]) => {
+    vector.value.setValue(text)
+    vector.value.setColor(color)
+    vector.value.setFontSize(size)
+    drawRef.value.renderer.autoRedraw()
+  }, 500)
+)
 
 const sizeOption = [];
 for (let i = 10; i < 30; i++) {
   sizeOption.push({label: i, value: i});
 }
-
-
-const color = ref("#000000")
-const size = ref(18)
 const menus = [
   {
     key: 'color',