For pixel processing in HTML5, you need to use two functions getImageData and putImageData. First use getImageData to copy the pixel data in the canvas canvas, then process the obtained pixel data, and finally paste the processed data into the canvas canvas through putImageData . We might as well call the process of processing pixels in the middle a pixel batch processing. Since copying and pasting pixels are two time-consuming processes, in order to process pixels more efficiently, we should process as much pixel data as possible in a batch process to reduce the two operations of copying and pasting pixels.
This sounds like a very troublesome process. Some friends may be impatient just by seeing the above sentences. In fact, I think so, so I encapsulated this troublesome process into the LBitmapData class in the lufylegend engine. You can handle canvas in HTML5 like pixels in flash. Doesn't this sound very interesting? If you are interested, please follow me to take a look at this fun little feature. First, let’s get to know LBitmapData, which is usually used to save Image objects. I won’t talk about the specific usage. You can take a look at the API documentation. Here I will mainly introduce how to use it to batch process pixels.
Below are two functions in LBitmapData
| function | Function |
|---|
| getPixel(x,y,colorType) | Returns an array representing the RGB pixel values in a BitmapData object at a specific point (x, y). where colorType is the format of the pixel data to be retrieved, and the default is a pixel array. When set to a string number, it returns a pixel of the number type. |
| setPixel(x,y,data) | Sets a single pixel of the LBitmapData object. Where data is a pixel value (supports three formats: pixel array, #FF0000, 0xFF000, etc.) |
The above two functions are to obtain and set a single pixel. When we need to obtain or set a pixel in an area at one time, the corresponding two functions are as follows
| function | Function |
|---|
| getPixels(rect) | Returns an array representing the RGB pixel values in a specific area in a BitmapData object. where rect is an LRectangle object, which is a rectangle. |
| setPixels(rect, data) | Converts and pastes the pixel data array to the specified rectangle area. Where data is a pixel value (supports three formats: pixel array, #FF0000, 0xFF000, etc.) |
Let's prepare a picture first, such as the handsome avatar of my man below, don't vomit...
If you want to copy the handsome face in the middle through getPixels, you can do it like this
[javascript] view plaincopy
- bitmapData=newLBitmapData(imglist[face]);
- bitmapData.lock();
- varimg=bitmapData.getPixels(newLRectangle(75,50,100,100));
Sometimes we need to copy and paste pixels on LBitmapData multiple times. At this time, we can use the lock function, which can cache the pixel array. In this process, all the pixel operations done are operated on this cache array. After the operation is completed, the corresponding unlock function is called to paste the operation pixel data back into LBitmapData.
For example, as shown below, we paste part of the copied array into four different locations in another LBitmapData in four times.
[javascript] view plaincopy
- bitmapData2=newLBitmapData(null,0,0,500,400,LBitmapData.DATA_CANVAS);
- bitmapData2.lock();
- bitmapData2.setPixels(newLRectangle(50,30,50,50),img);
- bitmapData2.setPixels(newLRectangle(100,30,50,50),img);
- bitmapData2.setPixels(newLRectangle(150,30,50,50),img);
- bitmapData2.setPixels(newLRectangle(200,30,50,50),img);
- bitmapData2.unlock();
The above code first creates an empty LBitrmapData object. The last parameter is a new feature in lufylegend-1.8.8 version, converting the data saved in the LBitrmapData object into a canvas object, which can improve the efficiency of pixel operations.
The execution code effect is as follows
Of course, you can also do some processing on these pixels, such as the following
[javascript] view plaincopy
- bitmapData2.lock();
- varrect=newLRectangle(50,100,100,100);
- varrect1=newLRectangle(150,100,100,100);
- for(vary=0;y<rect.height;y++){
- for(varx=0;x<rect.width;x++){
- vari=y*4*100+x*4;
- bitmapData2.setPixel(rect.x+rect.width-x,y+rect.y,[img.data[i],img.data[i+1],img.data[i+2],img.data[i+3]]);
- }
- }
- for(vary=0;y<rect1.height;y++){
- for(varx=0;x<rect1.width;x++){
- vari=y*4*100+x*4;
- bitmapData2.setPixel(x+rect1.x,y+rect1.y,[img.data[i],img.data[i+1],img.data[i+2],img.data[i+3]]);
- }
- }
- bitmapData2.unlock();
The effect is as follows
As you can see, we successfully flipped the picture over by processing pixels.
Of course, image flipping does not need to be so troublesome. In the lufylegend.js engine, you only need to set the object's property scaleX to -1 to achieve image flip. Here we mainly show that the pixel processing is very flexible.
Okay, with the above introduction, we can use these APIs to create a cool particle effect, the effect is as follows.
First, let's add a text to the canvas
[javascript] view plaincopy
- varlabelText=newLTextField();
- labelText.color=#000000;
- labelText.weight=bolder;
- labelText.text=getParameter(k);
- if(!labelText.text)labelText.text=lufylegend.js;
- labelText.size=50;
- varw=labelText.getWidth()*1.1;
- varh=labelText.size*1.5;
- labelText.width=w;
- labelText.setWordWrap(true,h);
- labelText.x=(LGlobal.width-w)*0.5;
- labelText.y=(LGlobal.height-h)*0.5;
- backLayer=newLSprite();
- addChild(backLayer);
- backLayer.addChild(labelText);
The effect is as follows
The only ones that need to be explained above are the following lines
[javascript] view plaincopy
- varw=labelText.getWidth()*1.1;
- varh=labelText.size*1.5;
- labelText.width=w;
- labelText.setWordWrap(true,h);
In fact, you only need to use getWidth() and getHeight() to get the height and width of the text. However, because there is no function to get the text height in canvas, the engine uses an inaccurate way to get it (of course, this will be perfectly solved in the next update of the engine). In this development, the text height and width used must be no less than the original size of the text, so I reset the slightly larger height and width for the text.
Next, we use the draw function of the LBitmapData object to convert this text into an LBitmapData object. Why do we need to convert it into an LBitmapData object? Please continue to look down and you will know in a while.
[javascript] view%20plaincopy
- bitmapData=newLBitmapData(#000000,0,0,LGlobal.width,LGlobal.height,LBitmapData.DATA_CANVAS);
- bitmapData.draw(backLayer);
The above processing is actually a prelude, not for real display. Let’s create an LBitmapData empty object and draw it on the canvas canvas through LBitmap.
[javascript] view%20plaincopy
- snowBack=newLBitmapData(null,0,0,LGlobal.width,LGlobal.height,LBitmapData.DATA_CANVAS);
- varbitmap=newLBitmap(snowBack);
- backLayer.addChild(bitmap);
The key point is here. I now need to continuously process the pixels of the snowBack object. This is simple, we can implement it through ENTER_FRAME.
[javascript] view%20plaincopy
- backLayer.addEventListener(LEvent.ENTER_FRAME,run);
As you can see in the above renderings, I need to constantly add white particles to the canvas, just like it is snowing. However, these white particles cannot be drawn directly on the canvas. We need to add these particles to a cache array first, and then operate them in batches. The following function is used to generate a particle, and the parameters are (x coordinates, y coordinates, descent acceleration, x-axis direction velocity, and y-axis direction velocity).
[javascript] view%20plaincopy
- functionparticle(px,py,ps,pvx,pvy){
- if(typeofps==UNDEFINED)ps=1;
- if(typeofpvx==UNDEFINED)pvx=0;
- if(typeofpvy==UNDEFINED)pvy=0;
- _snow.push({x:px,y:py,s:ps,vx:pvx,vy:pvy});
- }
By constantly calling this function, we constantly add white particles to the canvas. The particles added to the canvas will have accelerated downward movement similar to free fall. During the movement, we will encounter obstacles, that is, the text displayed on the screen before, when the particles encounter text, they will be subject to resistance and the movement becomes slow. In this way, the particles are constantly hindered by the text in places with text, and a large number of white particles will gather in the text, forming the particle effect above.
The following function is used to check whether the specified coordinate is on the text
[javascript] view%20plaincopy
- functioncheckPixel(x,y){
- varpixel=bitmapData.getPixel(x,y);
- for(vari=0;i<pixel.length;i++){
- if(pixel[i]) returntrue;
- }
- returnfalse;
- }
The principle is to obtain the pixels of the coordinate point and then check the color of the pixel points. Now you know why you need to convert the previous text into an LBitmapData object, just to get the pixel value of the specified point.
Finally, you only need to constantly add white particles and then allow the particles to continue to accelerate downward movement.
[javascript] view%20plaincopy
- functionrun(){
- varn=_snow.length,d;
- snowBack.lock();
- snowBack.setPixels(rect,0x000000);
- while(n--){
- varp=_snow[n];
- p.vy+=gravity*ps;
- p.y+=p.vy;
- if(checkPixel(px,py)){
- py-=p.vy;
- p.vy=0;
- p.y+=0.2;
- }
- snowBack.setPixel(px,py,0xffffffff);
- if(py>LGlobal.height){
- _snow.splice(n,1);
- }
- }
- snowBack.unlock();
- n=10;
- while(n--){
- partial(Math.random()*LGlobal.width,0,Math.random()+0.5);
- }
- }
OK, the job is done.
In the above example, the text [lufylegend.js] is fixed, and we can further expand it to set the text to be displayed through the URL. The following function can be used to get the value of the parameter in the URL.
[javascript] view%20plaincopy
- functiongetParameter(key){
- varstr=location.search.split(?);
- if(str.length<2){
- return;
- }
- varparams=str[1].split(&);
- for(vari=0;i<params.length;i++){
- varkeyVal=params[i].split(=);
- if(keyVal[0]==key&&keyVal.length==2){
- returndecodeURIComponent(keyVal[1]);
- }
- }
- return;
- }
Then call this function to set the value of the text
[javascript] view%20plaincopy
- labelText.text=getParameter(k);
Okay, you can test it. The following URL, you can change the following text into any character you like
http://lufylegend.com/demo/snow_word/index.html?k=Hello everyone
Reproduction diagram
Source code In fact, there is source code in the lufylegend engine download package, but it is slightly different from this article. The source code in this article only has one HTML file. You can see the complete source code by right-clicking the browser. Okay, next, please use your imagination to create more handsome and interesting particle effects, such as the more special particle effects below.
http://lufylegend.com/demo/particle01/
lufylegend.js engine official website http://lufylegend.com/lufylegend