Path动画--书写文字的动画实现

国际惯例,先看一下效果:屏幕上手写一些文字,然后让手机按照你的笔画顺序在屏幕上画出来一模一样的文字。

分析下实现原理:写一个类复写View,捕获onTouch事件;→处理这个事件,事件发生的坐标分别存放在一个集合和一个path中,path用于实时绘制,集合用于稍后动画绘制,按下事件path.moveTo,抬起path.lineTo;→手指抬起1s内不再按下则让手机自动绘制我们的文字。

一些实现细节:

1,设置画笔的一些属性,给定颜色,给定笔尖粗细,笔尖形状,抗锯齿等。

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStrokeWidth(STROKE_WIDTH);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setColor(PAINT_COLOR);

2,一些变量

  public final float STROKE_WIDTH = 10;//笔尖宽度
    public final int PAINT_COLOR = Color.GRAY;//画笔颜色
    ArrayList<ArrayList<PathPoint>> lines;//存放所有线
    Paint paint;
    ArrayList<PathPoint> line;//一条线即手指按下到抬起一个完整路径
    //ondraw中绘制用的path
    Path path;
    //触屏最后一次得到的点
    private PathPoint point = new PathPoint(0, 0);
    private boolean isTouching = false;//是不是正在用手指画
    private long upTime;//手指抬起的时刻
    private boolean isDrawing;//是不是在自动画

3,封装一个PathPoint类方便管理坐标

    class PathPoint {
        PathPoint(float x, float y) {
            this.x = x;
            this.y = y;
        }

        float x, y;

        /**
         * 到点p的距离
         *
         * @param p
         * @return
         */
        public double lenthToPoint(PathPoint p) {
            float f = (p.x - x) * (p.x - x) + (p.y - y) * (p.y - y);
            return Math.sqrt(f);
        }
    }

4,处理onTouch事件:主要是实时画线和储存待会儿自动画线的数据,记录手指抬起的时间,后边会做一个判断什么时候开始自动画线。

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isDrawing) return true;
        PathPoint pathPoint;
        pathPoint = getEventPoint(event);
        if (pathPoint.lenthToPoint(point) < 1) return true;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(pathPoint.x, pathPoint.y);
                line = new ArrayList<PathPoint>();
                isTouching = true;
                break;
            case MotionEvent.ACTION_UP:
                lines.add(line);
                isTouching = false;
                upTime = System.currentTimeMillis();

                autoDraw();
            default:
                path.lineTo(pathPoint.x, pathPoint.y);
                break;
        }
        line.add(pathPoint);
        invalidate();
        return true;
    }

