Pixel processing and Particle effect in HTML5 Advanced Programming

Source: Internet
Author: User
Tags image flip

The getImageData and putImageData functions are required for Pixel processing in HTML5.GetImageData copies the pixel data in the canvas, processes the acquired pixel data, and finally passesPutImageData paste the processed data to the canvas. The process of processing pixels in the middle is called the batch processing of pixels. Because copying and pasting pixels are two time-consuming processes, in order to process pixels more efficiently, we should try to process as much pixel data as possible during a batch process to reduce the copying and pasting of pixels.

This seems to be a very troublesome process. Some friends may just get impatient when they see the above words. In fact, I think so too, so I encapsulated this troublesome process into the LBitmapData class of the lufylegend engine. You can process canvas in HTML5 like processing flash pixels. Does this sound interesting? If you are interested, please take a look at the small functions of this notebook with me.

First, let's take a look at LBitmapData, which is usually used to save Image objects. I will not talk about the specific usage. You can refer to the API documentation. Here I will mainly introduce how to use it to batch process pixels.

The following are two functions in LBitmapData:

Function Function
GetPixel (x, y, colorType) Returns an array of RGB pixel values in a BitmapData object at a specific point (x, y. ColorType is the format of the pixel data to be obtained. The default value is the pixel array. When it is set to the string "number", the system returns the number-type pixel.
SetPixel (x, y, data) Set a single pixel of the LBitmapData object. Data is the pixel value (three formats are supported: pixel array, # FF0000, 0xFF000, and so on)

The above two functions are used to obtain and set a single pixel. When we need to obtain or set a region pixel at a time, the corresponding two functions are as follows:

Function Function
GetPixels (rect) Returns an array of RGB pixel values in a specific area of a BitmapData object. Rect is the LRectangle object, which is a rectangle.
SetPixels (rect, data) Convert the pixel data array and paste it to the specified rectangular area. Data is the pixel value (three formats are supported: pixel array, # FF0000, 0xFF000, and so on)

Let's prepare an image first, for example, the handsome figure of the person below...

If you want to copy the handsome face in the middle through getPixels, you can

bitmapData = new LBitmapData(imglist["face"]);bitmapData.lock();var img = bitmapData.getPixels(new LRectangle(75,50,100,100));
Sometimes we need to perform multiple pixel copy and paste operations on LBitmapData. In this case, we can use the lock function to cache the pixel array. In this process, all the pixel operations are performed on the cached array. After the operation, call the corresponding unlock function to paste the operated pixel data back to LBitmapData.

As shown in the following example, we paste a part of the copied array four times to four different locations of another LBitmapData.

bitmapData2 = new LBitmapData(null,0,0,500,400,LBitmapData.DATA_CANVAS);bitmapData2.lock();bitmapData2.setPixels(new LRectangle(50,30,50,50),img);bitmapData2.setPixels(new LRectangle(100,30,50,50),img);bitmapData2.setPixels(new LRectangle(150,30,50,50),img);bitmapData2.setPixels(new LRectangle(200,30,50,50),img);bitmapData2.unlock();

The above code first creates an empty LBitrmapData object, the last parameter is a new function in the lufylegend-1.8.8 version, the data stored in the LBitrmapData object is converted to the canvas object, this improves the efficiency of pixel operations.

The code execution result is as follows:


Of course, you can also process these pixels, such as the following:

bitmapData2.lock();var rect = new LRectangle(50,100,100,100);var rect1 = new LRectangle(150,100,100,100);for(var y=0;y<rect.height;y++){for(var x=0;x<rect.width;x++){var i = 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(var y=0;y<rect1.height;y++){for(var x=0;x<rect1.width;x++){var i = 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:

We can see that we successfully flipped the image by processing pixels.

Of course, image flip does not need to be so troublesome. In the lufylegend. js engine, you only need to set the scaleX attribute of the object to-1 to implement image flip. Here we mainly want to demonstrate that pixel processing is flexible.

Well, with the above introduction, we can use these APIs to create a cool particle effect. The effect is as follows.


First, add a text on the canvas.

var labelText = new LTextField();labelText.color = "#000000";labelText.weight = "bolder";labelText.text = getParameter("k");if(!labelText.text)labelText.text="lufylegend.js";labelText.size = 50;var w = labelText.getWidth()*1.1;var h = 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 = new LSprite();addChild(backLayer);backLayer.addChild(labelText);
The effect is as follows:

The only explanation above is the following lines:

var w = labelText.getWidth()*1.1;var h = 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, but because the canvas does not have a function to get the text height, therefore, the engine uses an inaccurate method (of course, this will be perfectly solved in the next update of the engine, the height and width of the text must not be smaller than the original size of the text. Therefore, I reset the height and width of the text.
Next, we will use the draw function of the LBitmapData object to convert the text to the LBitmapData object. Why should we convert it to the LBitmapData object? Next, let's take a look.

bitmapData = new LBitmapData("#000000",0,0,LGlobal.width,LGlobal.height,LBitmapData.DATA_CANVAS);bitmapData.draw(backLayer);
The above processing is actually a foreshadowing, not for real display. Next we will create an LBitmapData empty object and use LBitmap to draw it onto the canvas.

snowBack = new LBitmapData(null,0,0,LGlobal.width,LGlobal.height,LBitmapData.DATA_CANVAS);var bitmap = new LBitmap(snowBack);backLayer.addChild(bitmap);
The point is, I need to constantly process the pixels of the snowBack object. This is simple, and we implement it through ENTER_FRAME.

backLayer.addEventListener(LEvent.ENTER_FRAME,run);
As you can see, I need to add white particles to the canvas, just like snow. However, these white particles cannot be directly painted on the canvas. We need to add these particles to a cache array and then operate them in batches. The following function is used to generate a particle, the parameters are (x coordinate, y coordinate, descent acceleration, x-axis direction speed, and y-axis direction speed ).

function particle(px,py,ps,pvx,pvy){if(typeof ps == UNDEFINED)ps = 1;if(typeof pvx == UNDEFINED)pvx = 0;if(typeof pvy == UNDEFINED)pvy = 0;_snow.push({x:px,y:py,s:ps,vx:pvx,vy:pvy});}
By constantly calling this function, we can constantly add white particles to the canvas. The particles added to the canvas will perform a downward accelerated movement similar to the free falling body, in the process of motion, there will be obstacles, that is, the text displayed in front of the screen. When a particle encounters a text, it will be subject to resistance and the motion will become slow, in this way, the particles are constantly blocked by the text, and a large number of white particles will gather in the text to form the above particle effect.

The following function is used to check whether the specified coordinate is in the text.

function checkPixel(x,y){var pixel = bitmapData.getPixel(x,y);for(var i=0;i<pixel.length;i++){if(pixel[i])return true;}return false;}
The principle is to get the coordinate point pixel and then check the color of the pixel. Now you know why to convert the previous text to the LBitmapData object to get the pixel value of the specified point.

Finally, we only need to constantly add the white particles, and then let the particles continuously accelerate the motion downward.

function run(){var n = _snow.length, d;snowBack.lock();snowBack.setPixels(rect,0x000000);while(n--){var p = _snow[n];p.vy += gravity * p.s;p.y += p.vy;if(checkPixel(p.x, p.y)){p.y -= p.vy;p.vy = 0;p.y += 0.2;}snowBack.setPixel(p.x, p.y, 0xffffff);if(p.y > LGlobal.height) {_snow.splice(n, 1);}}snowBack.unlock();n = 10;while(n--) {particle(Math.random() * LGlobal.width, 0, Math.random() + 0.5);}}
All right, you're done.

In the above example, the text [lufylegend. js] is fixed and can be further expanded to set the text to be displayed through URL. The following functions can be used to obtain the value of parameters in a URL.

function getParameter(key) {var str = location.search.split("?");if (str.length < 2) {return "";}var params = str[1].split("&");for (var i = 0; i < params.length; i++) {var keyVal = params[i].split("=");if (keyVal[0] == key && keyVal.length == 2) {return decodeURIComponent(keyVal[1]);}}return "";}
Then, you can call this function to set the text value.

labelText.text = getParameter("k");
Now, you can test the following URL. You can change the following text to any character you like.

Http://lufylegend.com/demo/snow_word/index.html? K = Hello everyone




Source code
In fact, the lufylegend engine download package contains the source code, but it is slightly different from this article. The source code in this article only has one HTML file. You can right-click the browser to see the complete source code.


Now, let's use your imagination to make more handsome and interesting particle effects.

For example, the following is a special particle effect.

Http://lufylegend.com/demo/particle01/


Lufylegend. js engine Official Website

Http://lufylegend.com/lufylegend

Lufylegend. js engine online API documentation link

Http://lufylegend.com/lufylegend/api


Continue to follow my blog

Reprinted Please note:

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.