返回顶部
首页 > 资讯 > 前端开发 > JavaScript >如何突破canvas语法限制让他支持链式语法
  • 436
分享到

如何突破canvas语法限制让他支持链式语法

2024-04-02 19:04:59 436人浏览 薄情痞子
摘要

这篇文章给大家分享的是有关如何突破canvas语法限制让他支持链式语法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 先来看一段正常的canvas画

这篇文章给大家分享的是有关如何突破canvas语法限制让他支持链式语法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

先来看一段正常的canvas画图语法:

代码如下:


ctx.arc(centerX,centerY,radius,0,PI*2,true);
ctx.shadowColor = 'rgba(0,0,0,0.5)';
ctx.shadowBlur = "10";
ctx.fill();
ctx.beginPath();
ctx.shadowColor = 'rgba(0,0,0,0)';
ctx.moveTo(centerX-radius,centerY);
ctx.lineTo(centerX-radius,centerY - 50);
ctx.lineTo(centerX+radius,centerY - 50);
ctx.lineTo(centerX+radius,centerY);
// ctx.lineTo(centerX-radius,centerY);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgba(255,0,0,1)';
ctx.arc(centerX,centerY-50,radius,0,PI*2,true);
ctx.fill();


我对canvas原生语法不爽的有两点:1是每句前面都有写ctx(即canvas的context2d对象),2是每个函数或属性都要占一行,浪费空间。

我对Jquery的链式语法很欣赏,比如:

代码如下:


$('#div1').show(300).html(p).delay(3000).slideUp(300).remove();


所以,我也想用这种语法来进行canvas绘图:

代码如下:


ctx.moveTo(500,0).lineTo(500,500).strokeStyle('#f00').stroke();


有个办法就是模拟一个context2d对象,这个对象支持所有的原生context2d方法,但又支持链式。

不过,代码不能太多,多了就没人喜欢用了。

下面就是完整的代码段,这个“类”我取名为XtendCanvas(又是以X开头的哟):

代码如下:


// 让canvas支持链式语法,来自十年灯
~function  () {var pro = ['save','restore', 'scale', 'rotate', 'translate', 'transfORM',  'createLinearGradient', 'createRadialGradient', 'getLineDash', 'clearRect', 'fillRect', 'beginPath', 'closePath', 'moveTo', 'lineTo', 'quadraticCurveTo', 'bezierCurveTo', 'arcTo', 'rect', 'arc', 'fill', 'stroke', 'clip', 'isPointInPath', 'measureText', 'clearShadow', 'fillText', 'strokeText',   'strokeRect', 'drawImage', 'drawImageFromRect',  'putImageData', 'createPattern', 'createImageData', 'getImageData',    'lineWidth','strokeStyle','globalAlpha','fillStyle','font','shadowOffsetX','shadowOffsetY','shadowBlur','shadowColor','lineCap','lineJoin','miterLimit'];
   function XtendCanvas (canvas) {
   
       var ctx = canvas.getContext('2d'),
           fn = function(){},
           fnP = fn.prototype;
       for(var j = 0,p=pro[0];p;p=pro[j++]) {
           fn.prototype[p] = function  (p) {    
               return function  () {
                   var args = Array.prototype.slice.call(arguments);
                       // console.log(args);
                   if(typeof ctx[p] == 'function') {
                       ctx[p].apply(ctx,args);
                   } else {
                       ctx[p] = args+'';
                   }
                   return fnP;
               };
           }(p);
       }
       return new fn;
   };
   window.XtendCanvas = XtendCanvas;
}();


使用方法很简单,给他传一个canvas对象,他就会返回一个类似context2d的对象,你可以像普通的context2d一样使用,但不同的是,他支持链式语法了:

代码如下:


var cvs = document.getElementById('cvs');
var ctx = XtendCanvas(cvs);
ctx.moveTo(500,0).lineTo(500,500).strokeStyle('#f00').stroke();


这样一来你就可以把所有操作都放在一句话里,你也可以随时中断,做其他的事,然后继续。

这段代码并不是对canvas的增强,只是单纯的让他支持链式语法了。但胜在代码少,可以嵌入到任何js库中,在此我希望能得到你的一个“推荐”

代码中肯定有值得改进的地方,大家可以自行完善。但——吃水不忘挖井人,希望大家记得我,最重要的是思路,对吧?下面就是思路:
大家可以看到,代码中最长的部分,是那个保存方法名的数组pro,核心代码反而很短。为什么我要建这么一个数组呢?

本来我也想直接从CanvasRenderinGContext2D继承所有原生方法,但每个浏览器下面遍历这个CanvasRenderingContext2D,结果都不一致。如果我把他们直接继承,那么当你想用chrome中的方法套在firefox里执行,就会报错。

