mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-19 21:45:10 +00:00
add support for text clipping and support for text fill pattern
This commit is contained in:
@@ -138,6 +138,39 @@ class ClipPathElement extends Component{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TextClipping extends Component{
|
||||||
|
static title = 'Transform the text';
|
||||||
|
render() {
|
||||||
|
return <Svg
|
||||||
|
height="60"
|
||||||
|
width="200"
|
||||||
|
>
|
||||||
|
<Defs>
|
||||||
|
<ClipPath id="clip">
|
||||||
|
<Circle cx="-60" cy="15" r="10"/>
|
||||||
|
<Circle cx="-40" cy="15" r="10"/>
|
||||||
|
<Circle cx="-20" cy="15" r="10"/>
|
||||||
|
<Circle cx="0" cy="15" r="10"/>
|
||||||
|
<Circle cx="20" cy="15" r="10"/>
|
||||||
|
<Circle cx="40" cy="15" r="10"/>
|
||||||
|
<Circle cx="60" cy="15" r="10"/>
|
||||||
|
</ClipPath>
|
||||||
|
</Defs>
|
||||||
|
<Text
|
||||||
|
x="100"
|
||||||
|
y="30"
|
||||||
|
fill="red"
|
||||||
|
fontSize="22"
|
||||||
|
fontWeight="bold"
|
||||||
|
fill="red"
|
||||||
|
stroke="blue"
|
||||||
|
textAnchor="center"
|
||||||
|
clipPath="url(#clip)"
|
||||||
|
>NOT THE FACE</Text>
|
||||||
|
</Svg>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const icon = <Svg
|
const icon = <Svg
|
||||||
height="20"
|
height="20"
|
||||||
width="20"
|
width="20"
|
||||||
@@ -180,7 +213,7 @@ const icon = <Svg
|
|||||||
</G>
|
</G>
|
||||||
</Svg>;
|
</Svg>;
|
||||||
|
|
||||||
const samples = [ClipPathAttr, ClipRule, ClipPathElement];
|
const samples = [ClipPathAttr, ClipRule, ClipPathElement, TextClipping];
|
||||||
|
|
||||||
export {
|
export {
|
||||||
icon,
|
icon,
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import Svg, {
|
|||||||
Defs,
|
Defs,
|
||||||
Stop,
|
Stop,
|
||||||
RadialGradient,
|
RadialGradient,
|
||||||
Polyline
|
Polyline,
|
||||||
|
ClipPath,
|
||||||
|
Circle
|
||||||
} from 'react-native-svg';
|
} from 'react-native-svg';
|
||||||
|
|
||||||
class StrokeExample extends Component{
|
class StrokeExample extends Component{
|
||||||
@@ -25,34 +27,21 @@ class StrokeExample extends Component{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StrokeWidth extends Component{
|
|
||||||
static title = 'The stroke property defines the color of a line, text or outline of an element';
|
|
||||||
render() {
|
|
||||||
return <Svg height="80" width="225">
|
|
||||||
<G fill="none" stroke="black">
|
|
||||||
<Path strokeWidth="2" d="M5 20 l215 0" />
|
|
||||||
<Path strokeWidth="4" d="M5 40 l215 0" />
|
|
||||||
<Path strokeWidth="6" d="M5 60 l215 0" />
|
|
||||||
</G>
|
|
||||||
</Svg>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class StrokeLinecap extends Component{
|
class StrokeLinecap extends Component{
|
||||||
static title = 'The stroke-linecap property defines different types of endings to an open path';
|
static title = 'The stroke-linecap property defines different types of endings to an open path';
|
||||||
render() {
|
render() {
|
||||||
return <Svg height="80" width="225">
|
return <Svg height="80" width="225">
|
||||||
<G fill="none" stroke="black" strokeWidth="6">
|
<G fill="none" stroke="black">
|
||||||
<Path strokeLinecap="butt" d="M5 20 l215 0" />
|
<Path strokeLinecap="butt" strokeWidth="2" d="M5 20 l215 0" />
|
||||||
<Path strokeLinecap="round" d="M5 40 l215 0" />
|
<Path strokeLinecap="round" strokeWidth="4" d="M5 40 l215 0" />
|
||||||
<Path strokeLinecap="square" d="M5 60 l215 0" />
|
<Path strokeLinecap="square" strokeWidth="6" d="M5 60 l215 0" />
|
||||||
</G>
|
</G>
|
||||||
</Svg>;
|
</Svg>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StrokeDasharray extends Component{
|
class StrokeDasharray extends Component{
|
||||||
static title = 'The stroke-linecap property defines different types of endings to an open path';
|
static title = 'strokeDasharray';
|
||||||
render() {
|
render() {
|
||||||
return <Svg height="80" width="225">
|
return <Svg height="80" width="225">
|
||||||
<G fill="none" stroke="black" strokeWidth="4">
|
<G fill="none" stroke="black" strokeWidth="4">
|
||||||
@@ -65,7 +54,7 @@ class StrokeDasharray extends Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
class StrokePattern extends Component{
|
class StrokePattern extends Component{
|
||||||
static title = 'Stroke with gradient.';
|
static title = 'Advanced stroke example.';
|
||||||
render() {
|
render() {
|
||||||
return <Svg height="80" width="200">
|
return <Svg height="80" width="200">
|
||||||
<Defs>
|
<Defs>
|
||||||
@@ -81,6 +70,9 @@ class StrokePattern extends Component{
|
|||||||
stopOpacity="1"
|
stopOpacity="1"
|
||||||
/>
|
/>
|
||||||
</RadialGradient>
|
</RadialGradient>
|
||||||
|
<ClipPath id="clip">
|
||||||
|
<Circle r="96" cx="100" cy="40" />
|
||||||
|
</ClipPath>
|
||||||
</Defs>
|
</Defs>
|
||||||
<Rect
|
<Rect
|
||||||
x="5"
|
x="5"
|
||||||
@@ -91,6 +83,7 @@ class StrokePattern extends Component{
|
|||||||
stroke="url(#grad)"
|
stroke="url(#grad)"
|
||||||
strokeWidth="5"
|
strokeWidth="5"
|
||||||
strokeDasharray="10"
|
strokeDasharray="10"
|
||||||
|
clipPath="url(#clip)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Polyline
|
<Polyline
|
||||||
@@ -117,7 +110,7 @@ const icon = <Svg
|
|||||||
</G>
|
</G>
|
||||||
</Svg>;
|
</Svg>;
|
||||||
|
|
||||||
const samples = [StrokeExample, StrokeWidth, StrokeLinecap, StrokeDasharray, StrokePattern];
|
const samples = [StrokeExample, StrokeLinecap, StrokeDasharray, StrokePattern];
|
||||||
|
|
||||||
export {
|
export {
|
||||||
icon,
|
icon,
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import React, {
|
|||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
|
||||||
import Svg, {
|
import Svg, {
|
||||||
Text
|
Text,
|
||||||
|
LinearGradient,
|
||||||
|
Stop,
|
||||||
|
Defs,
|
||||||
|
ClipPath
|
||||||
} from 'react-native-svg';
|
} from 'react-native-svg';
|
||||||
|
|
||||||
class TextExample extends Component{
|
class TextExample extends Component{
|
||||||
@@ -55,6 +59,34 @@ class TextRotate extends Component{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TextFill extends Component{
|
||||||
|
static title = 'Fill the text with LinearGradient';
|
||||||
|
render() {
|
||||||
|
return <Svg
|
||||||
|
height="60"
|
||||||
|
width="200"
|
||||||
|
>
|
||||||
|
<Defs>
|
||||||
|
<LinearGradient id="grad" x1="0" y1="0" x2="200" y2="0">
|
||||||
|
<Stop offset="0%" stopColor="rgb(255,255,0)" stopOpacity="0" />
|
||||||
|
<Stop offset="100%" stopColor="red" stopOpacity="1" />
|
||||||
|
</LinearGradient>
|
||||||
|
</Defs>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
fill="url(#grad)"
|
||||||
|
stroke="purple"
|
||||||
|
fontSize="20"
|
||||||
|
fontWeight="bold"
|
||||||
|
x="100"
|
||||||
|
y="20"
|
||||||
|
textAnchor="center"
|
||||||
|
>FILL TEXT</Text>
|
||||||
|
</Svg>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: not supported
|
||||||
class TextStroke extends Component{
|
class TextStroke extends Component{
|
||||||
static title = 'Stroke the text';
|
static title = 'Stroke the text';
|
||||||
render() {
|
render() {
|
||||||
@@ -62,21 +94,28 @@ class TextStroke extends Component{
|
|||||||
height="60"
|
height="60"
|
||||||
width="200"
|
width="200"
|
||||||
>
|
>
|
||||||
|
<Defs>
|
||||||
|
<LinearGradient id="grad" x1="0" y1="0" x2="100" y2="0">
|
||||||
|
<Stop offset="100%" stopColor="rgb(255,255,0)" stopOpacity="0" />
|
||||||
|
<Stop offset="0%" stopColor="red" stopOpacity="1" />
|
||||||
|
</LinearGradient>
|
||||||
|
</Defs>
|
||||||
|
|
||||||
<Text
|
<Text
|
||||||
|
stroke="url(#grad)"
|
||||||
|
strokeWidth="4"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="purple"
|
|
||||||
fontSize="20"
|
fontSize="20"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
x="100"
|
x="100"
|
||||||
y="20"
|
y="20"
|
||||||
alignment="center"
|
textAnchor="center"
|
||||||
>STROKED TEXT</Text>
|
>STROKE TEXT</Text>
|
||||||
</Svg>;
|
</Svg>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: wait for official done
|
|
||||||
class TextPath extends Component{
|
class TextPath extends Component{
|
||||||
static title = 'Transform the text';
|
static title = 'Transform the text';
|
||||||
render() {
|
render() {
|
||||||
@@ -112,7 +151,7 @@ const icon = <Svg
|
|||||||
>字</Text>
|
>字</Text>
|
||||||
</Svg>;
|
</Svg>;
|
||||||
|
|
||||||
const samples = [TextExample, TextRotate, TextStroke, TextPath];
|
const samples = [TextExample, TextRotate, TextFill, TextPath];
|
||||||
|
|
||||||
export {
|
export {
|
||||||
icon,
|
icon,
|
||||||
|
|||||||
@@ -53,14 +53,13 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// to-do: draw along a path
|
// to-do: draw along a path
|
||||||
// to-do: fill-rule
|
|
||||||
// to-do: clip
|
|
||||||
CGTextDrawingMode mode = kCGTextStroke;
|
CGTextDrawingMode mode = kCGTextStroke;
|
||||||
|
|
||||||
if (self.fill) {
|
if (self.fill) {
|
||||||
if ([self.fill applyFillColor:context]) {
|
if ([self.fill applyFillColor:context]) {
|
||||||
mode = kCGTextFill;
|
mode = kCGTextFill;
|
||||||
} else {
|
} else {
|
||||||
|
[self clip: context];
|
||||||
for (int i = 0; i < frame.count; i++) {
|
for (int i = 0; i < frame.count; i++) {
|
||||||
CGContextSaveGState(context);
|
CGContextSaveGState(context);
|
||||||
// Inverse the coordinate space since CoreText assumes a bottom-up coordinate space
|
// Inverse the coordinate space since CoreText assumes a bottom-up coordinate space
|
||||||
@@ -80,9 +79,7 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self.stroke) {
|
if (self.stroke) {
|
||||||
if ([self.stroke applyStrokeColor:context] == NO) {
|
[self.stroke applyStrokeColor:context];
|
||||||
[self.stroke paint:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
CGContextSetLineWidth(context, self.strokeWidth);
|
CGContextSetLineWidth(context, self.strokeWidth);
|
||||||
CGContextSetLineCap(context, self.strokeLinecap);
|
CGContextSetLineCap(context, self.strokeLinecap);
|
||||||
@@ -97,7 +94,7 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CGContextSetTextDrawingMode(context, mode);
|
CGContextSetTextDrawingMode(context, mode);
|
||||||
|
[self clip:context];
|
||||||
// Inverse the coordinate space since CoreText assumes a bottom-up coordinate space
|
// Inverse the coordinate space since CoreText assumes a bottom-up coordinate space
|
||||||
CGContextScaleCTM(context, 1.0, -1.0);
|
CGContextScaleCTM(context, 1.0, -1.0);
|
||||||
for (int i = 0; i < frame.count; i++) {
|
for (int i = 0; i < frame.count; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user