Java Code Examples for android.graphics.Canvas#save()

The following examples show how to use android.graphics.Canvas#save() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ClockBuilder.java    From AndroidWallet with GNU General Public License v3.0 6 votes vote down vote up
@Override
protected void onDraw(Canvas canvas)
{
    super.onDraw(canvas);
    //外圆
    canvas.drawCircle(getViewCenterX(), getViewCenterY(), mOuterRadius, mStrokePaint);

    //上方按钮
    canvas.drawRect(mBtnRectF, mFillPaint);
    canvas.drawRect(mBottomBtnRectF, mFillPaint);

    //右侧按钮
    canvas.save();
    canvas.rotate(45, getViewCenterX(), getViewCenterY());
    canvas.drawRect(mBottomBtnRectF, mFillPaint);
    canvas.restore();

    canvas.translate(0, 20);
}
 
Example 2
Source File: PLA_ListView.java    From EverMemo with MIT License 6 votes vote down vote up
void drawOverscrollHeader(Canvas canvas, Drawable drawable, Rect bounds) {
	final int height = drawable.getMinimumHeight();

	canvas.save();
	canvas.clipRect(bounds);

	final int span = bounds.bottom - bounds.top;
	if (span < height) {
		bounds.top = bounds.bottom - height;
	}

	drawable.setBounds(bounds);
	drawable.draw(canvas);

	canvas.restore();
}
 
Example 3
Source File: PinnedHeaderItemDecoration.java    From LRecyclerView with Apache License 2.0 6 votes vote down vote up
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {

    if (mPinnedHeaderView != null) {
        c.save();

        mItemTouchListener.invalidTopAndBottom(mPinnedHeaderOffset);

        mClipBounds.top = mRecyclerViewPaddingTop + mHeaderTopMargin;
        // 锁定画布绘制范围,记为B
        // REVERSE_DIFFERENCE,实际上就是求得的B和A的差集范围,即B-A,只有在此范围内的绘制内容才会被显示
        // 因此,只绘制(0,0,parent.getWidth(),belowView.getTop())这个范围,然后画布移动了mPinnedHeaderTop,所以刚好是绘制顶部标签移动的范围
        // 低版本不行,换回Region.Op.UNION并集
        c.clipRect(mClipBounds, Region.Op.UNION);
        c.translate(mRecyclerViewPaddingLeft + mHeaderLeftMargin, mPinnedHeaderOffset + mRecyclerViewPaddingTop + mHeaderTopMargin);
        mPinnedHeaderView.draw(c);

        c.restore();
    }
}
 
Example 4
Source File: PieItem.java    From GravityBox with Apache License 2.0 6 votes vote down vote up
@Override
public void draw(Canvas canvas, Position position) {
    canvas.drawPath(mPath, (flags & SELECTED) != 0
            ? mSelectedPaint : mBackgroundPaint);
    canvas.drawPath(mPath, (flags & SELECTED) != 0
            ? mSelectedPaint : mOutlinePaint);

    if (mView != null) {
        int state = canvas.save();
        canvas.translate(mView.getLeft(), mView.getTop());
        // keep icons "upright" if we get displayed on TOP position
        if (position != Position.TOP) {
            canvas.rotate(mStart + mSweep / 2 - 270);
        } else {
            canvas.rotate(mStart + mSweep / 2 - 90);
        }
        canvas.translate(-mView.getWidth() / 2, -mView.getHeight() / 2);

        mView.draw(canvas);
        canvas.restoreToCount(state);
    }
}
 
Example 5
Source File: BitmapLayer.java    From MapView with MIT License 6 votes vote down vote up
@Override
public void draw(Canvas canvas, Matrix currentMatrix, float currentZoom, float
        currentRotateDegrees) {
    if (isVisible && bitmap != null) {
        canvas.save();
        float[] goal = {location.x, location.y};
        if (!autoScale) {
            currentMatrix.mapPoints(goal);
        } else {
            canvas.setMatrix(currentMatrix);
        }
        canvas.drawBitmap(bitmap, goal[0] - bitmap.getWidth() / 2,
                goal[1] - bitmap.getHeight() / 2, paint);
        canvas.restore();
    }
}
 
Example 6
Source File: CustomTextView.java    From android-performance with MIT License 5 votes vote down vote up
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(mStaticLayout != null){
        canvas.save();
        canvas.translate(getPaddingLeft(), getPaddingTop());
        mStaticLayout.draw(canvas);
        canvas.restore();
    }
}
 
