If you are looking for an Animated line drawing in sequence, you are at the right place. We have to download SVG Android library (i.e. Add jar to lib folder svg-android-1.1.jar) to use SVG image in application.
Working Logic
I elucidate the working logic step by step. We have to load the svg from the resources and render the svg to canvas and catch all the paths while rendering.public List<SvgPath> getPathsForViewport(final int width, final int height) { final float strokeWidth = mSourcePaint.getStrokeWidth(); Canvas canvas = new Canvas() { private final Matrix mMatrix = new Matrix(); @Override public int getWidth() { return width; } @Override public int getHeight() { return height; } @Override public void drawPath(Path path, Paint paint) { Path dst = new Path(); //noinspection deprecation getMatrix(mMatrix); path.transform(mMatrix, dst); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(strokeWidth); mPaths.add(new SvgPath(dst, paint)); } }; rescaleCanvas(width, height, strokeWidth, canvas); return mPaths; }then rescale the canvas with specific width and height.
private void rescaleCanvas(int width, int height, float strokeWidth, Canvas canvas) { if (mSvg == null) return; final RectF viewBox = mSvg.getDocumentViewBox(); final float scale = Math.min(width / (viewBox.width() + strokeWidth), height / (viewBox.height() + strokeWidth)); canvas.translate((width - viewBox.width() * scale) / 2.0f, (height - viewBox.height() * scale) / 2.0f); canvas.scale(scale, scale); mSvg.renderToCanvas(canvas); }
The line path is drawn on Canvas at onDraw() method. We pick either natural SVG image
color or custom color.
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); if(mTempBitmap==null || (mTempBitmap.getWidth()!=canvas.getWidth() ||mTempBitmap.getHeight()!=canvas.getHeight()) ) { mTempBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888); mTempCanvas = new Canvas(mTempBitmap); } mTempBitmap.eraseColor(0); synchronized (mSvgLock) { mTempCanvas.save(); mTempCanvas.translate(getPaddingLeft(), getPaddingTop()); fill(mTempCanvas); final int count = paths.size(); for (int i = 0; i < count; i++) { final SvgUtils.SvgPath svgPath = paths.get(i); final Path path = svgPath.path; final Paint paint1 = naturalColors ? svgPath.paint : paint; mTempCanvas.drawPath(path, paint1); } fillAfter(mTempCanvas); mTempCanvas.restore(); applySolidColor(mTempBitmap); canvas.drawBitmap(mTempBitmap,0,0,null); } }
If fillColor had value before then we replace untransparent pixels of bitmap by solid color.
private void applySolidColor(final Bitmap bitmap) { if(fill && fillColor!= Color.argb(0,0,0,0) ) if (bitmap != null) { for(int x=0;x<bitmap.getWidth();x++) { for(int y=0;y<bitmap.getHeight();y++) { int argb = bitmap.getPixel(x,y); int alpha = Color.alpha(argb); if(alpha!=0) { int red = Color.red(fillColor); int green = Color.green(fillColor); int blue = Color.blue(fillColor); argb = Color.argb(alpha,red,green,blue); bitmap.setPixel(x,y,argb); } } } } }
Then sets the duration of the animation. Since the AnimatorSet sets the duration for
each Animator, we have to divide it by the number of paths.
public AnimatorSetBuilder(final SVGPathView pathView) { paths = pathView.paths; for (SvgUtils.SvgPath path : paths) { path.setAnimationStepListener(pathView); ObjectAnimator animation = ObjectAnimator.ofFloat(path, "length", 0.0f, path.getLength()); animators.add(animation); } animatorSet.playSequentially(animators); }
How to use?
Add SVGPathView class in xml layout.
<com.truedreamz.svglinedrawing.LineDrawing.SVGPathView android:id="@+id/pathView" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="30dp" android:paddingRight="30dp" android:layout_marginTop="80dp" android:paddingBottom="30dp" app:svg="@raw/ironman" app:pathColor="@android:color/holo_blue_dark" app:naturalColors="true" app:pathWidth="2dp"/>
Use the animator for parallel animation
pathView.getPathAnimator(). delay(100). duration(8000). interpolator(new AccelerateDecelerateInterpolator()). listenerEnd(new SVGPathView.AnimatorBuilder.ListenerEnd() { @Override public void onAnimationEnd() { txtViewLoading.setText("Line drawing completed."); Toast.makeText(SVGDrawingActivity.this,"Line drawing is done.",Toast.LENGTH_LONG).show(); } }).start();
Use the animator for sequential animation
pathView.getSequentialPathAnimator().
delay(100).
duration(8000).
interpolator(new AccelerateDecelerateInterpolator()).
listenerEnd(new SVGPathView.AnimatorBuilder.ListenerEnd() {
@Override public void onAnimationEnd() {
txtViewLoading.setText("Line drawing completed.");
Toast.makeText(SVGDrawingActivity.this,"Line drawing is done.",Toast.LENGTH_LONG).show();
}
}).start();
I have uploaded complete source code in Github,
https://github.com/JayaprakashR-Zealot/SVGLineDrawing
Kindly raise your queries in the command section.
Happy coding !!!
Thanks.