KevinChen 发表于 2020-6-30 17:52:40

利用浮动对象实现标注区域的功能

这篇文章分享一个比较实用的功能:利用浮动对象实现标注区域的功能。
一、场景:
我先描绘几个应用场景,看看是不是大家也会遇到:
1、当用户选中某片区域,想做一个框选的标记,但又不想真的修改这部分区域的样式时,类似:


2、多人协同编辑时,其它用户选中的区域,需要用人名+标记的方式对这个区域进行标记,如图:


二、思路:


1、自定义单元格paint
可能有机智的同学已经想到了,用自定义单元格的paint方法,在paint中通过修改Style对象可以实现
既修改渲染样式,又能不影响单元格实际style属性。如下代码所示:
    CustomBase.prototype.paint = function (context, value, x1, y1, a1, b1, style, ctx) {
      if (!context) {
            return;
      }
      if(this.showEffect){
            if(sels && sels.length !== 0){
                var row = ctx.row, col = ctx.col;
                sels.forEach(function (sel) {
                  // 设置当前绘制样式,不会影响导出效果
                  var rowSpan = sel.row + sel.rowCount;
                  var colSpan = sel.col + sel.colCount;
                  if(row >= sel.row && row < rowSpan
                        || col >= sel.col && col < colSpan){
                        style.backColor = "red";
                  }
                })
            }
      }
      oldPaint.apply(this, );
    };
但是很可惜,在这个案例中,无法通过paint方法实时修改单元格的border,
原因在于border的渲染不是在paint中执行的,paint的渲染区域不包含border,因此这里不能实现。

2、利用浮动div,框选出对应的区域:
Dexter版主分享过一篇相关的文章,非常巧妙地利用div实现了这个功能:
https://gcdn.grapecity.com.cn/showtopic-76594-1-1.html
界面美观,自定制程度高,对用户操作没有任何影响。
唯一的小问题就是这个示例相对有一点点复杂,需要咱们做一些补充和封装。
强烈推荐。

3、利用SpreadJS的浮动对象,选出对应区域:
SpreadJS浮动对象是原生支持的功能,能够自动随单元格位置、尺寸的变动而变动,
不需要我们自己用事件去处理,只需要设置宽、高为0,仅保留边框,即可实现框选的效果。
关键代码:

var upperborder = new GC.Spread.Sheets.FloatingObjects.FloatingObject("userId_" + userId + "_upperborder");
// 起始行
upperborder.startRow(row);
// 起始列
upperborder.startColumn(col);
// 结束行
upperborder.endColumn(col + colCount);
// 结束列
upperborder.endRow(row);
// 是否允许移动
upperborder.allowMove(false);
// 是否允许更改尺寸
upperborder.allowResize(false);
// 是否选中
upperborder.isSelected(false);
// 是否锁定
upperborder.isLocked(true);
// 随单元格尺寸变化而变化
upperborder.dynamicSize(true);
// 设置样式
upperborder.content(topBorderElement);


完整代码见附件。
页: [1]
查看完整版本: 利用浮动对象实现标注区域的功能