Example 7
Source File: RedYellowBlueDrawStrategy.java    From styT with Apache License 2.0 5 votes vote down vote up
@Override
public void drawAppName(Canvas canvas, float fraction, String name, int colorOfAppName,
                        WidthAndHeightOfView widthAndHeightOfView) {
    canvas.save();
    int width = widthAndHeightOfView.getWidth();
    int height = widthAndHeightOfView.getHeight();
    Paint paint = new Paint();
    paint.setColor(colorOfAppName);
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(50);
    canvas.drawText(name, width / 2, height / 2 + 50, paint);
    canvas.restore();
}
 
Example 8
Source File: IndeterminateDrawable.java    From material-components-android with Apache License 2.0 5 votes vote down vote up
/** Draws the graphics based on the progress indicator's properties and the animation states. */
@Override
public void draw(@NonNull Canvas canvas) {
  Rect clipBounds = new Rect();

  if (getBounds().isEmpty() || !isVisible() || !canvas.getClipBounds(clipBounds)) {
    // Escape if bounds are empty, clip bounds are empty, or currently hidden.
    return;
  }

  canvas.save();
  drawingDelegate.adjustCanvas(canvas, progressIndicator, getGrowFraction());

  float displayedIndicatorWidth = progressIndicator.getIndicatorWidth() * getGrowFraction();
  float displayedRoundedCornerRadius =
      progressIndicator.getIndicatorCornerRadius() * getGrowFraction();

  // Draws the track first as the bottom layer.
  drawingDelegate.fillTrackWithColor(
      canvas,
      paint,
      combinedTrackColor,
      0f,
      1f,
      displayedIndicatorWidth,
      displayedRoundedCornerRadius);
  // Draws the indicators.
  for (int segmentIndex = 0;
      segmentIndex < animatorDelegate.segmentColors.length;
      segmentIndex++) {
    drawingDelegate.fillTrackWithColor(
        canvas,
        paint,
        animatorDelegate.segmentColors[segmentIndex],
        animatorDelegate.segmentPositions[2 * segmentIndex],
        animatorDelegate.segmentPositions[2 * segmentIndex + 1],
        displayedIndicatorWidth,
        displayedRoundedCornerRadius);
  }
}
 
Example 9
Source File: Plot2D.java    From audio-analyzer-for-android with Apache License 2.0 5 votes vote down vote up
void plotBarThick(Canvas c, double[] y_value, double[] x_values, int i_begin, int i_end, double x_inc, Paint linePainter) {
        if (tmpLineXY.length < 4*(y_value.length)) {
            Log.d(TAG, "plotBar(): new tmpLineXY");
            tmpLineXY = new float[4*(y_value.length)];
        }

        final double minYCanvas = axisY.pixelNoZoomFromV(AnalyzerGraphic.minDB);
        int pixelStep = 2;  // each bar occupy this virtual pixel
        c.save();
        matrix.reset();
        double extraPixelAlignOffset = 0.0f;
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
//          // There is an shift for Android 4.4, while no shift for Android 2.3
//          // I guess that is relate to GL ES acceleration
//          if (c.isHardwareAccelerated()) {
//            extraPixelAlignOffset = 0.5f;
//          }
//        }
        matrix.setTranslate((float)(-axisX.getShift() * (y_value.length - 1) * pixelStep - extraPixelAlignOffset),
                (float)(-axisY.getShift() * axisY.nCanvasPixel));
        matrix.postScale((float)(axisX.nCanvasPixel / ((axisX.vMaxInView() - axisX.vMinInView()) / x_inc * pixelStep)), (float)axisY.getZoom());
        c.concat(matrix);
        // fill interval same as canvas pixel width.
        for (int i = i_begin; i < i_end; i++) {
            float x = x_values == null ? i * pixelStep : (float)(x_values[i] / x_inc * pixelStep);
            float y = (float)axisY.pixelNoZoomFromV(clampDB(y_value[i]));
            tmpLineXY[4*i  ] = x;
            tmpLineXY[4*i+1] = (float)minYCanvas;
            tmpLineXY[4*i+2] = x;
            tmpLineXY[4*i+3] = y;
        }
        c.drawLines(tmpLineXY, 4*i_begin, 4*(i_end-i_begin), linePainter);
        c.restore();
    }
 
