Break through the canvas syntax limit and allow him to support the chain syntax _ html5 tutorial skills-

Source: Internet
Author: User
Tags linecap
A lot of friends may not believe the canvas syntax. This article will introduce in detail how to make canvas support the chained syntax, for more information about the canvas drawing syntax, see the following:

The Code is as follows:


Ctx. arc (centerX, centerY, radius, 0, PI * 2, true );
Ctx. shadowColor = 'rgba (0.5, 0 )';
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 (, 0 )';
Ctx. arc (centerX, centerY-50, radius, 0, PI * 2, true );
Ctx. fill ();


I am not happy with canvas native syntax. There are two points: 1. There is ctx in front of each sentence (that is, the context2d object of canvas), and 2. Each function or attribute occupies one row, waste of space.

I like jQuery's chain syntax very much, for example:

The Code is as follows:


Certificate ('{p1'{.show(300}.html (p). delay (3000). slideUp (300). remove ();


Therefore, I also want to use this syntax for canvas plotting:

The Code is as follows:


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


One way is to simulate a context2d object. This object supports all native context2d methods, but also supports chain.

However, the Code cannot be too much, and no one will like it if it is too much.

The following is the complete code snippet. This "class" is named XtendCanvas (it starts with X again ):

The Code is as follows:


// Let canvas support the chain syntax, from 10-year Lamp
~ 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', 'strokesty', '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 = 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;
}();


The method is simple. If you pass a canvas object to him, he will return an object similar to context2d. You can use it like a normal context2d, but the difference is that, he supports the chain Syntax:

The Code is as follows:


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


In this way, you can put all the operations in one sentence, and you can interrupt at any time, do other things, and then continue.

This code is not an enhancement to canvas, but simply to allow him to support the chain syntax. But it is better than less code and can be embedded into any JS library. Here I hope to get your "recommendation"

The code must be worth improving. You can improve it on your own. But I hope you will remember me and the most important thing is thinking, right? The following is the idea:
As you can see, the longest part of the code is the array pro that saves the method name. The core code is very short. Why should I create such an array?

Originally, I also wanted to inherit all native methods from CanvasRenderingContext2D directly, but the CanvasRenderingContext2D is traversed under each browser, and the results are inconsistent. If I inherit them directly, an error will be reported when you want to execute them in firefox using methods in chrome.

Therefore, I just extracted the non-objection methods and attribute names in CanvasRenderingContext2D. There is no way to create a Fixed Array. You can add your method to it by yourself.

Methods and attributes are extracted, and the Native method is added to my new object. I created an empty function named fn and placed it in my method.

Because these elements in the array have both functions and attributes, I have determined in the loop whether they are a function. If they are functions, they will be executed with parameters; it is not a function -- so it must be an attribute, and the parameter is assigned to this attribute.

In this way, when setting the canvas attribute, you don't need to interrupt the chain. You just need to directly transmit the attribute value as the parameter, for example:

The Code is as follows:


Ctx. strokeStyle ('# f00 ')


Finally, the key is to return fn, Which is learned from jQuery and the key to supporting the chain syntax.

This section uses anonymous functions, closures, prototypes, And the strange for loop I mentioned earlier.

It seems quite simple to say, but I have been thinking about it for a long time and hope it will be useful to everyone.

During code writing, I found that chrome is a good practice. He has a string of functions starting with set, such as setStrokeColor and setLineCap, and transmits parameters to them, it can replace the corresponding strokeStyle, lineCap, and other attributes. That is to say, the canvas contains all functions without attributes. In this case, I don't have to judge whether it is a function or a property. But firefox does not have these, so I can only use the previous ideas.

Let me release the set function.:

The Code is as follows:


Var bak = ['settransform', 'setalpha', 'setcompositeoperation', 'setlinewidth', 'setlinecap', 'setlinejoin', 'setmiterlimit ', 'setlinedash', 'setshadow ', 'setstrokecolor', 'setfillcolor'];


They can understand their usefulness at a glance. You can also select the pro array that is added to the previous code.

Finally, I was wondering how my code was not highlighted... If you have seen the final result, please give me a suggestion, so that I can be vain.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.