浏览代码

split stats into general and element stats

Ryan Di 2 年之前
父节点
当前提交
30743ec726
共有 4 个文件被更改,包括 131 次插入26 次删除
  1. 2 1
      src/actions/types.ts
  2. 10 0
      src/components/Stats.scss
  3. 105 24
      src/components/Stats.tsx
  4. 14 1
      src/locales/en.json

+ 2 - 1
src/actions/types.ts

@@ -115,7 +115,8 @@ export type ActionName =
   | "toggleLinearEditor"
   | "toggleEraserTool"
   | "toggleHandTool"
-  | "createContainerFromText";
+  | "createContainerFromText"
+  | "elementStats";
 
 export type PanelComponentProps = {
   elements: readonly ExcalidrawElement[];

+ 10 - 0
src/components/Stats.scss

@@ -9,6 +9,10 @@
     z-index: 10;
     pointer-events: all;
 
+    .section {
+      padding: 12px;
+    }
+
     h3 {
       margin: 0 24px 8px 0;
       white-space: nowrap;
@@ -39,6 +43,12 @@
       }
     }
 
+    .divider {
+      width: 100%;
+      height: 1px;
+      background-color: var(--default-border-color);
+    }
+
     :root[dir="rtl"] & {
       left: 12px;
       right: initial;

+ 105 - 24
src/components/Stats.tsx

@@ -2,6 +2,7 @@ import React from "react";
 import { getCommonBounds } from "../element/bounds";
 import { NonDeletedExcalidrawElement } from "../element/types";
 import { t } from "../i18n";
+import { getTargetElements } from "../scene";
 import { AppState, ExcalidrawProps } from "../types";
 import { CloseIcon } from "./icons";
 import { Island } from "./Island";
@@ -15,34 +16,114 @@ export const Stats = (props: {
   renderCustomStats: ExcalidrawProps["renderCustomStats"];
 }) => {
   const boundingBox = getCommonBounds(props.elements);
+  const selectedElements = getTargetElements(props.elements, props.appState);
+  const selectedBoundingBox = getCommonBounds(selectedElements);
 
   return (
     <div className="Stats">
-      <Island padding={2}>
-        <div className="close" onClick={props.onClose}>
-          {CloseIcon}
+      <Island>
+        <div className="section">
+          <div className="close" onClick={props.onClose}>
+            {CloseIcon}
+          </div>
+          <h3>{t("stats.generalStats")}</h3>
+          <table>
+            <tbody>
+              <tr>
+                <th colSpan={2}>{t("stats.scene")}</th>
+              </tr>
+              <tr>
+                <td>{t("stats.elements")}</td>
+                <td>{props.elements.length}</td>
+              </tr>
+              <tr>
+                <td>{t("stats.width")}</td>
+                <td>
+                  {Math.round(boundingBox[2]) - Math.round(boundingBox[0])}
+                </td>
+              </tr>
+              <tr>
+                <td>{t("stats.height")}</td>
+                <td>
+                  {Math.round(boundingBox[3]) - Math.round(boundingBox[1])}
+                </td>
+              </tr>
+              {props.renderCustomStats?.(props.elements, props.appState)}
+            </tbody>
+          </table>
         </div>
-        <h3>{t("stats.title")}</h3>
-        <table>
-          <tbody>
-            <tr>
-              <th colSpan={2}>{t("stats.scene")}</th>
-            </tr>
-            <tr>
-              <td>{t("stats.elements")}</td>
-              <td>{props.elements.length}</td>
-            </tr>
-            <tr>
-              <td>{t("stats.width")}</td>
-              <td>{Math.round(boundingBox[2]) - Math.round(boundingBox[0])}</td>
-            </tr>
-            <tr>
-              <td>{t("stats.height")}</td>
-              <td>{Math.round(boundingBox[3]) - Math.round(boundingBox[1])}</td>
-            </tr>
-            {props.renderCustomStats?.(props.elements, props.appState)}
-          </tbody>
-        </table>
+
+        {selectedElements.length > 0 && (
+          <>
+            <div className="divider"></div>
+
+            <div className="section">
+              <h3>{t("stats.elementStats")}</h3>
+
+              <table>
+                <tbody>
+                  {selectedElements.length === 1 && (
+                    <tr>
+                      <th colSpan={2}>
+                        {t(`element.${selectedElements[0].type}`)}
+                      </th>
+                    </tr>
+                  )}
+
+                  {selectedElements.length > 1 && (
+                    <>
+                      <tr>
+                        <th colSpan={2}>{t("stats.selected")}</th>
+                      </tr>
+                      <tr>
+                        <td>{t("stats.elements")}</td>
+                        <td>{selectedElements.length}</td>
+                      </tr>
+                    </>
+                  )}
+                  {selectedElements.length > 0 && (
+                    <>
+                      <tr>
+                        <td>{"x"}</td>
+                        <td>{Math.round(selectedBoundingBox[0])}</td>
+                      </tr>
+                      <tr>
+                        <td>{"y"}</td>
+                        <td>{Math.round(selectedBoundingBox[1])}</td>
+                      </tr>
+                      <tr>
+                        <td>{t("stats.width")}</td>
+                        <td>
+                          {Math.round(
+                            selectedBoundingBox[2] - selectedBoundingBox[0],
+                          )}
+                        </td>
+                      </tr>
+                      <tr>
+                        <td>{t("stats.height")}</td>
+                        <td>
+                          {Math.round(
+                            selectedBoundingBox[3] - selectedBoundingBox[1],
+                          )}
+                        </td>
+                      </tr>
+                    </>
+                  )}
+                  {selectedElements.length === 1 && (
+                    <tr>
+                      <td>{t("stats.angle")}</td>
+                      <td>
+                        {`${Math.round(
+                          (selectedElements[0].angle * 180) / Math.PI,
+                        )}°`}
+                      </td>
+                    </tr>
+                  )}
+                </tbody>
+              </table>
+            </div>
+          </>
+        )}
       </Island>
     </div>
   );

+ 14 - 1
src/locales/en.json

@@ -239,6 +239,17 @@
     "eraser": "Eraser",
     "hand": "Hand (panning tool)"
   },
+  "element": {
+    "rectangle": "Rectangle",
+    "diamond": "Diamond",
+    "ellipse": "Ellipse",
+    "arrow": "Arrow",
+    "line": "Line",
+    "freeDraw": "Freedraw",
+    "text": "Text",
+    "image": "Image",
+    "group": "Group"
+  },
   "headings": {
     "canvasActions": "Canvas actions",
     "selectedShapeActions": "Selected shape actions",
@@ -400,7 +411,9 @@
     "scene": "Scene",
     "selected": "Selected",
     "storage": "Storage",
-    "title": "General stats",
+    "title": "Stats",
+    "generalStats": "General stats",
+    "elementStats": "Element stats",
     "total": "Total",
     "version": "Version",
     "versionCopy": "Click to copy",