Example 10
Source File: MaterialProgressDrawable.java    From NewFastFrame with Apache License 2.0 5 votes vote down vote up
@Override
public void draw(Canvas c) {
    final Rect bounds = getBounds();
    final int saveCount = c.save();
    c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY());
    mRing.draw(c, bounds);
    c.restoreToCount(saveCount);
}
 
Example 11
Source File: DepthRendrer.java    From Android-Plugin-Framework with MIT License 5 votes vote down vote up
private void drawTopEdge(DepthLayout dl, Canvas canvas, float[] src) {

    float[] dst = new float[] {
        dl.getTopLeft().x, dl.getTopLeft().y, dl.getTopRight().x, dl.getTopRight().y,
        dl.getTopRightBack().x, dl.getTopRightBack().y, dl.getTopLeftBack().x, dl.getTopLeftBack().y
    };
    int count = canvas.save();
    matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
    canvas.concat(matrix);
    drawRectancle(dl, canvas);
    drawShadow(dl.getTopLeft(), dl.getTopRight(), -180f, canvas, dl);
    canvas.restoreToCount(count);
  }
 
Example 12
Source File: ClipHelper.java    From GestureViews with Apache License 2.0 5 votes vote down vote up
public void onPreDraw(@NonNull Canvas canvas) {
    if (isClipping) {
        canvas.save();

        if (State.equals(clipRotation, 0f)) {
            canvas.clipRect(clipRect);
        } else {
            // Note, that prior Android 4.3 (18) canvas matrix is not correctly applied to
            // clip rect, clip rect will be set to its upper bound, which is good enough for us.
            canvas.rotate(clipRotation, clipRect.centerX(), clipRect.centerY());
            canvas.clipRect(clipRect);
            canvas.rotate(-clipRotation, clipRect.centerX(), clipRect.centerY());
        }
    }
}
 
Example 13
Source File: PhotoDraweeView.java    From PhotoDraweeView with Apache License 2.0 5 votes vote down vote up
@Override protected void onDraw(@NonNull Canvas canvas) {
    int saveCount = canvas.save();
    if (mEnableDraweeMatrix) {
        canvas.concat(mAttacher.getDrawMatrix());
    }
    super.onDraw(canvas);
    canvas.restoreToCount(saveCount);
}
 
Example 14
Source File: FloatingActionsMenu.java    From android-floating-action-button with Apache License 2.0 5 votes vote down vote up
@Override
public void draw(Canvas canvas) {
  canvas.save();
  canvas.rotate(mRotation, getBounds().centerX(), getBounds().centerY());
  super.draw(canvas);
  canvas.restore();
}
 
Example 15
Source File: AudioPlaylistView.java    From VCL-Android with Apache License 2.0 5 votes vote down vote up
@Override
protected void dispatchDraw (@NonNull Canvas canvas) {
    super.dispatchDraw(canvas);

    if (mIsDragging) {
        canvas.save();
        // Position the drag shadow.
        float posY = mTouchY - (float)mDragShadow.getMeasuredHeight() / 2f;
        canvas.translate(0, posY);
        mDragShadow.draw(canvas);
        canvas.restore();
    }
}
 
Example 16
Source File: pageView.java    From Jreader with GNU General Public License v2.0 4 votes vote down vote up
/**
 * 绘制翻起页背面
 *
 * @param canvas
 * @param bitmap
 */
