GWT中如何绘制椭圆?原生调用Canvas ellipse方法无效如何解决
GWT Canvas绘制椭圆的可行方案
你现有JSNI调用无效通常是三个原因导致:
- 调用椭圆绘制指令前未执行
beginPath()开启新路径,绘制指令被追加到历史路径中无法正常渲染 - 部分GWT版本向JSNI传递double类型时存在自动装箱问题,原生API无法识别参数类型
- 低版本浏览器内核的Canvas 2D上下文对
ellipse方法支持带前缀,直接调用会找不到方法
方案1:修复JSNI原生调用(性能最优)
修正JSNI方法的参数处理和能力检测逻辑,调用前按Canvas规范先开启路径:
/** * 原生调用ellipse绘制椭圆 * 调用前必须先执行 context.beginPath() */ public final native void nativeEllipse(CanvasRenderingContext2D ctx, double x, double y, double rx, double ry, double rotation, double startAngle, double endAngle, boolean anticlockwise ) /*-{ // 兼容各浏览器带前缀的实现 const ellipseImpl = ctx.ellipse || ctx.webkitEllipse || ctx.mozEllipse || ctx.msEllipse; if (!ellipseImpl) return; // 显式转数值类型,避免GWT类型传递问题 ellipseImpl.call(ctx, Number(x), Number(y), Number(rx), Number(ry), Number(rotation), Number(startAngle), Number(endAngle), !!anticlockwise ); }-*/;
调用示例:
context.beginPath(); nativeEllipse(context, x, y, 50d, 80d, 0d, 0d, Math.PI * 2, false); context.fill(); // 描边用stroke(),按业务需求选择
方案2:用GWT现有API模拟实现(兼容性最好)
不需要写JSNI,完全基于GWT已封装的Canvas API实现,适配所有支持Canvas的环境,无兼容问题。原理是通过坐标系缩放,把圆弧拉伸为椭圆:
/** * 通用椭圆绘制方法,支持旋转、起始/结束角度,不依赖原生ellipse API */ public void drawEllipse(CanvasRenderingContext2D ctx, double x, double y, double rx, double ry, double rotation, double startAngle, double endAngle, boolean anticlockwise ) { ctx.save(); ctx.translate(x, y); ctx.rotate(rotation); ctx.scale(rx / ry, 1); ctx.arc(0, 0, ry, startAngle, endAngle, anticlockwise); ctx.restore(); }
如果只需要绘制完整椭圆,可以简化参数,代码更简洁。这个方案是生产环境最常用的实现,没有任何依赖风险。
方案3:升级依赖使用官方封装API
如果项目允许升级依赖,可以将GWT升级到2.8.2以上版本,或者引入Elemental2客户端API,其已经原生封装了Canvas 2D的所有标准方法,不需要自行编写JSNI,直接调用即可:
// 引入Elemental2依赖后可直接调用 ctx.beginPath(); ctx.ellipse(x, y, rx, ry, rotation, startAngle, endAngle, anticlockwise); ctx.stroke();
内容的提问来源于stack exchange,提问作者owlseeker
相关产品推荐
相关产品推荐

