查看原文
其他

React Native图像变换 Transforms详解

2017-02-16 刘成 一起众创



我们知道View的style的大多数属性的用法,但是有个Transforms的属性我们很少知道,而且中文网上也只是写了个属性列表,并没有介绍怎么使用,现将原理和使用方法介绍如下,还请各位参考:

入口在官网的View的style属性下面的Transforms...属性 View的style属性下面的Transforms...属性 中文网的Transforms属性

打开后我们可以看到有三个方法,分别是transform、transformMatrix、decomposedMatrix。

其中后两个方法已经过期了,需要用transform: [{ matrix: ... }]这种方法代替使用,最后会讲解matrix矩阵的用法。

首先讲解transform的这几个属性,首先transform必须是数组的形式存在:

1、translateY和translateX、translate

在官网的介绍里面是没有translate的,但是官方源码中给出了这个属性可以用,代码如下: translateY和translateX、translate代码

translateY和translateX分别是向Y、X轴偏移,值为可为正可为负,transform:[{translateX:100}],放在style里面。 translateY和translateX、translate运行结果

xyz轴的方向为(手机屏幕面向上,平方在手机上):

X轴正方向:手机右侧为正,向左为负;

Y轴正方向:手机下方为正,上方为负;

Z轴正方向:从手机背面向屏幕指向为负,反之从屏幕向背面指向为正;

而 transform:[{translate:[-100,100,50]}] ,则有单个参数,分别为X、Y、Z,Z不填的话为0

2、scaleX、scaleY、scale

代码如下: scaleX、scaleY、scale代码

运行结果:  scaleX、scaleY、scale的运行结果

scaleX表示width的缩放,scaleY表示height的缩放,而scale代表宽高都缩放;

值若为正数,则正常缩放,若为负数,则是以自己的中心为中心的镜像

3、rotateZ、rotateX、rotateY、rotate

其中rotateX、rotateY为绕X和Y轴旋转,在我们手机的XY平面中是看不到的,所以此处不做介绍,只介绍rotateZ和rotate,这两个是一样的结果: rotateZ代码

rotateZ的值为负数,旋转方向为逆时针,度数必须是string,且要加上deg单位,运行结果如下:  逆时针旋转,rotateZ为负

 顺时针旋转,rotateZ为正

4、skewY、skewX斜切

代码如下: skewY、skewX的代码

 skewY、skewX的运行结果 大家可能懵逼了,其中skewX表示的是以X轴为中心在YZ屏幕中旋转,而skewY表示的是以Y轴为中心在XZ屏幕中旋转。

5、perspective

这个是透视的概念,在RN中目前还看不到效果

6、

matrix矩阵

大家知道这是矩阵的意思,具体的代码如下:  实际上这个一个一维数组

如果第一行最后一个为0的话,在矩阵中也就是单位矩阵,代表的是原始的大小,没有任何变形。而这个0改为1的话就是下面的运行结果

运行结果如下:  左侧为正常模式,右侧改变了数组中的第四个0为1

这个在实际的开发过程中用的很少,

如过代码改成了如下:  第二行第四个0为1

运行结果为:  左侧为正常模式,数组第二行的第四个0为1

其他的值大家自行调整,自行验证,这个在开发中用的还是比较少的,上面讲的各种缩放和变换都可以用这个表示出来的,因为最终调用的方法都是这个方法(MatrixMath.multiplyInto(result, result, value)),源码如下:

 transform的部分源码

上面的代码是我粘出来的代码,开始都是调用createIdentityMatrix()方法,返回一个一维数组,这个数组只不过不同的值表示矩阵而已,最后都是调用MatrixMath.multiplyInto(result, result, value)的方法,

第一个参数result是result = MatrixMath.createIdentityMatrix();,

第二个参数是createIdentityMatrix方法或者MatrixMath中的其他方法,MatrixMath中的其他方法也是合并的第一个方法

第三个是你输入的值(如:translateY:100中的100,而矩阵的话就是如下代码

[    1,1,0,0,    0,1,0,-1,    0,0,1,0,    0,0,0,1]

7、举个例子translateX的由来

假设我们输入的是:transform:[{translateX:100}]

首先

_multiplyTransform(result, MatrixMath.reuseTranslate2dCommand, [value, 0]);

_multiplyTransform()方法内部是下面的四行----->

var matrixToApply = MatrixMath.createIdentityMatrix();var argsWithIdentity = [matrixToApply].concat(args); matrixMathFunction.apply(this, argsWithIdentity); MatrixMath.multiplyInto(result, result, matrixToApply);

大家可以看出最后又是调用6中的最后的方法,下面我就一步步的打印结果给看看,然后和我们直接修改matrix是一样的结果。

7.1、 matrixToApply的值为4*4的单位矩阵,也就是16个值得一维数组
[ 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 ] [    1,0,0,0,    0,1,0,0,    0,0,1,0,    0,0,0,1]

大家可以看出是一样的,

7.2 、argsWithIdentity =
[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1].concat[100,0]

argsWithIdentity现在有三个值,一个是单位矩阵,一个是100,一个是0

7.3、把argsWithIdentity的三个值作为三个参数传给MatrixMath.reuseTranslate2dCommand的方法中
7.4、reuseTranslate2dCommand
reuseTranslate2dCommand: function(matrixCommand, x, y) {   matrixCommand[12] = x;   matrixCommand[13] = y; },

也就是说单位矩阵中的第三行的最后一个是100,最后一行的第一个是0,矩阵变成了

[  1,0,0,0,  0,1,0,0,  0,0,1,0,  100,0,0,1]

 用矩阵代替translateX:100

最后的效果和我们之前的结果是一样的,  translateX:100

8、matrix代替其他的转换

从7中的分析我们可以看出,

[  a0,a1,a2,a3,  a4,a5,a6,a7,  a8,a9,a10,a11,  a12,a13,a14,a15 ]

translateX:改变矩阵的a12的值就是translateX的改变;

translateY:改变矩阵的a13的值就是translateY的改变;

translate:改变矩阵的a12,a13,a14的值就是translate的改变,其中a12代表的就是X,a13代表的就是Y,a14代表的就是Z(Z的默认值为0,可以不填);

skewX:就是改变a4 = Math.sin(radians),其中randians就是我们输入的‘60deg’,就是60度;同时还得改变a5 = Math.cos(radians);

skewY:就是改变a0 = Math.cos(radians),其中randians就是我们输入的‘60deg’,就是60度;同时还得改变a1 = Math.sin(radians);

scaleX:改变a0就可以了;

scaleY:改变a5就可以了;

scale:同理把a0和a5同时改变一个数值

rotateZ:改变的是

          a0 = Math.cos(radians);           a1= Math.sin(radians);            a4 = -Math.sin(radians);            a5= Math.cos(radians);

rotateY:改变的是

          a0 = Math.cos(radians);           a2= -Math.sin(radians);           a8 = Math.sin(radians);           a10= Math.cos(radians);

rotateX:改变的是

        a5 = Math.cos(radians);         a6= Math.sin(radians);         a9 = -Math.sin(radians);         a10= Math.cos(radians);

perspective:改变的是 a11= -1 / p;

也就是说大家以后可以用矩阵来变化图像了, 在此我只能说FB太牛了


React/React-Native/Flux/Redux/跨平台项目实战 6天魔鬼训练

Android 设计模式之Builder模式的简单使用

Swift 内存管理(一)

Swift 内存管理(2.1 高级)


扫描二维码

关注更多精彩



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存