当前位置: 首页 > news >正文

德州建设网站公司wordpress 画图插件

德州建设网站公司,wordpress 画图插件,渭南 网站集约化建设,网站建设小图标一、前言 幸运转盘在很多app中都有#xff0c;也有很多现实的例子#xff0c;不过这个难度并不是如何让转盘转起来#xff0c;真正的难度是如何统一个方向转动#xff0c;且转到指定的目标区域#xff08;中奖概率从来不是随机的#xff09;#xff0c;当然还不能太假也有很多现实的例子不过这个难度并不是如何让转盘转起来真正的难度是如何统一个方向转动且转到指定的目标区域中奖概率从来不是随机的当然还不能太假需要有一定的位置偏移。 效果预览 二、逻辑实现 2.1 平分区域 由于圆周是360度品分每个站preDegree那么起点和终点 但是为了让X轴初始化时对准第一个区域的中心我们做一下小偏移逆时针旋转一下 //圆点起始角度 可以理解为index0的起始角度我们以index0位参考点 float zeroStartDegree 0 -perDegree / 2; float endStartDegree 0 perDegree / 2;那么每个区域的起始角度如下 float startDegree i* perDegree - perDegree / 2; float endDegree i * perDegree perDegree / 2 ; 2.2 画弧 很简单不需要计算每个分区的大小因为平分的是同一个大圆因此Rect是大圆的范围但也要记住 ,弧的起始角绘制角度不能大于等于360最大貌似是359.9998399 canvas.drawArc(rectF, startDegree, endDegree - startDegree, true, mDrawerPaint); 2.3 文字绘制 由于Canvas.drawText不能设置角度那么意味着不能直接绘制需要做一定的角度转换要么旋转Canvas坐标要们旋转Path这次我们选后者吧。 使用Path的原因是他不仅具备矢量性质不失真而且还能转动文字的方向和从有到左绘制。 //计算出中心角度 float centerRadius (float) Math.toRadians((startDegree endDegree)/2F);float measuredTextWidth mDrawerPaint.measureText(item.text);float measuredTextHeight getTextHeight(mDrawerPaint,item.text);float innerRadius maxRadius - 2* measuredTextHeight;float cx (float) ((innerRadius - measuredTextHeight) * Math.cos(centerRadius));float cy (float) ((innerRadius - measuredTextHeight) * Math.sin(centerRadius));double degreeOffset Math.asin((measuredTextWidth/2F)/innerRadius);float startX (float) (innerRadius * Math.cos(centerRadius - degreeOffset));float startY (float) (innerRadius * Math.sin(centerRadius - degreeOffset));float endX (float) ((innerRadius) * Math.cos(centerRadius degreeOffset));float endY (float) ((innerRadius) * Math.sin(centerRadius degreeOffset));path.reset();path.moveTo(startX,startY);path.lineTo(endX,endY);//这里使用Path的原因是文本角度无法设置canvas.drawTextOnPath(item.text,path,0,0,mDrawerPaint); 2.4 核心逻辑 老板不会让中奖率随机的万一你中大奖了老板还得出钱或者花部门经费因此必须指定中奖物品可以让你100%中奖也能让你100%不中奖要看老板心情所以掘金的转盘你玩不玩都已经固定好你的胜率了。 计算出目标物品与初始角度的注意时初始角度而不是转过后的角度算起为什么呢原因是你按转过的角度计算复杂度就会提升而从起始点计算按照圆的三角函数定理转一圈就能绕过你转动的角度 也就是 rotateDegree 最终会大于你当前的所停留的角度 如果你在30度那么要转到20度的位置肯定不会倒转 需要 360 20,而360 20大于30所以莫有必要从当前角度计算。 //圆点起始角度 可以理解为index0的起始角度我们以index0位参考点 float zeroStartDegree 0 -perDegree / 2; float endStartDegree 0 perDegree / 2; //从圆点计算要旋转的角度 float targetDegree (perDegree * (index - 1) perDegree / 2); float rotateDegree zeroStartDegree - targetDegree; 算出来之后紧接着计算落点位置这里需要随机一下不然看着很假样子还是要做的。 但是这里我们一气呵成 【1】计算旋转速度主要是防止逆时针旋转其词转一下就到了也不太真实次数利用了三角函数定理 三角函数定理 n*360 degree 和 degree三角函数值最终夹角是等价的 【2】旋转次数这里我们用duration/speedTime实际上还可以用圆周边长除以duration也是可以的当然也要加一定的倍数。 【3】计算出随机落点位置不能骑线也不能超过指定区域 //防止逆时针旋转 三角函数定理 n*360 degree 和 degree最终夹角是等价的 while (rotateDegree offsetDegree) {rotateDegree 360;}if (speedTime 0) {speedTime 100L;}long count duration / speedTime - 1; //计算额外旋转圈数while (count 0) {rotateDegree 360; //三角函数定理 n*360 degree 和 degree最终夹角是等价的count--; //算出转多少圈}float targetStartDegree rotateDegree - perDegree / 2;float targetEndDegree rotateDegree perDegree / 2;float currentOffsetDegree offsetDegree;// float targetOffsetDegree (targetStartDegree targetEndDegree)/2 ;//让指针指向有一定的随机性float targetOffsetDegree (float) (targetStartDegree (targetEndDegree - targetStartDegree) * Math.random());2.5 全部代码 public class LuckWheelView extends View {Path path new Path();private final DisplayMetrics mDM;private TextPaint mArcPaint;private TextPaint mDrawerPaint;private int maxRadius;private float perDegree;private long duration 5000L;private ListItem items new ArrayList();private RectF rectF new RectF();private float offsetDegree 0;private TimeInterpolator timeInterpolator new AccelerateDecelerateInterpolator();private long speedTime 1000L; //旋转一圈需要多少时间private ValueAnimator animator null;public LuckWheelView(Context context) {this(context, null);}public LuckWheelView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public LuckWheelView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mDM getResources().getDisplayMetrics();initPaint();}public void setRotateIndex(int index) {if (items null || items.size() index) {return;}//圆点起始角度 可以理解为index0的起始角度我们以index0位参考点float zeroStartDegree 0 -perDegree / 2;float endStartDegree 0 perDegree / 2;//从圆点计算要旋转的角度float targetDegree (perDegree * (index - 1) perDegree / 2);float rotateDegree zeroStartDegree - targetDegree;//防止逆时针旋转 三角函数定理 n*360 degree 和 degree最终夹角是等价的 while (rotateDegree offsetDegree) {rotateDegree 360;}if (speedTime 0) {speedTime 100L;}long count duration / speedTime - 1; //计算额外旋转圈数while (count 0) {rotateDegree 360; //三角函数定理 n*360 degree 和 degree最终夹角是等价的count--;}float targetStartDegree rotateDegree - perDegree / 2;float targetEndDegree rotateDegree perDegree / 2;float currentOffsetDegree offsetDegree;// float targetOffsetDegree (targetStartDegree targetEndDegree)/2 ;//让指针指向有一定的随机性float targetOffsetDegree (float) (targetStartDegree (targetEndDegree - targetStartDegree) * Math.random());if (animator ! null) {animator.cancel();} //起点肯定要从当前角度算起不然会闪一下回到原点animator ValueAnimator.ofFloat(currentOffsetDegree, targetOffsetDegree).setDuration(duration);animator.setInterpolator(timeInterpolator);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {Overridepublic void onAnimationUpdate(ValueAnimator animation) {offsetDegree (float) animation.getAnimatedValue();postInvalidate();}});animator.addListener(new AnimatorListenerAdapter() {Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);offsetDegree offsetDegree % 360;}});animator.start();}private void initPaint() {// 实例化画笔并打开抗锯齿mArcPaint new TextPaint(Paint.ANTI_ALIAS_FLAG);mArcPaint.setAntiAlias(true);mArcPaint.setStyle(Paint.Style.STROKE);mArcPaint.setStrokeCap(Paint.Cap.ROUND);mDrawerPaint new TextPaint(Paint.ANTI_ALIAS_FLAG);mDrawerPaint.setAntiAlias(true);mDrawerPaint.setStyle(Paint.Style.FILL);mDrawerPaint.setStrokeCap(Paint.Cap.ROUND);mDrawerPaint.setStrokeWidth(5);mDrawerPaint.setTextSize(spTopx(14));}private float spTopx(float dp) {return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, dp, getResources().getDisplayMetrics());}Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode MeasureSpec.getMode(widthMeasureSpec);int widthSize MeasureSpec.getSize(widthMeasureSpec);if (widthMode ! MeasureSpec.EXACTLY) {widthSize mDM.widthPixels / 2;}int heightMode MeasureSpec.getMode(heightMeasureSpec);int heightSize MeasureSpec.getSize(heightMeasureSpec);if (heightMode ! MeasureSpec.EXACTLY) {heightSize widthSize / 2;}setMeasuredDimension(widthSize, heightSize);}Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int width getWidth();int height getHeight();if (width 0 || height 0 || items null || items.size() 0) {perDegree 0;return;}maxRadius Math.min(width / 2, height / 2);rectF.left -maxRadius;rectF.top -maxRadius;rectF.right maxRadius;rectF.bottom maxRadius;int size items.size();int saveCount canvas.save();canvas.translate(width * 1F / 2, height * 1F / 2); //平移坐标轴到view中心点canvas.rotate(-90); //逆时针旋转坐标轴 90度perDegree 360 * 1F / size;// rangeDegree start -end// rangeDegree.start perDegree/2 (i-1) * perDegree;// rangeDegree.end perDegree/2 (i) * perDegree;for (int i 0; i size; i) {//由于我们让第一个区域的中心点对准x轴了所以(i-1)意味着从y轴负方向顺时针转动float startDegree perDegree * (i - 1) perDegree / 2 offsetDegree;float endDegree i * perDegree perDegree / 2 offsetDegree;Item item items.get(i);mDrawerPaint.setColor(item.color); // double startDegreeRandians Math.toRadians(startDegree); //x1 // float x (float) (maxRadius * Math.cos(startDegreeRandians)); // float y (float) (maxRadius * Math.sin(startDegreeRandians)); // canvas.drawLine(0,0,x,y,mDrawerPaint);float centerRadius (float) Math.toRadians((startDegree endDegree)/2F);float measuredTextWidth mDrawerPaint.measureText(item.text);float measuredTextHeight getTextHeight(mDrawerPaint,item.text);float innerRadius maxRadius - 2* measuredTextHeight;float cx (float) ((innerRadius - measuredTextHeight) * Math.cos(centerRadius));float cy (float) ((innerRadius - measuredTextHeight) * Math.sin(centerRadius));double degreeOffset Math.asin((measuredTextWidth/2F)/innerRadius);float startX (float) (innerRadius * Math.cos(centerRadius - degreeOffset));float startY (float) (innerRadius * Math.sin(centerRadius - degreeOffset));float endX (float) ((innerRadius) * Math.cos(centerRadius degreeOffset));float endY (float) ((innerRadius) * Math.sin(centerRadius degreeOffset));path.reset();path.moveTo(startX,startY);path.lineTo(endX,endY);//这里使用Path的原因是文本角度无法设置canvas.drawArc(rectF, startDegree, endDegree - startDegree, true, mDrawerPaint);mDrawerPaint.setColor(Color.WHITE);canvas.drawCircle(cx,cy,5,mDrawerPaint);canvas.drawTextOnPath(item.text,path,0,0,mDrawerPaint);}canvas.drawLine(0, 0, maxRadius / 2F, 0, mDrawerPaint);canvas.restoreToCount(saveCount);}Rect textBounds new Rect();//真实宽度 笔画上下两侧间隙符合文本绘制基线private int getTextHeight(Paint paint,String text) {paint.getTextBounds(text,0,text.length(),textBounds);return textBounds.height();}public void setItems(ListItem items) {this.items.clear();this.items.addAll(items);invalidate();}public static class Item {Object tag;int color Color.TRANSPARENT;String text;public Item(int color, String text) {this.color color;this.text text;}}} 2.6 使用方法 ListLuckWheelView.Item items new ArrayList();items.add(new LuckWheelView.Item(argb(random.nextFloat(),random.nextFloat(),random.nextFloat()), 金元宝));items.add(new LuckWheelView.Item(argb(random.nextFloat(),random.nextFloat(),random.nextFloat()), 皮卡丘));items.add(new LuckWheelView.Item(argb(random.nextFloat(),random.nextFloat(),random.nextFloat()), 1元红包));items.add(new LuckWheelView.Item(argb(random.nextFloat(),random.nextFloat(),random.nextFloat()), 全球旅行));items.add(new LuckWheelView.Item(argb(random.nextFloat(),random.nextFloat(),random.nextFloat()), K歌会员卡));items.add(new LuckWheelView.Item(argb(random.nextFloat(),random.nextFloat(),random.nextFloat()), 双肩包));loopView.setItems(items);loopView.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View v) {int index (int) (Math.random() * items.size());Log.d(LuckWheelView, setRotateIndex- items.get(index).text , index index);loopView.setRotateIndex(index);}}); 三、总结 本篇简单而快捷的实现了幸运转盘难点主要是角度的转换一定要分析出初始角度和目标位置的夹角这一个定性标准其词作一些优化就能实现幸运转盘效果。
http://www.huolong8.cn/news/187888/

