YaolongHan 4 gadi atpakaļ
vecāks
revīzija
92aeca9453

+ 243 - 0
docs/.vuepress/components/edit/items/editimage/editimage.vue

@@ -0,0 +1,243 @@
+<template>
+  <div class="edit-line">
+    <!-- 所有按钮 -->
+    <div class="btn-list">
+      <el-button :class="[cmdStatus=='create' ? 'heightLight' : '']" size="small" @click="create">添加</el-button>
+      <el-button
+        :class="[cmdStatus=='deleteItem' ? 'heightLight' : '']"
+        size="small"
+        @click="deleteItem"
+      >删除</el-button>
+    </div>
+    <div class="content">
+      <div class="left">
+        <canvas id="edit_polygon" width="700" height="460" tabindex="0" />
+      </div>
+      <div class="line-property">
+        <el-card shadow="always">
+          <div slot="header" class="clearfix">
+            <span>属性修改</span>
+          </div>
+          <div class="always-item">
+            <span>边框宽:</span>
+            <el-input-number
+              size="small"
+              v-model="lineWidth"
+              @change="changeLineWidth"
+              :min="1"
+              :max="50"
+            ></el-input-number>
+          </div>
+          <div class="always-item">
+            <span>图展示类型:</span>
+            <el-select
+              style="width:130px"
+              size="small"
+              v-model="showType"
+              @change="changeType"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+          </div>
+          <div class="always-item">
+            <span>线颜色:</span>
+            <el-color-picker v-model="lineColor" @change="changeColor" show-alpha></el-color-picker>
+          </div>
+          <!-- <div class="always-item">
+            <span>填充色:</span>
+            <el-color-picker v-model="fillColor" @change="changeFillColor" show-alpha></el-color-picker>
+          </div>-->
+        </el-card>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { SGraphScene, SGraphView, SImageShowType } from "@persagy-web/graph/";
+import { SItemStatus } from "@persagy-web/big/lib/enums/SItemStatus";
+import { SPoint, SColor } from "@persagy-web/draw/";
+//注: 开发者引入 SImageItem 包为: import {SImageItem} from "@persagy-web/edit/";
+import { EditImageItem } from "./../../../../../guides/edit/items/src/EditImageItem";
+import { hexify } from "./../../../../public/until/rgbaUtil";
+class SScene extends SGraphScene {
+  cmdStatus = "";
+  imageItem = null;
+  constructor() {
+    super();
+  }
+  onMouseDown(event) {
+    if (this.cmdStatus == "create" && this.imageItem) {
+      this.imageItem.moveTo(event.x, event.y);
+      this.addItem(this.imageItem);
+      this.changeStatus("");
+    } else {
+      return super.onMouseDown(event);
+    }
+  }
+  //   触发cmdStatus
+  changeStatus() {}
+}
+export default {
+  name: "EditPolylineItem",
+  data() {
+    return {
+      scene: null, //场景
+      view: null, //view实例
+      isCreated: false, //是否创建完成
+      cmdStatus: "", //选中状态
+      imageItem: null, //存放创建的Item
+      lineWidth: 1, //border线宽
+      lineColor: "", //border线颜色
+      fillColor: "", //填充色
+      showType: "", //图展示类型
+      options: [
+        {
+          value: "Full",
+          label: "铺满"
+        },
+        {
+          value: "AutoFit",
+          label: "自适应"
+        },
+        {
+          value: "Equivalency",
+          label: "等比缩放"
+        }
+      ]
+    };
+  },
+  mounted() {
+    this.view = new SGraphView("edit_polygon");
+    this.scene = new SScene();
+    this.view.scene = this.scene;
+    this.scene.changeStatus = this.changeStatus
+  },
+  methods: {
+    create() {
+      this.cmdStatus = "create";
+      this.scene.root.children = [];
+      this.imageItem = new EditImageItem(null);
+      this.imageItem.url =
+        "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1591685374103&di=cd5a56b2e3f5e12d7145b967afbcfb7a&imgtype=0&src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201408%2F05%2F20140805191039_cuTPn.jpeg";
+      this.imageItem.width = 100;
+      this.imageItem.height = 100;
+      this.imageItem.moveable = true;
+      this.scene.imageItem = this.imageItem;
+    },
+    deleteItem() {
+      this.cmdStatus = "";
+      this.scene.removeItem(this.imageItem);
+      this.imageItem = null;
+      this.view.update();
+    },
+    edit() {
+      if (this.imageItem) {
+        if (this.imageItem.status == SItemStatus.Normal) {
+          this.scene.grabItem = this.imageItem;
+          this.imageItem.status = SItemStatus.Edit;
+          // this.imageItem.verAndLeve = false;
+          this.cmdStatus = "edit";
+        } else {
+          this.imageItem.status = SItemStatus.Normal;
+          this.scene.grabItem = null;
+          this.cmdStatus = "";
+        }
+      }
+    },
+    eqDrawLine() {
+      this.cmdStatus = "eqDrawLine";
+      this.scene.root.children = [];
+      //   this.imageItem = new EditPolylineItem(null, []);
+      this.imageItem.verAndLeve = true;
+      this.imageItem.status = SItemStatus.Create;
+      this.imageItem.connect("finishCreated", this, this.finishCreated);
+      this.imageItem.moveable = true;
+      this.scene.addItem(this.imageItem);
+      this.view.update();
+    },
+    // 改变线宽属性
+    changeLineWidth(val) {
+      if (this.imageItem) {
+        this.lineWidth = val;
+        this.imageItem.lineWidth = val;
+      }
+    },
+    // 改变颜色
+    changeColor(val) {
+      if (this.imageItem) {
+        this.lineColor = hexify(val);
+        this.imageItem.strokeColor = new SColor(this.lineColor);
+      }
+    },
+    // 改变填充颜色
+    changeFillColor(val) {
+      if (this.imageItem) {
+        this.fillColor = hexify(val);
+        this.imageItem.fillColor = new SColor(this.lineColor);
+      }
+    },
+    //改变图的展示类型
+    changeType(val) {
+      if (this.imageItem) {
+        this.imageItem.showType = SImageShowType[val];
+      }
+    },
+    // 完成创建后的回调
+    changeStatus() {
+      this.cmdStatus = "";
+    }
+  },
+  watch: {
+    imageItem(val) {
+      //   if (val) {
+      //     this.lineWidth = val.lineWidth; // 线宽
+          this.showType = this.options[val.showType].value;
+      //   } else {
+      //     this.lineWidth = 0;
+      //   }
+    },
+    cmdStatus(val) {
+      this.scene.cmdStatus = val;
+    }
+  }
+};
+</script>
+
+<style scoped lang="less">
+.edit-line {
+  width: 100%;
+  height: 500px;
+  .content {
+    display: flex;
+    justify-content: flex-start;
+    .left {
+      margin-right: 20px;
+    }
+    .line-property {
+      width: 300px;
+      margin-top: 20px;
+      .always {
+        width: 100%;
+        height: 100%;
+      }
+      .always-item {
+        display: flex;
+        margin-top: 10px;
+        justify-content: space-between;
+      }
+    }
+  }
+  .heightLight {
+    color: #409eff;
+    border-color: #c6e2ff;
+    background-color: #ecf5ff;
+  }
+}
+</style>