private void drawCurrentBackArea(Canvas canvas, Bitmap bitmap) {
    int i = (int) (mBezierStart1.x + mBezierControl1.x) / 2;
    float f1 = Math.abs(i - mBezierControl1.x);
    int i1 = (int) (mBezierStart2.y + mBezierControl2.y) / 2;
    float f2 = Math.abs(i1 - mBezierControl2.y);
    float f3 = Math.min(f1, f2);
    mPath1.reset();
    mPath1.moveTo(mBeziervertex2.x, mBeziervertex2.y);
    mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
    mPath1.lineTo(mBezierEnd1.x, mBezierEnd1.y);
    mPath1.lineTo(mTouch.x, mTouch.y);
    mPath1.lineTo(mBezierEnd2.x, mBezierEnd2.y);
    mPath1.close();
    GradientDrawable mFolderShadowDrawable;
    int left;
    int right;
    if (mIsRTandLB) {
        left = (int) (mBezierStart1.x - 1);
        right = (int) (mBezierStart1.x + f3 + 1);
        mFolderShadowDrawable = mFolderShadowDrawableLR;
    } else {
        left = (int) (mBezierStart1.x - f3 - 1);
        right = (int) (mBezierStart1.x + 1);
        mFolderShadowDrawable = mFolderShadowDrawableRL;
    }
    canvas.save();
    try {
        canvas.clipPath(mPath0);
        canvas.clipPath(mPath1, Region.Op.INTERSECT);
    } catch (Exception e) {
    }


    mPaint.setColorFilter(mColorMatrixFilter);

    float dis = (float) Math.hypot(mCornerX - mBezierControl1.x,
            mBezierControl2.y - mCornerY);
    float f8 = (mCornerX - mBezierControl1.x) / dis;
    float f9 = (mBezierControl2.y - mCornerY) / dis;
    mMatrixArray[0] = 1 - 2 * f9 * f9;
    mMatrixArray[1] = 2 * f8 * f9;
    mMatrixArray[3] = mMatrixArray[1];
    mMatrixArray[4] = 1 - 2 * f8 * f8;
    mMatrix.reset();
    mMatrix.setValues(mMatrixArray);
    mMatrix.preTranslate(-mBezierControl1.x, -mBezierControl1.y);
    mMatrix.postTranslate(mBezierControl1.x, mBezierControl1.y);
    canvas.drawBitmap(bitmap, mMatrix, mPaint);
    // canvas.drawBitmap(bitmap, mMatrix, null);
    mPaint.setColorFilter(null);
    canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
    mFolderShadowDrawable.setBounds(left, (int) mBezierStart1.y, right,
            (int) (mBezierStart1.y + mMaxLength));
    mFolderShadowDrawable.draw(canvas);
    canvas.restore();
}
 
