Angular9 Canvas实现多边形绘制与顶点拖拽时mouse对象未定义问题求解
Angular Canvas可编辑多边形mouse对象undefined问题解决方案
问题原因
- 核心原因为
update方法的this指向丢失:你将update作为回调传入requestAnimationFrame时,普通函数在浏览器API调用时this默认指向全局对象(严格模式下为undefined),所以方法内访问this.mouse时无法匹配到组件实例的mouse对象,返回undefined。 - 次要问题:
polygon对象的draw等内部方法中直接使用this.context访问画布上下文,这里的this指向polygon对象本身,而非组件实例,也会引发属性访问错误。
修复步骤
1. 修复update方法的this指向
选择任意一种方案即可:
- 方案A:
requestAnimationFrame调用时用箭头函数包裹回调,保留组件实例的this指向
// ngOnInit 中原有调用改为 requestAnimationFrame(() => this.update()); // update 方法末尾的递归调用也同步修改 requestAnimationFrame(() => this.update());
- 方案B:直接将update定义为箭头函数,从定义层面固定this指向
update = () => { // 原有update方法逻辑全部保留不变 }
2. 修正polygon内部的上下文访问
在定义polygon对象前先捕获组件实例的上下文,替换内部的this访问:
// ngOnInit 中定义poly前新增一行捕获组件实例 const component = this; const poly = () => ({ points: [], closed: false, addPoint(p) { this.points.push(point(p.x, p.y)); }, draw() { // 用捕获的component访问组件的context属性,不要用this const ctx = component.context; ctx.lineWidth = 2; ctx.strokeStyle = 'red'; ctx.fillStyle = 'rgba(255, 0, 0, 0.3)'; ctx.beginPath(); for (const p of this.points) { ctx.lineTo(p.x, p.y); } this.closed && ctx.closePath(); ctx.stroke(); this.closed && ctx.fill(); // 后续draw方法内所有context访问都替换为ctx即可 // drawLengthText、drawAngleText方法同理,都用component.context访问上下文 }, // 剩余的closest等方法逻辑无需修改 });
3. 可选优化(避免DOM未挂载异常)
当前你将canvas初始化逻辑写在ngOnInit中,此时@ViewChild查询的DOM元素还未完成挂载,建议将初始化逻辑挪到ngAfterViewInit生命周期钩子中,同时组件类实现AfterViewInit接口,避免偶发的canvas undefined问题。
内容的提问来源于stack exchange,提问作者Arter
相关产品推荐
相关产品推荐

