提示,以下是实现思路,文章未尾有完整项目仓库。

下面简单介绍了HTML5 Canvas的来历、浏览器兼容性,主要内容是如何实现转盘抽奖,最后的DEMO非常简陋,真实场景还会有很多需要考虑和改进的地方(比如:浏览器前缀),这里只讲一步步实现的思路。

Demo

在线演示

HTML5 Canvas

Canvas元素最早是Apple在Safari1.3中引入的,后在HTML5中标准化。

浏览器支持

查看详细浏览器支持

兼容旧版IE可使用:

1 . ExplorerCanvas Github, Google Code

Google工程师使用VML(Vector markup Language)技术模拟Canvas,不支持一些高级功能,如:渐变、阴影、剪切区域等。

2 . FlashCanvas

依赖Flash插件,增加了更多功能支持,有Free、Pro版。

ExploreCanvas、FlashCanvas Free、FlashCanvas Pro功能支持对比:

http://flashcanvas.net/docs/canvas-api

Canvas API

https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API

抽奖转盘

1. 绘制扇形

HTML

<canvas id="canvas" width="300" height="300">抱歉!浏览器不支持。</canvas>

JS

var num = 6;   // 奖品数量
var canvas = document.getElementById('canvas');
var btn = document.getElementById('btn');
if(!canvas.getContext){
alert('抱歉!浏览器不支持。');
return;
}
// 获取绘图上下文
var ctx = canvas.getContext('2d');
for (var i = 1; i <= num; i++) {
// 保存当前状态
ctx.save();
// 开始一条新路径
ctx.beginPath();
// 位移到圆心,下面需要围绕圆心旋转
ctx.translate(150, 150);
// 从(0, 0)坐标开始定义一条新的子路径
ctx.moveTo(0, 0);
// 旋转弧度,需将角度转换为弧度,使用 degrees * Math.PI/180 公式进行计算。
ctx.rotate(360 / num * i * Math.PI/180);
// 绘制圆弧
ctx.arc(0, 0, 150, 0, 2 * Math.PI / num, false);
if (i % 2 == 0) {
ctx.fillStyle = '#ffb820';
}else{
ctx.fillStyle = '#ffcb3f';
}
// 填充扇形
ctx.fill();
// 绘制边框
ctx.lineWidth = 0.5;
ctx.strokeStyle = '#f48d24';
ctx.stroke();
// 恢复前一个状态
ctx.restore();
}

调用绘图上下文的save()方法可以保存坐标系当前的状态。然后,再调用restore()方法可以返回保存过的前一个状态。如果要保存坐标系的状态,必须在应用任何变换之前调用save(),这样再调用restore()才能把坐标系恢复到正常状态。而在多步操作绘制复杂图形时,往往都需要多次保存坐标系状态。这些状态就如同浏览器中的历史记录一样。每次调用restore(),坐标系就会恢复到前一个最近的状态。

参考:

rotate: http://www.w3school.com.cn/tags/canvas_rotate.asp

arc: https://developer.mozilla.org/zh-CN/docs/Web/API/ CanvasRenderingContext2D/arc

http://www.w3school.com.cn/tags/canvas_arc.asp

2. 动画

CSS

#canvas{
border: 1px solid #000;
-webkit-transition: all 6s ease;
transition: all 6s ease;
} canvas.style.transform = 'rotate(1800deg)';

3. 优化

未获取中奖数据前预旋转,增强用户体验

CSS

/* 1. 点击抽奖,动画匀速执行linear */
#canvas{
border: 1px solid #000;
-webkit-transition: all 6s linear;
transition: all 6s linear;
}
/* 2. 获取中奖数据,动画匀速执行并慢慢结束ease-out */
#canvas{
border: 1px solid #000;
-webkit-transition: all 6s ease-out;
transition: all 6s ease-out;
}

参考:

贝塞尔曲线

工具

FabricJS

一个简单而强大的 JavaScript Canvas 库。

http://fabricjs.com

TwoJS

Two.js 是面向现代 Web 浏览器的一个2D绘图 API。

http://jonobr1.github.io/two.js/

