preface
Recently, I was doing the optimization of picture viewing, and I spent more than a week (plus other time needed to fix bugs), which made me angry.
So the next few articles will be about images or animations. This one will be an appetizer to show you how to use Matrix.
Take a look at the animation you can write after learning Matrix:
I. What is Matrix?
As an Android developer, we didn’t get to use Matrix directly.
However, we have been working with matrices, such as ImageView, by setting different ScaleTypes to get different matrices to show different effects. A little deeper, behind all kinds of View, Matrix has a contribution!
Matrix is a 3 by 3 Matrix, if you’ve forgotten what a Matrix is? You can review it here.
Since it is a 3 by 3 matrix, it consists of nine parameters:
The six numbers above control the scale, bevel and shift respectively. The scale and bevel are controlled together to achieve the effect of rotation.
The following three parameters control the 3D transformation, which we won’t cover too much in this article.
instructions
The rest of this section is from the GcsSloop article: “Matrix Introduction”
1. The zoom (Scale)
Expressed as a matrix:
You may notice that we coordinate a 1 more, this is the use of the homogeneous coordinate system, in our point and vector in the math are said (x, y), both look the same, computers are indistinguishable, so let the computer can also distinguish between them, added a logo, increase after looks like this:
(x, y, 1) minus the point (x, y, 0) minus the vector
In addition, homogeneous coordinates have the property of equal proportions, (2,3,1), (4,6,2)… (2N,3N,N) is the point (2,3). (This is where the misunderstanding of interpreting MPERSP_2 as scale comes from).
Legend:
2. Shear (Skew)
There are two special types of miscuts, horizontal (parallel to the X axis) and vertical (parallel to the Y axis).
Horizontal shear
Expressed as a matrix:
Legend:
Vertical shear
Expressed as a matrix:
Legend:
Composite shear
A combination of horizontal and vertical miscuts.
Expressed as a matrix:
Legend:
3. The rotation (Rotate)
Suppose A point A(x0, y0) is r away from the origin, the Angle between it and the horizontal axis is α degree, and it is rotated θ degree about the origin. After rotation, it is point B(x, y) as follows:
Expressed as a matrix:
Legend:
4. Translation (Translate)
Here is also one of the advantages of using homogeneous coordinates, actually in front of the three operation using 2 x2 matrix can meet the demand, but the use of 2 x2 matrix, to shift operations to join, and the extension of the coordinates for the homogeneous coordinates, with the extension of the matrix for the 3 x3 algorithm can be unified, four kinds of algorithms are completed you can use the matrix multiplication.
Expressed as a matrix:
Legend:
ScaleType and Matrix
From above we learned the basic Matrix operation from the GcsSloop boss, now we will learn about the ImageView ScaleType and its corresponding Matrix.
As we all know, the corresponding scaletyPs in ImageView are CENTER_CROP, CENTER, CENTER_INSIDE, FIT_END, FIT_CENTER, FIT_START, FIT_XY, and MATRIX.
Suppose the ImageView in the figure is 300 pixels wide and 600 pixels high, and the image is 1200 pixels wide and 600 pixels high.
1. CENTER_CROP
CENTER_CROP is the type we use most often. Rule: The image width and height ratio zoom, until the width and height is greater than or equal to the control’s width and height, the extra part of the image will be cropped.
How do I get the Matrix corresponding to CENTER_CROP? In fact, it is very simple, in two steps:
Step 1: Zoom the image so that either side of the width and height can be greater than or equal to the length of the control.
Control length/Picture Length = o.25 Control width/picture width = 0.5Copy the code
In order to fill the picture with the control and ensure no blank space, it is necessary to select the side with a larger control picture, so our current Matrix is:
[0 0 0] [0 0 0] [0 0 1]Copy the code
The current image and control becomes:
Step 2: Center panning, as shown in the figure above, the width of the picture is still larger than the width of the control, in order to display the middle position of the picture on the control, you need to do some panning of the picture.
TranslationX = (imageViewWidth – drawableWidth * scale) / 2
[1 0-150] [0.5 0 0] [0 1 0] * [0 0.5 0] = [0 0.5 0] [0 0 1] [0 0 1] [0 0 1] [0 0 1]Copy the code
The current image and control becomes:
This is the final shape of the ImageView with CENTER_CROP applied.
2. Center
Center rule: The image is not zoomed, only panned, and finally the Center of the image is displayed on the control.
Therefore, after calculation:
translationX = (imageViewWidth - drawableWidth) / 2;
translationY = (imageViewHeight - drawableHeight) / 2;
Copy the code
Matrix:
[1 0-150] [0 0 1]Copy the code
The resulting graph is:
CENTER_INSIDE
CENTER_INSIDE rule: Zoom out the image so that the control can display the full image and center it. Do not zoom in when the image is smaller than the width and height of the control.
FIT_XY
FIT_XY rule: Scale the image width and height separately. The width and height after scaling will be equal to the width and height of the control. The image may be distorted.
FIT_START
FIT_START rule: Scale the image equally in width and height. The control can display the image completely, panning it to the header area.
FIT_CENTER
FIT_CENTER rule: The control can display the picture completely by scaling the picture in equal proportion to its width and height. The control can be panted to the center of the control. When the width and height of the picture are smaller than the width and height of the control, the picture will be enlarged.
FIT_END
FIT_END rule: The control can display the image in its entirety, panning to the bottom and back of the control.
Matrix
Matrix rule: Customize Matrix.
3. Make a Matrix animation
Making a Matrix transition animation is relatively easy, since MatrixEvaluator MatrixEvaluator is readily available. You only need to specify two or more matrices.
val evaluator = MatrixEvaluator()
val matrix = evaluator.evaluate(it.animatedFraction, firstMatrix, secondMatrix)
iv.imageMatrix = matrix
Copy the code
In the animation at the beginning of this article, a total of 6 matrices are required (1 is the same as 5) :
So how do you get these matrices? ImageView provides the ImageView#getImageMatrix() method, which helps us to obtain the current ImageView Matrix.
- The first: current
Matrix
The same. - Second: current
Matrix
Pan it half to the right. - Third: current
Matrix
Pan it half wide to the right and half high to the down. - Fourth: current
Matrix
Let’s shift it down half the height. - Fifth: current
Matrix
Same as the first slide. - Sixth: current
Matrix
We’ll shift it to the right by a quarter of a width and down by a quarter of a height. - Seventh: current
Matrix
The same.
All that remains is the animation code:
fun doSomeThingAnimation(a){ ivContent? .let { iv ->val imgWidth = iv.width
val imgHeight = iv.height
iv.layoutParams.width = imgWidth / 2
iv.layoutParams.height = imgHeight / 2
val tX = imgWidth.toFloat() / 2
val ty = imgHeight.toFloat() / 2
val initMatrix = iv.imageMatrix
// Get 6 matrices
val oneMatrix = Matrix(initMatrix)
val twoMatrix = Matrix(initMatrix).apply {
postTranslate(-tX, 0f)}val threeMatrix = Matrix(initMatrix).apply {
postTranslate(-tX, -ty)
}
val fourthMatrix = Matrix(initMatrix).apply {
postTranslate(0f, -ty)
}
val fiveMatrix = Matrix(initMatrix).apply {
postTranslate(-tX / 2, - ty / 2)}val sixMatrix = Matrix(initMatrix)
iv.scaleType = ScaleType.MATRIX
iv.imageMatrix = oneMatrix
// Build 6 animations
val evaluator = MatrixEvaluator()
val firstAnimator = ValueAnimator.ofFloat(0f.1f)
firstAnimator.addUpdateListener {
val matrix = evaluator.evaluate(it.animatedFraction, oneMatrix, twoMatrix)
iv.translationX = it.animatedFraction * imgWidth / 2
iv.imageMatrix = matrix
}
val secondAnimator = ValueAnimator.ofFloat(0f.1f)
secondAnimator.addUpdateListener {
val fraction = it.animatedFraction
iv.translationY = fraction * imgHeight / 2
val matrix = evaluator.evaluate(fraction, twoMatrix, threeMatrix)
iv.imageMatrix = matrix
}
val threeAnimator = ValueAnimator.ofFloat(0f.1f)
threeAnimator.addUpdateListener {
val fraction = it.animatedFraction
iv.translationX = ((1 - fraction) * imgWidth / 2)
val matrix = evaluator.evaluate((fraction), threeMatrix, fourthMatrix)
iv.imageMatrix = matrix
}
val fourAnimator = ValueAnimator.ofFloat(0f.1f)
fourAnimator.addUpdateListener {
val fraction = it.animatedFraction
iv.translationY = ((1 - fraction) * imgHeight / 2)
val matrix = evaluator.evaluate((fraction), fourthMatrix, oneMatrix)
iv.imageMatrix = matrix
}
val fiveAnimator = ValueAnimator.ofFloat(0f.1f)
fiveAnimator.addUpdateListener {
val fraction = it.animatedFraction
iv.translationY = (fraction * imgHeight / 4)
iv.translationX = (fraction * imgWidth / 4)
val matrix = evaluator.evaluate((fraction), oneMatrix, fiveMatrix)
iv.imageMatrix = matrix
}
val sixAnimator = ValueAnimator.ofFloat(0f.1f)
sixAnimator.addUpdateListener {
val fraction = it.animatedFraction
iv.layoutParams.width = (imgWidth / 2 + imgWidth / 2 * fraction).toInt()
iv.layoutParams.height = (imgHeight / 2 + imgHeight / 2 * fraction).toInt()
iv.translationY = ((1 - fraction) * imgHeight / 4)
iv.translationX = ((1 - fraction) * imgWidth / 4)
val matrix = evaluator.evaluate((fraction), fiveMatrix, sixMatrix)
iv.imageMatrix = matrix
iv.requestLayout()
}
val set = AnimatorSet()
set.playSequentially(firstAnimator, secondAnimator, threeAnimator, fourAnimator, fiveAnimator, sixAnimator)
set.duration = 1000
set.start()
}
}
Copy the code
A simple animation skill Get!
conclusion
The actual scenes used in this animation are not many, but when you need to switch between the same image and different ScaleType, such as opening a small image into a large image, Matrix animation may help you!
Wonderful content
If you think this article is good, “like” is the biggest encouragement to the author ~
Technology more than, the article has material, concern public number nine heart said, a high quality good article every week, and nine hearts in Dachang road side by side.
Citation:
Matrix Introduction