+ 311 - 0
docs/.vuepress/components/edit/items/edittext/edittext.vue

@@ -0,0 +1,311 @@
+<template>
+  <div class="edit-line">
+    <!-- 所有按钮 -->
+    <div class="btn-list">
+      <textarea ref="aaa" autofocus class="text"></textarea>
+      <!-- <el-button @click="create">创建文本</el-button>
+      <el-button @click="undo">删除文本</el-button>
+      <el-button @click="undo">Undo</el-button>
+      <el-button @click="redo">Redo</el-button>
+      <el-button @click="reset">Reset</el-button>-->
+    </div>
+    <div class="content">
+      <div class="left">
+        <canvas @click="onMouseUp" id="edit_polygon" width="700" height="460" tabindex="0" />
+      </div>
+      <div class="line-property">
+        <el-card shadow="always">
+          <div slot="header" class="clearfix">
+            <span>属性修改</span>
+          </div>
+          <div class="always-item">
+            <span>字号:</span>
+            <el-input-number size="small" v-model="size" @change="updateSize" :min="1" :max="50"></el-input-number>
+          </div>
+          <div class="always-item">
+            <span>文本框:</span>
+            <el-input
+              v-model="text"
+              @change="handleChangeText"
+              type="textarea"
+              :autosize="{ minRows: 1, maxRows: 1}"
+              placeholder="请输入内容"
+              style="width:200px;"
+            ></el-input>
+          </div>
+          <div class="always-item">
+            <span>线颜色:</span>
+            <el-color-picker v-model="lineColor" @change="changeColor" show-alpha></el-color-picker>
+          </div>
+        </el-card>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  SGraphScene,
+  SGraphView,
+  SGraphPropertyCommand,
+  SGraphMoveCommand
+} from "@persagy-web/graph/";
+import { SUndoStack } from "@persagy-web/base/lib";
+import { SFont } from "@persagy-web/draw/lib";
+import { SPoint, SColor } from "@persagy-web/draw/";
+//注: 开发者引入 SImageItem 包为: import {SImageItem} from "@persagy-web/edit/";
+import { EditText } from "./../../../../../guides/edit/items/src/EditText";
+import { hexify } from "./../../../../public/until/rgbaUtil";
+class SScene extends SGraphScene {
+  undoStack = new SUndoStack();
+  textItem = new EditText(null);
+
+  constructor() {
+    super();
+    this.textItem.moveable = true;
+    this.textItem.x = 100;
+    this.textItem.y = 100;
+    this.addItem(this.textItem);
+    this.textItem.connect("onMove", this, this.onItemMove.bind(this));
+  }
+
+  updateText(str) {
+    if (this.textItem.text !== str) {
+      let old = this.textItem.text;
+      this.textItem.text = str;
+      this.undoStack.push(
+        new SGraphPropertyCommand(this, this.textItem, "text", old, str)
+      );
+    }
+  }
+
+  updateColor(color) {
+    if (this.textItem.color !== color) {
+      let old = this.textItem.color;
+      this.textItem.color = color;
+      this.undoStack.push(
+        new SGraphPropertyCommand(this, this.textItem, "color", old, color)
+      );
+    }
+  }
+
+  updateSize(size) {
+    if (this.textItem.font.size !== size) {
+      let old = new SFont(this.textItem.font);
+      let font = new SFont(this.textItem.font);
+      font.size = size;
+      this.textItem.font = font;
+      this.undoStack.push(
+        new SGraphPropertyCommand(this, this.textItem, "font", old, font)
+      );
+    }
+  }
+
+  onItemMove(item, ...arg) {
+    this.undoStack.push(
+      new SGraphMoveCommand(this, item, arg[0][0], arg[0][1])
+    );
+  }
+}
+
+class TestView extends SGraphView {
+  constructor() {
+    super("edit_polygon");
+  }
+}
+
+export default {
+  name: "edittext",
+  data() {
+    return {
+      scene: new SScene(),
+      text: "测试文本",
+      size: 20,
+      color: "#333333"
+    };
+  },
+  mounted() {
+    let view = new TestView();
+    this.scene.updateText(this.text);
+    this.scene.updateColor(this.color);
+    this.scene.updateSize(this.size);
+    view.scene = this.scene;
+    // this.scene.onMouseUp = this.onMouseUp;
+  },
+  methods: {
+    handleChangeText(text) {
+      this.scene.updateText(text);
+    },
+    handleChangeColor(color) {
+      this.scene.updateColor(color);
+    },
+    handleChangeSize(size) {
+      this.scene.updateSize(size);
+    },
+    undo() {
+      this.scene.undoStack.undo();
+    },
+    redo() {
+      this.scene.undoStack.redo();
+    },
+    reset() {
+      this.text = "测试文本";
+      this.size = 20;
+      this.color = "#333333";
+      this.scene.updateText(this.text);
+      this.scene.updateColor(this.color);
+      this.scene.updateSize(this.size);
+    },
+    // 改变颜色
+    changeColor(val) {
+      this.scene.updateColor(hexify(val));
+    },
+    // 设置tooltip位置
+    /**
+     * raduis 灵敏范围
+     * e 鼠标事件对象
+     * tipDom 浮动得dom
+     * boxDom 最外层盒子
+     * offset 偏移量
+     */
+    toolTipPosition(radius, e, tipDom, offset = 0) {
+      // 滚动高度
+      const screenTop =
+        document.documentElement.scrollTop || document.body.scrollTop;
+      const screenLeft =
+        document.documentElement.scrollLeft || document.body.scrollLeft;
+      radius = radius + offset;
+      const mapBox = document.getElementById("edit_polygon");
+      // 测试边界mousePosition =  1(右下) 2 (右上)3 (左上) 4 (左下)
+      const mousePosition = this.Boxboundary(radius, e, mapBox);
+      const absPosition = this.offsetTL(mapBox);
+      const absPositionLeft = absPosition.left;
+      const absPositionTop = absPosition.top;
+      const mClientY = e.clientY + screenTop;
+      const mClientX = e.clientX + screenLeft;
+      const fuzzy_model_width = tipDom.offsetWidth;
+      const fuzzy_model_height = tipDom.offsetHeight;
+      // let  offsetTL
+      if (mousePosition == 2) {
+        tipDom.style.left = `${mClientX - absPositionLeft + offset}px`;
+        tipDom.style.top = `${mClientY -
+          fuzzy_model_height -
+          absPositionTop -
+          offset}px`;
+      } else if (mousePosition == 3) {
+        tipDom.style.left = `${mClientX -
+          fuzzy_model_width -
+          absPositionLeft -
+          offset}px`;
+        tipDom.style.top = `${mClientY -
+          fuzzy_model_height -
+          absPositionTop -
+          offset}px`;
+      } else if (mousePosition == 4) {
+        tipDom.style.left = `${mClientX -
+          fuzzy_model_width -
+          absPositionLeft -
+          offset}px`;
+        tipDom.style.top = `${mClientY - absPositionTop + offset}px`;
+      } else {
+        tipDom.style.left = `${mClientX - absPositionLeft + offset}px`;
+        tipDom.style.top = `${mClientY - absPositionTop + offset}px`;
+      }
+    },
+    Boxboundary(radius, event, box) {
+      const screenTop =
+        document.documentElement.scrollTop || document.body.scrollTop;
+      const boxWidth = Number(box.style.width.slice(0, -2));
+      const boxHeight = Number(box.style.height.slice(0, -2));
+      const absPosition = this.offsetTL(box);
+      const boxClientX = absPosition.left;
+      const boxClientY = absPosition.top;
+      const mouseX = event.clientX;
+      const mouseY = event.clientY + screenTop;
+      if (mouseY >= boxClientY + boxHeight - radius) {
+        if (mouseX <= radius + boxClientX) {
+          return 2;
+        } else if (mouseX >= boxClientX + boxWidth - radius) {
+          return 3;
+        } else {
+          return 2;
+        }
+      } else if (mouseX >= boxClientX + boxWidth - radius) {
+        return 4;
+      } else {
+        return 1;
+      }
+    },
+    offsetTL(obj) {
+      //获取到body的offsetTop和offsetLeft
+      var t = 0,
+        l = 0;
+      while (obj) {
+        t = t + obj.offsetTop;
+        l = l + obj.offsetLeft;
+        obj = obj.offsetParent;
+      }
+      return {
+        top: t,
+        left: l
+      };
+    },
+    onMouseUp(event) {
+      const dom = this.$refs.aaa;
+      console.log('eventevent',event)
+      this.toolTipPosition(1, event, dom, 0);
+    }
+  },
+  watch: {
+    // cmdStatus(val) {
+    //   this.scene.cmdStatus = val;
+    // }
+  }
+};
+</script>
+
+<style scoped lang="less">
+.text {
+  // border: 0px;
+  max-height: 300px;
+  max-height: 100px;
+  min-width: 20px; /*自动适应父布局宽度*/
+  overflow: auto;
+  word-break: break-all;
+  outline: none;
+  // background: #409eff;
+  position: absolute;
+  left: 0;
+  top: 0;
+}
+.edit-line {
+  width: 100%;
+  height: 500px;
+  position: relative;
+  .content {
+    display: flex;
+    justify-content: flex-start;
+    .left {
+      margin-right: 20px;
+    }
+    .line-property {
+      width: 300px;
+      margin-top: 20px;
+      .always {
+        width: 100%;
+        height: 100%;
+      }
+      .always-item {
+        display: flex;
+        margin-top: 10px;
+        justify-content: space-between;
+      }
+    }
+  }
+  .heightLight {
+    color: #409eff;
+    border-color: #c6e2ff;
+    background-color: #ecf5ff;
+  }
+}
+</style>