其它实现方式

CSS实现大转盘

http://sbdccc.wx.bad.uctoo.com/?_a=reward&_u=index.christmas&r_uid=39

完整代码

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>Drawing sector</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style>
#turntable{
position: relative;
}
#canvas{
border: 1px solid #000;
-webkit-transform: all 6s ease;
transition: all 6s ease;
}
#btn{
position: absolute;
left: 120px;
top: 120px;
width: 60px;
height: 60px;
border-radius: 50%;
background-color: #fff;
line-height: 60px;
text-align: center;
}
#btn:after{
position: absolute;
display: block;
content: '';
left: 10px;
top: -32px;
width: 0;
height: 0;
overflow: hidden;
border-width: 20px;
border-style: solid;
border-color: transparent;
border-bottom-color: #fff;
}
</style>
</head>
<body>
<div id="turntable">
<canvas id="canvas" width="300" height="300">抱歉!浏览器不支持。</canvas>
<a id="btn" href="javascript:;">抽奖</a>
</div>
<script>
window.addEventListener('load', function(){
var num = 6; // 奖品数量
if (num % 2 !== 0){
alert('请配置偶数奖项');
}
var canvas = document.getElementById('canvas');
var btn = document.getElementById('btn');
if(!canvas.getContext){
alert('抱歉!浏览器不支持。');
return;
}
// 获取绘图上下文
var ctx = canvas.getContext('2d');
for (var i = 0; i < num; i++) {
// 保存当前状态
ctx.save();
// 开始一条新路径
ctx.beginPath();
// 位移到圆心,下面需要围绕圆心旋转
ctx.translate(150, 150);
// 从(0, 0)坐标开始定义一条新的子路径
ctx.moveTo(0, 0);
// 旋转弧度,需将角度转换为弧度,使用 degrees * Math.PI/180 公式进行计算。
ctx.rotate((360 / num * i + 360 / num / 2) * Math.PI/180);
// 绘制圆弧
ctx.arc(0, 0, 150, 0, 2 * Math.PI / num, false);
if (i % 2 == 0) {
ctx.fillStyle = '#ffb820';
}else{
ctx.fillStyle = '#ffcb3f';
}
// 填充扇形
ctx.fill();
// 绘制边框
ctx.lineWidth = 0.5;
ctx.strokeStyle = '#f48d24';
ctx.stroke(); // 文字
ctx.fillStyle = '#fff';
ctx.font="16px sans-serif";
ctx.fillText(i + 1, 100, 60); // 恢复前一个状态
ctx.restore();
} // 抽奖
btn.onclick = function(){
canvas.style.transform = 'rotate(1800deg)';
}
}, false);
</script>
</body>
</html>

新项目:完整的Canvas转盘抽奖代码

https://github.com/givebest/GB-canvas-turntable

演示

http://blog.givebest.cn/GB-canvas-turntable.html

转载请注明出处:http://www.cnblogs.com/givebest/p/5296335.html

