资讯专栏INFORMATION COLUMN

写一个图片预览器(react-native),温习一下初中数学

william / 2968人阅读

摘要:什么意思呢看图吧合理的解释缩放操作时,上面的始终触点在圆圆的眼睛上面对不起圆圆了,下面的触点始终在中指戒指上一点点。不过这也是为了满足自己的开发需求,没有开放很多可定制的内容。最后为了装个学英语,写英文的

statistics
source download download/month
npmjs.com
npm.taobao.org
cnpmjs.org

需求很简单:

可以放大任意一处我想放大的地方

可以移动,查看任意图片细节

支持网络图片和本地图片

技术实现 一、加载图片和获取图片尺寸 二、设置尺寸、放大到刚好满屏、居中

react-native图片transform的缩放的中心点在图片的中心,因此,把图片先发居中就好

比较图片的长宽比和屏幕的宽高比,如果是图片比较宽那么就横向满屏,如果比较高就纵向满屏,如下图:

    /*
    * center and zoom to fit the window
    * @ _width: the picture width
    * @ _height: the picture height
    * */
    center(_width, _height){
        let {width, height} = Dimensions.get("window"),
            rateImage = _width/_height,
            rateWindow = width/height,
            top,
            left,
            scale
        if (rateImage > rateWindow) {
            scale = width/_width
        } else {
            scale = height/_height
        }
        top = (height - _height)/2
        left = (width - _width)/2
        this.setState({
            left,
            top,
            width:_width,
            height: _height,
            scale,
            rate: scale
        })
    }
三、准备移动和缩放动作

1.设置两个变量来记录(上一次手指的和缩放的)状态

        this._touches = [
            {},
            {}
        ]
        this._zoom = undefined

2.每次动作结束之后清除状态

            onPanResponderRelease: (evt, gestureState) => {
                // reset
                this._touches = [
                    {},
                    {}
                ]
                this._zoom = undefined
            }

3.每次开始触摸的时候的时候记录状态

// touche start
onPanResponderGrant:(evt, gestureState) => {
    // mark touches info
    for (let x in this._touches) {
    if (evt.nativeEvent.touches[x]) {
        this._touches[x].x = evt.nativeEvent.touches[x].pageX
        this._touches[x].y = evt.nativeEvent.touches[x].pageY
        this._touches[x].identifier = evt.nativeEvent.touches[x].identifier
        }
    }
},

4.每次移动的时候,如果没有记录状态就记录状态,如果有记录就开始做动作啦↓↓↓

四、移动图片

1.这个很简单,只要图片跟着手指动就可以了,因为缩放变换的中心是图片的中心,所以只需要简单的改变left 和 top 就可以了,??

// compute the distance has touch moved
let moveX = evt.nativeEvent.touches[0].pageX - this._touches[0].x
let moveY = evt.nativeEvent.touches[0].pageY - this._touches[0].y
// set the state
this.state.left += moveX
this.state.top += moveY
this.setState({
    left: this.state.left,
    top: this.state.top
})
五、 放大图片

一个宗旨:图片跟着手指动。什么意思呢?看图吧!

合理的解释:缩放操作时,上面的始终触点在圆圆的眼睛上面(对不起圆圆了),下面的触点始终在中指戒指上一点点。

1、缩放比例计算(以上图为例)
// 缩放前,戒指到眼睛的距离为 d,这个是图片的真实距离
// 屏幕上,戒指到眼睛的距离为D
// 缩放比例为 S,屏幕的尺寸/图片的尺寸
// 因此有个等式
d * S = D
// 那么,在新的位置
dn * Sn = Dn
// 在图片中,dn是相等的
// 因此,解个方程可以得到
Sn = Dn/D * S
// Dn 和 D 分别可以有 新的触点的坐标 和 旧的 触点的坐标 表示,S已知
// 这样我们就得到了 新的缩放比例 和 触点坐标的关系了
2、图片位置的计算 (已上图为例)

刚刚已经说到,RN变换的中心点是图片的中心,那么,我要放大一个角落的位置,如何让图片看起来是以这个角落为缩放中心呢?改变left 和 top 就可以了。

// 以left为例,top同理可得
// 上图中,两个触点的连线的中点位置大约是圆圆的第二颗牙齿(下面称为牙齿)
// 设牙齿的X坐标为 X (屏幕的坐标)
// 牙齿在图片中距离图片中线的距离为 d
// 图片的实际宽度为w
// 图片的位置为l(事实上为放大前的左边距)
// 缩放比例为 S,屏幕的尺寸/图片的尺寸
// 图片的缩放中心是图片的中心,因此有一个等式:
X = (0.5 * w + l) - d * S
// 那么对于新的位置也有一样的等式
Xn = (0.5 * wn + ln) - dn * Sn
// 事实上就,X的位置不变,d的位置不变,w也不会变,那么就有等式了
(0.5 * w + l) - d * S = (0.5 * w + ln) - d * Sn
// 由这里就可以解出ln 和 l , S ,Sn的关系了。
// l,S已知,Sn上面已经算出来了
结语

到此整个思路已经出来了,代码看github。
不过这也是为了满足自己的开发需求,没有开放很多可定制的内容。
最后为了装个X(学英语??),写英文的README

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87206.html

相关文章

  • 小哥哥小姐姐看过来,这里有个组件库需要您签收一下

    摘要:如果你想减少包大小,你可以这样引入事实上,每个组件都是支持单独安装的,我们也推荐你使用这种方式引入组件。以下是运行示例后各界面的截图组件图标右上角的圆形徽标数字。 1. 前言 一直以来都想做个组件库,一方面是对工作中常遇问题的总结,另一方面也确实能够提升工作效率(谁又不想造一个属于自己的轮子呢~),于是乎就有了本文的主角儿rn-components-kit。 市面上web的UI组件库如...

    Alan 评论0 收藏0
  • 题库分库分表架构方案

    摘要:个人博客地址方案项目背景在现在题库架构下,针对新购买的多道数据进行整合,不影响现有功能。数据切分尽量通过数据冗余或表分组来降低跨库的可能。 个人博客地址 https://www.texixi.com/2019/0... 方案 项目背景 在现在题库架构下,针对新购买的1300W多道数据进行整合,不影响现有功能。由于数据量偏多,需要进行数据的切分 目标场景 兼容旧的功能 对1300多W...

    kohoh_ 评论0 收藏0
  • [零基础学python]永远强大的函数

    摘要:莱布尼兹所指的函数现在被称作可导函数,数学家之外的普通人一般接触到的函数即属此类。中文的函数一词由清朝数学家李善兰译出。前面提供的维基百科中的函数词条,里面可以做一个概览。 函数,对于人类来讲,能够发展到这个数学思维层次,是一个飞跃。可以说,它的提出,直接加快了现代科技和社会的发展,不论是现代的任何科技门类,乃至于经济学、政治学、社会学等,都已经普遍使用函数。 下面一段来自维基百科(...

    cangck_X 评论0 收藏0
  • [ 一起学React系列 -- 2 ] UI的灵魂--State

    摘要:首先卖个关子,下面我们一起来复习下小学还是初中的一枚数学知识。一旦更改了,会触发组件的重新渲染。为了页面渲染性能的考虑,有助于在中进行比较并确定是否重新渲染。 概念引入 对于React来说, 没有State就没有页面的渲染, 我们也将什么都看不到 咋一听怎么那么唬人?不过的确是这样,正如标题所言State是UI的灵魂。我们都知道React的核心思想之一是组件化,将页面所展示的东西按一定...

    XBaron 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<