Image & Video Editor
Relevant source files
The following files were used as context for generating this wiki page:- apps/portal/pages/edit/[id].tsx
- apps/portal/components/pagesComponents/_editorScreen/toolsPanel/ToolsPanel.tsx
- apps/portal/app/services/screenshots.ts
- apps/extensions/src/content/panel/hooks/useManageVideoData.ts
- apps/extensions/src/content/panel/hooks/useVideoChapters.ts
- apps/portal/hooks/useInitImageVideoItem.tsx
- apps/portal/components/pagesComponents/_editorScreen/editorHelpers/_commonComponents/ContentItemText.tsx
- apps/portal/components/pagesComponents/_editorScreen/editorHelpers/textDrawer.ts
- apps/portal/components/pagesComponents/_editorScreen/editorHelpers/arrowDrawer.ts
The Image & Video Editor is a core feature of the Ever Rec platform, providing a comprehensive suite of tools for annotating screen captures and editing video recordings. It is integrated into both the web portal and the browser extension, offering a consistent user experience for modifying media. The editor is built using React and leverages the Konva.js library for 2D canvas manipulations, allowing for rich, interactive annotation capabilities.
For images, the editor supports a wide range of tools including drawing, shapes, text, arrows, markers, and cropping. For videos, it provides functionality for trimming, managing chapters, and adding comments. All edits can be saved to the cloud, shared, or downloaded in various formats. The system is designed to be extensible, with a clear separation between the main editor component, the tools panel, and individual tool implementation helpers.
Architecture Overview
The editor's architecture is centered around the main EditorScreen component, which manages the Konva Stage and the overall state. The ToolsPanel provides the user interface for selecting and configuring annotation tools, while a set of editorHelpers contains the specific logic for each drawing function.
Sources: apps/portal/pages/edit/[id].tsx, apps/portal/components/pagesComponents/_editorScreen/toolsPanel/ToolsPanel.tsx
Core Components
| Component | Description | File Path |
|---|---|---|
EditorScreen | The main container component that initializes the Konva Stage, loads the image, manages state (active tool, history, etc.), and orchestrates interactions between the canvas and the tools panel. | apps/portal/pages/edit/[id].tsx |
ToolsPanel | A draggable UI panel that displays all available annotation tools and their respective configuration options (e.g., color, stroke width). | apps/portal/components/pagesComponents/_editorScreen/toolsPanel/ToolsPanel.tsx |
Konva Stage | The main canvas element where the image and all annotations are rendered. It contains multiple layers for different elements like the background image, drawings, and transformers. | apps/portal/pages/edit/[id].tsx:201 |
| Editor Helpers | A collection of TypeScript modules that implement the logic for each specific tool (e.g., drawing arrows, adding text, cropping). | apps/portal/components/pagesComponents/_editorScreen/editorHelpers/ |
Component Interaction Flow
The following diagram illustrates the interaction between the main components of the editor.
This diagram shows how user actions in the ToolsPanel update the editor's state, which in turn activates the corresponding drawing logic on the Konva Stage.
Sources: apps/portal/pages/edit/[id].tsx:190-220, 810-820, apps/portal/components/pagesComponents/_editorScreen/toolsPanel/ToolsPanel.tsx:200-210
State Management
The editor relies on a combination of React's useState for component-level state and Redux for some global state.
- Local State (
useState): TheEditorScreencomponent manages most of the editor's state locally. This includes:stage: The KonvaStageobject.activeTool: The currently selected tool from theToolsPanel.history&historyStep: An array of stage snapshots for undo/redo functionality.pointerTarget: The currently selected Konva shape for transformations.- Tool-specific options (e.g.,
pencilGroupOptions,textOptions).
- Redux State: Used for more global data, such as the
editorImageobject being edited, user authentication details, and workspace information.
Sources: apps/portal/pages/edit/[id].tsx:135-188
Tools Panel
The ToolsPanel is a draggable component that serves as the command center for all annotation activities. It provides buttons to select tools and sub-panels to configure their properties.
Sources: apps/portal/components/pagesComponents/_editorScreen/toolsPanel/ToolsPanel.tsx
Available Tools
| Tool | Icon | Description | Configuration Options |
|---|---|---|---|
| Video Record | 🎥 | Records a video of the editor screen. | N/A |
| Marker | 📍 | Adds numbered or lettered markers that can contain comments and media. | Color, Number/Letter type. |
| Text | T | Adds editable text boxes to the image. | Font family, size, color, style (bold, italic), alignment. |
| Arrow | ↗️ | Draws various types of arrows and lines. | Color, width, arrow type (line, arrow, curve). |
| Resize | ↔️ | Resizes the entire image canvas. | Width, Height. |
| Crop | ✂️ | Crops the image to a selected area. | N/A |
| Pointer | 🖱️ | Selects, moves, and transforms existing annotations. | N/A |
| Drawing | ✏️ | Free-form drawing with a pencil or highlighter. | Color, stroke width. |
| Shapes | 도형 | Draws predefined shapes like rectangles, ellipses, stars, etc. | Stroke color/width, fill color. |
| Emoji | 😀 | Adds emojis to the canvas. | Emoji selection. |
| Blur | 💧 | Applies a blur effect to a selected area. | N/A |
| Conversation | 💬 | Adds speech bubbles and other conversational graphics. | Style, colors, font properties. |
| Watermark | © | Adds a text or image watermark. | Text, font, color, opacity, image source. |
| Undo/Redo | ↩️/↪️ | Reverts or reapplies the last action. | N/A |
| Share/Save | 💾 | Saves the image to the cloud, downloads it, or shares it. | Format (PNG, JPG, PDF), cloud service. |
Sources: apps/portal/components/pagesComponents/_editorScreen/toolsPanel/ToolsPanel.tsx:260-890
Annotation and Drawing Logic
Each tool's functionality is encapsulated within a dedicated "drawer" or "helper" module. When a tool is selected from the ToolsPanel, the EditorScreen component invokes the corresponding helper function to initialize the drawing behavior on the Konva Stage.
Sources: apps/portal/pages/edit/[id].tsx:808-950
Tool Activation Flow
This diagram shows the sequence of events from a user selecting a tool to the corresponding shape being drawn on the canvas.
Sources: apps/portal/pages/edit/[id].tsx:808-820, 868-876, apps/portal/components/pagesComponents/_editorScreen/toolsPanel/ToolsPanel.tsx:199-205
Example: Text Tool (textDrawer.ts)
The text tool allows users to add and edit text directly on the canvas.
initTextDraweris called when the text tool is activated.- It listens for a
dblclickevent on the stage. - On double-click, it creates a
Konva.Textobject at the pointer's position. - A
<textarea>is created and positioned over theKonva.Textobject to allow for native text input. - When the user finishes editing (e.g., by pressing Enter or clicking away), the
textareais removed, and its content is applied to theKonva.Textobject. - The
saveHistoryfunction is called to record the change.
Sources: apps/portal/components/pagesComponents/_editorScreen/editorHelpers/textDrawer.ts:13-90
Example: Arrow Tool (arrowDrawer.ts)
The arrow tool allows for drawing straight, curved, or directional lines.
initArrowDrawis called when an arrow tool is selected.- It attaches
mousedown,mousemove, andmouseupevent listeners to the stage. - On
mousedown, a newKonva.Arrowis created with its starting and ending points at the current mouse position. - On
mousemove, the arrow's end point is updated to follow the mouse. - On
mouseup, the drawing is finalized, andsaveHistoryis called.
Sources: apps/portal/components/pagesComponents/_editorScreen/editorHelpers/arrowDrawer.ts:18-60
Data Persistence and History
Saving Edits
When the user saves their work, the editor captures the current state of the canvas and sends it to the backend.
The save function in EditorScreen performs these steps:
- Temporarily sets the stage scale to 1 to export at original resolution.
- Serializes the entire Konva
Stageinto a JSON object usingstage.toObject(). - Bundles the stage object, current markers, and other metadata into a
DbImgDataobject. - Calls the appropriate API service (
updateImageDataorupdateItemDataWorkspace) to persist the data.
Sources: apps/portal/pages/edit/[id].tsx:300-316, apps/portal/app/services/screenshots.ts:223-247
History (Undo/Redo)
The editor maintains a robust undo/redo capability by storing snapshots of the editor's state.
historyState: An array (IHistory[]) where each element contains a serialized stage object (stage), the original image URL (img), and the canvas dimensions (renderDimentions).saveHistory(): This function is called after almost every modification. It pushes a new history entry onto thehistoryarray and updates thehistorySteppointer.undo()/redo(): These functions navigate thehistoryarray by decrementing or incrementinghistoryStep. They then callrenderStepto load and display the stage from the selected history entry.
Sources: apps/portal/pages/edit/[id].tsx:143, 265-299, 342-397
Video Editing Features
The editor also includes features specifically for video files, managed primarily through the useManageVideoData hook.
Sources: apps/extensions/src/content/panel/hooks/useManageVideoData.ts
Video Trimming
Users can trim the beginning or end of a video.
- The
applyTrimfunction is called with a new length (in seconds). - It slices the
initialBlobsarray, which contains the raw video data chunks. - A new
Blobis created from the sliced array. - The
fix-webm-durationlibrary is used to correct the duration metadata of the new blob. - The trimmed video is then re-uploaded to the server via
applyVideoChangesoruploadVideoToService.
The flow for trimming a video is as follows:
Video Chapters
The useVideoChapters hook provides the logic for creating, editing, and viewing video chapters.
- Data Structure: Each chapter is an object with an
id,content(name),timestamp,timestampSeconds, andthumbnailURL. - Functionality:
chapterAdd: Adds a new chapter at the current video time.chapterUpdate: Modifies the content of an existing chapter.chapterClose: Deletes a chapter.saveChanges: Persists the chapter data to the backend via thesaveVideoChaptersAPI call.
- Validation: The system enforces rules, such as requiring a minimum of 3 chapters and ensuring the first chapter starts at
00:00.
Sources: apps/extensions/src/content/panel/hooks/useVideoChapters.ts:1-153
Real-time Collaboration (Markers)
The editor supports real-time updates for markers and their associated comments using WebSockets.
- When a user adds or modifies a marker, the changes are sent to the server.
- The server then broadcasts a
markers-updatedevent via Socket.IO. - The
EditorScreencomponent listens for this event and, upon receiving it, updates themarkersstate, re-rendering the markers on the canvas for all connected users. This ensures that collaborators see changes in real time.
Sources: apps/portal/pages/edit/[id].tsx:677-695, apps/portal/components/pagesComponents/_editorScreen/editorHelpers/_commonComponents/ContentItemText.tsx:50-67