+ 119 - 100
docs/.vuepress/components/scene/items/TextItem.vue

@@ -1,117 +1,136 @@
 <template>
-	<div>
-		<el-row>
-			<el-input v-model="text" @change="handleChangeText" type="textarea" :autosize="{ minRows: 1, maxRows: 1}" placeholder="请输入内容" style="width:200px;"></el-input>
-			<el-input-number v-model="size" @change="handleChangeSize" :min="1" label="字号"></el-input-number>
-			<el-color-picker v-model="color" @change="handleChangeColor" style="top: 15px;"></el-color-picker>
-			<el-button @click="undo">Undo</el-button>
-			<el-button @click="redo">Redo</el-button>
-			<el-button @click="reset">Reset</el-button>
-		</el-row>
-		<canvas id="TextItem1" width="740" height="400" tabindex="0"/>
-	</div>
+  <div>
+    <el-row>
+      <el-input
+        v-model="text"
+        @change="handleChangeText"
+        type="textarea"
+        :autosize="{ minRows: 1, maxRows: 1}"
+        placeholder="请输入内容"
+        style="width:200px;"
+      ></el-input>
+      <el-input-number v-model="size" @change="handleChangeSize" :min="1" label="字号"></el-input-number>
+      <el-color-picker v-model="color" @change="handleChangeColor" style="top: 15px;"></el-color-picker>
+      <el-button @click="undo">Undo</el-button>
+      <el-button @click="redo">Redo</el-button>
+      <el-button @click="reset">Reset</el-button>
+    </el-row>
+    <canvas id="TextItem1" width="740" height="400" tabindex="0" />
+  </div>
 </template>
 
 <script>
