ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

深入 ExplorerCanvas 源码:G_vmlCanvasManager 如何把 canvas 标签变成 VML 元素

深入 ExplorerCanvas 源码:G_vmlCanvasManager 如何把 canvas 标签变成 VML 元素 深入 ExplorerCanvas 源码G_vmlCanvasManager 如何把 canvas 标签变成 VML 元素【免费下载链接】ExplorerCanvasCanvas for IE8 and older项目地址: https://gitcode.com/gh_mirrors/ex/ExplorerCanvasExplorerCanvas是 Google 出品的经典兼容方案它通过 excanvas.js 一个脚本让 IE8 及更早版本也能运行标准的 canvas 二维绘图代码——核心就是G_vmlCanvasManager把每个canvas标签伪装成一组 VMLVector Markup Language元素。本文带你读懂这条从 canvas API 到 VML 的完整链路。上图正是项目示例 example3.html 通过drawImage绘制到 canvas 上的素材可见兼容层能还原真实的 canvas 视觉效果。 为什么 IE8 需要 canvas 兼容层Firefox、Safari、Opera 9 原生支持canvas而 IE8 及以下完全没有。ExplorerCanvas 的思路很巧妙不修改浏览器而是用 IE 自带的 VML 技术模拟一个 canvasREADME 中的项目描述。项目入口有一道闸门只有当前浏览器不支持getContext时才注入补丁if (!document.createElement(canvas).getContext) { // 整个兼容层全部封装在这个立即执行函数里 }对应源码见 excanvas.js#L35。这样在原生支持的浏览器中脚本什么都不做零副作用。 一键启用条件注释加载 excanvasREADME 给出的安装方式只有一行条件注释放在head中即可!--[if lte IE 8]script srcexcanvas.js[endif]--只有 IE8 及以下会下载执行脚本现代浏览器直接跳过。⚙️ G_vmlCanvasManager 的三步初始化核心管理器定义在 excanvas.js#L113-L173它分三步工作第 1 步init()注册文档事件L114-L120先document.createElement(canvas)创建一个哑元素——这一步是经典技巧IE 只要创建过某标签之后就会把它当作合法 HTML 元素解析监听onreadystatechange等页面结构就绪后执行第 2 步。第 2 步init_()批量扫描L122-L128用getElementsByTagName(canvas)找出页面里所有 canvas逐个交给initElement改造。第 3 步initElement()改造单个元素L138-L172做了四件事挂载 getContext给元素挂上getContext函数L139-L140调用时返回CanvasRenderingContext2D_实例——从此它看起来就是标准 canvas注册 VML 命名空间addNamespacesAndStylesheetL96-L108向文档注入g_vml_前缀指向urn:schemas-microsoft-com:vml并加入默认样式width:300px;height:150px与 Gecko 默认尺寸一致清理回退内容el.innerHTML 直接清空子节点同步尺寸与事件把width/height属性值写入 style并监听onpropertychangeL175-L191改宽/高时清空重绘和onresizeL193-L199窗口缩放时同步内部容器尺寸。脚本加载即自动执行G_vmlCanvasManager_.init()L201之后动态创建的 canvas 也可手动调用G_vmlCanvasManager.initElement(el)激活。️ 2D 上下文两层 div 搭出画布骨架getContext最终实例化CanvasRenderingContext2D_excanvas.js#L567-L604。构造函数里有两个关键 DOM 操作创建一个绝对定位的divthis.element_尺寸与 canvas 一致作为所有 VML 元素的承载容器L588-L592再克隆一层透明背景叠加层overlayElL594-L598用于覆盖绘制内容。同时初始化了标准画布属性strokeStyle、fillStyle、lineWidth、lineJoin、globalAlpha、font等以及一个 3×3 的变换矩阵m_L568。 绘图命令如何变成 VML这是整个项目最精彩的部分canvas 命令并不直接画图而是先记录再编译成 VML 字符串。1. 路径录制moveTo / lineTo / arcmoveTo、lineTo、bezierCurveTo、arc等方法只是把带类型的坐标对象压入currentPath_数组L621-L709例如arc会记录起点、终点和半径。所有坐标先经getCoordsL1098-L1104做矩阵变换并乘上系数Z 10——这是源码中注释的亚像素精度技巧excanvas.js#L47-L49。2. stroke()把路径编译成 g_vml_:shape调用stroke()时L877-L962遍历currentPath_把每个操作翻译成 VML 路径指令canvas 操作VML 路径指令moveTom x,ylineTol x,yclosePathxbezierCurveToc cp1x,cp1y, cp2x,cp2y, x,yarcat/wa椭圆弧指令最终拼接成g_vml_:shape ... path...并通过insertAdjacentHTML插入承载容器L884-L890、L961。描边样式由appendStroke生成g_vml_:stroke子标签L964-L985有个细节线宽不足 1px 时 VML 画不出来代码会通过降低透明度来稀释线条模拟细线效果L970-L974。3. fill 与渐变、图片、文字fill()就是stroke(true)走appendFillL987-L1088普通颜色生成g_vml_:fill color... /CanvasGradient_会换算角度与色标后生成带colors属性的渐变填充CanvasPattern_则生成typetile的平铺填充。drawImageL768-L875把图片包进g_vml_:groupg_vml_:image用cropleft/croptop等属性实现裁剪若当前有旋转矩阵则叠加DXImageTransform.Microsoft.Matrix滤镜L833-L857。fillText/strokeText走drawText_L1203-L1290用一个g_vml_:lineg_vml_:textpath渲染文本并用g_vml_:skew施加与画布一致的变换矩阵measureText则靠页面外隐藏的span量宽L1300-L1314。⚠️ 已知局限与替代方案文件头部excanvas.js#L16-L32诚实地列出了未实现项径向渐变、裁剪路径clip目前是空壳L1317-L1319、非等比缩放的描边等。此外仓库还提供一个Silverlight 版兼容实现 silverlight/excanvas.js供无法使用 VML 的场景参考。 动手验证示例与测试用例示例examples/example1.html 粒子动画、example2.html、example3.html绘制上文那张 ff.jpg测试用例集中在 testcases/ 目录arc.html、gradient.html、pattern.html、text.html 等可直接用 IE8 打开核对各绘图 API 的表现获取完整源码git clone https://gitcode.com/gh_mirrors/ex/ExplorerCanvas 小结ExplorerCanvas 的本质是一条录制 → 编译 → 注入的管线G_vmlCanvasManager负责把 canvas 元素转正CanvasRenderingContext2D_负责实现标准 2D API 并记录路径最后stroke()等出口函数把路径批量编译为 VML 字符串插入 DOM。理解它你就能看清 canvas 规范与底层绘制技术之间那座桥的完整构造。【免费下载链接】ExplorerCanvasCanvas for IE8 and older项目地址: https://gitcode.com/gh_mirrors/ex/ExplorerCanvas创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表