Android-安卓Canvas画小黄人

原地址:link.

看了大神 JR93的这篇文章:纯CSS3画出小黄人并实现动画效果 ,萌生了我在安卓上画小黄人的想法,同时他在文章中的步骤分解,在我的具体实现中起到了很大的帮助。话不多说,先上效果图

实现步骤

其实很简单

  1. 首先找到一张小黄人的图
  • 然后调用canvas.drawBitmap()后画到画布上 - -。
    好吧,一点都不好笑

正文

准备工作

自定义MinionView extends View,定义以下成员变量,备用(可以先不看,后面的代码看到莫名其妙出来的变量再上来看下)

    private Paint mPaint;
    private float bodyWidth;
    private float bodyHeigh;
    private static final float BODY_SCALE = 0.6f;//身体主干占整个view的比重
    private static final float BODY_WIDTH_HEIGHT_SCALE = 0.6f; //        身体的比例设定为 w:h = 3:5
<span class="token keyword">private</span> <span class="token keyword">float</span> mStrokeWidth <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span><span class="token comment">//描边宽度</span>
<span class="token keyword">private</span> <span class="token keyword">float</span> offset<span class="token punctuation">;</span><span class="token comment">//计算时,部分需要 考虑描边偏移</span>
<span class="token keyword">private</span> <span class="token keyword">float</span> radius<span class="token punctuation">;</span><span class="token comment">//身体上下半圆的半径</span>
<span class="token keyword">private</span> <span class="token keyword">int</span> colorClothes <span class="token operator">=</span> <span class="token class-name">Color</span><span class="token punctuation">.</span><span class="token function">rgb</span><span class="token punctuation">(</span><span class="token number">32</span><span class="token punctuation">,</span> <span class="token number">116</span><span class="token punctuation">,</span> <span class="token number">160</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//衣服的颜色</span>
<span class="token keyword">private</span> <span class="token keyword">int</span> colorBody <span class="token operator">=</span> <span class="token class-name">Color</span><span class="token punctuation">.</span><span class="token function">rgb</span><span class="token punctuation">(</span><span class="token number">249</span><span class="token punctuation">,</span> <span class="token number">217</span><span class="token punctuation">,</span> <span class="token number">70</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//身体的颜色</span>
<span class="token keyword">private</span> <span class="token keyword">int</span> colorStroke <span class="token operator">=</span> <span class="token class-name">Color</span><span class="token punctuation">.</span>BLACK<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">RectF</span> bodyRect<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">float</span> handsHeight<span class="token punctuation">;</span><span class="token comment">//计算出吊带的高度时,可以用来做手的高度</span>
<span class="token keyword">private</span> <span class="token keyword">float</span> footHeigh<span class="token punctuation">;</span><span class="token comment">//脚的高度,用来画脚部阴影时用</span>

初始化参数

重写protected void onDraw(Canvas canvas)方法,首先调用 如下 (会经常看到一些奇怪的数字,做比例,别问我怎么来的,目测+一点点微调得来的- -。)

    private void initParams() {
        bodyWidth = Math.min(getWidth(), getHeight() * BODY_WIDTH_HEIGHT_SCALE) * BODY_SCALE;
        bodyHeigh = Math.min(getWidth(), getHeight() * BODY_WIDTH_HEIGHT_SCALE) / BODY_WIDTH_HEIGHT_SCALE * BODY_SCALE;
    mStrokeWidth <span class="token operator">=</span> <span class="token builtin">Math</span><span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>bodyWidth <span class="token operator">/</span> <span class="token number">50</span><span class="token punctuation">,</span> mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    offset <span class="token operator">=</span> mStrokeWidth <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span>

    bodyRect <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RectF</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">getWidth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> bodyWidth<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span>
    bodyRect<span class="token punctuation">.</span>top <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">getHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> bodyHeigh<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span>
    bodyRect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">=</span> bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth<span class="token punctuation">;</span>
    bodyRect<span class="token punctuation">.</span>bottom <span class="token operator">=</span> bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> bodyHeigh<span class="token punctuation">;</span>

    radius <span class="token operator">=</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span>
    footHeigh <span class="token operator">=</span> radius <span class="token operator">*</span> <span class="token number">0</span><span class="token punctuation">.</span>4333f<span class="token punctuation">;</span>

    handsHeight <span class="token operator">=</span>  <span class="token punctuation">(</span><span class="token function">getHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> bodyHeigh<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span>   <span class="token operator">+</span> offset <span class="token operator">-</span> radius <span class="token operator">*</span> <span class="token number">1</span><span class="token punctuation">.</span>65f <span class="token punctuation">;</span>
<span class="token punctuation">}</span>

画身体

我来组成身体

显然身体是一个矩形加上,上下半圆,这边只要用一个圆角矩形,然后圆角的弧度半径用身体宽度的一半就可以达到这个效果了。
把身体的矩形外存起来,后面经常要用到其相对位置进行对其它部位的定位,代码如下。

    drawBody(canvas);//身体
    drawBodyStroke(canvas);//最后画身体的描边,可以摭住一些过渡的棱角
<span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">drawBody</span><span class="token punctuation">(</span>Canvas canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorBody<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span>Paint<span class="token punctuation">.</span>Style<span class="token punctuation">.</span>FILL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawRoundRect</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">,</span> radius<span class="token punctuation">,</span> radius<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>

 <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">drawBodyStroke</span><span class="token punctuation">(</span>Canvas canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorStroke<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span>Paint<span class="token punctuation">.</span>Style<span class="token punctuation">.</span>STROKE<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawRoundRect</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">,</span> radius<span class="token punctuation">,</span> radius<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

画衣服

这是穿上裤子的样子
  • 首先先画上底下的半圆

        RectF rect = new RectF();
    rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">getWidth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> bodyWidth<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> offset<span class="token punctuation">;</span>
    rect<span class="token punctuation">.</span>top <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">getHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> bodyHeigh<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">-</span> radius <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> offset<span class="token punctuation">;</span>
    rect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">=</span> rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">-</span> offset <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    rect<span class="token punctuation">.</span>bottom <span class="token operator">=</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">-</span> offset <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>

    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorClothes<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">FILL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawArc</span><span class="token punctuation">(</span>rect<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">180</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

  • 再画半圆上方的矩形,w表示矩形离左边身体的距离,h矩形的高
        int h = (int) (radius * 0.5);
        int w = (int) (radius * 0.3);
    rect<span class="token punctuation">.</span>left <span class="token operator">+=</span> w<span class="token punctuation">;</span>
    rect<span class="token punctuation">.</span>top <span class="token operator">=</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> h<span class="token punctuation">;</span>
    rect<span class="token punctuation">.</span>right <span class="token operator">-=</span> w<span class="token punctuation">;</span>
    rect<span class="token punctuation">.</span>bottom <span class="token operator">=</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> h<span class="token punctuation">;</span>

    canvas<span class="token punctuation">.</span><span class="token function">drawRect</span><span class="token punctuation">(</span>rect<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

  • 上面的画完之后,要在衣服上面描一层黑色的边,用canvas.drawLines把线一条条画出来吧,这边要同时考虑画笔的描边宽度,否则会出现连接点有锯齿的感觉。

        //画横线
        initPaint();
        mPaint.setColor(colorStroke);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(mStrokeWidth);
        float[] pts = new float[20];//5条线
    pts<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> rect<span class="token punctuation">.</span>left <span class="token operator">-</span> w<span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> h<span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">+</span> w<span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

    pts<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">+</span> offset<span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">-</span> h<span class="token punctuation">;</span>

    pts<span class="token punctuation">[</span><span class="token number">8</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span> <span class="token operator">-</span> offset<span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">8</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token punctuation">(</span>radius <span class="token operator">-</span> w<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">11</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

    pts<span class="token punctuation">[</span><span class="token number">12</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">11</span><span class="token punctuation">]</span> <span class="token operator">-</span> offset<span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">12</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">15</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span> <span class="token operator">+</span> h<span class="token punctuation">;</span>

    pts<span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span> <span class="token operator">-</span> offset<span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">17</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">15</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">18</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span> <span class="token operator">+</span> w<span class="token punctuation">;</span>
    pts<span class="token punctuation">[</span><span class="token number">19</span><span class="token punctuation">]</span> <span class="token operator">=</span> pts<span class="token punctuation">[</span><span class="token number">17</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawLines</span><span class="token punctuation">(</span>pts<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

  • 画吊带 就是一个直角梯形,把梯形的四个顶点计算出来,使用canvas.drawPath将其画上去,然后纽扣用一个实心的小圆表示
       //画左吊带
        initPaint();
        mPaint.setColor(colorClothes);
        mPaint.setStrokeWidth(mStrokeWidth);
        mPaint.setStyle(Paint.Style.FILL);
        Path path = new Path();
        path.moveTo(rect.left - w - offset, handsHeight);
        path.lineTo(rect.left + h / 4, rect.top + h / 2);
        final float smallW = w / 2 * (float) Math.sin(Math.PI / 4);
        path.lineTo(rect.left + h / 4 + smallW, rect.top + h / 2 - smallW);
        final float smallW2 = w / (float) Math.sin(Math.PI / 4) / 2;
        path.lineTo(rect.left - w - offset, handsHeight - smallW2);
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorStroke<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">STROKE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">FILL_AND_STROKE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">,</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">,</span> mStrokeWidth<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">//画右吊带</span>

    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorClothes<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">FILL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">moveTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">-</span> w <span class="token operator">+</span> <span class="token number">2</span> <span class="token operator">*</span> radius <span class="token operator">-</span> offset<span class="token punctuation">,</span> handsHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> h <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">,</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> h <span class="token operator">/</span> <span class="token number">4</span> <span class="token operator">-</span> smallW<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">-</span> smallW<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">-</span> w <span class="token operator">+</span> <span class="token number">2</span> <span class="token operator">*</span> radius <span class="token operator">-</span> offset<span class="token punctuation">,</span> handsHeight<span class="token operator">-</span> smallW2<span class="token punctuation">)</span><span class="token punctuation">;</span>

    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorStroke<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">STROKE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">FILL_AND_STROKE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> h <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">,</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">,</span> mStrokeWidth<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

  • 画中间的口袋 是一个下面两边是圆角的圆角矩形,但是貌似不能直接画这样的圆角矩形,所以我就用土办法,不就是一个多边形吗,用canvas.drawPath来画,在圆角的地方添加圆弧过渡path.addArc
       //中间口袋
        initPaint();
        mPaint.setColor(colorStroke);
        mPaint.setStrokeWidth(mStrokeWidth);
        mPaint.setStyle(Paint.Style.STROKE);
    path<span class="token punctuation">.</span><span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    float radiusBigPokect <span class="token operator">=</span> w <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">.</span>0f<span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">moveTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">-</span> h <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">-</span> h <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">addArc</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w <span class="token operator">-</span> radiusBigPokect <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span> <span class="token operator">-</span> radiusBigPokect<span class="token punctuation">,</span>
            rect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span> <span class="token operator">+</span> radiusBigPokect<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">90</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w <span class="token operator">+</span> radiusBigPokect<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span> <span class="token operator">+</span> radiusBigPokect<span class="token punctuation">)</span><span class="token punctuation">;</span>

    path<span class="token punctuation">.</span><span class="token function">addArc</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span> <span class="token operator">-</span> radiusBigPokect<span class="token punctuation">,</span>
            rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w <span class="token operator">+</span> <span class="token number">2</span> <span class="token operator">*</span> radiusBigPokect<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">4</span> <span class="token operator">+</span> radiusBigPokect<span class="token punctuation">,</span> <span class="token number">90</span><span class="token punctuation">,</span> <span class="token number">90</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">.</span>5f <span class="token operator">*</span> w<span class="token punctuation">,</span> rect<span class="token punctuation">.</span>bottom <span class="token operator">-</span> h <span class="token operator">/</span> <span class="token number">4</span> <span class="token operator">-</span> offset<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

  • 左右两个小口袋也直接用一个小弧来解决掉
     //        下边一竖,分开裤子
        canvas.drawLine(bodyRect.left + bodyWidth / 2, bodyRect.bottom - h * 0.8f, bodyRect.left + bodyWidth / 2, bodyRect.bottom, mPaint);
//      左边的小口袋
        float radiusSamllPokect = w * 1.2f;
        canvas.drawArc(bodyRect.left - radiusSamllPokect, bodyRect.bottom - radius - radiusSamllPokect,
                bodyRect.left + radiusSamllPokect, bodyRect.bottom - radius + radiusSamllPokect, 80, -60, false, mPaint);
//      右边小口袋
        canvas.drawArc(bodyRect.right - radiusSamllPokect, bodyRect.bottom - radius - radiusSamllPokect,
                bodyRect.right + radiusSamllPokect, bodyRect.bottom - radius + radiusSamllPokect, 100, 60, false, mPaint);
//        canvas.drawArc(left + w/5,);
  • 嗯,衣服画完了。
    drawClothes(canvas);//衣服
<span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">drawClothes</span><span class="token punctuation">(</span>Canvas canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//就是上面那一堆代码按顺序合起来啦。。。。。</span>
<span class="token punctuation">}</span>

画脚

萌萌的小短腿

脚这部分比较简单,从身体的下方,一个竖直的矩形下来,再加上一个左边圆角的圆角矩形,还是通过画Path来实现。

        drawFeet(canvas);//脚
<span class="token keyword">private</span> void <span class="token function">drawFeet</span><span class="token punctuation">(</span><span class="token builtin">Canvas</span> canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorStroke<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">FILL_AND_STROKE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    float radiusFoot <span class="token operator">=</span> radius <span class="token operator">/</span> <span class="token number">3</span> <span class="token operator">*</span> <span class="token number">0</span><span class="token punctuation">.</span>4f<span class="token punctuation">;</span>
    float leftFootStartX <span class="token operator">=</span> bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> radius <span class="token operator">-</span> offset <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    float leftFootStartY <span class="token operator">=</span> bodyRect<span class="token punctuation">.</span>bottom <span class="token operator">-</span> offset<span class="token punctuation">;</span>
    float footWidthA <span class="token operator">=</span> radius <span class="token operator">*</span> <span class="token number">0</span><span class="token punctuation">.</span>5f<span class="token punctuation">;</span><span class="token comment">//脚宽度大-到半圆结束</span>
    float footWidthB <span class="token operator">=</span> footWidthA <span class="token operator">/</span> <span class="token number">3</span><span class="token punctuation">;</span><span class="token comment">//脚宽度-比较细的部分</span>

    <span class="token comment">//      左脚</span>
    <span class="token builtin">Path</span> path <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Path</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">moveTo</span><span class="token punctuation">(</span>leftFootStartX<span class="token punctuation">,</span> leftFootStartY<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>leftFootStartX<span class="token punctuation">,</span> leftFootStartY <span class="token operator">+</span> footHeigh<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>leftFootStartX <span class="token operator">-</span> footWidthA <span class="token operator">+</span> radiusFoot<span class="token punctuation">,</span> leftFootStartY <span class="token operator">+</span> footHeigh<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token builtin">RectF</span> rectF <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RectF</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    rectF<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">=</span> leftFootStartX <span class="token operator">-</span> footWidthA<span class="token punctuation">;</span>
    rectF<span class="token punctuation">.</span>top <span class="token operator">=</span> leftFootStartY <span class="token operator">+</span> footHeigh <span class="token operator">-</span> radiusFoot <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    rectF<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">=</span> rectF<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> radiusFoot <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    rectF<span class="token punctuation">.</span>bottom <span class="token operator">=</span> rectF<span class="token punctuation">.</span>top <span class="token operator">+</span> radiusFoot <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">addArc</span><span class="token punctuation">(</span>rectF<span class="token punctuation">,</span> <span class="token number">90</span><span class="token punctuation">,</span> <span class="token number">180</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rectF<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> radiusFoot <span class="token operator">+</span> footWidthB<span class="token punctuation">,</span> rectF<span class="token punctuation">.</span>top<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rectF<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> radiusFoot <span class="token operator">+</span> footWidthB<span class="token punctuation">,</span> leftFootStartY<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>leftFootStartX<span class="token punctuation">,</span> leftFootStartY<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

// 右脚
float rightFootStartX = bodyRect.left + radius + offset * 2;
float rightFootStartY = leftFootStartY;
path.reset();
path.moveTo(rightFootStartX, rightFootStartY);
path.lineTo(rightFootStartX, rightFootStartY + footHeigh);
path.lineTo(rightFootStartX + footWidthA - radiusFoot, rightFootStartY + footHeigh);

    rectF<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">=</span> rightFootStartX <span class="token operator">+</span> footWidthA <span class="token operator">-</span> radiusFoot <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    rectF<span class="token punctuation">.</span>top <span class="token operator">=</span> rightFootStartY <span class="token operator">+</span> footHeigh <span class="token operator">-</span> radiusFoot <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    rectF<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">=</span> rectF<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> radiusFoot <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    rectF<span class="token punctuation">.</span>bottom <span class="token operator">=</span> rectF<span class="token punctuation">.</span>top <span class="token operator">+</span> radiusFoot <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">addArc</span><span class="token punctuation">(</span>rectF<span class="token punctuation">,</span> <span class="token number">90</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">180</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rectF<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> radiusFoot <span class="token operator">-</span> footWidthB<span class="token punctuation">,</span> rectF<span class="token punctuation">.</span>top<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rectF<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">-</span> radiusFoot <span class="token operator">-</span> footWidthB<span class="token punctuation">,</span> rightFootStartY<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>rightFootStartX<span class="token punctuation">,</span> rightFootStartY<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token punctuation">}</span>

画手

这里是双手放在后背的样子

手我用的是一个等腰直角三角形来实现,斜边就是吊带到裤子,从直角顶点作高到斜边,通过小直角三角形的直角边相等就可以算出顶点的坐标。这个时候还是有个圆角,刚开始我实现的时候是像上面那些通过path.addArc加上圆角,但是这边计算好之后和原来的衔接一直有问题,在调了半天之后,偶然发现mPaint.setPathEffect(new CornerPathEffect(radiusHand));这个方法,可以使path的拐角用圆角来过渡,一下子就简单到爆了,果然科学技术是第一生产力。

        drawHands(canvas);//手
<span class="token keyword">private</span> void <span class="token function">drawHands</span><span class="token punctuation">(</span><span class="token builtin">Canvas</span> canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">FILL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorBody<span class="token punctuation">)</span><span class="token punctuation">;</span>

// 左手
Path path = new Path();
float hypotenuse = bodyRect.bottom - radius - handsHeight;
float radiusHand = hypotenuse / 6;
mPaint.setPathEffect(new CornerPathEffect(radiusHand));

    path<span class="token punctuation">.</span><span class="token function">moveTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span><span class="token punctuation">,</span> handsHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">-</span> hypotenuse <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">,</span> handsHeight <span class="token operator">+</span> hypotenuse <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span><span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>bottom <span class="token operator">-</span> radius<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">STROKE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorStroke<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

// 右手
path.reset();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(colorBody);

    path<span class="token punctuation">.</span><span class="token function">moveTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">right</span><span class="token punctuation">,</span> handsHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">+</span> hypotenuse <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">,</span> handsHeight <span class="token operator">+</span> hypotenuse <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">right</span><span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>bottom <span class="token operator">-</span> radius<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">STROKE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorStroke<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

// 一个慢动作 - -||| 拐点内侧
path.reset();
mPaint.setStyle(Paint.Style.FILL);
path.moveTo(bodyRect.left, handsHeight + hypotenuse / 2 - mStrokeWidth);
path.lineTo(bodyRect.left - mStrokeWidth 2, handsHeight + hypotenuse / 2 + mStrokeWidth 2);
path.lineTo(bodyRect.left, handsHeight + hypotenuse / 2 + mStrokeWidth);
canvas.drawPath(path, mPaint);

    path<span class="token punctuation">.</span><span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">moveTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">right</span><span class="token punctuation">,</span> handsHeight <span class="token operator">+</span> hypotenuse <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">-</span> mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">right</span> <span class="token operator">+</span> mStrokeWidth <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">,</span> handsHeight <span class="token operator">+</span> hypotenuse <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> mStrokeWidth <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    path<span class="token punctuation">.</span><span class="token function">lineTo</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">right</span><span class="token punctuation">,</span> handsHeight <span class="token operator">+</span> hypotenuse <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> mStrokeWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>

画眼睛,嘴巴

三个字,圆圆圆

反正就是各种画圆,或者弧形,嘴巴部分偷懒也就一条小弧一笔带过了,哈哈

        drawEyesMouth(canvas);//眼睛,嘴巴
private void drawEyesMouth(Canvas canvas) {
    float eyesOffset <span class="token operator">=</span> radius <span class="token operator">*</span> <span class="token number">0</span><span class="token punctuation">.</span>1f<span class="token punctuation">;</span><span class="token comment">//眼睛中心处于上半圆直径 往上的高度偏移</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStrokeWidth</span><span class="token punctuation">(</span>mStrokeWidth <span class="token operator">*</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

// 计算眼镜带弧行的半径 分两段,以便眼睛中间有隔开的效果
float radiusGlassesRibbon = (float) (radius / Math.sin(Math.PI / 20));
RectF rect = new RectF();
rect.left = bodyRect.left + radius - radiusGlassesRibbon;
rect.top = bodyRect.top + radius - (float) (radius / Math.tan(Math.PI / 20)) - radiusGlassesRibbon - eyesOffset;
rect.right = rect.left + radiusGlassesRibbon 2;
rect.bottom = rect.top + radiusGlassesRibbon 2;
canvas.drawArc(rect, 81, 3, false, mPaint);
canvas.drawArc(rect, 99, -3, false, mPaint);

//眼睛半径
float radiusEyes = radius / 3;
initPaint();
mPaint.setColor(Color.WHITE);
mPaint.setStrokeWidth(mStrokeWidth);
mPaint.setStyle(Paint.Style.FILL);

    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">-</span> radiusEyes <span class="token operator">-</span> offset<span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> eyesOffset<span class="token punctuation">,</span> radiusEyes<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> radiusEyes <span class="token operator">+</span> offset<span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> eyesOffset<span class="token punctuation">,</span> radiusEyes<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span>colorStroke<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">STROKE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">-</span> radiusEyes <span class="token operator">-</span> offset<span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> eyesOffset<span class="token punctuation">,</span> radiusEyes<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> radiusEyes <span class="token operator">+</span> offset<span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> eyesOffset<span class="token punctuation">,</span> radiusEyes<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">final</span> float radiusEyeballBlack <span class="token operator">=</span> radiusEyes <span class="token operator">/</span> <span class="token number">3</span><span class="token punctuation">;</span>
    mPaint<span class="token punctuation">.</span><span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token builtin">Paint</span><span class="token punctuation">.</span><span class="token builtin">Style</span><span class="token punctuation">.</span><span class="token constant">FILL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">-</span> radiusEyes <span class="token operator">-</span> offset<span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> eyesOffset<span class="token punctuation">,</span> radiusEyeballBlack<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> radiusEyes <span class="token operator">+</span> offset<span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> eyesOffset<span class="token punctuation">,</span> radiusEyeballBlack<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span><span class="token builtin">Color</span><span class="token punctuation">.</span><span class="token constant">WHITE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">final</span> float radiusEyeballWhite <span class="token operator">=</span> radiusEyeballBlack <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">-</span> radiusEyes <span class="token operator">+</span> radiusEyeballWhite <span class="token operator">-</span> offset <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">,</span>
            bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> radiusEyeballWhite <span class="token operator">+</span> offset <span class="token operator">-</span> eyesOffset<span class="token punctuation">,</span>
            radiusEyeballWhite<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawCircle</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span><span class="token keyword">left</span> <span class="token operator">+</span> bodyWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> radiusEyes <span class="token operator">+</span> radiusEyeballWhite<span class="token punctuation">,</span>
            bodyRect<span class="token punctuation">.</span>top <span class="token operator">+</span> radius <span class="token operator">-</span> radiusEyeballWhite <span class="token operator">+</span> offset <span class="token operator">-</span> eyesOffset<span class="token punctuation">,</span>
            radiusEyeballWhite<span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>

// 画嘴巴,因为位置和眼睛有相对关系,所以写在一块
mPaint.setColor(colorStroke);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth);
float radiusMonth = radius;
rect.left = bodyRect.left;
rect.top = bodyRect.top - radiusMonth / 2.5f;
rect.right = rect.left + radiusMonth 2;
rect.bottom = rect.top + radiusMonth 2;
canvas.drawArc(rect, 95, -20, false, mPaint);

<span class="token punctuation">}</span>

脚下的阴影

这是最后一步了,直接画一个非常扁的椭圆放在脚下面就可以了

不科学啊,长这么胖,为毛影子这么瘦(别在意这些细节)
        drawFeetShadow(canvas);//脚下的阴影
<span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">drawFeetShadow</span><span class="token punctuation">(</span>Canvas canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>

    mPaint<span class="token punctuation">.</span><span class="token function">setColor</span><span class="token punctuation">(</span><span class="token function">getResources</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getColor</span><span class="token punctuation">(</span>android<span class="token punctuation">.</span>R<span class="token punctuation">.</span>color<span class="token punctuation">.</span>darker_gray<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    canvas<span class="token punctuation">.</span><span class="token function">drawOval</span><span class="token punctuation">(</span>bodyRect<span class="token punctuation">.</span>left <span class="token operator">+</span> bodyWidth <span class="token operator">*</span> <span class="token number">0.15f</span><span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>bottom <span class="token operator">-</span> offset <span class="token operator">+</span> footHeigh<span class="token punctuation">,</span>
            bodyRect<span class="token punctuation">.</span>right <span class="token operator">-</span> bodyWidth <span class="token operator">*</span> <span class="token number">0.15f</span><span class="token punctuation">,</span> bodyRect<span class="token punctuation">.</span>bottom <span class="token operator">-</span> offset <span class="token operator">+</span> footHeigh <span class="token operator">+</span> mStrokeWidth <span class="token operator">*</span> <span class="token number">1.3f</span><span class="token punctuation">,</span> mPaint<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

onDraw方法,依次调用上述的各种方法,画完收工。


<span class="token annotation punctuation">@Override</span>
<span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">onDraw</span><span class="token punctuation">(</span><span class="token class-name">Canvas</span> canvas<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">initParams</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">initPaint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">drawFeetShadow</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//脚下的阴影</span>
    <span class="token function">drawFeet</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//脚</span>
    <span class="token function">drawHands</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//手</span>
    <span class="token function">drawBody</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//身体</span>
    <span class="token function">drawClothes</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//衣服</span>
    <span class="token function">drawEyesMouth</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//眼睛,嘴巴</span>
    <span class="token function">drawBodyStroke</span><span class="token punctuation">(</span>canvas<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//最后画身体的描边,可以摭住一些过渡的棱角</span>
<span class="token punctuation">}</span>

画完了,好像少了点什么。。。。。对了,头发。好吧,我画的是程序猿,哪来的头发 - -,


至此,正常画风的小黄人已经画完了,但是吧,好不容易画好,好像没啥意思,脑洞大开一下吧。
电影中的小黄人中病毒后是会变成紫色的,那我们用代码画,换个颜色还不是分分钟,不但要紫色,还要各种颜色。

三行代码搞定脑洞

    public void randomBodyColor() {
        Random random = new Random();
        colorBody = Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255));
        invalidate();
    }

然后效果就变成了这样。

看起来还有点小酷炫

希望大家喜欢 ,上述有任何问题或者表述不清楚的,欢迎评论交流。
完整源码 github

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值