mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-20 14:05:09 +00:00
move SerializablePath dependency to local lib
move SerializablePath dependency to local lib fix issue #29
This commit is contained in:
@@ -19,6 +19,8 @@ class PathExample extends Component{
|
||||
<Path
|
||||
d="M50 0 L15 100 L85 100 Z"
|
||||
/>
|
||||
|
||||
<Path fill='red' d="M38.459,1.66A0.884,0.884,0,0,1,39,2.5a0.7,0.7,0,0,1-.3.575L23.235,16.092,27.58,26.1a1.4,1.4,0,0,1,.148.3,1.3,1.3,0,0,1,0,.377,1.266,1.266,0,0,1-2.078.991L15.526,20.6l-7.58,4.35a1.255,1.255,0,0,1-.485,0,1.267,1.267,0,0,1-1.277-1.258q0-.01,0-0.02a1.429,1.429,0,0,1,0-.446C7.243,20.253,8.6,16.369,8.6,16.29L3.433,13.545A0.743,0.743,0,0,1,2.9,12.822a0.822,0.822,0,0,1,.623-0.773l8.164-2.972,3.018-8.5A0.822,0.822,0,0,1,15.427,0a0.752,0.752,0,0,1,.752.555l2.563,6.936S37.65,1.727,37.792,1.685A1.15,1.15,0,0,1,38.459,1.66Z"/>
|
||||
</Svg>;
|
||||
}
|
||||
}
|
||||
@@ -96,7 +98,6 @@ class BezierCurve extends Component{
|
||||
</Svg>;
|
||||
}
|
||||
}
|
||||
|
||||
const icon = <Svg
|
||||
height="20"
|
||||
width="20"
|
||||
|
||||
@@ -7,7 +7,7 @@ import React, {
|
||||
import Defs from './Defs';
|
||||
import createReactNativeComponentClass from 'react-native/Libraries/ReactNative/createReactNativeComponentClass';
|
||||
import extractProps from '../lib/extract/extractProps';
|
||||
import SerializablePath from 'react-native/Libraries/ART/ARTSerializablePath';
|
||||
import SerializablePath from '../lib/SerializablePath';
|
||||
import {PathAttributes} from '../lib/attributes';
|
||||
import {pathProps} from '../lib/props';
|
||||
|
||||
|
||||
277
lib/SerializablePath.js
Normal file
277
lib/SerializablePath.js
Normal file
@@ -0,0 +1,277 @@
|
||||
const MOVE_TO = 0;
|
||||
const CLOSE = 1;
|
||||
const LINE_TO = 2;
|
||||
const CURVE_TO = 3;
|
||||
const ARC = 4;
|
||||
|
||||
|
||||
export default class SerializablePath {
|
||||
constructor(path) {
|
||||
this.reset();
|
||||
if (path instanceof SerializablePath) {
|
||||
this.path = path.path.slice();
|
||||
} else if (path) {
|
||||
this.push(path);
|
||||
}
|
||||
}
|
||||
|
||||
/* parser */
|
||||
|
||||
push = () => {
|
||||
let p = Array.prototype.join.call(arguments, ' ')
|
||||
.replace(/(\.[\d]+)\-?(\.)/ig, '$1,$2') //-.3-.575 => -.3,.575
|
||||
.match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
|
||||
if (!p) return this;
|
||||
|
||||
let last,
|
||||
cmd = p[0],
|
||||
i = 1;
|
||||
|
||||
while (cmd){
|
||||
switch (cmd){
|
||||
case 'm': this.move(p[i++], p[i++]); break;
|
||||
case 'l': this.line(p[i++], p[i++]); break;
|
||||
case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
|
||||
case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
|
||||
case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
|
||||
case 't': this.curve(p[i++], p[i++]); break;
|
||||
case 'a': this.arc(p[i+5], p[i+6], p[i], p[i+1], p[i+3], !+p[i+4], p[i+2]); i += 7; break;
|
||||
case 'h': this.line(p[i++], 0); break;
|
||||
case 'v': this.line(0, p[i++]); break;
|
||||
|
||||
case 'M': this.moveTo(p[i++], p[i++]); break;
|
||||
case 'L': this.lineTo(p[i++], p[i++]); break;
|
||||
case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
|
||||
case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
|
||||
case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
|
||||
case 'T': this.curveTo(p[i++], p[i++]); break;
|
||||
case 'A': this.arcTo(p[i+5], p[i+6], p[i], p[i+1], p[i+3], !+p[i+4], p[i+2]); i += 7; break;
|
||||
case 'H': this.lineTo(p[i++], this.penY); break;
|
||||
case 'V': this.lineTo(this.penX, p[i++]); break;
|
||||
|
||||
case 'Z': case 'z': this.close(); break;
|
||||
default: cmd = last; i--; continue;
|
||||
}
|
||||
|
||||
last = cmd;
|
||||
if (last == 'm') last = 'l';
|
||||
else if (last == 'M') last = 'L';
|
||||
cmd = p[i++];
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/* utility methods */
|
||||
|
||||
reset = () => {
|
||||
this.penX = this.penY = 0;
|
||||
this.penDownX = this.penDownY = null;
|
||||
this._pivotX = this._pivotY = 0;
|
||||
this.onReset();
|
||||
return this;
|
||||
};
|
||||
|
||||
move = (x,y) => {
|
||||
this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
|
||||
return this;
|
||||
};
|
||||
|
||||
moveTo = (x,y) => {
|
||||
this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
|
||||
return this;
|
||||
};
|
||||
|
||||
line = (x,y) => {
|
||||
return this.lineTo(this.penX + (+x), this.penY + (+y));
|
||||
};
|
||||
|
||||
lineTo = (x,y) => {
|
||||
if (this.penDownX == null) {
|
||||
this.penDownX = this.penX; this.penDownY = this.penY;
|
||||
}
|
||||
this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
|
||||
return this;
|
||||
};
|
||||
|
||||
curve = (c1x, c1y, c2x, c2y, ex, ey) => {
|
||||
let x = this.penX,
|
||||
y = this.penY;
|
||||
|
||||
return this.curveTo(
|
||||
x + (+c1x), y + (+c1y),
|
||||
c2x == null ? null : x + (+c2x),
|
||||
c2y == null ? null : y + (+c2y),
|
||||
ex == null ? null : x + (+ex),
|
||||
ey == null ? null : y + (+ey)
|
||||
);
|
||||
};
|
||||
|
||||
curveTo = (c1x, c1y, c2x, c2y, ex, ey) => {
|
||||
let x = this.penX,
|
||||
y = this.penY;
|
||||
|
||||
if (c2x == null){
|
||||
c2x = +c1x; c2y = +c1y;
|
||||
c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
|
||||
}
|
||||
|
||||
if (ex == null){
|
||||
this._pivotX = +c1x; this._pivotY = +c1y;
|
||||
ex = +c2x; ey = +c2y;
|
||||
c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
|
||||
c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
|
||||
} else {
|
||||
this._pivotX = +c2x; this._pivotY = +c2y;
|
||||
}
|
||||
if (this.penDownX == null) {
|
||||
this.penDownX = x; this.penDownY = y;
|
||||
}
|
||||
this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
|
||||
return this;
|
||||
};
|
||||
|
||||
arc = (x, y, rx, ry, outer, counterClockwise, rotation) => {
|
||||
return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
|
||||
};
|
||||
|
||||
arcTo = (x, y, rx, ry, outer, counterClockwise, rotation) => {
|
||||
ry = Math.abs(+ry || +rx || (+y - this.penY));
|
||||
rx = Math.abs(+rx || (+x - this.penX));
|
||||
|
||||
if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
|
||||
|
||||
let tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
|
||||
|
||||
let rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
|
||||
x -= tX; y -= tY;
|
||||
|
||||
// Ellipse Center
|
||||
let cx = cos * x / 2 + sin * y / 2,
|
||||
cy = -sin * x / 2 + cos * y / 2,
|
||||
rxry = rx * rx * ry * ry,
|
||||
rycx = ry * ry * cx * cx,
|
||||
rxcy = rx * rx * cy * cy,
|
||||
a = rxry - rxcy - rycx;
|
||||
|
||||
if (a < 0){
|
||||
a = Math.sqrt(1 - a / rxry);
|
||||
rx *= a; ry *= a;
|
||||
cx = x / 2; cy = y / 2;
|
||||
} else {
|
||||
a = Math.sqrt(a / (rxcy + rycx));
|
||||
if (large == clockwise) a = -a;
|
||||
let cxd = -a * cy * rx / ry,
|
||||
cyd = a * cx * ry / rx;
|
||||
cx = cos * cxd - sin * cyd + x / 2;
|
||||
cy = sin * cxd + cos * cyd + y / 2;
|
||||
}
|
||||
|
||||
// Rotation + Scale Transform
|
||||
let xx = cos / rx, yx = sin / rx,
|
||||
xy = -sin / ry, yy = cos / ry;
|
||||
|
||||
// Start and End Angle
|
||||
let sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
|
||||
ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
|
||||
|
||||
cx += tX; cy += tY;
|
||||
x += tX; y += tY;
|
||||
|
||||
// Circular Arc
|
||||
if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
|
||||
this.onArc(
|
||||
tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
|
||||
cx, cy, rx, ry, sa, ea, !clockwise, rotation
|
||||
);
|
||||
return this;
|
||||
};
|
||||
|
||||
counterArc = (x, y, rx, ry, outer) =>{
|
||||
return this.arc(x, y, rx, ry, outer, true);
|
||||
};
|
||||
|
||||
counterArcTo = (x, y, rx, ry, outer) => {
|
||||
return this.arcTo(x, y, rx, ry, outer, true);
|
||||
};
|
||||
|
||||
close = () => {
|
||||
if (this.penDownX != null){
|
||||
this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
|
||||
this.penDownX = null;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/* overridable handlers */
|
||||
|
||||
onReset = () => {
|
||||
this.path = [];
|
||||
};
|
||||
|
||||
onMove = (sx, sy, x, y) => {
|
||||
this.path.push(MOVE_TO, x, y);
|
||||
};
|
||||
|
||||
onLine = (sx, sy, x, y) => {
|
||||
this.path.push(LINE_TO, x, y);
|
||||
};
|
||||
|
||||
onBezierCurve = (sx, sy, p1x, p1y, p2x, p2y, x, y) => {
|
||||
this.path.push(CURVE_TO, p1x, p1y, p2x, p2y, x, y);
|
||||
};
|
||||
|
||||
_arcToBezier = (sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation) => {
|
||||
// Inverse Rotation + Scale Transform
|
||||
let rad = rotation ? rotation * Math.PI / 180 : 0,
|
||||
cos = Math.cos(rad), sin = Math.sin(rad),
|
||||
xx = cos * rx, yx = -sin * ry,
|
||||
xy = sin * rx, yy = cos * ry;
|
||||
|
||||
// Bezier Curve Approximation
|
||||
let arc = ea - sa;
|
||||
if (arc < 0 && !ccw) {
|
||||
arc += Math.PI * 2;
|
||||
} else if (arc > 0 && ccw) {
|
||||
arc -= Math.PI * 2;
|
||||
}
|
||||
|
||||
let n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
|
||||
step = arc / n,
|
||||
k = (4 / 3) * Math.tan(step / 4);
|
||||
|
||||
let x = Math.cos(sa), y = Math.sin(sa);
|
||||
|
||||
for (let i = 0; i < n; i++){
|
||||
let cp1x = x - k * y, cp1y = y + k * x;
|
||||
|
||||
sa += step;
|
||||
x = Math.cos(sa); y = Math.sin(sa);
|
||||
|
||||
let cp2x = x + k * y, cp2y = y - k * x;
|
||||
|
||||
this.onBezierCurve(
|
||||
sx, sy,
|
||||
cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
|
||||
cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
|
||||
(sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
onArc = (sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation) => {
|
||||
if (rx !== ry || rotation) {
|
||||
return this._arcToBezier(
|
||||
sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation
|
||||
);
|
||||
}
|
||||
this.path.push(ARC, cx, cy, rx, sa, ea, ccw ? 0 : 1);
|
||||
};
|
||||
|
||||
onClose = () => {
|
||||
this.path.push(CLOSE);
|
||||
};
|
||||
|
||||
toJSON = () => {
|
||||
return this.path;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user