Skip to content

Commit

Permalink
add some features
Browse files Browse the repository at this point in the history
  • Loading branch information
879479119 committed Oct 15, 2016
1 parent cf1015e commit bc4e7ee
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 63 deletions.
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

Since there is no "shadow" attribute in style list of Android,if we want to add a shadow effect on a component,we must patch a PNG-24 picture,but it's so non-graceful;therefore here comes a SVG shadow plugin to help with this problem. **We suggest you to use native shadow on iOS**

![Effect](http://7xsm7w.com1.z0.glb.clouddn.com/20161015151531.png)

There are two BoxShadow Elements in the picture which support `border-radius`,and the Line at the bottom is generated with `BorderShadow` which provide with a top or bottom shadow(can also be inset shadow)


## HOW TO USE IT

### First
Expand Down Expand Up @@ -85,7 +90,7 @@ protected List<ReactPackage> getPackages() {

After config the SVG component,you can simply use it in your project(*show ES6 only*):

1. `import Shadow from 'react-native-shadow'`
1. `import {BoxShadow} from 'react-native-shadow'`(For BorderShadow,import it as 'BoxShadow')
2. set an opption object:
```js
const shadowOpt = {
Expand Down Expand Up @@ -130,7 +135,7 @@ import {
TouchableHighlight
} from 'react-native'

import Shadow from '../util/shadow'
import {BoxShadow} from 'react-native-shadow'

export default class VideoCell extends Component {
render = () => {
Expand All @@ -147,7 +152,7 @@ export default class VideoCell extends Component {
}

return (
<Shadow setting={shadowOpt}>
<BoxShadow setting={shadowOpt}>
<TouchableHighlight style={{
position:"relative",
width: 160,
Expand All @@ -158,16 +163,17 @@ export default class VideoCell extends Component {
overflow:"hidden"}}>
…………………………
</TouchableHighlight>
</Shadow>
</BoxShadow>
)
}
}
```

## Information
## Manual

#### the attribute we supported now:

###BoxShadow
+ **width**: you must set the value the same as your child component
+ **height**: the same as above
+ **color**: the color of shadow,it **doesn't support rgba now**,you may use opacity
Expand All @@ -178,6 +184,11 @@ export default class VideoCell extends Component {
+ **y**: the offsetY of shadow
+ **style**: the style you want to add to the wrapper box

###BorderShadow
+ **width**,**color**,**border**,**opacity**,**style**: these attributes are the same as above
+ **side**: "top" or "bottom",you can choose where the shadow shows
+ **inset**: `true` or `false`,this is similar to CSS - `shadow: color inset`

#### what to notice

This component is so simple,and we are making efforts to make it better;
Expand Down
61 changes: 4 additions & 57 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,9 @@
* @repo
*/

import React, {Component} from 'react'
import {View} from 'react-native'
import Svg,{ Rect,Defs,LinearGradient,Stop,RadialGradient,Path } from 'react-native-svg'
import BoxShadow from './lib/BoxShadow'
import BorderShadow from './lib/BorderShadow'

export default class Shadow extends Component{

render = () => {
//get the shadow settings and give them default values
const { setting:{width=0,height=0,color="#fff",border=0,radius=0,opacity=1,x=0,y=0,style={}}, children } = this.props
export {BoxShadow, BorderShadow}

//define the lengths
const lineWidth = border,
rectWidth = width-radius*2,
rectHeight = height-radius*2

//the same parts for gradients
const linear = [
<Stop offset="0" stopColor={color} stopOpacity={opacity} />,
<Stop offset="1" stopColor={color} stopOpacity="0" />
], radial = [
<Stop offset="0" stopColor={color} stopOpacity={opacity} />,
<Stop offset={(radius/(lineWidth+radius)).toString()} stopColor={color} stopOpacity={opacity} />,
<Stop offset="1" stopColor={color} stopOpacity="0" />
]

const outerWidth = lineWidth+radius

//return a view ,whose background is a svg picture
return (
<View style={[{position:"relative",width:width,height:height},style]}>
<Svg height={height+lineWidth*2+radius*2} width={width+lineWidth*2+radius*2} style={{position:"absolute",top:y-lineWidth,left:x-lineWidth}}>
<Defs>
<LinearGradient id="top" x1="0" y1={lineWidth} x2="0" y2="0">{linear}</LinearGradient>
<LinearGradient id="bottom" x1="0" y1={rectHeight+lineWidth+2*radius} x2="0" y2={rectHeight+2*lineWidth+2*radius}>{linear}</LinearGradient>
<LinearGradient id="left" x1={lineWidth} y1="0" x2="0" y2="0">{linear}</LinearGradient>
<LinearGradient id="right" x1={rectWidth+lineWidth+2*radius} y1="0" x2={rectWidth+lineWidth*2+2*radius} y2={0}>{linear}</LinearGradient>
<RadialGradient id="border-left-top" r={outerWidth} cx={outerWidth} cy={outerWidth}>{radial}</RadialGradient>
<RadialGradient id="border-left-bottom" r={outerWidth} cx={outerWidth} cy={lineWidth+radius+rectHeight}>{radial}</RadialGradient>
<RadialGradient id="border-right-top" r={outerWidth} cx={lineWidth+radius+rectWidth} cy={outerWidth}>{radial}</RadialGradient>
<RadialGradient id="border-right-bottom" r={outerWidth} cx={lineWidth+radius+rectWidth} cy={lineWidth+radius+rectHeight}>{radial}</RadialGradient>
</Defs>

<Path d={`M 0 ${outerWidth},Q 0 0 ${outerWidth} 0,v ${lineWidth},q ${-radius} 0 ${-radius} ${radius},h ${-lineWidth},z`} fill="url(#border-left-top)"/>
<Path d={`M ${rectWidth+lineWidth+radius} 0,q ${outerWidth} 0 ${outerWidth} ${outerWidth},h ${-lineWidth},q 0 ${-radius} ${-radius} ${-radius},v ${-lineWidth},z`} fill="url(#border-right-top)"/>
<Path d={`M ${rectWidth+lineWidth+2*radius} ${rectHeight+lineWidth+radius},h ${lineWidth},q 0 ${outerWidth} -${outerWidth} ${outerWidth},v ${-lineWidth},q ${radius} 0 ${radius} ${-radius},z`} fill="url(#border-right-bottom)"/>
<Path d={`M 0 ${rectHeight+lineWidth+radius},q 0 ${outerWidth} ${outerWidth} ${outerWidth},v ${-lineWidth},q ${-radius} 0 ${-radius} ${-radius},h ${-lineWidth},z`} fill="url(#border-left-bottom)"/>

<Rect x={outerWidth} y="0" width={rectWidth} height={lineWidth} fill="url(#top)" />
<Rect x="0" y={outerWidth} width={lineWidth} height={rectHeight} fill="url(#left)" />
<Rect x={rectWidth+lineWidth+2*radius} y={outerWidth} width={lineWidth} height={rectHeight} fill="url(#right)" />
<Rect x={outerWidth} y={rectHeight+lineWidth+2*radius} width={rectWidth} height={lineWidth} fill="url(#bottom)" />

<Path d={`M ${outerWidth} ${lineWidth},h ${rectWidth},q ${radius} 0 ${radius} ${radius},v ${rectHeight},q 0 ${radius} -${radius} ${radius},h -${rectWidth},q -${radius} 0 -${radius} -${radius},v -${rectHeight},q 0 -${radius} ${radius} -${radius}`} fill={`rgba(0,0,0,${opacity || 1})`}/>
</Svg>
{children}
</View>
)
}
}
//BorderShadow only support top and bottom shadow now
47 changes: 47 additions & 0 deletions lib/BorderShadow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, {Component} from 'react'
import {View} from 'react-native'
import Svg,{ Rect,Defs,LinearGradient,Stop,RadialGradient,Path } from 'react-native-svg'

export default class BorderShadow extends Component {
render = () => {

const { setting:{side="bottom",width=0,color="#000",border=0,opacity=1,inset=false,style={}}, children } = this.props

const linear = [
<Stop offset="0" stopColor={color} stopOpacity={opacity} />,
<Stop offset="1" stopColor={color} stopOpacity="0" />
]

const lineWidth = border

return (
<View style={[{position:"relative",width:width},style]}>
{(()=>{
switch (side){
case "top":
return [
<Svg height={lineWidth} width={width+lineWidth} style={{position:"absolute",top:(inset?0:-lineWidth)}}>
<Defs><LinearGradient id="top" x1="0" y1={lineWidth} x2="0" y2="0">{linear}</LinearGradient>
<LinearGradient id="top-inset" x1="0" y1="0" x2="0" y2={lineWidth}>{linear}</LinearGradient></Defs>
<Rect x={0} y={0} width={width} height={lineWidth} fill={`url(#top${inset?"-inset":""})`} />
</Svg>,
...children
]
case "bottom":
return [
...children,
<Svg height={lineWidth} width={width+lineWidth} style={{position:"absolute",bottom:(inset?-lineWidth:0)}}>
<Defs><LinearGradient id="bottom" x1="0" y1="0" x2="0" y2={lineWidth}>{linear}</LinearGradient>
<LinearGradient id="bottom-inset" x1="0" y1={lineWidth} x2="0" y2="0">{linear}</LinearGradient></Defs>
<Rect x={0} y={0} width={width} height={lineWidth} fill={`url(#bottom${inset?"-inset":""})`} />
</Svg>
]
default:
throw new Error("Wrong Type of Side! We just support 'top' and 'bottom'")
return null
}
})()}
</View>
)
}
}
58 changes: 58 additions & 0 deletions lib/BoxShadow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, {Component} from 'react'
import {View} from 'react-native'
import Svg,{ Rect,Defs,LinearGradient,Stop,RadialGradient,Path } from 'react-native-svg'

export default class BoxShadow extends Component {
render = () => {
//get the shadow settings and give them default values
const { setting:{width=0,height=0,color="#000",border=0,radius=0,opacity=1,x=0,y=0,style={}}, children } = this.props

//define the lengths
const lineWidth = border,
rectWidth = width-radius*2,
rectHeight = height-radius*2

//the same parts for gradients
const linear = [
<Stop offset="0" stopColor={color} stopOpacity={opacity} />,
<Stop offset="1" stopColor={color} stopOpacity="0" />
], radial = [
<Stop offset="0" stopColor={color} stopOpacity={opacity} />,
<Stop offset={(radius/(lineWidth+radius)).toString()} stopColor={color} stopOpacity={opacity} />,
<Stop offset="1" stopColor={color} stopOpacity="0" />
]

const outerWidth = lineWidth+radius

//return a view ,whose background is a svg picture
return (
<View style={[{position:"relative",width:width,height:height},style]}>
<Svg height={height+lineWidth*2+radius*2} width={width+lineWidth*2+radius*2} style={{position:"absolute",top:y-lineWidth,left:x-lineWidth}}>
<Defs>
<LinearGradient id="top" x1="0" y1={lineWidth} x2="0" y2="0">{linear}</LinearGradient>
<LinearGradient id="bottom" x1="0" y1={rectHeight+lineWidth+2*radius} x2="0" y2={rectHeight+2*lineWidth+2*radius}>{linear}</LinearGradient>
<LinearGradient id="left" x1={lineWidth} y1="0" x2="0" y2="0">{linear}</LinearGradient>
<LinearGradient id="right" x1={rectWidth+lineWidth+2*radius} y1="0" x2={rectWidth+lineWidth*2+2*radius} y2={0}>{linear}</LinearGradient>
<RadialGradient id="border-left-top" r={outerWidth} cx={outerWidth} cy={outerWidth}>{radial}</RadialGradient>
<RadialGradient id="border-left-bottom" r={outerWidth} cx={outerWidth} cy={lineWidth+radius+rectHeight}>{radial}</RadialGradient>
<RadialGradient id="border-right-top" r={outerWidth} cx={lineWidth+radius+rectWidth} cy={outerWidth}>{radial}</RadialGradient>
<RadialGradient id="border-right-bottom" r={outerWidth} cx={lineWidth+radius+rectWidth} cy={lineWidth+radius+rectHeight}>{radial}</RadialGradient>
</Defs>

<Path d={`M 0 ${outerWidth},Q 0 0 ${outerWidth} 0,v ${lineWidth},q ${-radius} 0 ${-radius} ${radius},h ${-lineWidth},z`} fill="url(#border-left-top)"/>
<Path d={`M ${rectWidth+lineWidth+radius} 0,q ${outerWidth} 0 ${outerWidth} ${outerWidth},h ${-lineWidth},q 0 ${-radius} ${-radius} ${-radius},v ${-lineWidth},z`} fill="url(#border-right-top)"/>
<Path d={`M ${rectWidth+lineWidth+2*radius} ${rectHeight+lineWidth+radius},h ${lineWidth},q 0 ${outerWidth} -${outerWidth} ${outerWidth},v ${-lineWidth},q ${radius} 0 ${radius} ${-radius},z`} fill="url(#border-right-bottom)"/>
<Path d={`M 0 ${rectHeight+lineWidth+radius},q 0 ${outerWidth} ${outerWidth} ${outerWidth},v ${-lineWidth},q ${-radius} 0 ${-radius} ${-radius},h ${-lineWidth},z`} fill="url(#border-left-bottom)"/>

<Rect x={outerWidth} y="0" width={rectWidth} height={lineWidth} fill="url(#top)" />
<Rect x="0" y={outerWidth} width={lineWidth} height={rectHeight} fill="url(#left)" />
<Rect x={rectWidth+lineWidth+2*radius} y={outerWidth} width={lineWidth} height={rectHeight} fill="url(#right)" />
<Rect x={outerWidth} y={rectHeight+lineWidth+2*radius} width={rectWidth} height={lineWidth} fill="url(#bottom)" />

<Path d={`M ${outerWidth} ${lineWidth},h ${rectWidth},q ${radius} 0 ${radius} ${radius},v ${rectHeight},q 0 ${radius} -${radius} ${radius},h -${rectWidth},q -${radius} 0 -${radius} -${radius},v -${rectHeight},q 0 -${radius} ${radius} -${radius}`} fill={`rgba(0,0,0,${opacity || 1})`}/>
</Svg>
{children}
</View>
)
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-shadow",
"version": "1.0.0",
"version": "1.1.0",
"description": "A SVG shadow component powered with react-native-svg,which can provide shadow on Android like iOS ^_^",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit bc4e7ee

Please sign in to comment.