相关文章:

  • 网站建设所需材料网站建设分析图
  • 甘肃省住房建设厅网站中国还有多少人没有打新冠疫苗
  • 北京做网站要多少钱长沙本地论坛有哪些
  • 关于网站开发人员的薪资宝塔自助建站系统源码
  • 广西注册公司网站如何在微信公众号里建设微网站
  • 手机里面的网站怎么制作网站为什么做静态
  • 怎么把网站上传到空间做鞋子有什么好网站
  • 微信做一元云购网站大航母网站建设怎么样
  • 音乐网站建设论文数据网站建设工具模板
  • 织梦网站登录市场营销策略是什么
  • 临沂市住房和城乡建设厅网站抖音logo在线设计生成器免费
  • 中山建网站价格河南网站建设哪家公司好
  • 如何做网站推广广告网站曝光率
  • 南阳网站seo设计网页的快捷网站
  • 做网站属于什么专业做微商有哪些网站可以免费宣传
  • 网站开发做网站高端网站建设需要多少钱
  • 怎么用ftp修改网站图片网站更换域名注意事项
  • wordpress 多站点建站教程顺平网站建设
  • 网站建设的简要任务执行书网站怎么做全屏的
  • 自己的网站做怎样的优化调整长沙水业网站是哪家公司做的
  • 网站建设行业新闻手机网站的视频怎么才能下载
  • 先做网站再付款设计师共享平台
  • 制作论坛类网站模板创意设计公司业务范围
  • flash网站模板带后台舒城县建设局网站
  • 群晖wordpress站点地址绍兴网站建设价格
  • 有哪些简单的网站中铁建设集团有限公司
  • 俄罗斯网站域名注册泰安网络推广平台
  • 青浦区网站建设万能短视频素材库
  • 怎么查看什么公司做的网站吗阿里建设网站
  • 微信网站开发语言搜索引擎优化指的是什么