5,开始自动画线

  @Override
    public void run() {
        while (System.currentTimeMillis() - upTime < 1000) {//手指抬起够不够1s,不够返回
            if (isTouching) return;
        }
        isDrawing = true;
        Log.i("info", "你倒是画啊,线数:" + lines.size());
        path = new Path();
        for (int i = 0; i < lines.size(); i++) {
            ArrayList<PathPoint> l = lines.get(i);
            Log.i("info", "点数:" + l.size());
            for (int j = 0; j < l.size(); j++) {
                PathPoint p = l.get(j);
                if (j == 0) path.moveTo(p.x, p.y);
                else path.lineTo(p.x, p.y);
                postInvalidate();
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
<span style="white-space:pre">	</span>//复原
        lines.clear();
        line.clear();
        path = new Path();
        isDrawing = false;

    }

完整代码:

package com.sovnem.administrator.boxmenu;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;

/**
 * Created by Sovnem on 2015/1/29.
 */
public class PathAnimationView extends View implements Runnable {
    public final float STROKE_WIDTH = 10;//笔尖宽度
    public final int PAINT_COLOR = Color.GRAY;//画笔颜色
    ArrayList<ArrayList<PathPoint>> lines;//存放所有线
    Paint paint;
    ArrayList<PathPoint> line;//一条线即手指按下到抬起一个完整路径
    //ondraw中绘制用的path
    Path path;
    //触屏最后一次得到的点
    private PathPoint point = new PathPoint(0, 0);
    private boolean isTouching = false;//是不是正在用手指画
    private long upTime;//手指抬起的时刻
    private boolean isDrawing;//是不是在自动画

    public PathAnimationView(Context context) {
        super(context);
        init();
    }

    public PathAnimationView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PathAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void init() {
        paint = new Paint();
        paint.setStrokeWidth(STROKE_WIDTH);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setColor(PAINT_COLOR);
        lines = new ArrayList<>();
        path = new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        canvas.drawPath(path, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isDrawing) return true;
        PathPoint pathPoint;
        pathPoint = getEventPoint(event);
        if (pathPoint.lenthToPoint(point) < 1) return true;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(pathPoint.x, pathPoint.y);
                line = new ArrayList<PathPoint>();
                isTouching = true;
                break;
            case MotionEvent.ACTION_UP:
                lines.add(line);
                isTouching = false;
                upTime = System.currentTimeMillis();

                autoDraw();
            default:
                path.lineTo(pathPoint.x, pathPoint.y);
                break;
        }
        line.add(pathPoint);
        invalidate();
        return true;
    }

    private void autoDraw() {
        new Thread(this).start();

    }

    @Override
    public void run() {
        while (System.currentTimeMillis() - upTime < 1000) {
            if (isTouching) return;
        }
        isDrawing = true;
        Log.i("info", "你倒是画啊,线数:" + lines.size());
        path = new Path();
        for (int i = 0; i < lines.size(); i++) {
            ArrayList<PathPoint> l = lines.get(i);
            Log.i("info", "点数:" + l.size());
            for (int j = 0; j < l.size(); j++) {
                PathPoint p = l.get(j);
                if (j == 0) path.moveTo(p.x, p.y);
                else path.lineTo(p.x, p.y);
                postInvalidate();
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        lines.clear();
        line.clear();
        path = new Path();
        isDrawing = false;

    }

    private PathPoint getEventPoint(MotionEvent event) {

        return new PathPoint(event.getX(), event.getY());
    }

    class PathPoint {
        PathPoint(float x, float y) {
            this.x = x;
            this.y = y;
        }

        float x, y;

        /**
         * 到点p的距离
         *
         * @param p
         * @return
         */
        public double lenthToPoint(PathPoint p) {
            float f = (p.x - x) * (p.x - x) + (p.y - y) * (p.y - y);
            return Math.sqrt(f);
        }
    }
}

。。。回头看了看有点水啊,全是代码。

那么,说点更水的:

可以自己在手机上给你的手机应用写点关键文字,在上边的代码里加点方法,把得到的坐标保存到本地,数据库、文件随你,在你的引用引导页中加载这些数据,然后在一笔一笔的把字写在手机屏幕上,是不是有种电影高大上的效果。

手机上的svg动画的原理也大概如此吧,svg也是包含了一大堆点坐标,github有很多关于svg动画的项目。淘宝手机app第一次进入开场那个动画想着应该是svg之类吧,不过那个炫酷多了,有兴趣可以研究一下。

也可以把你想对女神说的话以这种方式记录出来,假装给她测试应用,不经意间show给她看。

恩。。。效率是什么东西?

以上,纯玩。

时间: 2024-10-06 16:08:03

Path动画--书写文字的动画实现的相关文章

svg文字描边动画

svg动画在网页中是经常见到的,svg动画使得网页看起来清新美观 任何不规则图形都可以由svg绘制完成,当然也包括文字,文字本身就可以看作一个不规则图形?? 还是按以前的流程,开始放代码前,先看效果: 很酷炫有木有?!!! 在我发现这个效果的时候,我觉得碉堡了,直到我知道了它的代码 代码真的很简单,很简单... 咳咳.不扯了,现在进入正题 在使用网页做svg动画的时候首先我们要有svg文件,这里我使用的是Ai来做svg文件 其实我感觉Ai和PS真的好像, 新建文件-->文字工具-->选自己喜欢

CSS3伪类nth-child结合transiton动画实现文字若影若现

css3伪类nth-child结合transiton动画实现文字若影若现收先创建一个div盒子,然后包裹在div中的有10个span标签每个span标签填上内容一次为A,B,C,D,E,F,G,H,I,,J先看下效果图: 看HTML5代码: <div class="box"> <span>A</span> <span>B</span> <span>C</span> <span>D</s

【注释张豪华版 Path酷炫动画】极速get花式Path (支付宝支付成功动画)

转载请标明出处: http://blog.csdn.net/zxt0601/article/details/54018970 本文出自:[张旭童的博客](http://blog.csdn.net/zxt0601) 代码传送门:喜欢的话,随手点个star.多谢 https://github.com/mcxtzhang/PathAnimView 概述 新年第一篇技术文章哈,大家新年快乐,先来个简单点的,主要介绍工具的使用,预预热,下周一奉上一个骚气的购物车动画按钮,敬请期待. 在前文 给我一个Pat

语音输入和文字输入动画切换

随着语音的快速普及,很多应用都开始增加语音输入功能.下面是一个简单的语音和文字输入的动画切换: 布局文件: <ViewFlipper android:id="@+id/viewFlipper1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" &g

【Android】 给我一个Path,还你一个动画

转载请标明出处: http://blog.csdn.net/zxt0601/article/details/53040506 本文出自:[张旭童的CSDN](http://blog.csdn.net/zxt0601) 代码传送门:喜欢的话,随手点个star.多谢 https://github.com/mcxtzhang/PathAnimView 一 概述 原本只是想模仿一下我魂牵梦萦的StoreHouse效果,没想到意外撸出来一个工具库. 最简单用法,给我一个path(可以有多段),我还你一个动

easyUI draggable插件使用不当,导致拖动div内部文本框无法输入;设置echarts数据为空时就显示空白,不要动画和文字

先上一个Demo <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text

css3实现文字渐变动画效果

利用css3这个属性(背景剪裁): background-clip: border-box || padding-box || context-box || no-clip || text 本次用到的就是: -webkit-background-clip:text; 栗子: 1. <style> .masked{ text-align: center; background-image: -webkit-linear-gradient(left, #147B96, #E6D205 25%, #

动画(Animation) 、 高级动画(Core Animation)

1 演示UIImage制作的动画 1.1 问题 UIImage动画是IOS提供的最基本的动画,通常用于制作一些小型的动画,本案例使用UIImage制作一个小狗跑动的动画,如图-1所示: 图-1 1.2 方案 首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件,并关联成TRViewController的属性imageView. 然后在viewDidLoad方法中使用工厂方法animatedImageNamed:创建UIImage对象image. 最后将imageVi

Android动画效果——1.帧动画2.补间动画3.跳转画面(三)

Android--动画效果1.帧动画2.补间动画3.跳转画面 插值器类 xml属性值 说明 LinearInterpolator @android:anim/linear_interpolatorr 动画以均匀的速度改变. AccelerateInterpolator @android:anim/accelerate_interpolator 在动画开始时改变速度较慢,然后开始加速. AccelerateDecelerateInterpolator @android:anim/accelerat