Example 17
Source File: ElectricFanLoadingRenderer.java    From DevUtils with Apache License 2.0 4 votes vote down vote up
@Override
protected void draw(Canvas canvas, Rect bounds) {
    int saveCount = canvas.save();

    RectF arcBounds = mTempBounds;
    arcBounds.set(bounds);
    arcBounds.inset(mStrokeXInset, mStrokeYInset);

    mCurrentProgressBounds.set(arcBounds.left, arcBounds.bottom - 2 * mCenterRadius,
            arcBounds.right, arcBounds.bottom);

    //draw loading drawable
    mLoadingDrawable.setBounds((int) arcBounds.centerX() - mLoadingDrawable.getIntrinsicWidth() / 2,
            0,
            (int) arcBounds.centerX() + mLoadingDrawable.getIntrinsicWidth() / 2,
            mLoadingDrawable.getIntrinsicHeight());
    mLoadingDrawable.draw(canvas);

    //draw progress background
    float progressInset = mCenterRadius - mProgressCenterRadius;
    RectF progressRect = new RectF(mCurrentProgressBounds);
    //sub DEFAULT_STROKE_INTERVAL, otherwise will have a interval between progress background and progress outline
    progressRect.inset(progressInset - DEFAULT_STROKE_INTERVAL, progressInset - DEFAULT_STROKE_INTERVAL);
    mPaint.setColor(mProgressBgColor);
    mPaint.setStyle(Paint.Style.FILL);
    canvas.drawRoundRect(progressRect, mProgressCenterRadius, mProgressCenterRadius, mPaint);

    //draw progress
    mPaint.setColor(mProgressColor);
    mPaint.setStyle(Paint.Style.FILL);
    canvas.drawPath(createProgressPath(mProgress, mProgressCenterRadius, progressRect), mPaint);

    //draw leaves
    for (int i = 0; i < mLeafHolders.size(); i++) {
        int leafSaveCount = canvas.save();
        LeafHolder leafHolder = mLeafHolders.get(i);
        Rect leafBounds = leafHolder.mLeafRect;

        canvas.rotate(leafHolder.mLeafRotation, leafBounds.centerX(), leafBounds.centerY());
        mLeafDrawable.setBounds(leafBounds);
        mLeafDrawable.draw(canvas);

        canvas.restoreToCount(leafSaveCount);
    }

    //draw progress background outline,
    //after drawing the leaves and then draw the outline of the progress background can
    //prevent the leaves from flying to the outside
    RectF progressOutlineRect = new RectF(mCurrentProgressBounds);
    float progressOutlineStrokeInset = (mCenterRadius - mProgressCenterRadius) / 2.0f;
    progressOutlineRect.inset(progressOutlineStrokeInset, progressOutlineStrokeInset);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setColor(mProgressBgColor);
    mPaint.setStrokeWidth(mCenterRadius - mProgressCenterRadius);
    canvas.drawRoundRect(progressOutlineRect, mCenterRadius, mCenterRadius, mPaint);

    //draw electric fan outline
    float electricFanCenterX = arcBounds.right - mCenterRadius;
    float electricFanCenterY = arcBounds.bottom - mCenterRadius;

    mPaint.setColor(mElectricFanOutlineColor);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(mStrokeWidth);
    canvas.drawCircle(arcBounds.right - mCenterRadius, arcBounds.bottom - mCenterRadius,
            mCenterRadius - mStrokeWidth / 2.0f, mPaint);

    //draw electric background
    mPaint.setColor(mElectricFanBgColor);
    mPaint.setStyle(Paint.Style.FILL);
    canvas.drawCircle(arcBounds.right - mCenterRadius, arcBounds.bottom - mCenterRadius,
            mCenterRadius - mStrokeWidth + DEFAULT_STROKE_INTERVAL, mPaint);

    //draw electric fan
    int rotateSaveCount = canvas.save();
    canvas.rotate(mRotation, electricFanCenterX, electricFanCenterY);
    mElectricFanDrawable.setBounds((int) (electricFanCenterX - mElectricFanDrawable.getIntrinsicWidth() / 2 * mScale),
            (int) (electricFanCenterY - mElectricFanDrawable.getIntrinsicHeight() / 2 * mScale),
            (int) (electricFanCenterX + mElectricFanDrawable.getIntrinsicWidth() / 2 * mScale),
            (int) (electricFanCenterY + mElectricFanDrawable.getIntrinsicHeight() / 2 * mScale));
    mElectricFanDrawable.draw(canvas);
    canvas.restoreToCount(rotateSaveCount);

    //draw 100% text
    if (mScale < 1.0f) {
        mPaint.setTextSize(mTextSize * (1 - mScale));
        mPaint.setColor(mElectricFanOutlineColor);
        Rect textRect = new Rect();
        mPaint.getTextBounds(PERCENTAGE_100, 0, PERCENTAGE_100.length(), textRect);
        canvas.drawText(PERCENTAGE_100, electricFanCenterX - textRect.width() / 2.0f,
                electricFanCenterY + textRect.height() / 2.0f, mPaint);
    }

    canvas.restoreToCount(saveCount);
}
 
Example 18
Source File: TapTargetView.java    From styT with Apache License 2.0 4 votes vote down vote up
@Override
protected void onDraw(Canvas c) {
    if (isDismissed || outerCircleCenter == null) return;

    if (topBoundary > 0 && bottomBoundary > 0) {
        c.clipRect(0, topBoundary, getWidth(), bottomBoundary);
    }

    if (dimColor != -1) {
        c.drawColor(dimColor);
    }

    int saveCount;
    outerCirclePaint.setAlpha(outerCircleAlpha);
    if (shouldDrawShadow && outlineProvider == null) {
        saveCount = c.save();
        {
            c.clipPath(outerCirclePath, Region.Op.DIFFERENCE);
            drawJitteredShadow(c);
        }
        c.restoreToCount(saveCount);
    }
    c.drawCircle(outerCircleCenter[0], outerCircleCenter[1], outerCircleRadius, outerCirclePaint);

    targetCirclePaint.setAlpha(targetCircleAlpha);
    if (targetCirclePulseAlpha > 0) {
        targetCirclePulsePaint.setAlpha(targetCirclePulseAlpha);
        c.drawCircle(targetBounds.centerX(), targetBounds.centerY(),
                targetCirclePulseRadius, targetCirclePulsePaint);
    }
    c.drawCircle(targetBounds.centerX(), targetBounds.centerY(),
            targetCircleRadius, targetCirclePaint);

    saveCount = c.save();
    {
        c.translate(textBounds.left, textBounds.top);
        titlePaint.setAlpha(textAlpha);
        if (titleLayout != null) {
            titleLayout.draw(c);
        }

        if (descriptionLayout != null && titleLayout != null) {
            c.translate(0, titleLayout.getHeight() + TEXT_SPACING);
            descriptionPaint.setAlpha((int) (0.54f * textAlpha));
            descriptionLayout.draw(c);
        }
    }
    c.restoreToCount(saveCount);

    saveCount = c.save();
    {
        if (tintedTarget != null) {
            c.translate(targetBounds.centerX() - tintedTarget.getWidth() / 2,
                    targetBounds.centerY() - tintedTarget.getHeight() / 2);
            c.drawBitmap(tintedTarget, 0, 0, targetCirclePaint);
        } else if (target.icon != null) {
            c.translate(targetBounds.centerX() - target.icon.getBounds().width() / 2,
                    targetBounds.centerY() - target.icon.getBounds().height() / 2);
            target.icon.setAlpha(targetCirclePaint.getAlpha());
            target.icon.draw(c);
        }
    }
    c.restoreToCount(saveCount);

    if (debug) {
        drawDebugInformation(c);
    }
}
 
