React Native图像变换 Transforms详解

我们知道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,

VR:第三个参数可以再react-Vr中使用,这样就是3维立体的了如下代码:


VR中的立体字

上面的代码就是VR中的代码,可以看到translate的第三个参数是-3,这样用VR眼镜看就是立体的字体了,后面的Z轴数据在VR中就更真实了,由此可看见FB以后也将在VR领域大房光彩了

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;

也就是说大家以后可以用矩阵来变化图像了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,376评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,126评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,966评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,432评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,519评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,792评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,933评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,701评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,143评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,488评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,626评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,292评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,896评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,494评论 2 348

推荐阅读更多精彩内容