public Builder pathData(String initialPathData) { return pathData(PathData.parse(initialPathData)); }
@Override public void onInitPath(Path outPath) { PathData.toPath(pathData.getAnimatedValue(), outPath); } }
@NonNull @Override public PathData evaluate(float fraction, PathData startValue, PathData endValue) { if (pathData == null || !pathData.canMorphWith(startValue)) { pathData = new PathData(startValue); } pathData.interpolate(startValue, endValue, fraction); return pathData; } }
private KyrieDrawable createLapsDrawable() { final KyrieDrawable.Builder builder = KyrieDrawable.builder().viewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); for (Polygon polygon : polygons) { builder.child( PathNode.builder() .pathData(PathData.parse(polygon.pathData)) .strokeWidth(4f) .strokeColor(polygon.color)); } for (Polygon polygon : polygons) { final PathData pathData = PathData.parse(TextUtils.join(" ", Collections.nCopies(polygon.laps, polygon.pathData))); final Animation<PointF, PointF> pathMotion = Animation.ofPathMotion(PathData.toPath(pathData)) .repeatCount(Animation.INFINITE) .duration(DURATION); builder.child( CircleNode.builder() .fillColor(Color.BLACK) .radius(8) .centerX(pathMotion.transform(p -> p.x)) .centerY(pathMotion.transform(p -> p.y))); } return builder.build(); }
final String fromString = styledAttributes.getString(valueFromId); final String toString = styledAttributes.getString(valueToId); final PathData nodesFrom = PathData.parse(fromString); final PathData nodesTo = PathData.parse(toString); if (!nodesFrom.canMorphWith(nodesTo)) { throw new InflateException("Can't morph from " + fromString + " to " + toString);
/** * Interpolates this {@link PathData} object between two {@link PathData} objects by the given * fraction. * * @param from The starting {@link PathData} object. * @param to The ending {@link PathData} object. * @param fraction The interpolation fraction. * @throws IllegalArgumentException If the from or to {@link PathData} arguments aren't morphable * with this {@link PathData} object. */ void interpolate(PathData from, PathData to, float fraction) { if (!canMorphWith(from) || !canMorphWith(to)) { throw new IllegalArgumentException("Can't interpolate between two incompatible paths"); } for (int i = 0; i < from.pathDatums.length; i++) { pathDatums[i].interpolate(from.pathDatums[i], to.pathDatums[i], fraction); } }
@NonNull static PathData parse(@Nullable String pathData) { if (pathData == null) { pathData = ""; } int start = 0; int end = 1; final List<PathData.PathDatum> list = new ArrayList<>(); while (end < pathData.length()) { end = nextStart(pathData, end); final String s = pathData.substring(start, end).trim(); if (s.length() > 0) { float[] val = getFloats(s); addNode(list, s.charAt(0), val); } start = end; end++; } if ((end - start) == 1 && start < pathData.length()) { addNode(list, pathData.charAt(start), EMPTY_PARAMS); } return new PathData(list.toArray(new PathData.PathDatum[list.size()])); }
@Override public void onDraw(Canvas canvas, Matrix parentMatrix, PointF viewportScale) { final float matrixScale = getMatrixScale(parentMatrix); if (matrixScale == 0) { return; } final float scaleX = viewportScale.x; final float scaleY = viewportScale.y; tempMatrix.set(parentMatrix); if (scaleX != 1f || scaleY != 1f) { tempMatrix.postScale(scaleX, scaleY); } tempRenderPath.reset(); tempPath.reset(); PathData.toPath(pathData.getAnimatedValue(), tempPath); tempRenderPath.addPath(tempPath, tempMatrix); tempRenderPath.setFillType(getPaintFillType(fillType)); if (clipType == ClipType.INTERSECT) { canvas.clipPath(tempRenderPath); } else { canvas.clipPath(tempRenderPath, Region.Op.DIFFERENCE); } }
public Builder pathData(String initialPathData) { return pathData(PathData.parse(initialPathData)); }
PathData.toPath(pathData), propertyXName, propertyYName));
private KyrieDrawable createDrawable() { final Context ctx = requireContext(); final PathData hippoPathData = PathData.parse(getString(R.string.hippo)); final PathData elephantPathData = PathData.parse(getString(R.string.elephant)); final PathData buffaloPathData = PathData.parse(getString(R.string.buffalo)); final int hippoFillColor = ContextCompat.getColor(ctx, R.color.hippo); final int elephantFillColor = ContextCompat.getColor(ctx, R.color.elephant);
TypedArrayUtils.getNamedString( a, parser, "pathData", Styleable.PathInterpolator.PATH_DATA); final Path path = PathData.toPath(pathData); if (path.isEmpty()) { throw new InflateException("The path cannot be empty");
private KyrieDrawable createVortexDrawable() { final KyrieDrawable.Builder builder = KyrieDrawable.builder().viewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); for (Polygon polygon : polygons) { final float length = polygon.length; final float totalLength = length * polygon.laps; builder.child( PathNode.builder() .pathData(PathData.parse(polygon.pathData)) .strokeWidth(4f) .strokeColor(polygon.color) .strokeDashArray( Animation.ofFloatArray(new float[] {0, length}, new float[] {length, 0}) .repeatCount(Animation.INFINITE) .duration(DURATION)) .strokeDashOffset( Animation.ofFloat(0f, 2 * totalLength) .repeatCount(Animation.INFINITE) .duration(DURATION))); } return builder.build(); }