如何设置Konva舞台无限高度及解决IE/Firefox兼容性问题
针对AngularJS+Konva项目的解决方案:无限高度舞台、大节点量性能与跨浏览器兼容
一、实现Konva舞台的无限高度
Konva舞台本身是固定尺寸的,但我们可以通过可视区域适配+滚动偏移的方式模拟无限高度效果——核心思路是让舞台仅占浏览器可视区域高度,通过监听滚动动态调整舞台的Y轴偏移,从而展示超出视口的节点内容:
angular.module('testModule').controller('compabilityTestCtrl', [ '$window', function ($window) { var compabilityTestCtrl = this; // 初始化舞台,高度设为可视窗口高度 var stage = compabilityTestCtrl.stage = new Konva.Stage({ container: angular.element('#stage-container')[0], // 确保页面存在对应容器 width: angular.element($window).width(), height: angular.element($window).height() }); // 创建可无限扩展内容的主层 var mainLayer = new Konva.Layer(); stage.add(mainLayer); // 监听窗口滚动,调整舞台Y偏移实现"无限滚动"效果 angular.element($window).on('scroll', function() { var scrollTop = angular.element($window).scrollTop(); // 反向偏移舞台,让内容跟随滚动条移动 stage.y(-scrollTop); stage.batchDraw(); // 批量绘制,避免频繁重绘导致卡顿 }); // 监听窗口 resize,同步更新舞台宽度 angular.element($window).on('resize', function() { stage.width(angular.element($window).width()); stage.height(angular.element($window).height()); stage.batchDraw(); }); // 示例:添加节点到无限高度层(可传入任意大的Y坐标) compabilityTestCtrl.addNode = function(yPosition) { var rect = new Konva.Rect({ x: 50, y: yPosition, width: 100, height: 50, fill: '#ccc', stroke: '#333' }); mainLayer.add(rect); mainLayer.batchDraw(); }; }]);
关键注意点:
- 舞台高度始终保持为可视窗口高度,避免创建超大Canvas导致内存溢出
- 用
batchDraw()替代draw(),减少重绘次数,提升滚动流畅度 - IE浏览器中需对
scroll事件做节流处理(比如用$timeout控制触发间隔),避免事件触发过频繁导致卡顿
二、8000节点的性能优化方案
面对8000个节点的量级,直接渲染会导致严重性能问题(尤其是IE),可以通过以下手段优化:
- 分层渲染:将静态节点(不会移动/变化的)和动态节点拆分到不同层,仅在动态节点变化时重绘对应层
- 节点缓存:对静态节点使用
cache()方法,将节点渲染为Canvas缓存,减少重复绘制计算:staticNode.cache(); staticNode.drawCache(); - 批量操作:增删节点时,先暂停层的自动绘制,完成所有操作后再批量绘制:
mainLayer.stopListening(); // 暂停事件监听,减少中间计算 // 批量添加/删除节点逻辑 for(let i=0; i<100; i++){ mainLayer.add(new Konva.Rect({/* 节点配置 */})); } mainLayer.startListening(); mainLayer.batchDraw(); - AngularJS digest优化:避免在滚动/节点操作时频繁触发$digest,使用
$applyAsync()或者$timeout延迟更新,减少AngularJS的脏检查次数
三、跨浏览器兼容要点(Chrome/IE/Firefox)
IE兼容:
- 确保使用Konva 2.x版本(3.x及以上不再支持IE)
- 避免使用IE不支持的Konva特性(如部分滤镜、高值
shadowBlur) - 针对IE9,需引入ES5-shim/polyfill,确保Konva的JS代码正常运行
- 滚动事件必须节流,避免IE因事件触发过频繁导致页面卡顿
Firefox/Chrome:
- Chrome对Canvas渲染性能较好,但仍需坚持批量绘制和分层策略
- Firefox中需注意
stage.y()的偏移计算,避免滚动时出现视觉错位 - 高DPI屏幕可设置
stage.scale({x: window.devicePixelRatio, y: window.devicePixelRatio})提升清晰度,但会增加性能开销,需根据场景权衡
四、节点增删功能的实现示例
结合AngularJS的双向绑定,实现直观的节点增删:
<div id="stage-container"></div> <button ng-click="compabilityTestCtrl.addNode()">添加节点</button> <button ng-click="compabilityTestCtrl.removeLastNode()">删除最后一个节点</button>
// 在controller中补充以下代码: compabilityTestCtrl.nextY = 0; compabilityTestCtrl.nodeList = []; // 维护节点列表,方便后续删除操作 compabilityTestCtrl.addNode = function() { var rect = new Konva.Rect({ x: 50, y: compabilityTestCtrl.nextY, width: 100, height: 50, fill: '#ccc', stroke: '#333' }); mainLayer.add(rect); compabilityTestCtrl.nodeList.push(rect); compabilityTestCtrl.nextY += 60; // 节点间留10px间距 mainLayer.batchDraw(); }; compabilityTestCtrl.removeLastNode = function() { if(compabilityTestCtrl.nodeList.length === 0) return; var lastNode = compabilityTestCtrl.nodeList.pop(); lastNode.remove(); mainLayer.batchDraw(); };
内容的提问来源于stack exchange,提问作者blown.eye
相关产品推荐
相关产品推荐

