Simulation twist of the Android flip effect principle

Source: Internet
Author: User

Respect the original reprint please specify: from Aigestudio (Http://blog.csdn.net/aigestudio) Power by aige infringement must investigate!

Artillery Zhen Lou

In the previous section we realized the curve of the page turn effect, but the effect is a bit small flaw do not know that we found no:


, we found that the folding area was strange, and did not achieve our previous "bending" effect, why? Is the calculation wrong? In fact, we used to fill the canvas before the test, but here we use a bitmap, although our path is a curve, region has a curved area, but our bitmap is a well-behaved rectangle, how to bend ~ How to do? When it comes to twisting, the first thing we think about is the Drawbitmapmesh method, which is the only one that we now know is the only API that can distort the image, and the Drawbitmapmesh method we can have a variety of ideas, the simplest is to maximize the constant subdivision value, By dividing the image into a certain grid area, and then judging the subdivision line closest to the beginning and vertex of the curve to get the segment intersection in that area, the distance between the starting point and the vertex is reduced by the specified direction percentage, which is simple and rough, but the distortion is not very precise, the accuracy is determined by the subdivision, The subdivision is also more accurate, of course, the more cost-effective, and the second method is based on the curve's starting point and vertex dynamic generation of subdivision values, we can ensure that there is a subdivision line at the beginning and vertex, so that can be very accurate calculation of the distortion range, but we need to dynamically calculate the subdivision value is rather troublesome, which one? Here, in view of the time relationship, or try to do the first, first define a wide-height subdivision value:

private static final int sub_width = Sub_height = 19;//Subdivision value 19 grid
19 meshes split the control into 20x20 's grid subdivision line area, and then we don't need to use Drawbitmap to draw the collapsed area instead of Drawbitmapmesh. Before talking about 1/6, there are many small window of the time I am off the screen buffer is what the meaning need to pay attention to what, here I right when the demo, when drawing distorted images using a separate bitmap and loading it into an additional canvas:

Private Canvas mcanvasfoldcache;//performs drawing off-screen buffered canvasprivate Bitmap mbitmapfoldcache;//store draws off-screen buffered data Bitmap
In the construction method we instantiate the Mcanvasfoldcache:

/* Instantiation of canvas */mcanvasfoldcache = new canvas ();
In onsizechanged we generate Mbitmapfoldcache:

/* * Generate buffer bitmap and inject canvas */mbitmapfoldcache = bitmap.createbitmap (Mviewwidth +, Mviewheight +, Bitmap.Config.ARGB_888 8); Mcanvasfoldcache.setbitmap (Mbitmapfoldcache);
Here +100 of the purpose is to let bitmap have extra space to draw the distorted part of the image, we said before the size of the canvas actually depends on the internal loading of the bitmap, if we do not + 100, then the size of the Mbitmapfoldcache is just as big as our control, but the part of the image that we are distorting is outside that range:


such as transparent red range is the size of our mbitmapfoldcache, but the bottom and the right side of the twist is not included, in order to compensate for this loss I will mbitmapfoldcache the width of the +100, of course, you can also calculate the specific value, here only to do the demonstration.

While drawing, we first draw all the data onto the Mbitmapfoldcache and then draw the bitmap into our canvas:

Mcanvasfoldcache.drawbitmapmesh (Mbitmaps.get (end-1), Sub_width, Sub_height, mverts, 0, NULL, 0, NULL); Canvas.drawbitmap (mbitmapfoldcache, 0, 0, NULL);
It is important to note that our Mbitmapfoldcache is generated in the Onsizechanged method, and every time we draw it is no longer regenerated, that is, each drawing is superimposed on the last drawing data, then this will bring us a problem, Although it is possible to display the results without error, but each time the drawing is constantly calculating the number of pixels in front of a number of times will certainly greatly affect performance, when we consider to draw each result before the content of the Mbitmapfoldcache:

Mcanvasfoldcache.drawcolor (Color.transparent, PorterDuff.Mode.CLEAR); Mcanvasfoldcache.drawbitmapmesh ( Mbitmaps.get (end-1), Sub_width, Sub_height, mverts, 0, NULL, 0, NULL); Canvas.drawbitmap (mbitmapfoldcache, 0, 0, NULL);
This is the end of the topic, in fact we do not need to buffer drawing, directly using Drawbitmapmesh:

Canvas.drawbitmapmesh (Mbitmaps.get (end-1), Sub_width, Sub_height, mverts, 0, NULL, 0, NULL);
The point is how we generate these distortions, and in our constructor we instantiate the array of coordinates:

Instantiate an array and initialize the default array data Mverts = new float[(sub_width + 1) * (Sub_height + 1) * 2];
After calculating the coordinates of each point of the curve we generate the warp coordinates:

if (Sizelong > Mviewheight) {//omit a large amount of code ...} else {//Omit massive code ... */* generates warp coordinates for collapsed regions */int index = 0;for (int y = 0; y <= SUB _height; y++) {Float FY = mviewheight * y/sub_height;for (int x = 0; x <= sub_width; + +) {Float FX = mviewwidth * X/sub_wid Th;mverts[index * 2 + 0] = Fx;mverts[index * 2 + 1] = Fy;index + = 1;}}
Although we have generated an array of coordinates above, but we have not distorted the image, we will analyze how to distort it before we proceed to the next step, when we draw the bitmap in the folded area in a drawbitmapmesh way, the image is essentially segmented by the mesh:


Our approach is very simple, just want to start from the short edge length minus the length of the edge to the position of the short edge length of 1/4 to the point of the position of the shorter side to drag the increment downward can be:


As shown in the two blue dots representing the short side length minus the short edge length multiplied by the position of 1/4 and the short edge length position, because our grid is constant, but the position is changing, we should get the nearest grid point from the current position, such as the two blue dots in this case we should get to the corresponding position in the grid is:


Medium green Blue Point, considering the better tolerance value, we make the starting point to move back a point and the end of the move forward a point, the final point of our choice is as follows:


Similarly, our right side is the same:


The implementation in the code is also simple:

Calculates the starting subdivision subscript for the bottom twist Msubwidthstart = Math.Round ((btmx/msubminwidth))-1;msubwidthend = Math.Round (((btmx + curvature * size Short)/msubminwidth) + 1;//calculates the starting subdivision of the right twist subscript Msubheightstart = (int) (lefty/msubminheight)-1;msubheightend = (int) (lef TY + curvature * sizelong/msubminheight) + 1;
We just need to msubwidthstart to msubwidthend between the point down "drag", Msubheightstart to the point of Msubheightend to the right "drag" can achieve the initial "twist" effect, but this drag is fastidious, first, The distance is multiplied,


The offset value of each point is multiplied by the previous point, and how much is multiplied? is based on the maximum offset value, here in order to simplify a certain problem, I do not calculate, but given a fixed starting value and the multiplier rate:

Long Edge offset Float Offsetlong = curvature/2f * sizelong;//long edge offset multiply float muloffsetlong = 1.0f;//Short Edge offset float offsetshort = Curvatu RE/2F * sizeshort;//Short edge offset multiply float muloffsetshort = 1.0F;
At this point we can consider starting to calculate the warp coordinates:

Calculates the starting subdivision subscript for the bottom twist Msubwidthstart = Math.Round ((btmx/msubminwidth))-1;msubwidthend = Math.Round (((btmx + curvature * size Short)/msubminwidth) + 1;//calculates the starting subdivision of the right twist subscript Msubheightstart = (int) (lefty/msubminheight)-1;msubheightend = (int) (lef  TY + curvature * sizelong/msubminheight) + 1;/* * Generate warp coordinates for collapsed regions */int index = 0;//long edge offset float Offsetlong = curvature/2f * sizelong;//Long edge offset multiply float muloffsetlong = 1.0f;//Short Edge offset float offsetshort = curvature/2f * sizeshort;//Short edge offset multiply float muloffs Etshort = 1.0f;for (int y = 0; y <= sub_height; y++) {Float FY = mviewheight * y/sub_height;for (int x = 0; x <= S Ub_width; X + +) {Float FX = mviewwidth * x/sub_width;/* * Right twist */if (x = = Sub_width) {if (y >= msubheightstart && y < = msubheightend) {FX = Mviewwidth * x/sub_width + offsetlong * muloffsetlong;muloffsetlong = muloffsetlong/1.5f;}} /* * Bottom twist */if (y = = sub_height) {if (x >= msubwidthstart && x <= msubwidthend) {fy = mviewheight * y/sub_ HEIGHT + OffsetshoRT * Muloffsetshort;muloffsetshort = muloffsetshort/1.5f;}} Mverts[index * 2 + 0] = Fx;mverts[index * 2 + 1] = Fy;index + = 1;}}
The effect is as follows:


The above figure because of the size of the upload limit I compressed may not be able to see clearly, if everyone DL I want to run the project can see the distorted part of the process will have a little bounce, the reason is very simple, our distortion only for the bottom of the last line of y = = Sub_height and right-most right column X = = Sub_width, and the fact that the distortion is a pull linkage effect, distortion will not only affect the last row/column will also affect the countdown combined second line, etc., but this effect is diminishing, this part left to everyone to do, the principle I speak very clearly.

This section ends with the next section we will refine the final effect end This example all study~

SOURCE Download: Portal

Simulation twist of the Android flip effect principle

Related Article

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.