-
Notifications
You must be signed in to change notification settings - Fork 2
/
SkewableView.js
114 lines (107 loc) · 4.88 KB
/
SkewableView.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import React, { Component } from 'react';
import { View, Text, ScrollView } from 'react-native';
export default class SkewableView extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
let renderable = true;
let additionalAngle = 0;
if (this.props.skewDirection=='horizontal-right' || this.props.skewDirection=='horizontal-left') {
additionalAngle = -90;
}
let angleMultiplier = 1;
if (this.props.skewDirection=='vertical-top' || this.props.skewDirection=='horizontal-left') {
angleMultiplier = -1;
}
let innerHeight = 0;
let innerWidth = 0;
let translateX = 0;
let translateY = 0;
let angleDeg = 0;
if (this.props.skewDirection=='vertical-top' || this.props.skewDirection=='vertical-bottom' || this.props.skewDirection=='horizontal-right' || this.props.skewDirection=='horizontal-left') {
if (this.props.skewDirection=='horizontal-right' || this.props.skewDirection=='horizontal-left') {
//horizontal skew
innerHeight = this.props.boundingBoxWidth;
innerWidth = this.props.boundingBoxHeight*2;
} else if (this.props.skewDirection=='vertical-top' || this.props.skewDirection=='vertical-bottom') {
//vertical skew
innerHeight = this.props.boundingBoxHeight;
innerWidth = this.props.boundingBoxWidth*2;
}
let angleRad = 0;
if(this.props.skewUnits=='rad' || this.props.skewUnits=='px') {
if(this.props.skewUnits == 'px') {
if (this.props.skewDirection=='horizontal-right' || this.props.skewDirection=='horizontal-left') {
//horizontal skew
angleRad = Math.atan(this.props.skewValue / this.props.boundingBoxHeight);
} else if (this.props.skewDirection=='vertical-top' || this.props.skewDirection=='vertical-bottom') {
//vertical skew
angleRad = Math.atan(this.props.skewValue / this.props.boundingBoxWidth);
}
}
else {
angleRad = this.props.skewValue;
}
angleDeg = angleRad * 180 / Math.PI;
angleDeg = Math.floor(angleDeg);
angleDeg *= angleMultiplier;
} else if(this.props.skewUnits == 'deg'){
angleDeg = this.props.skewValue;
angleRad = angleDeg * Math.PI/180;
angleDeg = Math.floor(angleDeg);
angleDeg *= angleMultiplier;
} else {
renderable = false;
}
innerMaxHeight = innerHeight;
innerHeight = innerHeight * Math.cos(angleRad) - innerWidth/2 * Math.tan(angleRad);
innerHeight = Math.floor(innerHeight);
translateX = -(innerWidth-this.props.boundingBoxWidth)/2;
translateY = (this.props.boundingBoxHeight-innerHeight)/2;
}
else {
renderable = false;
}
if(renderable) {//example is vertical skew!
return (
<View style={[this.props.style, {overflow: 'hidden', width:this.props.boundingBoxWidth, height:this.props.boundingBoxHeight}]}>
<View style={{
alignSelf: 'stretch',
width:innerWidth,
height:innerHeight,
transform:[{translateX:translateX}, {translateY:translateY}, { rotateZ: angleDeg+additionalAngle + 'deg' }],
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
}}>
<View style={{
height: this.props.boundingBoxHeight,
alignSelf: 'stretch',
overflow: 'hidden',
justifyContent: 'center',
alignItems: 'center',
}}>
<ScrollView style={{
height: this.props.boundingBoxHeight,
transform:[{ rotateZ: -1*(angleDeg+additionalAngle) + 'deg' }],
width:this.props.boundingBoxWidth,
backgroundColor: this.props.backgroundColor,
}}>
{this.props.children}
</ScrollView>
</View>
</View>
</View>
);
}
else {
return (
<View>
<Text>Could not render SkewableView</Text>
</View>
);
}
}
}