react-native-view-transformer
Advanced tools
Comparing version 0.0.3 to 0.0.4
{ | ||
"name": "react-native-view-transformer", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -1,1 +0,3 @@ | ||
# react-native-view-transformer | ||
# react-native-view-transformer | ||
`react-native-view-transformer` is a React Native view. |
'use strict'; | ||
export default class Rect { | ||
@@ -53,3 +52,3 @@ | ||
valid() { | ||
isValid() { | ||
if(this.left === undefined || this.left === null) { | ||
@@ -56,0 +55,0 @@ return false; |
@@ -16,8 +16,13 @@ 'use strict'; | ||
function ensure(value, otherwise) { | ||
return invalidValue(value) ? otherwise : value; | ||
function isValidNumber(number) { | ||
if (typeof number === 'number') { | ||
if (!isNaN(number)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
function invalidValue(value) { | ||
if (value === undefined || value === null) { | ||
function isValidRect(rect) { | ||
if (rect instanceof Rect && rect.isValid()) { | ||
return true; | ||
@@ -28,3 +33,10 @@ } | ||
export function fitCenterRect(contentAspectRatio, containerRect: Rect) { | ||
function isValidTransform(transform) { | ||
if (transform && isValidNumber(transform.scale) && isValidNumber(transform.translateX) && isValidNumber(transform.translateY)) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
export function fitCenterRect(contentAspectRatio, containerRect:Rect) { | ||
let w = containerRect.width(); | ||
@@ -48,18 +60,24 @@ let h = containerRect.height(); | ||
/** | ||
* The React Native transform system use the center of the view as the pivot when scaling. | ||
* The translations are applied before scaling. | ||
* @param rect | ||
* @param transform | ||
* @returns {*} | ||
*/ | ||
export function transformedRect(rect:Rect, transform:Transform) { | ||
if (!transform) { | ||
if (!isValidRect(rect)) { | ||
throw new Error('transformedRect...invalid rect'); | ||
} | ||
if (!isValidTransform(transform)) { | ||
throw new Error('transformedRect...invalid transform'); | ||
} | ||
if (!rect || !rect.valid()) { | ||
throw new Error('transformedRect...invalid rect'); | ||
} | ||
let scale = ensure(transform.scale, 1); | ||
let translateX = ensure(transform.translateX, 0); | ||
let translateY = ensure(transform.translateY, 0); | ||
let scale = transform.scale; | ||
let translateX = transform.translateX; | ||
let translateY = transform.translateY; | ||
let pivot = transform.pivot; | ||
if (pivot === undefined || pivot === null) { | ||
//no pivot provided, we make the center of the rect as the pivot when scaling | ||
//so the center point remains still | ||
let width = rect.width() * scale; | ||
@@ -69,2 +87,3 @@ let height = rect.height() * scale; | ||
let centerY = rect.centerY() + translateY * scale; | ||
return new Rect( | ||
@@ -79,3 +98,3 @@ centerX - width / 2, | ||
let pivotY = pivot.y; | ||
if (invalidValue(pivotX) || invalidValue(pivotY)) { | ||
if (!isValidNumber(pivotX) || !isValidNumber(pivotY)) { | ||
throw new Error('transformedRect...invalid pivot x=' + pivot.x + ', y=' + pivot.y); | ||
@@ -96,5 +115,9 @@ } | ||
/** | ||
* Calculate the transform from fromRect to toRect | ||
* @param fromRect | ||
* @param toRect | ||
* @returns {Transform} | ||
*/ | ||
export function getTransform(fromRect, toRect) { | ||
console.log('getTransform...' + JSON.stringify(fromRect) + ' ' + JSON.stringify(toRect)); | ||
let scale = toRect.width() / fromRect.width(); | ||
@@ -104,3 +127,3 @@ let translateX = (toRect.centerX() - fromRect.centerX()) / scale; | ||
return new Transform(scale, translateX, translateY, undefined); | ||
return new Transform(scale, translateX, translateY); | ||
} | ||
@@ -107,0 +130,0 @@ |
@@ -5,3 +5,2 @@ 'use strict'; | ||
View, | ||
Image, | ||
Animated, | ||
@@ -14,3 +13,3 @@ Easing, | ||
import Scroller from './library/scroller/Scroller'; | ||
import TransformableImage from './Image'; | ||
import TransformableImage from './TransformableImage'; | ||
@@ -35,3 +34,9 @@ import {Rect, Transform, transformedRect, availableTranslateSpace, fitCenterRect, alignedRect, getTransform} from './TransformUtils'; | ||
//animation state | ||
animator: new Animated.Value(0) | ||
animator: new Animated.Value(0), | ||
//layout | ||
width: 0, | ||
height: 0, | ||
pageX: 0, | ||
pageY: 0 | ||
}; | ||
@@ -81,9 +86,12 @@ | ||
render() { | ||
let gestureResponder = this.panAndPinchResponder; | ||
if (!this.props.enableTransform) { | ||
gestureResponder = {}; | ||
} | ||
return ( | ||
<View | ||
{...this.props} | ||
{...this.panAndPinchResponder} | ||
style={[this.props.style, {overflow: 'hidden'}]} | ||
> | ||
{...gestureResponder} | ||
style={[this.props.style, {overflow: 'hidden'}]}> | ||
<View | ||
@@ -99,3 +107,2 @@ ref={'innerViewRef'} | ||
], | ||
}}> | ||
@@ -125,3 +132,2 @@ {this.props.children} | ||
onLayout(e) { | ||
console.log('onLayout...' + JSON.stringify(e)); | ||
let {width, height} = e.nativeEvent.layout; | ||
@@ -138,3 +144,2 @@ this.setState({ | ||
onMeasure(x, y, width, height, pageX, pageY) { | ||
console.log('onMeasure...' + x + ' ' + y + ' ' + width + ' ' + height + ' ' + pageX + ' ' + pageY); | ||
this.setState({ | ||
@@ -149,3 +154,2 @@ width: width, | ||
handleScroll(dx, dy, scroller:Scroller) { | ||
console.log('onScroll...dx=' + dx + ', dy=' + dy); | ||
if (dx === 0 && dy === 0 && scroller.isFinished()) { | ||
@@ -233,2 +237,3 @@ this.animateBounce(); | ||
)); | ||
rect = transformedRect(rect, new Transform(1, this.viewPortRect().centerX() - pivotX, this.viewPortRect().centerY() - pivotY)); | ||
rect = alignedRect(rect, this.viewPortRect()); | ||
@@ -243,2 +248,10 @@ | ||
let dx = gestureState.dxSinceLast; | ||
let dy = gestureState.dySinceLast; | ||
if(this.props.enableResistance) { | ||
let d = this.applyResistanceX(dx, dy); | ||
dx = d.dx; | ||
dy = d.dy; | ||
} | ||
let transform = {}; | ||
@@ -250,6 +263,6 @@ if (gestureState.previousPinchDistance && gestureState.currentPinchDistance && this.props.enableScale) { | ||
let rect = transformedRect(transformedRect(this.contentRect(), this.currentTransform()), new Transform( | ||
scaleBy, | ||
gestureState.dxSinceLast, | ||
gestureState.dySinceLast, | ||
scaleBy, dx, dy, | ||
{ | ||
@@ -262,4 +275,2 @@ x: pivotX, | ||
} else { | ||
let dx = gestureState.dxSinceLast; | ||
let dy = gestureState.dySinceLast; | ||
if (Math.abs(dx) > 2 * Math.abs(dy)) { | ||
@@ -276,2 +287,20 @@ dy = 0; | ||
applyResistanceX(dx, dy) { | ||
let availablePanDistance = availableTranslateSpace(this.transformedContentRect(), this.viewPortRect()); | ||
if ((dx > 0 && availablePanDistance.left < 0) | ||
|| | ||
(dx < 0 && availablePanDistance.right < 0)) { | ||
dx /= 3; | ||
} | ||
if ((dy > 0 && availablePanDistance.top < 0) | ||
|| | ||
(dy < 0 && availablePanDistance.bottom < 0)) { | ||
dy /= 3; | ||
} | ||
return { | ||
dx, dy | ||
} | ||
} | ||
handleEnd(e, gestureState) { | ||
@@ -299,3 +328,2 @@ if (this.props.onGestureEnd) { | ||
animate(targetRect, durationInMillis) { | ||
this.debug(); | ||
let duration = 200; | ||
@@ -306,8 +334,5 @@ if (durationInMillis) { | ||
let fromRect = this.transformedContentRect(); | ||
console.log('animate...to=' + JSON.stringify(targetRect) + ' from=' + JSON.stringify(fromRect)); | ||
if (fromRect.equals(targetRect)) { | ||
console.log('animate...equal rect'); | ||
console.log('animate...equal rect, skip animation'); | ||
return; | ||
@@ -320,3 +345,2 @@ } | ||
let progress = state.value; | ||
console.log('animate...progress=' + state.value); | ||
@@ -373,3 +397,5 @@ let left = fromRect.left + (targetRect.left - fromRect.left) * progress; | ||
enableScale: true, | ||
maxScale: 1 | ||
enableTransform: true, | ||
maxScale: 1, | ||
enableResistance: false | ||
}; |
44567
1287
3