所以我只是把CanvasRenderingContext2D中的通用的,无异议的方法与属性名提取了出来,没办法,只有建一个固定的数组——大家可以自行决定往里面添加你的方法。

方法与属性提取出来了,接着就是把原生的方法加在我的新对象上。我建了一个叫fn的空函数,放置我的方法。

由于数组中的这些元素既有函数,也有属性,所以我在循环中判断了他是否是一个函数,如果是函数,就带参数执行;不是函数——那么就肯定是属性了,就把参数赋给这个属性。

这样大家在碰到设置canvas属性的时候,就不用中断链了,直接把属性值当参数传进去就行了,比如:

代码如下:


ctx.strokeStyle('#f00')


最后,关键的关键,就是返回fn,这招是从jQuery学来的,是支持链式语法的关键。

这段中用到了匿名函数,闭包,原型,以及我以前文章讲过的奇怪的for循环。

说起来好像挺简单的,不过我实在是想了很久,希望对大家有用。

在写代码的过程中,我发现chrome的做法很不错,他有一串以set开头的函数,如setStrokeColor,setLineCap等函数,给他们传参数,就可以替代对应的strokeStyle和lineCap等属性,也就是说,他的canvas里面就全是函数而没有属性了那样的话我就不用判断是函数还是是属性了。但firefox里面没有这些,所以我还是只能用前面的思路。

我也把那一串set函数给放出来吧

代码如下:


var bak = ['setTransform','setAlpha', 'setCompositeOperation', 'setLineWidth', 'setLineCap', 'setLineJoin', 'setMiterLimit', 'setLineDash','setShadow','setStrokeColor','setFillColor'];


他们的用处一看就懂。你也可以选择一些加入前面代码的pro数组中。

感谢各位的阅读!关于“如何突破canvas语法限制让他支持链式语法”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: 如何突破canvas语法限制让他支持链式语法

本文链接: https://lsjlt.com/news/83166.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何突破canvas语法限制让他支持链式语法
    这篇文章给大家分享的是有关如何突破canvas语法限制让他支持链式语法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 先来看一段正常的canvas画...
    99+
    2024-04-02
  • 如何让小程序支持JSX语法
    今天小编给大家分享一下如何让小程序支持JSX语法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下...
    99+
    2024-04-02
  • Linux系统里让vim支持markdown格式的语法高亮
    Markdown是深受程序员喜爱的一个文件格式。然而Linux里默认的vim设置,并不支持markdown格式的语法高亮显示。下面就来介绍如何设置使得markdown格式的文件在vim里也能享有语法高亮的待遇。首先安装一个vim的插件管理工...
    99+
    2023-06-06
  • vscode不支持es6语法如何解决
    这篇文章主要讲解了“vscode不支持es6语法如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vscode不支持es6语法如何解决”吧! ...
    99+
    2024-04-02
  • idea中es6语法不支持如何解决
    这篇文章主要介绍“idea中es6语法不支持如何解决”,在日常操作中,相信很多人在idea中es6语法不支持如何解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”idea中e...
    99+
    2024-04-02
  • vscode不支持nvue语法高亮如何解决
    本篇内容介绍了“vscode不支持nvue语法高亮如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!问题描述例如:vscode中使用*....
    99+
    2023-07-05
  • Go语言重定向实现方法,如何支持并发?
    Go语言是一门强大的编程语言,它提供了许多实用的功能和工具,其中之一就是重定向。重定向是一种将输入或输出流从一个文件或设备转移到另一个文件或设备的方式。在本文中,我们将讨论Go语言中的重定向实现方法,以及如何支持并发。 一、重定向实现方法 ...
    99+
    2023-10-08
    重定向 并发 教程
  • 在WebStorm中如何添加Vue.js单文件组件的高亮及语法支持
    这篇文章将为大家详细讲解有关在WebStorm中如何添加Vue.js单文件组件的高亮及语法支持,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:一个小遗憾 ...
    99+
    2024-04-02
  • 麒麟操作系统如何支持多种语言和输入法的切换
    麒麟操作系统(HarmonyOS)支持多种语言和输入法的切换,具体的实现方式如下:1. 多语言支持:麒麟操作系统提供了多语言切换的功...
    99+
    2023-10-10
    麒麟操作系统
  • 如何理解支持自动补全和语法高亮的MySQL/MariaDB客户端MyCLI
    这篇文章给大家介绍如何理解支持自动补全和语法高亮的MySQL/MariaDB客户端MyCLI,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。MyCLI 是一个易于使用的命令行客户端,可用...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作