Reputation: 157
I'm using react-native
ART
library to draw scalable vector elements in my mobile app, ART
is the perfect library due to it can be animated and morph easily with its own tools. But ART
don't have custom elements like SVG's Circle
, Rect
etch..., ART have only one type called Shape
and is powerful enough to create almost any shapes. But I'm having difficulties with drawing a scalable rounded cornered rectangle with Shape
.
import React from 'react'
import PropTypes from 'prop-types'
import {ART} from 'react-native'
const {Group, Shape} = ART
export default class Graphics extends React.Component{
render(){
const {x, y, width, height, fill, stroke} = this.props;
const d = `M0,0L${width},0L${width},${height}L0,${height}L0,0z`
return(
<Group x={x} y={y}>
<Path d={d} fill={fill} stroke={stroke}>
</Group>
)
}
}
as you can see I create rectangle shape with given width and height but I don't have any idea how to generate rounded corners.
I dont know about d3 is it possible to do this with either d3?
Upvotes: 2
Views: 4703
Reputation: 3548
You can use ART
Path
object to create paths along with paths curve
or curveTo
methods or arc
arcTo
methods. Please check the example Rect
component below.
import React from 'react'
import PropTypes from 'prop-types'
import {ART} from 'react-native'
const {Group, Shape, Path} = ART
function Rect({fill, stroke, x, width, y, rc, height, topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius, ...rest}){
const startX = 0;
const startY = 0;
const smallDimension = width > height ? height : width;
let tlr = topLeftRadius !== null ? topLeftRadius : rc; tlr = tlr > smallDimension/2 ? smallDimension /2 : tlr;
let trr = topRightRadius !== null ? topRightRadius : rc; trr = trr > smallDimension/2 ? smallDimension /2 : trr;
let brr = bottomRightRadius !== null ? bottomRightRadius : rc; brr = brr > smallDimension/2 ? smallDimension /2 : brr;
let blr = bottomLeftRadius !== null ? bottomLeftRadius : rc; blr = blr > smallDimension/2 ? smallDimension /2 : blr;
const d = Path()
.move(startX, startY)
.move(startX, tlr)
.arc( tlr, startY-tlr, tlr, tlr, false, false) // top left
.lineTo(width - trr, startY)
.arc( trr, startX+trr, trr, trr, false, false) // top right
.lineTo(width, startY+ (height - brr))
.arc(startX-brr, brr, brr, brr, false, false) // bottom right
.lineTo(startX + blr, height)
.arc(startX-blr, startY-blr, blr, blr, false, false) // bottom right
.close()
return(
<Group x={x} y={y}>
<Shape {...rest} fill={fill} stroke={stroke} d={d}/>
</Group>
)
}
Rect.propTypes = {
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
x: PropTypes.number,
y: PropTypes.number,
fill: PropTypes.string,
stroke: PropTypes.string,
topLeftRadius: PropTypes.number,
topRightRadius: PropTypes.number,
bottomRightRadius: PropTypes.number,
bottomLeftRadius: PropTypes.number,
rc: PropTypes.number
}
Rect.defaultProps = {
x: 0,
y: 0,
fill: 'transparent',
stroke: 'red',
topLeftRadius: null,
topRightRadius: null,
bottomRightRadius: null,
bottomLeftRadius: null,
rc: 0
}
export default Rect
Here you have completely scalable independent rounded-corner support rectangle component.
width
& height
- will normal rect no rounded corner at all.width
, height
& rc
- will give you equal rounded of all corner.width
, height
& topRightRadius
(or any other corner) - will give you each given rouned corner.Please check this gist for complete usage.
Upvotes: 2