-	import { SUndoStack } from "@persagy-web/base/lib";
-    import { SFont } from "@persagy-web/draw/lib";
-	import { SGraphScene, SGraphView, SGraphPropertyCommand, SGraphMoveCommand, STextItem } from "@persagy-web/graph/lib";
+import { SUndoStack } from "@persagy-web/base/lib";
+import { SFont } from "@persagy-web/draw/lib";
+import {
+  SGraphScene,
+  SGraphView,
+  SGraphPropertyCommand,
+  SGraphMoveCommand,
+  STextItem
+} from "@persagy-web/graph/lib";
 
-	class SScene extends SGraphScene {
-		undoStack = new SUndoStack();
-		textItem = new STextItem(null);
+class SScene extends SGraphScene {
+  undoStack = new SUndoStack();
+  textItem = new STextItem(null);
 
-		constructor() {
-			super();
-			this.textItem.moveable = true;
-			this.textItem.x = 100;
-			this.textItem.y = 100;
-			this.addItem(this.textItem);
-			this.textItem.connect("onMove", this, this.onItemMove.bind(this));
-		}
+  constructor() {
+    super();
+    this.textItem.moveable = true;
+    this.textItem.x = 100;
+    this.textItem.y = 100;
+    this.addItem(this.textItem);
+    this.textItem.connect("onMove", this, this.onItemMove.bind(this));
+  }
 
-		updateText(str) {
-			if (this.textItem.text !== str) {
-				let old = this.textItem.text;
-				this.textItem.text = str;
-				this.undoStack.push(new SGraphPropertyCommand(this, this.textItem, "text", old, str));
-			}
-		}
-
-		updateColor(color) {
-			if (this.textItem.color !== color) {
-				let old = this.textItem.color;
-				this.textItem.color = color;
-				this.undoStack.push(new SGraphPropertyCommand(this, this.textItem, "color", old, color));
-			}
-		}
+  updateText(str) {
+    if (this.textItem.text !== str) {
+      let old = this.textItem.text;
+      this.textItem.text = str;
+      this.undoStack.push(
+        new SGraphPropertyCommand(this, this.textItem, "text", old, str)
+      );
+    }
+  }
 
-		updateSize(size) {
-			if (this.textItem.font.size !== size) {
-				let old = new SFont(this.textItem.font);
-				let font = new SFont(this.textItem.font);
-				font.size = size;
-				this.textItem.font = font;
-				this.undoStack.push(new SGraphPropertyCommand(this, this.textItem, "font", old, font));
-			}
-		}
+  updateColor(color) {
+    if (this.textItem.color !== color) {
+      let old = this.textItem.color;
+      this.textItem.color = color;
+      this.undoStack.push(
+        new SGraphPropertyCommand(this, this.textItem, "color", old, color)
+      );
+    }
+  }
 
-		onItemMove(item, ...arg) {
-            this.undoStack.push(new SGraphMoveCommand(this, item, arg[0][0], arg[0][1]));
-        }
+  updateSize(size) {
+    if (this.textItem.font.size !== size) {
+      let old = new SFont(this.textItem.font);
+      let font = new SFont(this.textItem.font);
+      font.size = size;
+      this.textItem.font = font;
+      this.undoStack.push(
+        new SGraphPropertyCommand(this, this.textItem, "font", old, font)
+      );
+    }
+  }
 
-	}
+  onItemMove(item, ...arg) {
+    this.undoStack.push(
+      new SGraphMoveCommand(this, item, arg[0][0], arg[0][1])
+    );
+  }
+}
 