HTML5 Canvas绘制转盘抽奖的更多相关文章

  1. 学习笔记:HTML5 Canvas绘制简单图形

    HTML5 Canvas绘制简单图形 1.添加Canvas标签,添加id供js操作. <canvas id="mycanvas" height="700" ...

  2. 使用 HTML5 Canvas 绘制出惊艳的水滴效果

    HTML5 在不久前正式成为推荐标准,标志着全新的 Web 时代已经来临.在众多 HTML5 特性中,Canvas 元素用于在网页上绘制图形,该元素标签强大之处在于可以直接在 HTML 上进行图形操作 ...

  3. 使用html5 canvas绘制图片

    注意:本文属于<html5 Canvas绘制图形入门详解>系列文章中的一部分.如果你是html5初学者,仅仅阅读本文,可能无法较深入的理解canvas,甚至无法顺畅地通读本文.请点击上述链 ...

  4. 使用html5 canvas绘制圆形或弧线

    注意:本文属于<html5 Canvas绘制图形入门详解>系列文章中的一部分.如果你是html5初学者,仅仅阅读本文,可能无法较深入的理解canvas,甚至无法顺畅地通读本文.请点击上述链 ...

  5. html5 Canvas绘制图形入门详解

    html5,这个应该就不需要多作介绍了,只要是开发人员应该都不会陌生.html5是「新兴」的网页技术标准,目前,除IE8及其以下版本的IE浏览器之外,几乎所有主流浏览器(FireFox.Chrome. ...

  6. 解决html5 canvas 绘制字体、图片与图形模糊问题

    html5 canvas 绘制字体.图片与图形模糊问题 发生情况 多出现在高dpi设备,这意味着每平方英寸有更多的像素,如手机,平板电脑.当然很多高端台式电脑也有高分辨率高dpi的显示器. canva ...

  7. 使用html5 Canvas绘制线条(直线、折线等)

    使用html5 Canvas绘制直线所需的CanvasRenderingContext2D对象的主要属性和方法(有"()"者为方法)如下: 属性或方法 基本描述 strokeSty ...

  8. html5 canvas绘制环形进度条,环形渐变色仪表图

    html5 canvas绘制环形进度条,环形渐变色仪表图                                             在绘制圆环前,我们需要知道canvas arc() 方 ...

  9. 怎样用JavaScript和HTML5 Canvas绘制图表

    原文:https://code.tutsplus.com/zh-...原作:John Negoita翻译:Stypstive 在这篇教程中,我将展示用JavaScript和canvas作为手段,在饼状 ...

随机推荐

  1. mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法!

    mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法! 修改mysql5.7的配置文件即可解决,方法如下: linux版:找到mysql的安装路径进入默认的为/usr/shar ...

  2. 浅谈iptables 入站 出站以及NAT实例

    --------------本文是自己工作上的笔记总结,适合的可以直接拿去用,不适合的,适当修改即可!--------------- iptbales默认ACCEPT策略,也称通策略,这种情况下可以做 ...

  3. ubuntu+mono+jexus 搭建.net的web平台 实现.net跨平台

    准备工作: vmware 用来安装 ubuntu 下载地址:VMware-workstation-9.0.1-894247.exe.tar 注册码: 1A4P8-DMK0N-FZ431-7K8NH-2 ...

  4. EQueue文件持久化消息关键点设计思路

    要持久化的关键数据有三种 消息: 队列,队列中存放的是消息索引信息,即消息在文件中的物理位置(messageOffset)和在队列中的逻辑位置(queueOffset)的映射信息: 队列消费进度,表示 ...

  5. 探索 Linux 系统的启动过程

    引言 之所以想到写这些东西,那是因为我确实想让大家也和我一样,把 Linux 桌面系统打造成真真正正日常使用的工具,而不是安装之后试用几把再删掉.我是真的在日常生活和工作中都使用 Linux,比如在 ...

  6. 页面中调用系统常用的对话框需要用到的classid

    ■打开■ <input name=Button onClick=document.all.WebBrowser.ExecWB(1,1) type=button value=打开> < ...

  7. 实现ABP中Person类的权限功能

    菜单项的显示功能已经完全OK了.那么我们就开始制作视图功能吧. 首先测试接口是否正常 我们通过代码生成器将权限和application中大部分功能已经实现了.那么我们来测试下这些接口ok不. 浏览/a ...

  8. [Java面经] 关于面试的二三事.

    今天终于闲下来了, 那么也好总结下这几天面试的经历.四天的时间一共面了七家, 有一家是自己推迟了没有去.声明:如若转载请注明出处:http://www.cnblogs.com/wang-meng/p/ ...

  9. C# 根据类型名称 生成实体 调用方法

    System.Reflection.Assembly ass = System.Reflection.Assembly.Load("项目名称或者DLL"); //System.Th ...

  10. 2016网易春招Java在线笔试回忆录

    别看是在线笔试,但是非常严格,全称窗口不得最小化和关闭,转移,全称需要打开摄像头监控,使用草稿纸需要摄像头对准……反正2个小时,题量在那儿摆着,有作弊的功夫不如好好做做最后的编程题呢……网易不让泄漏原 ...