Example 19
Source File: GroupItemDecoration.java    From CalendarView with Apache License 2.0 4 votes vote down vote up
/**
 * 绘制悬浮组
 *
 * @param c      Canvas
 * @param parent RecyclerView
 */
protected void onDrawOverGroup(Canvas c, RecyclerView parent) {
    int firstVisiblePosition = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
    if (firstVisiblePosition == RecyclerView.NO_POSITION) {
        return;
    }
    Group group = getCroup(firstVisiblePosition);
    if (group == null)
        return;
    String groupTitle = group.toString();
    if (TextUtils.isEmpty(groupTitle)) {
        return;
    }
    boolean isRestore = false;
    Group nextGroup = getCroup(firstVisiblePosition + 1);
    if (nextGroup != null && !group.equals(nextGroup)) {
        //说明是当前组最后一个元素,但不一定碰撞了
        View child = parent.findViewHolderForAdapterPosition(firstVisiblePosition).itemView;
        if (child.getTop() + child.getMeasuredHeight() < mGroupHeight) {
            //进一步检测碰撞
            c.save();//保存画布当前的状态
            isRestore = true;
            c.translate(0, child.getTop() + child.getMeasuredHeight() - mGroupHeight);
        }
    }
    int left = parent.getPaddingLeft();
    int right = parent.getWidth() - parent.getPaddingRight();
    int top = parent.getPaddingTop();
    int bottom = top + mGroupHeight;
    c.drawRect(left, top, right, bottom, mBackgroundPaint);
    float x;
    float y = top + mTextBaseLine;
    if (isCenter) {
        x = parent.getMeasuredWidth() / 2 - getTextX(groupTitle);
    } else {
        x = mPaddingLeft;
    }
    c.drawText(groupTitle, x, y, mTextPaint);
    if (isRestore) {
        //还原画布为初始状态
        c.restore();
    }
}
 
Example 20
Source File: BossPlane.java    From StormPlane with Apache License 2.0 4 votes vote down vote up
/**
 * 绘制Boss机体
 *
 * @param canvas
 */
private void drawBoss(Canvas canvas) {
    // 极限状态
    if (isLimit) {
        int y = (int) (currentFrame * object_height);
        canvas.save();
        canvas.clipRect(object_x, object_y,
                object_x + object_width, object_y + object_height);
        canvas.drawBitmap(bossPlane_crazy, object_x, object_y - y,
                paint);
        canvas.restore();
        currentFrame++;
        if (currentFrame >= 2) {
            currentFrame = 0;
        }

    }

    // 疯狂状态
    else if (isCrazy) {
        canvas.save();
        canvas.clipRect(object_x, object_y,
                object_x + object_width, object_y + object_height);
        canvas.drawBitmap(bossPlane_crazy, object_x, object_y
                - object_height, paint);
        canvas.restore();
    }

    // 愤怒状态
    else if (isAnger) {
        canvas.save();
        canvas.clipRect(object_x, object_y,
                object_x + object_width, object_y + object_height);
        canvas.drawBitmap(boosPlane, object_x, object_y
                - object_height, paint);
        canvas.restore();

    }

    // 普通状态
    else {
        canvas.save();
        canvas.clipRect(object_x, object_y,
                object_x + object_width, object_y + object_height);
        canvas.drawBitmap(boosPlane, object_x, object_y, paint);
        canvas.restore();
    }

    logic();
    shoot(canvas); // 射击
}