-	class TestView extends SGraphView {
-        constructor() {
-			super("TextItem1");
-        }
-	}
+class TestView extends SGraphView {
+  constructor() {
+    super("TextItem1");
+  }
+}
 
-    export default {
-		data() {
-			return {
-				scene: new SScene(),
-				text: '测试文本',
-				size: 20,
-				color: "#333333",
-			}
-		},
-        mounted() {
-			let view = new TestView();
-			this.scene.updateText(this.text);
-			this.scene.updateColor(this.color);
-			this.scene.updateSize(this.size);
-			view.scene = this.scene;
-		},
-		methods: {
-			handleChangeText(text) {
-				this.scene.updateText(text);
-			},
-			handleChangeColor(color) {
-				this.scene.updateColor(color);
-			},
-			handleChangeSize(size) {
-				this.scene.updateSize(size);
-			},
-			undo() {
-				this.scene.undoStack.undo();
-			},
-			redo() {
-				this.scene.undoStack.redo();
-			},
-			reset() {
-				this.text = "测试文本";
-				this.size = 20;
-				this.color = "#333333";
-				this.scene.updateText(this.text);
-				this.scene.updateColor(this.color);
-				this.scene.updateSize(this.size);
-			}
-		},
+export default {
+  data() {
+    return {
+      scene: new SScene(),
+      text: "测试文本",
+      size: 20,
+      color: "#333333"
+    };
+  },
+  mounted() {
+    let view = new TestView();
+    this.scene.updateText(this.text);
+    this.scene.updateColor(this.color);
+    this.scene.updateSize(this.size);
+    view.scene = this.scene;
+  },
+  methods: {
+    handleChangeText(text) {
+      this.scene.updateText(text);
+    },
+    handleChangeColor(color) {
+      this.scene.updateColor(color);
+    },
+    handleChangeSize(size) {
+      this.scene.updateSize(size);
+    },
+    undo() {
+      this.scene.undoStack.undo();
+    },
+    redo() {
+      this.scene.undoStack.redo();
+    },
+    reset() {
+      this.text = "测试文本";
+      this.size = 20;
+      this.color = "#333333";
+      this.scene.updateText(this.text);
+      this.scene.updateColor(this.color);
+      this.scene.updateSize(this.size);
     }
+  }
+};
 </script>
 
 <style scoped>
-
 </style>

+ 54 - 0
docs/guides/edit/items/editImage.md

@@ -0,0 +1,54 @@
+
+# 线编辑类 ImageEditItem 示例
+::: details 目录
+[[toc]]
+:::
+
+## 绘制示例
+
+<edit-items-editimage-editimage />
+
+::: details 示例代码
+
+<<< @/docs/.vuepress/components/edit/items/editimage/editimage.vue
+
+:::
+
+## 源代码
+
+::: details 查看代码
+
+<<< @/docs/guides/edit/items/src/EditLineItem.ts
+
+:::
+
+## 代码说明
+### 1 当 LineEditItem 为编辑状态时,需要将 LineEditItem 赋给 grabItem
+``` js {4}
+ // 编辑状态时的 LineItem
+ this.lineItem = new EditLineItem(null, []);
+ this.lineItem.status = SItemStatus.Create;
+ this.scene.grabItem = this.lineItem;
+```
+### 2 当 LineEditItem 为正常状态时,需要将 grabItem 置为 null
+``` js {4}
+ // 正常状态时的 LineItem
+ this.lineItem = new EditLineItem(null, []);
+ this.lineItem.status = SItemStatus.Normal;
+ this.scene.grabItem = null;
+```
+### 3 当 LineEditItem 为试图垂直水平绘制时需要修改 verAndLeve 属性
+``` js {3}
+ // 编辑状态时的 LineItem
+ this.lineItem = new EditLineItem(null, []);
+ this.lineItem.status = SItemStatus.Create;
+ this.lineItem.verAndLeve = true;
+ this.scene.grabItem = this.lineItem;
+```
+### 4 当 LineEditItem 修改属性但是画板尚未变化时需要刷新
+``` js {4}
+ // 编辑状态时的 LineItem
+  this.lineItem = new EditLineItem(null, []);
+ this.lineItem.status = SItemStatus.Create;
+ this.view.update();
+```

+ 53 - 0
docs/guides/edit/items/editText.md

@@ -0,0 +1,53 @@
+# 图编辑类 ImageEditItem 示例
+::: details 目录
+[[toc]]
+:::
+
+## 绘制示例
+
+<edit-items-edittext-edittext />
+
+::: details 示例代码
+
+<<< @/docs/.vuepress/components/edit/items/edittext/edittext.vue
+
+:::
+
+## 源代码
+
+::: details 查看代码
+
+<<< @/docs/guides/edit/items/src/EditLineItem.ts
+
+:::
+
+## 代码说明
+### 1 当 LineEditItem 为编辑状态时,需要将 LineEditItem 赋给 grabItem
+``` js {4}
+ // 编辑状态时的 LineItem
+ this.lineItem = new EditLineItem(null, []);
+ this.lineItem.status = SItemStatus.Create;
+ this.scene.grabItem = this.lineItem;
+```
+### 2 当 LineEditItem 为正常状态时,需要将 grabItem 置为 null
+``` js {4}
+ // 正常状态时的 LineItem
+ this.lineItem = new EditLineItem(null, []);
+ this.lineItem.status = SItemStatus.Normal;
+ this.scene.grabItem = null;
+```
+### 3 当 LineEditItem 为试图垂直水平绘制时需要修改 verAndLeve 属性
+``` js {3}
+ // 编辑状态时的 LineItem
+ this.lineItem = new EditLineItem(null, []);
+ this.lineItem.status = SItemStatus.Create;
+ this.lineItem.verAndLeve = true;
+ this.scene.grabItem = this.lineItem;
+```
+### 4 当 LineEditItem 修改属性但是画板尚未变化时需要刷新
+``` js {4}
+ // 编辑状态时的 LineItem
+  this.lineItem = new EditLineItem(null, []);
+ this.lineItem.status = SItemStatus.Create;
+ this.view.update();
+```

+ 35 - 0
docs/guides/edit/items/src/EditImageItem.ts

@@ -0,0 +1,35 @@
+
+import { SPainter, SRect, SSize, SColor, SPoint } from "@persagy-web/draw";
+import { SImageShowType, STextOrigin } from "@persagy-web/graph";
+import { SGraphItem, SImageItem } from "@persagy-web/graph";
+
+/**
+ * 图片item
+ *
+ * @author  张宇(taohuzy@163.com)
+ */
+export class EditImageItem extends SImageItem {
+    constructor(parent: SGraphItem | null, url) {
+        super(parent);
+        this.url = url;
+        this.initItem();
+        this.origin = new SPoint(this.width / 2, this.height / 2);
+    }
+    // 初始化item
+    initItem() {
+        if (!this.url) {
+            this.strokeColor = SColor.Black;
+            this.width = 100;
+            this.height = 100
+        }
+    }
+
+    /**
+     * 根据显示模式计算图片的宽高
+     */
+    computeImgSize(): void {
+        super.computeImgSize();
+        this.origin = new SPoint(this.width / 2, this.height / 2);
+        this.update();
+    } // Function computeImgSize()
+} // Class SImageItem

+ 218 - 0
docs/guides/edit/items/src/EditText.ts

@@ -0,0 +1,218 @@
+import { SObjectItem } from "@persagy-web/graph/";
+import { SPainter, SRect, SColor, SFont, SPoint } from "@persagy-web/draw";
+import { SGraphItem } from "@persagy-web/graph/";
+import { SLineStyle } from "@persagy-web/graph/";
+import { STextOrigin } from "@persagy-web/graph/";
+
+/**
+ * 文本item
+ *
+ * @author  张宇(taohuzy@163.com)
+ */
+export class EditText extends SObjectItem {
+    /** 记录painter */
+    private _painter: SPainter | null = null;
+
+    /** 文本内容 */
+    private _text: string = "";
+    get text(): string {
+        return this._text;
+    }
+    set text(v: string) {
+        this._text = v;
+        this._textArr = this.text.split(/\n/g);
+        this.drawFormatText();
+        this.update();
+    }
+
+    /** 切割后的文本数组 */
+    private _textArr: string[] = [];
+
+    /** 文本颜色 */
+    private _color: SColor = new SColor("#333333");
+    get color(): SColor {
+        return this._color;
+    }
+    set color(v: SColor) {
+        this._color = v;
+        this.update();
+    }
+
+    /** 字体 */
+    private _font: SFont;
+    get font(): SFont {
+        return this._font;
+    }
+    set font(v: SFont) {
+        this._font = v;
+        this.drawFormatText();
+        this.update();
+    }
+
+    /** 背景色 */
+    private _backgroundColor: SColor = SColor.Transparent;
+    get backgroundColor(): SColor {
+        return this._backgroundColor;
+    }
+    set backgroundColor(v: SColor) {
+        this._backgroundColor = v;
+        this.update();
+    }
+
+    /** 边框色 */
+    private _strokeColor: SColor = SColor.Transparent;
+    get strokeColor(): SColor {
+        return this._strokeColor;
+    }
+    set strokeColor(v: SColor) {
+        this._strokeColor = v;
+        this.update();
+    }
+
+    /** 边框宽度 */
+    private _lineWidth: number = 1;
+    get lineWidth(): number {
+        return this._lineWidth;
+    }
+    set lineWidth(v: number) {
+        this._lineWidth = v;
+        this.update();
+    }
+
+    /** 边框样式    */
+    private _borderStyle: SLineStyle = SLineStyle.None;
+    get borderStyle(): SLineStyle {
+        return this._borderStyle;
+    }
+    set borderStyle(v: SLineStyle) {
+        this._borderStyle = v;
+        this.update();
+    }
+
+    /** 原点位置    */
+    private _originPosition: STextOrigin = STextOrigin.LeftTop;
+    get originPosition(): STextOrigin {
+        return this._originPosition;
+    }
+    set originPosition(v: STextOrigin) {
+        this._originPosition = v;
+        this.update();
+    }
+
+    /** 文本绘制最大宽 */
+    maxWidth: number | undefined = undefined;
+
+    /**
+     * 构造函数
+     *
+     * @param   parent      指向父Item
+     * @param   str         文本内容
+     */
+    constructor(parent: SGraphItem | null, str: string = "") {
+        super(parent);
+        this._text = str;
+        this._font = new SFont("sans-serif", 12);
+        this.height = 12;
+    } // Constructor
+
+    /**
+     * 对象边界区域
+     *
+     * @return  边界区域
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            -this.origin.x,
+            -this.origin.y,
+            this.width,
+            this.height
+        );
+    } // Function boundingRect()
+
+    /**
+     * 移动后处理所有坐标,并肩原点置为场景原点
+     *
+     * @param   x   x坐标
+     * @param   y   y坐标
+     * */
+    moveToOrigin(x: number, y: number): void {
+        this.moveTo(this.x + x, this.y + y);
+    } // Function moveToOrigin()
+
+    /**
+     * 绘制显示状态文本Item
+     *
+     * @param painter    绘制类
+     */
+    protected drawShowText(painter: SPainter): void {
+        painter.translate(-this.origin.x, -this.origin.y);
+        //绘制矩形轮廓
+        if (this.selected) {
+            painter.shadow.shadowBlur = 10;
+            painter.shadow.shadowColor = new SColor(`#00000033`);
+            painter.shadow.shadowOffsetX = 5;
+            painter.shadow.shadowOffsetY = 5;
+        } else {
+            painter.shadow.shadowColor = SColor.Transparent;
+        }
+        painter.brush.color = this.backgroundColor;
+        painter.pen.lineWidth = this.lineWidth;
+        painter.pen.color = this.strokeColor;
+        painter.drawRect(0, 0, this.width, this.height);
+
+        //绘制文本
+        painter.brush.color = new SColor(this.color);
+        painter.shadow.shadowColor = SColor.Transparent;
+        painter.font = this.font;
+        this._textArr.forEach((text: string, index: number) => {
+            painter.drawText(
+                text,
+                this.font.size / 4,
+                index * (this.font.size * 1.25) + this.font.size / 4,
+                this.maxWidth
+            );
+        });
+    } // Function drawShowText()
+
+    /**
+     * 根据换行切割文本,绘制多行并计算外轮廓宽高
+     *
+     */
+    protected drawFormatText(): void {
+        if (this._painter instanceof SPainter) {
+            this._painter.save();
+            this._painter.font = this.font;
+            let textMaxWidth = 0;
+            let fontSize: number = this.font.size;
+            this._textArr.forEach((text: string, index: number) => {
+                let textWidth: number = this._painter
+                    ? this._painter.textWidth(text) + fontSize / 2
+                    : fontSize / 2;
+                if (textWidth > textMaxWidth) {
+                    textMaxWidth = textWidth;
+                }
+            });
+            // 在绘制文本后计算文本的宽高
+            this.width = textMaxWidth;
+            this.height = fontSize * 1.25 * this._textArr.length + fontSize / 8;
+            // 设置原点位置(默认左上角)
+            if (this.originPosition == STextOrigin.Centrum) {
+                this.origin = new SPoint(this.width / 2, this.height / 2);
+            }
+            this._painter.restore();
+        }
+    } // Function drawFormatText()
+
+    /**
+     * Item绘制操作
+     *
+     * @param   painter      绘画类
+     */
+    onDraw(painter: SPainter): void {
+        if (!(this._painter instanceof SPainter)) {
+            this._painter = painter;
+            this.drawFormatText();
+        }
+        this.drawShowText(painter);
+    } // Function onDraw()
+} // Class STextItem

+ 2 - 0
docs/guides/index.js

@@ -81,6 +81,8 @@ const content = [
                     ["/guides/edit/items/editLine", "编辑线"],
                     ["/guides/edit/items/editPolygon", "编辑多边形"],
                     ["/guides/edit/items/editPolyline", "编辑折线"],
+                    ["/guides/edit/items/editImage", "编辑图片"],
+                    ["/guides/edit/items/editText", "编辑文字"],
                 ]
             },
             ["/guides/edit/undo/undo", "Undo示例"],