抽奖转盘
1:画抽奖转盘
public class LuckyPanView extends SurfaceView implements Callback, Runnable
{
private SurfaceHolder mHolder;
/**
* 与SurfaceHolder绑定的Canvas
*/
private Canvas mCanvas;
/**
* 用于绘制的线程
*/
private Thread t;
/**
* 线程的控制开关
*/
private boolean isRunning;
/**
* 抽奖的文字
*/
private ArrayList<String> list ;
/**
* 每个盘块的颜色
*/
private int[] mColors = new int[] { 0xFFFFEB0A, 0xFFFFBF26};
/**
* 绘制盘块的范围
*/
private RectF mRange = new RectF();
/**
* 盘块的个数
*/
private int mItemCount=0;
/**
* 圆的直径
*/
private int mRadius;
/**
* 绘制盘快的画笔
*/
private Paint mArcPaint;
/**
* 绘制文字的画笔
*/
private Paint mTextPaint;
/**
* 浮雕效果
*/
private BlurMaskFilter maskFilter ;
/**
* 滚动的速度
*/
private double mSpeed;
private volatile float mStartAngle = 0;
private float tragetTo;
/**
* 是否点击了停止
*/
private boolean isShouldEnd;
/**
* 控件的中心位置
*/
private int mCenter;
private TimerTask timerTask;
private Timer timer ;
/**
* 文字的大小
*/
private float mTextSize = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
public LuckyPanView(Context context)
{
this(context, null);
}
public LuckyPanView(Context context, AttributeSet attrs)
{
super(context, attrs);
mHolder = getHolder();
mHolder.addCallback(this);
setZOrderOnTop(true);// 设置画布 背景透明
mHolder.setFormat(PixelFormat.TRANSLUCENT);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
}
private int widths ;
/**
* 设置控件为正方形
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
widths = Math.min(getMeasuredWidth(), getMeasuredHeight());
// 获取圆形的直径
mRadius = widths - getPaddingLeft() - getPaddingRight();
// 中心点
mCenter = widths / 2;
setMeasuredDimension(widths, widths);
// 圆弧的绘制范围
mRange = new RectF(getPaddingLeft(), getPaddingLeft(), mRadius
+ getPaddingLeft(), mRadius + getPaddingLeft());
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
maskFilter = new BlurMaskFilter(10, BlurMaskFilter.Blur.SOLID);
// 初始化绘制圆弧的画笔
mArcPaint = new Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setDither(true);
// 初始化绘制文字的画笔
mTextPaint = new Paint();
mTextPaint.setColor(0xFFffffff);
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(mTextSize);
// 开启线程
startThread();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
// 通知关闭线程
isRunning = false;
}
@Override
public void run()
{
// 不断的进行draw
while (isRunning) {
long start = System.currentTimeMillis();
draw();
long end = System.currentTimeMillis();
try
{
if (end - start < 50) {
Thread.sleep(50 - (end - start));
}
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
private void draw()
{
try
{
// 获得canvas
mCanvas = mHolder.lockCanvas();
if (mCanvas != null) {
drawBg();
// 如果mSpeed不等于0,则相当于在滚动
drawIcon(mStartAngle);
// 点击停止时,设置mSpeed为递减,为0值转盘停止
mStartAngle += mSpeed;
LogCat.i(mStartAngle % 360 + "::" + isShouldEnd + "::" + mSpeed + "::" + tragetTo);
if (isShouldEnd)
{
mSpeed -= 0.5;
}
if (mSpeed <= 0)
{
mSpeed = 0;
isShouldEnd = false;
}
}
} catch (Exception e)
{
e.printStackTrace();
} finally
{
if (mCanvas != null)
mHolder.unlockCanvasAndPost(mCanvas);
}
}
/**
* 绘制图片
*
* @param startAngle
* @param
* @param
*/
private Path path = new Path();
private void drawIcon(float startAngle) {
mCanvas.save();
mCanvas.rotate(startAngle % 360, mCenter, mCenter);
path.reset();
path.moveTo(mCenter, mCenter * 1/2 + 10);
path.lineTo(mCenter - mCenter /5 , mCenter);
path.lineTo(mCenter + mCenter /5 , mCenter);
path.close();
mArcPaint.setColor(getContext().getResources().getColor(R.color.fen_se));
mCanvas.drawPath(path, mArcPaint);
mCanvas.drawCircle(mCenter, mCenter, mCenter / 5 + 15, mArcPaint);
mArcPaint.setColor(getContext().getResources().getColor(R.color.hong_se));
mCanvas.drawCircle(mCenter, mCenter, mCenter / 5, mArcPaint);
mArcPaint.setMaskFilter(null);
mTextPaint.setTextSize(30);
mTextPaint.setColor(Color.WHITE);
mTextPaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
mCanvas.drawText("抽奖", mCenter - 30, mCenter + 13, mTextPaint);
mCanvas.restore();
}
private boolean huandeng = true ;
private void drawLamp(int d){
mArcPaint.setMaskFilter(maskFilter);
if(huandeng){
if(d%2 == 0){
mArcPaint.setColor(getResources().getColor(R.color.huang_se4));
}else {
mArcPaint.setColor(Color.WHITE);
}
}else {
if(d%2 == 1){
mArcPaint.setColor(getResources().getColor(R.color.huang_se4));
}else {
mArcPaint.setColor(Color.WHITE);
}
}
if(mCanvas == null ) return;
mCanvas.save();
mCanvas.rotate((float) (d * 22.5), mCenter, mCenter);
mCanvas.drawCircle(mCenter, 20, 5, mArcPaint);
mCanvas.restore();
mArcPaint.setMaskFilter(null);
}
/**
* 绘制背景
*/
private void drawBg(){
mArcPaint.setColor(getContext().getResources().getColor(R.color.huang_se2));
mCanvas.drawArc(new RectF(5, 5, widths - 5, widths - 5), 0, 360, false, mArcPaint);
mArcPaint.setColor(getContext().getResources().getColor(R.color.tu_se));
mCanvas.drawArc(new RectF(10, 10, widths - 10, widths - 10), 0, 360, false, mArcPaint);
for(int m=0;m<16;m++){
drawLamp(m);
}
/**
* 绘制每个块块,每个块块上的文本,每个块块上的图片
*/
pathText.reset();
if(mItemCount>0){
float tmpAngle = 270;
float sweepAngle = (float) (360 / mItemCount);
for (int i = 0; i < mItemCount; i++) {
// 绘制快快
mArcPaint.setColor(mColors[i % 2]);
//mArcPaint.setStyle(Paint.Style.STROKE);
mCanvas.drawArc(mRange, tmpAngle,sweepAngle, true,
mArcPaint);
tmpAngle += sweepAngle;
}
mTextPaint.setColor(getResources().getColor(R.color.text_color));
for (int i = 0; i < mItemCount; i++)
{drawText(i+1,list.get(i));}
}
mArcPaint.setColor(getContext().getResources().getColor(R.color.bai_se));
mCanvas.drawCircle(mCenter, mCenter, mCenter / 5 + 34, mArcPaint);
mArcPaint.setColor(getContext().getResources().getColor(R.color.huang_se));
mCanvas.drawCircle(mCenter, mCenter, mCenter / 5 + 25, mArcPaint);
}
/**
* 绘制文本
*
* @param
* @param startAngle
* @param sweepAngle
* @param string
*/
Path pathText = new Path();
private void drawText(int number, String string) {
mCanvas.save();
mCanvas.rotate(number * 360 / mItemCount - 180 / mItemCount , mCenter, mCenter);
pathText.reset();
pathText.moveTo(mCenter, mCenter);
pathText.lineTo(mCenter, 0);
int size = 30 ;
mTextPaint.setTextSize(size);
float textWidth = mTextPaint.measureText(string);
for(size=30;textWidth>(mRadius-mCenter/5-30)/3;size--){
mTextPaint.setTextSize(size);
textWidth = mTextPaint.measureText(string);
}
pathText.close();
mCanvas.drawTextOnPath(string, pathText, mCenter / 5 + 30, size / 2, mTextPaint);
mCanvas.restore();
}
/**
* 点击开始旋转
*
* @param name
*/
public void luckyStart(String name,Handler handler,String openid, WebView webView) {
int luckyIndex = 0;
for(int i=0 ;i<list.size();i++){
if(list.get(i).equals(name))
luckyIndex = i+1 ;
}
if(luckyIndex==0) return;
// 每项角度大小
float angle = (float) (360 / mItemCount);
double delt = 1/4 + 4 * tragetTo;
// 中奖角度范围(因为指针向上,所以水平第一项旋转到指针指向,需要旋转210-270;)
float from = angle*(luckyIndex-1)+angle/3;
float to = (float) (from + angle*Math.random()/3);
// 停下来时旋转的距离
tragetTo = to +4 * 360 ;
mSpeed = Math.sqrt(delt)/2 -1/2;
isShouldEnd = false;
returnLuckpan(webView,handler,openid);
}
public void luckyEnd(){
mStartAngle = mStartAngle%360 ;
tragetTo = tragetTo + 360 - mStartAngle%360 - 20;
double delt = 1/4 + 4 * tragetTo;
mSpeed = Math.sqrt(delt)/2 ;
isShouldEnd = true;
}
private void startThread(){
isRunning = true;
t = new Thread(this);
t.start();
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
if(huandeng) {
huandeng = false;
}else {
huandeng = true ;
}
}
};
timer.schedule(timerTask, 1000, 1500);
}
/***
* 转盘转完之后调用
* @param webView
* @param handler
* @param openid
*/
private void returnLuckpan(WebView webView ,Handler handler,String openid){
Random random = new Random();
int m =(3+random.nextInt(3))*1000 ;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(m);
luckyEnd();
handler.postDelayed(new Runnable() {
@Override
public void run() {
webView.loadUrl("javascript:endLuckdrawCall('" + openid + "')");
}
}, 8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public boolean isStart()
{
return mSpeed != 0;
}
/***
* 设置礼物
* @param _list
*/
public void setList(ArrayList<String> _list){
mItemCount = _list.size() ;
mStartAngle = 0 ;
this.list = _list ;
}
public boolean isShouldEnd()
{
return isShouldEnd;
}
}