手写签名
This commit is contained in:
parent
24ce192f76
commit
08288d205d
@ -4,6 +4,9 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import com.tenlionsoft.baselib.constant.Constant;
|
||||||
|
import com.tenlionsoft.baselib.utils.LogUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
@ -12,7 +15,7 @@ public abstract class BasePen {
|
|||||||
/**
|
/**
|
||||||
* 绘制计算的次数,数值越小计算的次数越多
|
* 绘制计算的次数,数值越小计算的次数越多
|
||||||
*/
|
*/
|
||||||
public static final int STEP_FACTOR = 20;
|
public static final int STEP_FACTOR = 10;
|
||||||
|
|
||||||
protected ArrayList<ControllerPoint> mHWPointList = new ArrayList<>();
|
protected ArrayList<ControllerPoint> mHWPointList = new ArrayList<>();
|
||||||
protected ControllerPoint mLastPoint = new ControllerPoint(0, 0);
|
protected ControllerPoint mLastPoint = new ControllerPoint(0, 0);
|
||||||
@ -51,7 +54,7 @@ public abstract class BasePen {
|
|||||||
// event会被下一次事件重用,这里必须生成新的,否则会有问题
|
// event会被下一次事件重用,这里必须生成新的,否则会有问题
|
||||||
int action = event.getAction() & event.getActionMasked();
|
int action = event.getAction() & event.getActionMasked();
|
||||||
MotionEvent event2 = MotionEvent.obtain(event);
|
MotionEvent event2 = MotionEvent.obtain(event);
|
||||||
|
LogUtils.e("绘制"+action);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
lastId = event2.getPointerId(0);
|
lastId = event2.getPointerId(0);
|
||||||
@ -197,6 +200,15 @@ public abstract class BasePen {
|
|||||||
mHWPointList.clear();
|
mHWPointList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDo() {
|
||||||
|
LogUtils.e(mHWPointList.size());
|
||||||
|
if(mHWPointList.size()>0){
|
||||||
|
LogUtils.e(mHWPointList.size());
|
||||||
|
mHWPointList.remove(mHWPointList.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制
|
* 绘制
|
||||||
* 当现在的点和触摸点的位置在一起的时候不用去绘制
|
* 当现在的点和触摸点的位置在一起的时候不用去绘制
|
||||||
|
@ -96,7 +96,7 @@ public class PaintView extends View {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
//通过压感值来设置画笔的粗细
|
//通过压感值来设置画笔的粗细
|
||||||
setPaintPressure(event.getPressure());
|
setPaintPressure(event.getPressure(), event.getToolType(event.getActionIndex()));
|
||||||
//获取触摸的工具
|
//获取触摸的工具
|
||||||
toolType = event.getToolType(event.getActionIndex());
|
toolType = event.getToolType(event.getActionIndex());
|
||||||
// FINGER手指 STYLUS手写笔 MOUSE鼠标
|
// FINGER手指 STYLUS手写笔 MOUSE鼠标
|
||||||
@ -133,8 +133,9 @@ public class PaintView extends View {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建Bitmap,用来保存绘制的图
|
* 构建Bitmap,用来保存绘制的图
|
||||||
* @isCrop 是否清除边界空白
|
*
|
||||||
* @return 所绘制的bitmap
|
* @return 所绘制的bitmap
|
||||||
|
* @isCrop 是否清除边界空白
|
||||||
*/
|
*/
|
||||||
public Bitmap buildAreaBitmap(boolean isCrop) {
|
public Bitmap buildAreaBitmap(boolean isCrop) {
|
||||||
Bitmap result;
|
Bitmap result;
|
||||||
@ -150,11 +151,16 @@ public class PaintView extends View {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置压力传感值
|
* 设置压力传感值
|
||||||
|
*
|
||||||
* @param pressure
|
* @param pressure
|
||||||
*/
|
*/
|
||||||
private void setPaintPressure(float pressure) {
|
private void setPaintPressure(float pressure, int type) {
|
||||||
if (mPaint != null) {
|
if (mPaint != null) {
|
||||||
mPaint.setStrokeWidth(strokeWidth*pressure);
|
if (type == 2) {
|
||||||
|
mPaint.setStrokeWidth(strokeWidth * pressure * 5);
|
||||||
|
} else {
|
||||||
|
mPaint.setStrokeWidth(strokeWidth * pressure);
|
||||||
|
}
|
||||||
mStokeBrushPen.setPaint(mPaint);
|
mStokeBrushPen.setPaint(mPaint);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
@ -162,6 +168,7 @@ public class PaintView extends View {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置画笔大小
|
* 设置画笔大小
|
||||||
|
*
|
||||||
* @param width 大小
|
* @param width 大小
|
||||||
*/
|
*/
|
||||||
public void setPaintWidth(int width) {
|
public void setPaintWidth(int width) {
|
||||||
@ -176,6 +183,7 @@ public class PaintView extends View {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置画笔颜色
|
* 设置画笔颜色
|
||||||
|
*
|
||||||
* @param color 颜色
|
* @param color 颜色
|
||||||
*/
|
*/
|
||||||
public void setPaintColor(int color) {
|
public void setPaintColor(int color) {
|
||||||
@ -200,6 +208,15 @@ public class PaintView extends View {
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDo(){
|
||||||
|
mStokeBrushPen.onDo();
|
||||||
|
if (mStepOperation != null) {
|
||||||
|
mStepOperation.reset();
|
||||||
|
mStepOperation.addBitmap(mBitmap);
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 释放
|
* 释放
|
||||||
|
@ -4,6 +4,8 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import com.tenlionsoft.baselib.utils.LogUtils;
|
||||||
|
|
||||||
public class SteelPen extends BasePen {
|
public class SteelPen extends BasePen {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -23,6 +25,7 @@ public class SteelPen extends BasePen {
|
|||||||
ControllerPoint point = mBezier.getPoint(t);
|
ControllerPoint point = mBezier.getPoint(t);
|
||||||
mHWPointList.add(point);
|
mHWPointList.add(point);
|
||||||
}
|
}
|
||||||
|
LogUtils.e("doMove==" + mHWPointList.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,459 @@
|
|||||||
|
package com.tenlionsoft.baselib.core.widget.pens;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author:Double
|
||||||
|
* Time:2019/4/22
|
||||||
|
* Description:This is DrawingStrokes
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DrawingStrokes {
|
||||||
|
private final static String TAG = DrawingStrokes.class.getSimpleName();
|
||||||
|
public Paint mPaint;
|
||||||
|
public Vector<TimePoint> myPoints = new Vector<>();
|
||||||
|
public Path strokesPath = null;
|
||||||
|
public float lastLineX;
|
||||||
|
public float lastLineY;
|
||||||
|
|
||||||
|
public float mLastX;
|
||||||
|
public float mLastY;
|
||||||
|
public float mLLastX;
|
||||||
|
public float mLLastY;
|
||||||
|
public Bitmap myBitmap;
|
||||||
|
public Canvas myCanvas;
|
||||||
|
public Vector<TimePoint> mPoint;
|
||||||
|
|
||||||
|
public TimePoint lastTop= new TimePoint();
|
||||||
|
public TimePoint lastBottom=new TimePoint();
|
||||||
|
public boolean isDown = false,isUp = false;
|
||||||
|
public float mLastK = 0;
|
||||||
|
public View strokeView;
|
||||||
|
public Strokes strokes = null;
|
||||||
|
//抬笔和操作笔划时的绘图
|
||||||
|
public Canvas canvasStroke;
|
||||||
|
public Bitmap bitmapStroke;
|
||||||
|
|
||||||
|
public boolean isUnDo = false;
|
||||||
|
public SplineCurveStrategy splineCurveStrategy;
|
||||||
|
|
||||||
|
public int state = -1;
|
||||||
|
public final static int X_ADD_Y_ADD = 0X00;
|
||||||
|
public final static int X_ADD_Y_DEC = 0X01;
|
||||||
|
public final static int X_ADD_Y_SAM = 0X02;
|
||||||
|
public final static int X_DEC_Y_ADD = 0X03;
|
||||||
|
public final static int X_DEC_Y_DEC = 0X04;
|
||||||
|
public final static int X_DEC_Y_SAM = 0X05;
|
||||||
|
public final static int X_SAM_Y_ADD = 0X06;
|
||||||
|
public final static int X_SAM_Y_DEC = 0X07;
|
||||||
|
public final static int X_SAM_Y_SAM = 0X08;
|
||||||
|
public boolean debug = false;
|
||||||
|
public float mLastWidth ;
|
||||||
|
private float width, height;
|
||||||
|
private float maxWidth;
|
||||||
|
private PenType penType;
|
||||||
|
public DrawingStrokes(View strokeView, Strokes strokes){
|
||||||
|
this.strokes = strokes;
|
||||||
|
this.strokeView = strokeView;
|
||||||
|
this.strokesPath = new Path();
|
||||||
|
mPoint = new Vector<>();
|
||||||
|
}
|
||||||
|
public void setSize(float width,float height,Paint mPaint){
|
||||||
|
if (myBitmap != null) return;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
initBitmap();
|
||||||
|
initBitmapStroke();
|
||||||
|
if(this.mPaint == null) {
|
||||||
|
this.mPaint = mPaint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void setPenType(PenType penType) {
|
||||||
|
this.penType = penType;
|
||||||
|
}
|
||||||
|
private void initBitmap(){
|
||||||
|
if(myBitmap == null){
|
||||||
|
myBitmap = Bitmap.createBitmap((int)width,(int)height, Bitmap.Config.ARGB_8888);
|
||||||
|
myCanvas = new Canvas(myBitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initBitmapStroke(){
|
||||||
|
if(bitmapStroke == null){
|
||||||
|
bitmapStroke = Bitmap.createBitmap((int)width,(int)height, Bitmap.Config.ARGB_8888);
|
||||||
|
canvasStroke = new Canvas(bitmapStroke);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float strokeWidth(float press,float widthDelta){
|
||||||
|
float width = Math.min(maxWidth , (0.1f * (1 + press * (maxWidth * 10 - 1) ))) * 0.9f + mLastWidth * 0.1f;
|
||||||
|
if(width>mLastWidth)
|
||||||
|
return Math.min(width , mLastWidth + widthDelta);
|
||||||
|
else
|
||||||
|
return Math.max(width , mLastWidth - widthDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxWidth(float maxWidth){
|
||||||
|
this.maxWidth = maxWidth;
|
||||||
|
Log.i(TAG, "maxWidth " + maxWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMaxWidth() {
|
||||||
|
return maxWidth;
|
||||||
|
}
|
||||||
|
public void addPoint(TimePoint timePoint,float pressure){
|
||||||
|
mPoint.add(timePoint);
|
||||||
|
|
||||||
|
if(mPoint.size() > 3){
|
||||||
|
SplineCurve splineCurve = new SplineCurve(mPoint.get(0),
|
||||||
|
mPoint.get(1), mPoint.get(2), mPoint.get(3));
|
||||||
|
float velocity = splineCurve.point3.velocityFrom(splineCurve.point2);
|
||||||
|
float widthDelta = 0;
|
||||||
|
float newWidth;
|
||||||
|
if (false) {
|
||||||
|
if (velocity > 3) {
|
||||||
|
splineCurve.steps = 4;
|
||||||
|
widthDelta = 0.8f;
|
||||||
|
} else if (velocity > 2) {
|
||||||
|
splineCurve.steps = 3;
|
||||||
|
widthDelta = 0.7f;
|
||||||
|
} else if (velocity > 1) {
|
||||||
|
splineCurve.steps = 3;
|
||||||
|
widthDelta = 0.6f;
|
||||||
|
} else if (velocity > 0.5) {
|
||||||
|
splineCurve.steps = 2;
|
||||||
|
widthDelta = 0.5f;
|
||||||
|
} else if (velocity > 0.2) {
|
||||||
|
splineCurve.steps = 2;
|
||||||
|
widthDelta = 0.4f;
|
||||||
|
} else if (velocity > 0.1) {
|
||||||
|
splineCurve.steps = 1;
|
||||||
|
widthDelta = 0.3f;
|
||||||
|
} else {
|
||||||
|
splineCurve.steps = 1;
|
||||||
|
widthDelta = 0.2f;
|
||||||
|
}
|
||||||
|
Log.i(TAG, "pressure: " + pressure);
|
||||||
|
if (pressure < 0.4)
|
||||||
|
newWidth = strokeWidth(pressure, 1 - pressure);
|
||||||
|
else
|
||||||
|
newWidth = strokeWidth(pressure, widthDelta);
|
||||||
|
} else {
|
||||||
|
if (velocity > 3) {
|
||||||
|
splineCurve.steps = 4;
|
||||||
|
widthDelta = 3.0f;
|
||||||
|
} else if (velocity > 2) {
|
||||||
|
splineCurve.steps = 3;
|
||||||
|
widthDelta = 2.0f;
|
||||||
|
} else if (velocity > 1) {
|
||||||
|
splineCurve.steps = 3;
|
||||||
|
widthDelta = 1.0f;
|
||||||
|
} else if (velocity > 0.5) {
|
||||||
|
splineCurve.steps = 2;
|
||||||
|
widthDelta = 0.8f;
|
||||||
|
} else if (velocity > 0.2) {
|
||||||
|
splineCurve.steps = 2;
|
||||||
|
widthDelta = 0.6f;
|
||||||
|
} else if (velocity > 0.1) {
|
||||||
|
splineCurve.steps = 1;
|
||||||
|
widthDelta = 0.3f;
|
||||||
|
} else {
|
||||||
|
splineCurve.steps = 1;
|
||||||
|
widthDelta = 0.2f;
|
||||||
|
}
|
||||||
|
newWidth = strokeWidth(pressure, widthDelta) ;
|
||||||
|
}
|
||||||
|
newWidth = Float.isNaN(newWidth) ? mLastWidth : newWidth;
|
||||||
|
Log.i(TAG, "newWidth" + newWidth);
|
||||||
|
if(strokes.getMyPathSize() >= 1) {
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize() - 1).addOriginPoint(new TimePoint(timePoint.x, timePoint.y));
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize() - 1).addOriginWidth(newWidth);
|
||||||
|
}
|
||||||
|
if(isUp){
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize() - 1).addOriginPoint(new TimePoint(timePoint.x, timePoint.y));
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize() - 1).addOriginWidth(newWidth);
|
||||||
|
}
|
||||||
|
if (splineCurveStrategy == null) {
|
||||||
|
splineCurveStrategy = new SplineCurveStrategy(splineCurve, mLastWidth, newWidth, myCanvas, mPaint);
|
||||||
|
splineCurveStrategy.initLastPoint(lastTop, lastBottom);
|
||||||
|
} else {
|
||||||
|
splineCurveStrategy.updateData(mLastWidth, newWidth, splineCurve);
|
||||||
|
}
|
||||||
|
Log.i("penType", penType.getPenType() + "");
|
||||||
|
switch (penType.getPenType()) {
|
||||||
|
case PenType.PEN:
|
||||||
|
splineCurveStrategy.drawPen(this);//钢笔
|
||||||
|
break;
|
||||||
|
case PenType.BRUSH:
|
||||||
|
splineCurveStrategy.drawBrushPen(this);//毛笔
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mPoint.remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double mult(float x1,float y1,float x2,float y2,float x3,float y3){
|
||||||
|
return (x1 - x3)*(y2 - y3) - (x2 - x3)*(y1 - y3);
|
||||||
|
}
|
||||||
|
public boolean intersect(float x1,float y1,float x2,float y2,float x3,float y3,
|
||||||
|
float x4,float y4){
|
||||||
|
if(Math.max(x1,x2)<Math.min(x3,x4)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(Math.max(y1,y2)<Math.min(y3,y4)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(Math.max(x3,x4)<Math.min(x1,x2)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(Math.max(y3,y4)<Math.min(y1,y2)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(mult(x3,y3,x2,y2,x1,y1)*mult(x2,y2,x4,y4,x1,y1)<0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(mult(x1,y1,x4,y4,x3,y3)*mult(x4,y4,x2,y2,x3,y3)<0){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public float calculateDegree(float x1,float y1,float x2,float y2,float x3,float y3){
|
||||||
|
float b = (float)Math.sqrt((x1 - x2)*( x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||||
|
float c = (float)Math.sqrt((x2 - x3)*( x2 - x3) +
|
||||||
|
(y2 - y3) * (y2 - y3));
|
||||||
|
float a = (float)Math.sqrt((x1 - x3)*( x1 - x3) +
|
||||||
|
(y1 - y3) * (y1 - y3));
|
||||||
|
if(c==0||b==0) return 0;
|
||||||
|
float sum = (b * b + c * c - a * a)/(2*b*c);
|
||||||
|
float degree =(float) Math.acos(sum) * 180 / (float)Math.PI;
|
||||||
|
Log.i(TAG, "degree : " + degree);
|
||||||
|
if(Float.isNaN(degree)) degree = 0;
|
||||||
|
return degree;
|
||||||
|
}
|
||||||
|
public Handler myHandler = new Handler(){
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
super.handleMessage(msg);
|
||||||
|
//当所有笔划都画到bitmapStroke上时
|
||||||
|
//清除myBitmap上的笔划 这步很重要
|
||||||
|
if(myCanvas!=null) {
|
||||||
|
myCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
||||||
|
myCanvas.drawBitmap(bitmapStroke, 0, 0, mPaint);
|
||||||
|
strokeView.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public void updatePathToCanvas(){
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
canvasStroke.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
||||||
|
strokes.draw(canvasStroke,mPaint);
|
||||||
|
myHandler.sendEmptyMessage(0);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moveTo(float x,float y,float pressure){
|
||||||
|
strokesPath.reset();
|
||||||
|
myPoints.clear();
|
||||||
|
mPoint.clear();
|
||||||
|
isDown = true;
|
||||||
|
isUp = false;
|
||||||
|
mLLastX = x;
|
||||||
|
mLLastY = y;
|
||||||
|
mLastX = x;
|
||||||
|
mLastY = y;
|
||||||
|
mLastWidth = Math.min(maxWidth , 0.1f * (1 + (pressure+0.2f) * (maxWidth * 10 - 1) ));
|
||||||
|
mLastK = 0;
|
||||||
|
strokes.addMyPath(strokes.getMyPathSize(), strokes.getMyPathSize() + strokes.getRecycleStrokesListSize());
|
||||||
|
addPoint(new TimePoint(x, y), pressure);
|
||||||
|
addPoint(new TimePoint(x, y), pressure);
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize()-1).addOriginPoint(new TimePoint(x, y));
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize()-1).addOriginPoint(new TimePoint(x,y));
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize()-1).addOriginWidth(mLastWidth);
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize()-1).addOriginWidth(mLastWidth);
|
||||||
|
}
|
||||||
|
public void lineTo(float x,float y,float pressure,boolean isUp){
|
||||||
|
if (isUp) {
|
||||||
|
addPoint(new TimePoint(x, y), pressure);
|
||||||
|
this.isUp = true;
|
||||||
|
addPoint(new TimePoint(x, y), pressure);
|
||||||
|
for(int i = myPoints.size() - 1;i>=0;i--){
|
||||||
|
strokesPath.lineTo(myPoints.elementAt(i).getX(),myPoints.elementAt(i).getY());
|
||||||
|
strokes.getMyPathList().get(strokes.getMyPathSize()-1).addPoint(new TimePoint(myPoints.elementAt(i).getX(),myPoints.elementAt(i).getY()));
|
||||||
|
}
|
||||||
|
myPoints.clear();
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getMyPathSize()-1).setStroke(strokesPath);
|
||||||
|
setUnDo(false);
|
||||||
|
Log.i(TAG, "拟合前的点数量" + strokes.getMyPathList().elementAt(strokes.getMyPathSize() - 1).getOriginPoints().size());
|
||||||
|
Log.i(TAG,"拟合后的点数量" + strokes.getMyPathList().elementAt(strokes.getMyPathSize() - 1).getPoints().size());
|
||||||
|
} else {
|
||||||
|
addPoint(new TimePoint(x, y), pressure);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas,Paint mPaint) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
canvas.drawBitmap(myBitmap, 0, 0, mPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
//撤销
|
||||||
|
public void unDo(){
|
||||||
|
Log.i(TAG, "unDo");
|
||||||
|
setUnDo(true);
|
||||||
|
//首先判断两个vector中笔划的优先级
|
||||||
|
int recycleVectorPriority = -1;
|
||||||
|
int myVectorPriority = -1;
|
||||||
|
int myPicturePriority = -1;
|
||||||
|
int recyclePicturePriority = -1;
|
||||||
|
if(strokes.getMyPathSize() > 0){
|
||||||
|
myVectorPriority = strokes.getMyPathList().elementAt(strokes.getMyPathSize()-1).getPriority();
|
||||||
|
}
|
||||||
|
if(strokes.getRecycleStrokesListSize() > 0){
|
||||||
|
recycleVectorPriority = strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).getPriority();
|
||||||
|
}
|
||||||
|
//说明有可以撤销的笔划
|
||||||
|
if(recycleVectorPriority != -1 || myVectorPriority != -1||myPicturePriority!=-1||recyclePicturePriority!=-1){
|
||||||
|
if(myVectorPriority >= recycleVectorPriority && myVectorPriority >= myPicturePriority &&myVectorPriority>=recyclePicturePriority){
|
||||||
|
//将笔划压入撤销栈
|
||||||
|
strokes.addUnDoStrokes(strokes.getMyPathList().elementAt(strokes.getMyPathSize()-1));
|
||||||
|
//移除myPath最后一个
|
||||||
|
strokes.deleteMyPath(strokes.getMyPathSize()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(recycleVectorPriority>=myPicturePriority&&recycleVectorPriority>=myVectorPriority&&recycleVectorPriority>=recyclePicturePriority){//可能一次会撤销很多笔划 因为当初可能一次删除多个笔划 所以要循环
|
||||||
|
int priority = -1;
|
||||||
|
do {
|
||||||
|
//降低回收栈中笔划的优先级
|
||||||
|
strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).setPriority(
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).getLocation()).getPriority());
|
||||||
|
//设置撤销栈中笔划的优先级继承回收站的 方便恢复多个笔划
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).getLocation()).setPriority(
|
||||||
|
recycleVectorPriority);
|
||||||
|
//将myPath对应位置的笔划压入撤销栈
|
||||||
|
Log.i(TAG,strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).getLocation()+" ");
|
||||||
|
strokes.addUnDoStrokes(strokes.getMyPathList().elementAt(strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).getLocation()));
|
||||||
|
//移除myPath对应位置的笔划
|
||||||
|
strokes.deleteMyPath(strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).getLocation());
|
||||||
|
strokes.getMyPathList().add(strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).getLocation(),
|
||||||
|
strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1));
|
||||||
|
strokes.deleteRecycleStrokesList(strokes.getRecycleStrokesListSize() - 1);
|
||||||
|
//继续判断下一个笔划的优先级
|
||||||
|
priority = -1;
|
||||||
|
if(strokes.getRecycleStrokesListSize() > 0)
|
||||||
|
priority = strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).getPriority();
|
||||||
|
}while(priority == recycleVectorPriority);
|
||||||
|
}
|
||||||
|
updatePathToCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void reDo(){
|
||||||
|
Log.i(TAG, "reDo");
|
||||||
|
//对三个栈都做清空
|
||||||
|
if(isUnDo) setUnDo(false);
|
||||||
|
strokes.getMyPathList().clear();
|
||||||
|
strokes.getRecycleStrokesList().clear();
|
||||||
|
updatePathToCanvas();
|
||||||
|
}
|
||||||
|
public void clear(){
|
||||||
|
//对三个栈都做清空
|
||||||
|
if(isUnDo) setUnDo(false);
|
||||||
|
strokes.getMyPathList().clear();
|
||||||
|
strokes.getRecycleStrokesList().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recover(){
|
||||||
|
//上一步必须是撤销
|
||||||
|
if(isUnDo){
|
||||||
|
Log.i(TAG, "recover");
|
||||||
|
int strokePriority = -1;
|
||||||
|
int strokeSize = strokes.getUnDoStrokesList().size();
|
||||||
|
if(strokeSize>0)
|
||||||
|
strokePriority = strokes.getUnDoStrokesList().elementAt(strokeSize - 1).getPriority();
|
||||||
|
int picturePriority = -1;
|
||||||
|
Log.i(TAG,strokePriority+" "+picturePriority);
|
||||||
|
if(strokePriority!=-1||picturePriority!=-1) {
|
||||||
|
int addPriority = strokes.getMyPathSize() + strokes.getRecycleStrokesListSize();
|
||||||
|
if ((picturePriority!=-1&&strokePriority <= picturePriority && strokePriority!=-1)||
|
||||||
|
(picturePriority==-1&&strokePriority!=-1)) {
|
||||||
|
//可能是恢复多个
|
||||||
|
int priority = -1;
|
||||||
|
int finalPriority = strokePriority;
|
||||||
|
do {
|
||||||
|
//恢复的位置是插入
|
||||||
|
if (strokes.getUnDoStrokesList().elementAt(strokeSize - 1).getLocation() < strokes.getMyPathSize()) {
|
||||||
|
//降低撤销栈中笔划的优先级
|
||||||
|
strokes.getUnDoStrokesList().elementAt(strokeSize - 1).setPriority(
|
||||||
|
strokes.getMyPathList().elementAt(strokes.getUnDoStrokesList().elementAt(strokeSize - 1).getLocation()).getPriority()
|
||||||
|
);
|
||||||
|
//将myPath对应位置上的压入回收栈
|
||||||
|
strokes.getRecycleStrokesList().add(strokes.getMyPathList().elementAt(strokes.getUnDoStrokesList().elementAt(strokeSize - 1).getLocation()));
|
||||||
|
//增加优先级
|
||||||
|
strokes.getRecycleStrokesList().elementAt(strokes.getRecycleStrokesListSize() - 1).setPriority(addPriority);
|
||||||
|
//删除myPath对应的笔划
|
||||||
|
strokes.deleteMyPath(strokes.getUnDoStrokesList().elementAt(strokeSize - 1).getLocation());
|
||||||
|
}
|
||||||
|
//将撤销栈中最后一个压入myPath对应的位置上
|
||||||
|
strokes.getMyPathList().add(strokes.getUnDoStrokesList().elementAt(strokeSize - 1).getLocation(),
|
||||||
|
strokes.getUnDoStrokesList().elementAt(strokeSize - 1));
|
||||||
|
//删除撤销栈最后一个
|
||||||
|
strokes.deleteUnDoStrokesList(strokeSize - 1);
|
||||||
|
//继续判断下一个笔划的优先级
|
||||||
|
priority = -1;
|
||||||
|
strokeSize = strokes.getUnDoStrokesList().size();
|
||||||
|
if (strokeSize > 0)
|
||||||
|
priority = strokes.getUnDoStrokesList().elementAt(strokeSize - 1).getPriority();
|
||||||
|
} while (priority == finalPriority);
|
||||||
|
updatePathToCanvas();
|
||||||
|
}
|
||||||
|
if ((strokePriority!=-1&&strokePriority >= picturePriority&&picturePriority!=-1)||
|
||||||
|
(strokePriority==-1&&picturePriority!=-1)) {
|
||||||
|
//可能是恢复多个
|
||||||
|
int priority = -1;
|
||||||
|
int finalPriority = picturePriority;
|
||||||
|
updatePathToCanvas();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUnDo() {
|
||||||
|
return isUnDo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnDo(boolean unDo) {
|
||||||
|
isUnDo = unDo;
|
||||||
|
if(!unDo){
|
||||||
|
strokes.clearUnDoStrokesList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void onDestroy(){
|
||||||
|
if(myBitmap!=null&&!myBitmap.isRecycled()){
|
||||||
|
myCanvas = null;
|
||||||
|
myBitmap.recycle();
|
||||||
|
myBitmap = null;
|
||||||
|
}
|
||||||
|
if(bitmapStroke != null && !bitmapStroke.isRecycled()){
|
||||||
|
canvasStroke = null;
|
||||||
|
bitmapStroke.recycle();
|
||||||
|
bitmapStroke = null;
|
||||||
|
}
|
||||||
|
setUnDo(false);
|
||||||
|
clear();
|
||||||
|
myPoints.clear();
|
||||||
|
}
|
||||||
|
}
|
19
baselib/src/main/java/com/tenlionsoft/baselib/core/widget/pens/PenType.java
Executable file
19
baselib/src/main/java/com/tenlionsoft/baselib/core/widget/pens/PenType.java
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
package com.tenlionsoft.baselib.core.widget.pens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by BJ-00314 on 2019/5/20.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PenType {
|
||||||
|
/**笔的类型*/
|
||||||
|
public static final int PEN = 0x00;
|
||||||
|
public static final int BRUSH = 0x01;
|
||||||
|
/**记录当前笔类型 默认刚开始都是钢笔*/
|
||||||
|
private int penType = PEN;
|
||||||
|
public void setPenType(int penType) {
|
||||||
|
this.penType = penType;
|
||||||
|
}
|
||||||
|
public int getPenType() {
|
||||||
|
return penType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.tenlionsoft.baselib.core.widget.pens;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author:Double
|
||||||
|
* Time:2019/4/22
|
||||||
|
* Description:This is SplineCurve
|
||||||
|
*/
|
||||||
|
public class SplineCurve {
|
||||||
|
public TimePoint point1;
|
||||||
|
public TimePoint point2;//起点
|
||||||
|
public TimePoint point3;//结束点
|
||||||
|
public TimePoint point4;
|
||||||
|
public int steps = 10;//设定在曲线上取的点数
|
||||||
|
|
||||||
|
public SplineCurve(TimePoint point1, TimePoint point2,
|
||||||
|
TimePoint point3, TimePoint point4){
|
||||||
|
this.point1 = point1;
|
||||||
|
this.point2 = point2;
|
||||||
|
this.point3 = point3;
|
||||||
|
this.point4 = point4;
|
||||||
|
}
|
||||||
|
//获得贝塞尔曲线中取得的10个点的相邻点距离和
|
||||||
|
public float length(){
|
||||||
|
int length = 0;
|
||||||
|
float perStep;
|
||||||
|
double cx, cy, px = 0, py = 0, xdiff, ydiff;
|
||||||
|
for(int i = 0;i <= steps; i++){
|
||||||
|
perStep = (float)i / steps;
|
||||||
|
cx = point(perStep, this.point1.x, this.point2.x, this.point3.x,
|
||||||
|
this.point4.x);
|
||||||
|
cy = point(perStep, this.point1.y, this.point2.y, this.point3.y,
|
||||||
|
this.point4.y);
|
||||||
|
if(i > 0){//计算与上一个点的距离
|
||||||
|
xdiff = cx - px;
|
||||||
|
ydiff = cy - py;
|
||||||
|
length += Math.sqrt(xdiff * xdiff + ydiff * ydiff);
|
||||||
|
}
|
||||||
|
px = cx;
|
||||||
|
py = cy;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
//通过贝塞尔算法返回每个点的x或者y值
|
||||||
|
public double point(float perStep, float point1, float point2, float point3, float point4){
|
||||||
|
return point1 * (1.0 - perStep) * (1.0 - perStep) * (1.0 - perStep) / 6.0
|
||||||
|
+ point2 * (3 * perStep * perStep * perStep - 6 * perStep * perStep + 4) / 6.0
|
||||||
|
+ point3 * (-3 * perStep * perStep * perStep + 3 * perStep * perStep + 3 * perStep + 1)/6.0
|
||||||
|
+point4 * perStep * perStep * perStep / 6.0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,686 @@
|
|||||||
|
package com.tenlionsoft.baselib.core.widget.pens;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.DashPathEffect;
|
||||||
|
import android.graphics.LinearGradient;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.Shader;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author:Double
|
||||||
|
* Time:2019/4/22
|
||||||
|
* Description:This is SplineCurveStrategy
|
||||||
|
*/
|
||||||
|
public class SplineCurveStrategy {
|
||||||
|
public int curveIndex = 2;
|
||||||
|
public float startWidth;
|
||||||
|
public float endWidth;
|
||||||
|
public SplineCurve splineCurve;
|
||||||
|
public Paint blurryPaint;
|
||||||
|
public Paint mMosaicPaint;
|
||||||
|
public Paint eraserPaint;
|
||||||
|
public final int eraserWidth = 50;
|
||||||
|
protected Canvas canvas;
|
||||||
|
protected Paint mPaint;
|
||||||
|
public TimePoint lastTop,lastBottom;
|
||||||
|
protected Path mPath;
|
||||||
|
public SplineCurveStrategy(SplineCurve splineCurve, float startWidth, float endWidth, Canvas canvas, Paint mPaint){
|
||||||
|
this.splineCurve = splineCurve;
|
||||||
|
this.startWidth = startWidth;
|
||||||
|
this.endWidth = endWidth;
|
||||||
|
this.blurryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
this.mMosaicPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
this.eraserPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
this.eraserPaint.setColor(Color.WHITE);
|
||||||
|
this.eraserPaint.setStrokeWidth(eraserWidth);
|
||||||
|
this.eraserPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
this.eraserPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
mMosaicPaint.setAlpha(80);
|
||||||
|
mMosaicPaint.setStrokeCap(Paint.Cap.BUTT);
|
||||||
|
mMosaicPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
//mMosaicPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mMosaicPaint.setStrokeWidth(12f);
|
||||||
|
this.canvas = canvas;
|
||||||
|
this.mPaint = mPaint;
|
||||||
|
this.mPath = new Path();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateData(float startWidth,float endWidth, SplineCurve splineCurve){
|
||||||
|
this.splineCurve = splineCurve;
|
||||||
|
this.startWidth = startWidth;
|
||||||
|
this.endWidth = endWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double mult(float x1,float y1,float x2,float y2,float x3,float y3){
|
||||||
|
return (x1 - x3)*(y2 - y3) - (x2 - x3)*(y1 - y3);
|
||||||
|
}
|
||||||
|
public void initLastPoint(TimePoint lastTop,TimePoint lastBottom){
|
||||||
|
this.lastTop = lastTop;
|
||||||
|
this.lastBottom = lastBottom;
|
||||||
|
}
|
||||||
|
public void drawPen(DrawingStrokes drawingStrokes) {
|
||||||
|
if(drawingStrokes.debug)
|
||||||
|
mPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
else mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mPaint.setColor(Color.BLACK);
|
||||||
|
//获得笔在两点间不同宽度的差值
|
||||||
|
int drawSteps = (int)Math.floor(splineCurve.length());
|
||||||
|
if(drawingStrokes.isUp) {
|
||||||
|
//curveIndex = 1;
|
||||||
|
if(drawSteps > 2)
|
||||||
|
curveIndex = (drawSteps - 2)/2;
|
||||||
|
else curveIndex = 1;
|
||||||
|
if(curveIndex < 1) curveIndex = 1;
|
||||||
|
if(drawSteps == 0) drawSteps = 2;
|
||||||
|
}else if(drawingStrokes.isDown){
|
||||||
|
curveIndex = 1;
|
||||||
|
if(drawSteps == 0) drawSteps = 2;
|
||||||
|
}else{
|
||||||
|
if(drawSteps > 100) curveIndex = 40;
|
||||||
|
else if(drawSteps > 80) curveIndex = 35;
|
||||||
|
else if(drawSteps > 70) curveIndex = 30;
|
||||||
|
else if(drawSteps > 60) curveIndex = 25;
|
||||||
|
else if(drawSteps > 50) curveIndex = 20;
|
||||||
|
else if(drawSteps > 40) curveIndex = 15;
|
||||||
|
else if(drawSteps > 30) curveIndex = 13;
|
||||||
|
else if(drawSteps > 20) curveIndex = 9;
|
||||||
|
else if(drawSteps > 10) curveIndex = 7;
|
||||||
|
else if(drawSteps >= 4) curveIndex = 3;
|
||||||
|
else curveIndex = 1;
|
||||||
|
}
|
||||||
|
float widthDelta = endWidth - startWidth;
|
||||||
|
//两点间实际轨迹距离
|
||||||
|
float k = 0;
|
||||||
|
TimePoint myPointC,myPointD,myPointA,myPointB;
|
||||||
|
//危险
|
||||||
|
boolean modify = false;
|
||||||
|
if(drawSteps==0) {
|
||||||
|
drawSteps = 1;
|
||||||
|
modify = true;
|
||||||
|
}
|
||||||
|
Log.i("w_pen",drawSteps+" "+curveIndex);
|
||||||
|
// curveIndex = drawSteps/2;
|
||||||
|
// if(curveIndex==0) curveIndex=1;
|
||||||
|
for(int i = 0,num = 1; i < drawSteps; i+=curveIndex,num++){
|
||||||
|
mPath.reset();
|
||||||
|
float t = (float)(i) / drawSteps;
|
||||||
|
float tt = t * t;
|
||||||
|
float ttt = tt * t;
|
||||||
|
float u = 1 - t;
|
||||||
|
float uu = u * u;
|
||||||
|
float uuu = uu * u;
|
||||||
|
float x = uuu * splineCurve.point1.x / 6.0f;
|
||||||
|
x += (3*ttt-6*tt+4) * splineCurve.point2.x/ 6.0f;
|
||||||
|
x += (-3*ttt+3*tt+3*t+1)* splineCurve.point3.x/ 6.0f;
|
||||||
|
x += ttt * splineCurve.point4.x/ 6.0f;
|
||||||
|
float y = uuu * splineCurve.point1.y/ 6.0f;
|
||||||
|
y += (3*ttt-6*tt+4) * splineCurve.point2.y/ 6.0f;
|
||||||
|
y += (-3*ttt+3*tt+3*t+1) * splineCurve.point3.y/ 6.0f;
|
||||||
|
y += ttt * splineCurve.point4.y/ 6.0f;
|
||||||
|
float currentWidth = startWidth + t * widthDelta ;
|
||||||
|
if(!drawingStrokes.isUp)
|
||||||
|
if(Math.abs(t*widthDelta)>0.2f*num) {
|
||||||
|
if(t*widthDelta>0)
|
||||||
|
currentWidth = startWidth + 0.2f*num;
|
||||||
|
else currentWidth = startWidth - 0.2f*num;
|
||||||
|
}
|
||||||
|
int currentState = 0;
|
||||||
|
float numX = x - drawingStrokes.mLastX;
|
||||||
|
float numY = y - drawingStrokes.mLastY;
|
||||||
|
if(numX > 0 && numY >0) currentState = drawingStrokes.X_ADD_Y_ADD;
|
||||||
|
if(numX > 0 && numY < 0) currentState = drawingStrokes.X_ADD_Y_DEC;
|
||||||
|
if(numX > 0 && numY == 0) currentState = drawingStrokes.X_ADD_Y_SAM;
|
||||||
|
if(numX < 0 && numY > 0) currentState = drawingStrokes.X_DEC_Y_ADD;
|
||||||
|
if(numX < 0 && numY <0) currentState = drawingStrokes.X_DEC_Y_DEC;
|
||||||
|
if(numX < 0 && numY == 0) currentState = drawingStrokes.X_DEC_Y_SAM;
|
||||||
|
if(numX == 0 && numY > 0) currentState = drawingStrokes.X_SAM_Y_ADD;
|
||||||
|
if(numX == 0 && numY < 0) currentState = drawingStrokes.X_SAM_Y_DEC;
|
||||||
|
if(numX == 0 && numY == 0) currentState = drawingStrokes.X_SAM_Y_SAM;
|
||||||
|
// if(drawingStrokes.state!=currentState&&modify&&!drawingStrokes.isUp&&!drawingStrokes.isDown){//保证转弯处不恶意修改值
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
if( x != drawingStrokes.mLastX){
|
||||||
|
k = (y - drawingStrokes.mLastY) / (x - drawingStrokes.mLastX);
|
||||||
|
//上个点的上下端点MyPointA,MyPointB
|
||||||
|
myPointA = new TimePoint( (drawingStrokes.mLastWidth / 2 )* (-k) / (float) Math.sqrt(k * k + 1) + drawingStrokes.mLastX,
|
||||||
|
(drawingStrokes.mLastWidth / 2 ) / (float) Math.sqrt(k * k + 1) + drawingStrokes.mLastY);
|
||||||
|
myPointB = new TimePoint( (-drawingStrokes.mLastWidth / 2 )* (-k) / (float) Math.sqrt(k * k + 1) + drawingStrokes.mLastX,
|
||||||
|
(-drawingStrokes.mLastWidth / 2 ) / (float) Math.sqrt(k * k + 1) + drawingStrokes.mLastY);
|
||||||
|
//当前点的上下端点MyPointC,MyPointD
|
||||||
|
myPointC = new TimePoint( (currentWidth / 2 )* (-k) / (float) Math.sqrt(k * k + 1) + x,
|
||||||
|
(currentWidth / 2 ) / (float) Math.sqrt(k * k + 1) + y);
|
||||||
|
myPointD = new TimePoint( (-currentWidth / 2 )* (-k) / (float) Math.sqrt(k * k + 1) + x,
|
||||||
|
(-currentWidth / 2 ) / (float) Math.sqrt(k * k + 1) + y);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
myPointA = new TimePoint( drawingStrokes.mLastWidth / 2 + drawingStrokes.mLastX,
|
||||||
|
drawingStrokes.mLastY);
|
||||||
|
myPointB = new TimePoint( -drawingStrokes.mLastWidth / 2 + drawingStrokes.mLastX,
|
||||||
|
drawingStrokes.mLastY);
|
||||||
|
myPointC = new TimePoint( currentWidth / 2 + x,
|
||||||
|
y);
|
||||||
|
myPointD = new TimePoint( -currentWidth / 2 + x,
|
||||||
|
y);
|
||||||
|
}
|
||||||
|
if(drawingStrokes.isDown){//起点 需要算AB
|
||||||
|
//算出矩形的四个点
|
||||||
|
TimePoint A,B,C,D;
|
||||||
|
if( myPointA.x != myPointB.x){
|
||||||
|
k = (myPointA.y - myPointB.y) / (myPointA.x - myPointB.x);
|
||||||
|
A = new TimePoint( (drawingStrokes.mLastWidth )* (-k) / (float) Math.sqrt(k * k + 1) + myPointA.x,
|
||||||
|
(drawingStrokes.mLastWidth ) / (float) Math.sqrt(k * k + 1) + myPointA.y);
|
||||||
|
B = new TimePoint( (-drawingStrokes.mLastWidth )* (-k) / (float) Math.sqrt(k * k + 1) + myPointA.x,
|
||||||
|
(-drawingStrokes.mLastWidth ) / (float) Math.sqrt(k * k + 1) + myPointA.y);
|
||||||
|
//当前点的上下端点MyPointC,MyPointD
|
||||||
|
C = new TimePoint( (drawingStrokes.mLastWidth )* (-k) / (float) Math.sqrt(k * k + 1) + myPointB.x,
|
||||||
|
(drawingStrokes.mLastWidth ) / (float) Math.sqrt(k * k + 1) + myPointB.y);
|
||||||
|
D = new TimePoint( (-drawingStrokes.mLastWidth )* (-k) / (float) Math.sqrt(k * k + 1) + myPointB.x,
|
||||||
|
(-drawingStrokes.mLastWidth ) / (float) Math.sqrt(k * k + 1) + myPointB.y);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
A = new TimePoint( drawingStrokes.mLastWidth + myPointA.x,
|
||||||
|
myPointA.y);
|
||||||
|
B = new TimePoint( -drawingStrokes.mLastWidth + myPointA.x,
|
||||||
|
myPointA.y);
|
||||||
|
C = new TimePoint( drawingStrokes.mLastWidth + myPointB.x,
|
||||||
|
myPointB.y);
|
||||||
|
D = new TimePoint( -drawingStrokes.mLastWidth / 2 + myPointB.x,
|
||||||
|
myPointB.y);
|
||||||
|
}
|
||||||
|
TimePoint centerAC = new TimePoint((A.x+C.x)/2,(A.y+C.y)/2);
|
||||||
|
TimePoint centerBD = new TimePoint((B.x+D.x)/2,(B.y+D.y)/2);
|
||||||
|
boolean isAC = true;
|
||||||
|
if( myPointA.x != myPointB.x){
|
||||||
|
float b = myPointA.y - k *myPointA.x;
|
||||||
|
if((centerAC.y - k* centerAC.x - b)*(drawingStrokes.mPoint.get(3).y - k*drawingStrokes.mPoint.get(3).x - b)<=0){
|
||||||
|
isAC = true;
|
||||||
|
}else {
|
||||||
|
isAC = false;
|
||||||
|
}
|
||||||
|
// if ((drawingStrokes.mLastY - centerAC.y) / (drawingStrokes.mLastX - centerAC.x) * k >0) {
|
||||||
|
// isAC = true;
|
||||||
|
// } else {
|
||||||
|
// isAC = false;
|
||||||
|
// }
|
||||||
|
}else{
|
||||||
|
if((centerAC.y-myPointA.y)*(drawingStrokes.mPoint.get(3).y - myPointA.y)<=0){
|
||||||
|
isAC = true;
|
||||||
|
}else {
|
||||||
|
isAC = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!drawingStrokes.debug) {
|
||||||
|
//填充
|
||||||
|
// mPath.moveTo(myPointB.x, myPointB.y);
|
||||||
|
// mPath.lineTo(myPointD.x, myPointD.y);
|
||||||
|
//// //**mPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
// mPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
// mPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.moveTo(myPointB.x, myPointB.y);
|
||||||
|
if(isAC)
|
||||||
|
mPath.quadTo(centerAC.x,centerAC.y,myPointA.x,myPointA.y);
|
||||||
|
else mPath.quadTo(centerBD.x,centerBD.y,myPointA.x,myPointA.y);
|
||||||
|
mPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
mPath.lineTo(myPointD.x, myPointD.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
canvas.drawPath(mPath,mPaint);
|
||||||
|
mPath.reset();
|
||||||
|
}else {
|
||||||
|
//测试
|
||||||
|
// mPath.moveTo(myPointB.x, myPointB.y);
|
||||||
|
// mPath.lineTo(myPointD.x, myPointD.y);
|
||||||
|
// //**mPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
// mPath.moveTo(myPointC.x, myPointC.y);
|
||||||
|
// mPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
|
||||||
|
mPath.moveTo(myPointB.x, myPointB.y);
|
||||||
|
if(isAC)
|
||||||
|
mPath.quadTo(centerAC.x,centerAC.y,myPointA.x,myPointA.y);
|
||||||
|
else mPath.quadTo(centerBD.x,centerBD.y,myPointA.x,myPointA.y);
|
||||||
|
mPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
mPath.moveTo(myPointB.x, myPointB.y);
|
||||||
|
mPath.lineTo(myPointD.x, myPointD.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawingStrokes.isDown = false;
|
||||||
|
|
||||||
|
drawingStrokes.strokesPath.moveTo(myPointB.x, myPointB.y);
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointB.x,myPointB.y));
|
||||||
|
if(isAC) {
|
||||||
|
drawingStrokes.strokesPath.quadTo(centerAC.x, centerAC.y, myPointA.x, myPointA.y);
|
||||||
|
drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new TimePoint(centerAC.x, centerAC.y));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
drawingStrokes.strokesPath.quadTo(centerBD.x, centerBD.y, myPointA.x, myPointA.y);
|
||||||
|
drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new TimePoint(centerBD.x, centerBD.y));
|
||||||
|
}
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointA.x, myPointA.y));
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointC.x, myPointC.y));
|
||||||
|
drawingStrokes.lastLineX = myPointC.x;
|
||||||
|
drawingStrokes.lastLineY = myPointC.y;
|
||||||
|
//drawingStrokes.myPoints.add(new MyPoints(myPointA.x,myPointA.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointB.x,myPointB.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointD.x,myPointD.y));
|
||||||
|
|
||||||
|
}else{
|
||||||
|
//相交为180
|
||||||
|
if((drawingStrokes.mLLastX == drawingStrokes.mLastX &&drawingStrokes.mLastX == x)
|
||||||
|
||(drawingStrokes.mLLastX != drawingStrokes.mLastX &&drawingStrokes.mLastX != x && (k == drawingStrokes.mLastK || -k == drawingStrokes.mLastK))){
|
||||||
|
if (-k == drawingStrokes.mLastK&&k!=0) {//特殊情况
|
||||||
|
Log.d("123","特殊来了"+k);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//判断外端点画弧
|
||||||
|
float degereeA = drawingStrokes.calculateDegree(drawingStrokes.mLastX,drawingStrokes.mLastY,
|
||||||
|
drawingStrokes.mLLastX, drawingStrokes.mLLastY, myPointA.x,myPointA.y);
|
||||||
|
float degereeB = drawingStrokes.calculateDegree(drawingStrokes.mLastX,drawingStrokes.mLastY,
|
||||||
|
drawingStrokes.mLLastX, drawingStrokes.mLLastY, myPointB.x,myPointB.y);
|
||||||
|
float degereeLT = drawingStrokes.calculateDegree(drawingStrokes.mLastX,drawingStrokes.mLastY,
|
||||||
|
x, y, lastTop.x,lastTop.y);
|
||||||
|
float degereeLB = drawingStrokes.calculateDegree(drawingStrokes.mLastX,drawingStrokes.mLastY,
|
||||||
|
x, y, lastBottom.x,lastBottom.y);
|
||||||
|
//谁大谁是外端点
|
||||||
|
if ((degereeA >= degereeB&°ereeLT >= degereeLB)||(degereeA <= degereeB&°ereeLT <= degereeLB)) {
|
||||||
|
if(!drawingStrokes.debug) {
|
||||||
|
//填充
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(lastTop.x, lastTop.y);
|
||||||
|
mPath.lineTo(lastBottom.x, lastBottom.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
mPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
canvas.drawPath(mPath,mPaint);
|
||||||
|
mPath.reset();
|
||||||
|
}else {
|
||||||
|
//测试
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(lastTop.x, lastTop.y);
|
||||||
|
mPath.moveTo(lastBottom.x, lastBottom.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
}
|
||||||
|
if(drawingStrokes.lastLineX == lastTop.x && drawingStrokes.lastLineY == lastTop.y){
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointA.x, myPointA.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointB.x,myPointB.y));
|
||||||
|
drawingStrokes.lastLineX = myPointA.x;
|
||||||
|
drawingStrokes.lastLineY = myPointA.y;
|
||||||
|
}else{
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointB.x, myPointB.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointA.x,myPointA.y));
|
||||||
|
drawingStrokes.lastLineX = myPointB.x;
|
||||||
|
drawingStrokes.lastLineY = myPointB.y;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//测试
|
||||||
|
if (drawingStrokes.intersect(myPointA.x, myPointA.y, lastBottom.x, lastBottom.y, x, y, drawingStrokes.mLastX, drawingStrokes.mLastY)
|
||||||
|
|| drawingStrokes.intersect(myPointA.x, myPointA.y, lastBottom.x, lastBottom.y, drawingStrokes.mLLastX, drawingStrokes.mLLastY,
|
||||||
|
drawingStrokes.mLastX, drawingStrokes.mLastY)) {
|
||||||
|
//转弯了
|
||||||
|
if(drawingStrokes.state!=-1&&drawingStrokes.state != currentState) {
|
||||||
|
if(!drawingStrokes.debug) {
|
||||||
|
//填充
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(lastBottom.x, lastBottom.y);
|
||||||
|
mPath.lineTo(lastTop.x, lastTop.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
mPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
canvas.drawPath(mPath,mPaint);
|
||||||
|
mPath.reset();
|
||||||
|
}else {
|
||||||
|
//测试
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(lastBottom.x, lastBottom.y);
|
||||||
|
mPath.moveTo(lastTop.x, lastTop.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
}
|
||||||
|
if(drawingStrokes.lastLineX == lastBottom.x && drawingStrokes.lastLineY == lastBottom.y){
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointA.x, myPointA.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointB.x,myPointB.y));
|
||||||
|
drawingStrokes.lastLineX = myPointA.x;
|
||||||
|
drawingStrokes.lastLineY = myPointA.y;
|
||||||
|
}else{
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointB.x, myPointB.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointA.x,myPointA.y));
|
||||||
|
drawingStrokes.lastLineX = myPointB.x;
|
||||||
|
drawingStrokes.lastLineY = myPointB.y;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(!drawingStrokes.debug) {
|
||||||
|
//填充
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(lastTop.x, lastTop.y);
|
||||||
|
mPath.lineTo(lastBottom.x, lastBottom.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
mPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
canvas.drawPath(mPath,mPaint);
|
||||||
|
mPath.reset();
|
||||||
|
}else {
|
||||||
|
//测试
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(lastTop.x, lastTop.y);
|
||||||
|
mPath.moveTo(lastBottom.x, lastBottom.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
}
|
||||||
|
if(drawingStrokes.lastLineX == lastTop.x && drawingStrokes.lastLineY == lastTop.y){
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointA.x, myPointA.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointB.x,myPointB.y));
|
||||||
|
drawingStrokes.lastLineX = myPointA.x;
|
||||||
|
drawingStrokes.lastLineY = myPointA.y;
|
||||||
|
}else{
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointB.x, myPointB.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointA.x,myPointA.y));
|
||||||
|
drawingStrokes.lastLineX = myPointB.x;
|
||||||
|
drawingStrokes.lastLineY = myPointB.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(!drawingStrokes.debug) {
|
||||||
|
//填充
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(lastBottom.x, lastBottom.y);
|
||||||
|
mPath.lineTo(lastTop.x, lastTop.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
mPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
canvas.drawPath(mPath,mPaint);
|
||||||
|
mPath.reset();
|
||||||
|
}else {
|
||||||
|
//测试
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(lastBottom.x, lastBottom.y);
|
||||||
|
mPath.moveTo(lastTop.x, lastTop.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
}
|
||||||
|
if(drawingStrokes.lastLineX == lastBottom.x && drawingStrokes.lastLineY == lastBottom.y){
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointA.x, myPointA.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointB.x,myPointB.y));
|
||||||
|
drawingStrokes.lastLineX = myPointA.x;
|
||||||
|
drawingStrokes.lastLineY = myPointA.y;
|
||||||
|
}else{
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointB.x, myPointB.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointA.x,myPointA.y));
|
||||||
|
drawingStrokes.lastLineX = myPointB.x;
|
||||||
|
drawingStrokes.lastLineY = myPointB.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!drawingStrokes.debug) {
|
||||||
|
//填充
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
mPath.lineTo(myPointD.x, myPointD.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
mPath.lineTo(myPointA.x, myPointA.y);
|
||||||
|
canvas.drawPath(mPath,mPaint);
|
||||||
|
mPath.reset();
|
||||||
|
}else {
|
||||||
|
//测试
|
||||||
|
mPath.moveTo(myPointA.x, myPointA.y);
|
||||||
|
mPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
mPath.moveTo(myPointD.x, myPointD.y);
|
||||||
|
mPath.lineTo(myPointB.x, myPointB.y);
|
||||||
|
}
|
||||||
|
if(drawingStrokes.lastLineX == myPointA.x && drawingStrokes.lastLineY == myPointA.y){
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointC.x, myPointC.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointD.x,myPointD.y));
|
||||||
|
drawingStrokes.lastLineX = myPointC.x;
|
||||||
|
drawingStrokes.lastLineY = myPointC.y;
|
||||||
|
}else{
|
||||||
|
drawingStrokes.strokesPath.lineTo(myPointD.x, myPointD.y);
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointD.x, myPointD.y));
|
||||||
|
drawingStrokes.myPoints.add(new TimePoint(myPointC.x,myPointC.y));
|
||||||
|
drawingStrokes.lastLineX = myPointD.x;
|
||||||
|
drawingStrokes.lastLineY = myPointD.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(drawingStrokes.isUp && i >= drawSteps -curveIndex ){
|
||||||
|
// mPath.moveTo(myPointC.x, myPointC.y);
|
||||||
|
// //控制点+结束点
|
||||||
|
// mPath.lineTo(myPointD.x,myPointD.y);
|
||||||
|
drawingStrokes.isUp = false;
|
||||||
|
TimePoint A,B,C,D;
|
||||||
|
if( myPointC.x != myPointD.x){
|
||||||
|
k = (myPointC.y - myPointD.y) / (myPointC.x - myPointD.x);
|
||||||
|
A = new TimePoint( (currentWidth )* (-k) / (float) Math.sqrt(k * k + 1) + myPointC.x,
|
||||||
|
(currentWidth ) / (float) Math.sqrt(k * k + 1) + myPointC.y);
|
||||||
|
B = new TimePoint( (-currentWidth )* (-k) / (float) Math.sqrt(k * k + 1) + myPointD.x,
|
||||||
|
(-currentWidth ) / (float) Math.sqrt(k * k + 1) + myPointD.y);
|
||||||
|
//当前点的上下端点MyPointC,MyPointD
|
||||||
|
C = new TimePoint( (currentWidth )* (-k) / (float) Math.sqrt(k * k + 1) + myPointC.x,
|
||||||
|
(currentWidth ) / (float) Math.sqrt(k * k + 1) + myPointC.y);
|
||||||
|
D = new TimePoint( (-currentWidth )* (-k) / (float) Math.sqrt(k * k + 1) + myPointD.x,
|
||||||
|
(-currentWidth ) / (float) Math.sqrt(k * k + 1) + myPointD.y);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
A = new TimePoint( currentWidth + myPointC.x,
|
||||||
|
myPointC.y);
|
||||||
|
B = new TimePoint( -currentWidth + myPointD.x,
|
||||||
|
myPointD.y);
|
||||||
|
C = new TimePoint( currentWidth + myPointC.x,
|
||||||
|
myPointC.y);
|
||||||
|
D = new TimePoint( -currentWidth + myPointD.x,
|
||||||
|
myPointD.y);
|
||||||
|
}
|
||||||
|
TimePoint centerAC = new TimePoint((A.x+C.x)/2,(A.y+C.y)/2);
|
||||||
|
TimePoint centerBD = new TimePoint((B.x+D.x)/2,(B.y+D.y)/2);
|
||||||
|
boolean isAC = true;
|
||||||
|
if( myPointC.x != myPointD.x){
|
||||||
|
float b = myPointC.y - k *myPointC.x;
|
||||||
|
if((centerAC.y - k* centerAC.x - b)*(drawingStrokes.mLastY - k*drawingStrokes.mLastX - b)<=0){
|
||||||
|
isAC = true;
|
||||||
|
}else {
|
||||||
|
isAC = false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if((centerAC.y-myPointC.y)*(drawingStrokes.mLastY - myPointC.y)<=0){
|
||||||
|
isAC = true;
|
||||||
|
}else {
|
||||||
|
isAC = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPath.moveTo(myPointC.x, myPointC.y);
|
||||||
|
if(isAC){
|
||||||
|
mPath.quadTo(centerAC.x,centerAC.y,myPointD.x,myPointD.y);
|
||||||
|
if(drawingStrokes.lastLineX == myPointC.x&&drawingStrokes.lastLineY == myPointC.y) {
|
||||||
|
drawingStrokes.strokesPath.quadTo(centerAC.x, centerAC.y, myPointD.x, myPointD.y);
|
||||||
|
//rawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(centerAC.x, centerAC.y));
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointD.x, myPointD.y));
|
||||||
|
}else{
|
||||||
|
drawingStrokes.strokesPath.quadTo(centerAC.x, centerAC.y, myPointC.x, myPointC.y);
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(centerAC.x, centerAC.y));
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointC.x, myPointC.y));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
mPath.quadTo(centerBD.x,centerBD.y,myPointD.x,myPointD.y);
|
||||||
|
if(drawingStrokes.lastLineX == myPointC.x&&drawingStrokes.lastLineY == myPointC.y) {
|
||||||
|
drawingStrokes.strokesPath.quadTo(centerBD.x, centerBD.y, myPointD.x, myPointD.y);
|
||||||
|
// drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(centerBD.x, centerBD.y));
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointD.x, myPointD.y));
|
||||||
|
}else{
|
||||||
|
drawingStrokes.strokesPath.quadTo(centerBD.x, centerBD.y, myPointC.x, myPointC.y);
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(centerBD.x, centerBD.y));
|
||||||
|
//drawingStrokes.strokes.getMyPathList().get(drawingStrokes.strokes.getMyPathSize()-1).addPoint(new MyPoints(myPointC.x, myPointC.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPath.lineTo(myPointC.x, myPointC.y);
|
||||||
|
canvas.drawPath(mPath,mPaint);
|
||||||
|
mPath.reset();
|
||||||
|
}
|
||||||
|
lastTop.x = myPointC.x;
|
||||||
|
lastTop.y = myPointC.y;
|
||||||
|
lastBottom.x = myPointD.x;
|
||||||
|
lastBottom.y = myPointD.y;
|
||||||
|
drawingStrokes.mLastWidth = currentWidth;
|
||||||
|
drawingStrokes.mLLastX = drawingStrokes.mLastX;
|
||||||
|
drawingStrokes.mLLastY = drawingStrokes.mLastY;
|
||||||
|
drawingStrokes.mLastX = x;
|
||||||
|
drawingStrokes.mLastY = y;
|
||||||
|
drawingStrokes.mLastK = k;
|
||||||
|
drawingStrokes.state = currentState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* 毛笔*/
|
||||||
|
public void drawBrushPen(DrawingStrokes drawingStrokes) {
|
||||||
|
// if(drawingStrokes.debug)
|
||||||
|
int[] colors = new int[] {
|
||||||
|
Color.parseColor("#66111111"),
|
||||||
|
Color.parseColor("#77111111"),
|
||||||
|
Color.parseColor("#88111111")};
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mPaint.setStrokeWidth(1f);
|
||||||
|
blurryPaint.setStrokeWidth(1f);
|
||||||
|
blurryPaint.setColor(Color.RED);
|
||||||
|
//blurryPaint.setColor(drawingStrokes.context.getResources().getColor(R.color.pencil_nine));
|
||||||
|
// blurryPaint.setPathEffect(new DashPathEffect(new float[] {1f, 1f}, 0));
|
||||||
|
blurryPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
//blurryPaint.setAlpha(100);
|
||||||
|
//mPaint.setAlpha(250);
|
||||||
|
// mPaint.setAntiAlias(false);
|
||||||
|
// mPaint.setPathEffect(new DashPathEffect(new float[] {2f, 2f}, 0));
|
||||||
|
//mPaint.setPathEffect(new DiscretePathEffect(3.0f, 5.0f));
|
||||||
|
//mPaint.setPathEffect(new CornerPathEffect(10));
|
||||||
|
// mPaint.setColor(drawingStrokes.context.getResources().getColor(R.color.pencil_two));
|
||||||
|
mPaint.setColor(Color.parseColor("#111111"));
|
||||||
|
//获得笔在两点间不同宽度的差值
|
||||||
|
int drawSteps = (int) Math.floor(splineCurve.length());
|
||||||
|
if (drawingStrokes.isUp) {
|
||||||
|
//curveIndex = 1;
|
||||||
|
if (drawSteps > 2)
|
||||||
|
curveIndex = (drawSteps - 2) / 2;
|
||||||
|
else curveIndex = 1;
|
||||||
|
if (curveIndex < 1) curveIndex = 1;
|
||||||
|
if (drawSteps == 0) drawSteps = 2;
|
||||||
|
} else if (drawingStrokes.isDown) {
|
||||||
|
curveIndex = 1;
|
||||||
|
if (drawSteps == 0) drawSteps = 2;
|
||||||
|
} else {
|
||||||
|
if (drawSteps > 100) curveIndex = 40;
|
||||||
|
else if (drawSteps > 80) curveIndex = 35;
|
||||||
|
else if (drawSteps > 70) curveIndex = 30;
|
||||||
|
else if (drawSteps > 60) curveIndex = 25;
|
||||||
|
else if (drawSteps > 50) curveIndex = 20;
|
||||||
|
else if (drawSteps > 40) curveIndex = 15;
|
||||||
|
else if (drawSteps > 30) curveIndex = 13;
|
||||||
|
else if (drawSteps > 20) curveIndex = 9;
|
||||||
|
else if (drawSteps > 10) curveIndex = 7;
|
||||||
|
else if (drawSteps >= 4) curveIndex = 3;
|
||||||
|
else curveIndex = 1;
|
||||||
|
}
|
||||||
|
float widthDelta = endWidth - startWidth;
|
||||||
|
//两点间实际轨迹距离
|
||||||
|
if (drawSteps == 0) {
|
||||||
|
drawSteps = 1;
|
||||||
|
}
|
||||||
|
Log.i("endWidth", " " + endWidth);
|
||||||
|
// curveIndex = drawSteps/2;
|
||||||
|
// if(curveIndex==0) curveIndex=1;
|
||||||
|
for (float i = 0, num = 1; i < drawSteps; i += 0.5f, num++) {
|
||||||
|
mPath.reset();
|
||||||
|
float t = (float) (i) / drawSteps;
|
||||||
|
float tt = t * t;
|
||||||
|
float ttt = tt * t;
|
||||||
|
float u = 1 - t;
|
||||||
|
float uu = u * u;
|
||||||
|
float uuu = uu * u;
|
||||||
|
float x = uuu * splineCurve.point1.x / 6.0f;
|
||||||
|
x += (3 * ttt - 6 * tt + 4) * splineCurve.point2.x / 6.0f;
|
||||||
|
x += (-3 * ttt + 3 * tt + 3 * t + 1) * splineCurve.point3.x / 6.0f;
|
||||||
|
x += ttt * splineCurve.point4.x / 6.0f;
|
||||||
|
float y = uuu * splineCurve.point1.y / 6.0f;
|
||||||
|
y += (3 * ttt - 6 * tt + 4) * splineCurve.point2.y / 6.0f;
|
||||||
|
y += (-3 * ttt + 3 * tt + 3 * t + 1) * splineCurve.point3.y / 6.0f;
|
||||||
|
y += ttt * splineCurve.point4.y / 6.0f;
|
||||||
|
float currentWidth = startWidth + t * widthDelta;
|
||||||
|
// if (!drawingStrokes.isUp)
|
||||||
|
// if (Math.abs(t * widthDelta) > 0.4f * num) {
|
||||||
|
// if (t * widthDelta > 0)
|
||||||
|
// currentWidth = startWidth + 0.4f * num;
|
||||||
|
// else currentWidth = startWidth - 0.4f * num;
|
||||||
|
// }
|
||||||
|
// mPaint.setMaskFilter(new BlurMaskFilter(currentWidth, BlurMaskFilter.Blur.SOLID));
|
||||||
|
// mPaint.setShadowLayer(currentWidth / 2, 0, 0, drawingStrokes.context.getResources().getColor(R.color.pencil_nine));
|
||||||
|
if (drawingStrokes.isDown) {
|
||||||
|
// canvas.drawLine(drawingStrokes.mLastX + currentWidth / 2, drawingStrokes.mLastY - currentWidth / 2, x + currentWidth / 2, y - currentWidth/ 2, blurryPaint);
|
||||||
|
// mPaint.setStrokeWidth(1f);
|
||||||
|
// mPaint.setColor(drawingStrokes.context.getResources().getColor(R.color.pencil_two));
|
||||||
|
//canvas.drawOval(new RectF(x - currentWidth / 2, y - currentWidth / 2, x + currentWidth / 2, y + currentWidth / 2), blurryPaint);
|
||||||
|
canvas.drawOval(new RectF(x - currentWidth / 2, y - currentWidth / 2, x + currentWidth / 2, y + currentWidth / 2), mPaint);
|
||||||
|
drawingStrokes.mLastWidth = currentWidth;
|
||||||
|
drawingStrokes.mLastX = x;
|
||||||
|
drawingStrokes.mLastY = y;
|
||||||
|
drawingStrokes.isDown = false;
|
||||||
|
} else {
|
||||||
|
// float width = currentWidth / 2;
|
||||||
|
// while (width < currentWidth) {
|
||||||
|
// canvas.drawLine(drawingStrokes.mLastX + width, drawingStrokes.mLastY - width , x + width, y - width, blurryPaint);
|
||||||
|
// width += 0.5f;
|
||||||
|
// }
|
||||||
|
LinearGradient linearGradient = new LinearGradient(x - currentWidth / 2, y - currentWidth / 2, x + currentWidth / 2, y + currentWidth / 2, colors, null, Shader.TileMode.REPEAT);
|
||||||
|
// RadialGradient radialGradient = new RadialGradient(x, y, currentWidth / 2, colors[1], colors[0], Shader.TileMode.MIRROR);
|
||||||
|
blurryPaint.setShader(linearGradient);
|
||||||
|
//mPaint.setAlpha(0);
|
||||||
|
float k;
|
||||||
|
if( x != drawingStrokes.mLastX) {
|
||||||
|
k = Math.abs((drawingStrokes.mLastY - y) / (drawingStrokes.mLastX - x));
|
||||||
|
Log.d("123","myk: " + k);
|
||||||
|
if(k < 0.005) {
|
||||||
|
canvas.drawLine(x , y - currentWidth, x , y - currentWidth / 4, blurryPaint);
|
||||||
|
} else if(k < 0.05) {
|
||||||
|
canvas.drawLine(x , y - currentWidth * 15 / 16, x , y - currentWidth / 4, blurryPaint);
|
||||||
|
} else if( k < 0.1) {
|
||||||
|
canvas.drawLine(x , y - currentWidth * 14 / 16, x , y - currentWidth / 4, blurryPaint);
|
||||||
|
} else if(k < 0.3) {
|
||||||
|
canvas.drawLine(x , y - currentWidth * 13 / 16, x , y - currentWidth / 4, blurryPaint);
|
||||||
|
} else if(k < 0.5) {
|
||||||
|
canvas.drawLine(x , y - currentWidth * 3 / 4, x , y - currentWidth / 4, blurryPaint);
|
||||||
|
} else if(k > 100) {
|
||||||
|
canvas.drawLine(x + currentWidth, y , x + currentWidth / 4, y, blurryPaint);
|
||||||
|
} else if(k > 50) {
|
||||||
|
canvas.drawLine(x + currentWidth * 15 / 16, y , x + currentWidth / 4, y, blurryPaint);
|
||||||
|
} else if(k > 20) {
|
||||||
|
canvas.drawLine(x + currentWidth * 14 / 16, y , x + currentWidth / 4, y, blurryPaint);
|
||||||
|
} else if(k > 10) {
|
||||||
|
canvas.drawLine(x + currentWidth * 13 / 16, y , x + currentWidth / 4, y, blurryPaint);
|
||||||
|
} else if(k > 5) {
|
||||||
|
canvas.drawLine(x + currentWidth * 3 / 4, y , x + currentWidth / 4, y, blurryPaint);
|
||||||
|
} else {
|
||||||
|
k = (drawingStrokes.mLastY - y) / (drawingStrokes.mLastX - x);
|
||||||
|
//根据斜率计算另一点
|
||||||
|
TimePoint myPointC = new TimePoint( (currentWidth * 11 / 16 )* (-k) / (float) Math.sqrt(k * k + 1) + x,
|
||||||
|
(currentWidth * 11 / 16 ) / (float) Math.sqrt(k * k + 1) + y);
|
||||||
|
TimePoint myPointD = new TimePoint( (-currentWidth * 11 / 16 )* (-k) / (float) Math.sqrt(k * k + 1) + x,
|
||||||
|
(-currentWidth * 11 / 16 ) / (float) Math.sqrt(k * k + 1) + y);
|
||||||
|
canvas.drawLine(myPointC.x, myPointC.y, x, y, blurryPaint);
|
||||||
|
canvas.drawLine(myPointD.x, myPointD.y, x, y, blurryPaint);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
canvas.drawLine(x , y - currentWidth, x , y - currentWidth / 4, blurryPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
//canvas.drawOval(new RectF(x + currentWidth , y - currentWidth , x , y ), blurryPaint);
|
||||||
|
//mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
|
||||||
|
canvas.drawOval(new RectF(x - currentWidth / 2, y - currentWidth / 2, x + currentWidth / 2, y + currentWidth / 2), mPaint);
|
||||||
|
drawingStrokes.mLastWidth = currentWidth;
|
||||||
|
drawingStrokes.mLastX = x;
|
||||||
|
drawingStrokes.mLastY = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
141
baselib/src/main/java/com/tenlionsoft/baselib/core/widget/pens/Strokes.java
Executable file
141
baselib/src/main/java/com/tenlionsoft/baselib/core/widget/pens/Strokes.java
Executable file
@ -0,0 +1,141 @@
|
|||||||
|
package com.tenlionsoft.baselib.core.widget.pens;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author:Double
|
||||||
|
* Time:2019/4/22
|
||||||
|
* Description:This is Strokes
|
||||||
|
*/
|
||||||
|
public class Strokes {
|
||||||
|
//当前笔划列表
|
||||||
|
private Vector<Stroke> myPath = null;
|
||||||
|
//保存删除 移动 旋转等更新后回收的笔划
|
||||||
|
private Vector<Stroke> recycleStrokesList = null;
|
||||||
|
//恢复操作保存的笔划
|
||||||
|
private Vector<Stroke> unDoStrokesList = null;
|
||||||
|
public Strokes(){
|
||||||
|
myPath = new Vector<>();
|
||||||
|
recycleStrokesList = new Vector<>();
|
||||||
|
unDoStrokesList = new Vector<>();
|
||||||
|
}
|
||||||
|
public int getRecycleStrokesListSize(){
|
||||||
|
return recycleStrokesList.size();
|
||||||
|
}
|
||||||
|
public int getMyPathSize(){
|
||||||
|
return myPath.size();
|
||||||
|
}
|
||||||
|
public Vector<Stroke> getRecycleStrokesList(){
|
||||||
|
return recycleStrokesList;
|
||||||
|
}
|
||||||
|
public Vector<Stroke> getMyPathList(){
|
||||||
|
return myPath;
|
||||||
|
}
|
||||||
|
public Vector<Stroke> getUnDoStrokesList(){
|
||||||
|
return unDoStrokesList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addMyPath(int location, int priority) {
|
||||||
|
myPath.add(new Stroke(location,priority));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas,Paint paint){
|
||||||
|
paint.setStyle(Paint.Style.FILL);
|
||||||
|
for(int i = 0;i < myPath.size(); i++){
|
||||||
|
if(myPath.size() == 0) break;
|
||||||
|
Path stroke = myPath.elementAt(i).getStroke();
|
||||||
|
if(!stroke.isEmpty()){
|
||||||
|
canvas.drawPath(stroke,paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void deleteMyPath(int index){
|
||||||
|
myPath.remove(index);
|
||||||
|
}
|
||||||
|
public void deleteRecycleStrokesList(int index){
|
||||||
|
recycleStrokesList.remove(index);
|
||||||
|
}
|
||||||
|
public void deleteUnDoStrokesList(int index){
|
||||||
|
unDoStrokesList.remove(index);
|
||||||
|
}
|
||||||
|
public void clearUnDoStrokesList(){
|
||||||
|
checkUnDoNull();
|
||||||
|
unDoStrokesList.clear();
|
||||||
|
}
|
||||||
|
public void checkUnDoNull(){
|
||||||
|
if(unDoStrokesList==null){
|
||||||
|
unDoStrokesList = new Vector<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void addUnDoStrokes(Stroke stroke){
|
||||||
|
checkUnDoNull();
|
||||||
|
unDoStrokesList.add(stroke);
|
||||||
|
}
|
||||||
|
public class Stroke{
|
||||||
|
private Path stroke;
|
||||||
|
private int location;//删除笔划原来所在笔划列表中的位置
|
||||||
|
private int priority;//所有笔划执行撤销动作的优先级
|
||||||
|
private Vector<TimePoint> points; //拟合后的几个点
|
||||||
|
private Vector<TimePoint> originPoints;//最原始的几个点
|
||||||
|
private Vector<Float> originWidth;
|
||||||
|
public Stroke(int index,int priority){
|
||||||
|
this.stroke = new Path();
|
||||||
|
this.location = index;
|
||||||
|
this.priority = priority;
|
||||||
|
this.points = new Vector<>();
|
||||||
|
originWidth = new Vector<>();
|
||||||
|
originPoints = new Vector<>();
|
||||||
|
}
|
||||||
|
public Path getStroke(){
|
||||||
|
return stroke;
|
||||||
|
}
|
||||||
|
public void setStroke(Path path){
|
||||||
|
stroke = new Path(path);
|
||||||
|
}
|
||||||
|
public Vector<TimePoint> getOriginPoints(){
|
||||||
|
return originPoints;
|
||||||
|
}
|
||||||
|
public void setOriginPoints(Vector<TimePoint> timePoints){
|
||||||
|
this.originPoints = timePoints;
|
||||||
|
}
|
||||||
|
public void setOriginWidth(Vector<Float> originWidth){
|
||||||
|
this.originWidth = originWidth;
|
||||||
|
}
|
||||||
|
public void addOriginPoint(TimePoint myPoints){
|
||||||
|
originPoints.add(myPoints);
|
||||||
|
}
|
||||||
|
public Vector<Float> getOriginWidth(){
|
||||||
|
return originWidth;
|
||||||
|
}
|
||||||
|
public void addOriginWidth(float width){
|
||||||
|
originWidth.add(width);
|
||||||
|
}
|
||||||
|
public void addPoint(TimePoint point){
|
||||||
|
points.add(point);
|
||||||
|
}
|
||||||
|
public Vector<TimePoint> getPoints(){
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
public int getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(int location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(int priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package com.tenlionsoft.baselib.core.widget.pens;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
/**
|
||||||
|
* Author:Double
|
||||||
|
* Time:2019/4/22
|
||||||
|
* Description:This is StrokesView
|
||||||
|
*/
|
||||||
|
public class StrokesView extends View{
|
||||||
|
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
//笔划
|
||||||
|
private Strokes strokes;
|
||||||
|
private DrawingStrokes mDrawing;
|
||||||
|
private PenType penType;
|
||||||
|
public StrokesView(Context context, AttributeSet attributeSet){
|
||||||
|
super(context,attributeSet);
|
||||||
|
strokes = new Strokes();
|
||||||
|
mDrawing = new DrawingStrokes(this, strokes);
|
||||||
|
mDrawing.setMaxWidth(2);//刚笔
|
||||||
|
penType = new PenType();
|
||||||
|
penType.setPenType(PenType.PEN);
|
||||||
|
mDrawing.setPenType(penType);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
if(mDrawing != null) {
|
||||||
|
mDrawing.setSize(canvas.getWidth(),canvas.getHeight(),mPaint);
|
||||||
|
mDrawing.draw(canvas, mPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
int action = event.getAction();
|
||||||
|
if (action == MotionEvent.ACTION_DOWN) {
|
||||||
|
mDrawing.moveTo(event.getX(), event.getY(), event.getPressure());
|
||||||
|
} else if(action == MotionEvent.ACTION_MOVE){
|
||||||
|
int historySize = event.getHistorySize();
|
||||||
|
for (int i = 0; i < historySize; i++) {
|
||||||
|
float historicalX = event.getHistoricalX(i);
|
||||||
|
float historicalY = event.getHistoricalY(i);
|
||||||
|
//判断两点之间的距离是否太短
|
||||||
|
double distance = Math.sqrt((historicalX - mDrawing.mPoint.get(mDrawing.mPoint.size() - 1).getX())
|
||||||
|
* (historicalX - mDrawing.mPoint.get(mDrawing.mPoint.size() - 1).getX())
|
||||||
|
+ (historicalY - mDrawing.mPoint.get(mDrawing.mPoint.size() - 1).getY())
|
||||||
|
* (historicalY - mDrawing.mPoint.get(mDrawing.mPoint.size() - 1).getY()));
|
||||||
|
if(mDrawing.mPoint.size() > 0 && distance > 0.2)
|
||||||
|
mDrawing.lineTo(historicalX, historicalY, event.getHistoricalPressure(i),false);
|
||||||
|
}
|
||||||
|
}else if(action == MotionEvent.ACTION_UP) {
|
||||||
|
mDrawing.lineTo(event.getX(), event.getY(), event.getPressure(),true);
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reDo() {
|
||||||
|
mDrawing.reDo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unDo() {
|
||||||
|
mDrawing.unDo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recover() {
|
||||||
|
mDrawing.recover();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenType(int penType) {
|
||||||
|
this.penType.setPenType(penType);
|
||||||
|
switch (penType) {
|
||||||
|
case PenType.BRUSH:
|
||||||
|
mDrawing.setMaxWidth(8);//毛笔
|
||||||
|
break;
|
||||||
|
case PenType.PEN:
|
||||||
|
mDrawing.setMaxWidth(2);//刚笔
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDestroy() {
|
||||||
|
mDrawing.onDestroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.tenlionsoft.baselib.core.widget.pens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author:Double
|
||||||
|
* Time:2019/4/22
|
||||||
|
* Description:This is TimePoint
|
||||||
|
*/
|
||||||
|
public class TimePoint {
|
||||||
|
public float x;
|
||||||
|
public float y;
|
||||||
|
public long timestamp;
|
||||||
|
public TimePoint(){};
|
||||||
|
public TimePoint(float x, float y){
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
// this.timestamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
public TimePoint(float x, float y, long time){
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.timestamp = time;
|
||||||
|
}
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
public float getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(float x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(float y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获得两个点间的速度
|
||||||
|
public float velocityFrom(TimePoint start){
|
||||||
|
return distanceTo(start) / (this.timestamp - start.timestamp);
|
||||||
|
}
|
||||||
|
//获得两个点间的距离
|
||||||
|
public float distanceTo(TimePoint point){
|
||||||
|
return (float) Math.sqrt(Math.pow(point.x - this.x, 2) + Math.pow(point.y - this.y, 2));
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@ import com.tenlionsoft.baselib.core.retrofit_net.conver.RxTransformer;
|
|||||||
import com.tenlionsoft.baselib.core.widget.base.BaseFragment;
|
import com.tenlionsoft.baselib.core.widget.base.BaseFragment;
|
||||||
import com.tenlionsoft.baselib.core.widget.base.FragmentUtils;
|
import com.tenlionsoft.baselib.core.widget.base.FragmentUtils;
|
||||||
import com.tenlionsoft.baselib.core.widget.base.FunctionTitleNumAdapter;
|
import com.tenlionsoft.baselib.core.widget.base.FunctionTitleNumAdapter;
|
||||||
|
import com.tenlionsoft.baselib.core.widget.views.CustomHandWritingDialog;
|
||||||
import com.tenlionsoft.baselib.core.widget.views.CustomStateView;
|
import com.tenlionsoft.baselib.core.widget.views.CustomStateView;
|
||||||
import com.tenlionsoft.baselib.core.widget.views.ItemSplitDivider;
|
import com.tenlionsoft.baselib.core.widget.views.ItemSplitDivider;
|
||||||
import com.tenlionsoft.baselib.utils.ExceptionHandler;
|
import com.tenlionsoft.baselib.utils.ExceptionHandler;
|
||||||
|
Loading…
Reference in New Issue
Block a user