You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ember中实现类似谷歌反馈的矩形高亮工具?

用Ember实现谷歌风格矩形高亮工具

要实现谷歌官网反馈功能里的矩形高亮工具,核心是在页面上层构建一个可交互的遮罩图层,通过监听全局鼠标事件完成矩形的绘制、调整和管理。以下是基于Ember的具体实现方案:

核心组件拆分

把工具拆分为两个核心组件,贴合Ember的组件化设计思路:

  • highlight-tool:主组件,负责管理所有高亮矩形的状态、全局鼠标事件监听、工具的激活/关闭逻辑。
  • highlight-rect:单个高亮矩形组件,处理矩形的拖拽、调整大小和删除(若需求简单,也可合并到主组件中简化实现)。

关键实现步骤

1. 主组件初始化与事件绑定

主组件需要监听全局鼠标事件(绑定到document),同时维护高亮矩形数组、绘制状态等跟踪属性:

// app/components/highlight-tool.js
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

export default class HighlightToolComponent extends Component {
  @tracked highlights = [];
  @tracked isDrawing = false;
  @tracked currentRect = null;
  @tracked startX = 0;
  @tracked startY = 0;

  didInsertElement() {
    // 绑定全局鼠标事件
    document.addEventListener('mousedown', this.handleMouseDown);
    document.addEventListener('mousemove', this.handleMouseMove);
    document.addEventListener('mouseup', this.handleMouseUp);
  }

  willDestroyElement() {
    // 组件销毁时解绑事件,避免内存泄漏
    document.removeEventListener('mousedown', this.handleMouseDown);
    document.removeEventListener('mousemove', this.handleMouseMove);
    document.removeEventListener('mouseup', this.handleMouseUp);
  }
}

2. 实现矩形绘制逻辑

通过mousedown、mousemove、mouseup事件的联动,完成矩形的绘制流程:

// 继续在highlight-tool.js中添加以下action
@action
handleMouseDown(event) {
  // 仅在遮罩层上点击时启动绘制
  if (event.target.classList.contains('highlight-mask')) {
    this.isDrawing = true;
    this.startX = event.pageX;
    this.startY = event.pageY;
    this.currentRect = {
      x: this.startX,
      y: this.startY,
      width: 0,
      height: 0
    };
  }
}

@action
handleMouseMove(event) {
  if (!this.isDrawing) return;

  const currentX = event.pageX;
  const currentY = event.pageY;

  // 处理从右下往左上拖拽的情况,确保矩形坐标正确
  this.currentRect = {
    x: Math.min(this.startX, currentX),
    y: Math.min(this.startY, currentY),
    width: Math.abs(currentX - this.startX),
    height: Math.abs(currentY - this.startY)
  };
}

@action
handleMouseUp() {
  // 过滤掉过小的误操作矩形
  if (this.isDrawing && this.currentRect.width > 10 && this.currentRect.height > 10) {
    this.highlights = [...this.highlights, this.currentRect];
  }
  this.isDrawing = false;
  this.currentRect = null;
}

3. 渲染遮罩层与高亮矩形

在组件模板中添加全屏遮罩层,渲染已完成的高亮矩形和绘制中的临时矩形:

{{! app/templates/components/highlight-tool.hbs }}
{{#if @isActive}}
  {{! 全屏遮罩层,半透明背景 }}
  <div class="highlight-mask" style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.3); pointer-events: auto;"></div>

  {{! 渲染已保存的高亮矩形 }}
  {{#each this.highlights as |highlight index|}}
    <div class="highlight-rect"
         style="position: fixed; left: {{highlight.x}}px; top: {{highlight.y}}px; width: {{highlight.width}}px; height: {{highlight.height}}px; background: rgba(255,255,0,0.5); border: 2px solid #ffeb3b; cursor: move;"
         {{on "click" (fn this.removeHighlight index)}}>
    </div>
  {{/each}}

  {{! 渲染绘制中的临时矩形 }}
  {{#if this.currentRect}}
    <div class="highlight-rect"
         style="position: fixed; left: {{this.currentRect.x}}px; top: {{this.currentRect.y}}px; width: {{this.currentRect.width}}px; height: {{this.currentRect.height}}px; background: rgba(255,255,0,0.5); border: 2px solid #ffeb3b;">
    </div>
  {{/if}}
{{/if}}

4. 添加删除与调整功能

给每个高亮矩形添加删除逻辑,如需拖拽调整大小,可以扩展highlight-rect组件添加控制点和对应的事件处理:

// 在highlight-tool.js中添加删除action
@action
removeHighlight(index) {
  this.highlights = this.highlights.filter((_, i) => i !== index);
}

5. 集成到应用中

在需要使用工具的路由模板中,通过开关状态控制工具的显示:

{{! 示例页面模板 }}
<button {{on "click" (fn (mut this.showHighlightTool) true)}}>开启高亮工具</button>
<HighlightTool @isActive={{this.showHighlightTool}} />

细节优化

  • 坐标兼容性:使用pageX/pageY而非clientX/clientY,避免页面滚动导致的坐标偏移。
  • 交互隔离:工具激活时,遮罩层设置pointer-events: auto,底层页面可临时设置pointer-events: none,防止误操作。
  • 样式精细化:调整高亮矩形的透明度、边框样式,使其更接近谷歌的视觉效果;添加调整控制点(如四个角的小方块)提升交互体验。

内容的提问来源于stack exchange,提问作者agustinvaca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:02:19