alvin-canvasturntable
Version:
canvasTurntable:用 Canvas 根据传入的数据绘制转盘
278 lines (231 loc) • 9.84 kB
JavaScript
var $ = require("jquery");
var jQuery = require("jquery");
(function ($) {
$.fn.AddCanvasTurntable = function (options) {
var defaults = {
/********** 标签属性设置 **********/
sectorText: '', /* 扇形的文本值,应设置成数组形式 */
colors: '', /* 插件用到的颜色,应设置成数组形式 */
rotateTime: '', /* 转盘旋转一次的时间,单位 s,默认是 6s */
alertText: '', /* 全部选中之后的弹框内容 */
resultTitle: '' /* result 描述 */
},
settings = $.extend(defaults, options); //把传入的参数 options 合并到 defaults 里并赋给 settings;若 options 里的参数与 defaults 有重复,则 options 会覆盖 defaults 里的参数
var _this = this;
//转到当前选中的扇形需要旋转的角度
var angles;
//旋转次数
var rotNum = 0;
//当前选中的文本索引
var curIndex = 0;
//当前抽中内容
var notice = null;
//转盘旋转一次时间
var rotateTime = settings.rotateTime?settings.rotateTime:6;
//result 描述
var resultTitle = settings.resultTitle?settings.resultTitle:"当前已选中的结果如下:";
//全部选中之后的弹框内容
var alertText = settings.alertText?settings.alertText:"转盘里的内容已全部被选中!";
//转盘用到的颜色: [扇形颜色一,扇形颜色二,扇形颜色三,扇形字体颜色,指针字体颜色,指针和边框颜色]
//当扇形为奇数时,最后一块扇形的背景色为颜色三
var colors = settings.colors?settings.colors:["#e9536a","#fbd7a1","#df6679","#000","#fff","#666"];
//扇形的文本内容
var sectorText = settings.sectorText?settings.sectorText:["扇形一","扇形二","扇形三","扇形四","扇形五","扇形六","扇形七","扇形八","扇形九","扇形十","扇形十一","扇形十二","扇形十三","扇形十四"];
var textNum = sectorText.length;
//已选中过的文本内容
var selectedText = new Array();
//转盘 Canvas 参数
var canvasWidth = _this.width();//转盘为圆形,宽高相等
//ID 后缀
var idSuffix = Date.parse(new Date())/1000,
canvasWrapperID = "canvasWrapper-"+ idSuffix,
canvas1ID = "canvas1-"+ idSuffix,
canvas2ID = "canvas2-"+ idSuffix,
clickBtnID = "clickBtn-"+ idSuffix,
resultID = "result-"+ idSuffix;
//初始化转盘的 html 元素
initCanvasNode();
//初始化转盘
initTurntable();
//为指针绑定点击事件
$("body").on("click", "#"+clickBtnID+"", function(){
if(selectedText.length<sectorText.length){
//拿到随机数,计算旋转角度和当前选中文本
for(var i=0;i>-1;i++){
curIndex = rnd(0,sectorText.length-1);
if(!ifRepeat(selectedText,sectorText[curIndex])){
angles = 6*360*(rotNum+1) - curIndex*(360/textNum);
notice = sectorText[curIndex];
break;
}
}
//转盘旋转
runCup();
//转盘旋转过程“开始”按钮无法点击
$("#"+clickBtnID+"").attr("disabled", true);
//旋转次数加一
rotNum = rotNum + 1;
//恢复“开始”按钮的点击
setTimeout(function(){
console.log(notice);
var newText = $('<span>');
newText.html(sectorText[curIndex]);
if(selectedText.length!=0){
//$("#"+resultID+"").append('、');
}
selectedText.push(sectorText[curIndex]);
$("#"+resultID+"").append(newText);
$("#"+clickBtnID+"").removeAttr("disabled", true);
},rotateTime*1000);
}else{
alert(alertText);
}
});
//初始化转盘的 html 元素
function initCanvasNode(){
var canvasWrapper = $("<div id='"+canvasWrapperID+"'>");
canvasWrapper.css({"height":_this.width(),"width":_this.width(),"position":"relative"});
var canvasZhuanPan = $("<canvas id='"+canvas1ID+"' width='" + canvasWidth +"' height='" + canvasWidth +"'>");
canvasZhuanPan.css({"border-radius":"100%","transition":"transform "+rotateTime+"s","-o-transition":"transform "+rotateTime+"s","-ms-transition":"transform "+rotateTime+"s","-moz-transition":"transform "+rotateTime+"s","-webkit-transition":"transform "+rotateTime+"s","transform-origin":"50% 50%","-o-transform-origin":"50% 50%","-ms-transform-origin":"50% 50%","-moz-transform-origin":"50% 50%","-webkit-transform-origin":"50% 50%"});
canvasWrapper.append(canvasZhuanPan);
var canvasZhiZhen = $("<canvas id='"+canvas2ID+"' width='" + canvasWidth +"' height='" + canvasWidth +"'>");
canvasZhiZhen.css({"position":"absolute","top":"0","left":"0","z-index":"30"});
canvasWrapper.append(canvasZhiZhen);
var clickBtn = $("<button id='"+clickBtnID+"'>");
clickBtn.css({"position":"absolute","top":"50%","left":"50%","width":canvasWidth/5,"height":canvasWidth/5,"margin-top":-canvasWidth/10,"margin-left":-canvasWidth/10,"border-radius":"100%","cursor":"pointer","border":"none","background":"transparent","outline":"none","z-index":"40"});
canvasWrapper.append(clickBtn);
var resultDiv = $("<div id='"+resultID+"' class='result' width='" + canvasWidth +"'>");
resultDiv.css({"padding":"10px","border":"2px solid #aaa","margin-top":"20px","border-radius":"4px"});
var resultTitleNode = $("<h3>"+resultTitle+"</h3>");
resultDiv.append(resultTitleNode);
_this.append(canvasWrapper);
_this.append(resultDiv);
}
//初始化绘制转盘
function initTurntable(){
var canvas1 = document.getElementById(canvas1ID);
var canvas2 = document.getElementById(canvas2ID);
var ctx1 = canvas1.getContext('2d');
var ctx2 = canvas2.getContext('2d');
//初始化扇形
initSector();
//初始化扇形文本
initSectorText();
//初始化指针
initPoint();
//初始化扇形转盘
function initSector(){
var startAngle = 0;//扇形的开始弧度
var endAngle = 0;//扇形的终止弧度
//画一个 textNum 等份扇形组成的圆形
for (var i = 0; i< textNum; i++){
startAngle = i*Math.PI*2/textNum - Math.PI/2 + Math.PI*2/textNum/2; //保证初始化时指针正好对应在 扇形一 的中间
endAngle = startAngle+Math.PI*2*(1/textNum);
ctx1.save();
ctx1.beginPath();
ctx1.arc(canvasWidth/2,canvasWidth/2,canvasWidth/2, startAngle, endAngle, false);
ctx1.lineWidth = canvasWidth;
if (i%2 == 0) {
ctx1.strokeStyle = colors[0];
}else{
ctx1.strokeStyle = colors[1];
}
if(i==textNum-1 && textNum%2!=0){
ctx1.strokeStyle = colors[2];
}
ctx1.stroke();
ctx1.restore();
}
//中间白底圆圈:半径:canvasWidth/10
ctx1.beginPath();
ctx1.arc(canvasWidth/2,canvasWidth/2,canvasWidth/10,0,Math.PI*2,false);
ctx1.fillStyle = colors[4];
ctx1.fill();
ctx1.closePath();
}
//初始化扇形转盘文字
function initSectorText(){
ctx1.textAlign='start';
ctx1.textBaseline='middle';
ctx1.fillStyle = colors[3];
var step = 2*Math.PI/textNum;
for ( var i = 0; i < textNum; i++) {
ctx1.save();
ctx1.beginPath();
ctx1.translate(canvasWidth/2,canvasWidth/2);
ctx1.rotate(i*step);
ctx1.font = "Bold 16px Microsoft YaHei";
ctx1.fillStyle = colors[3];
var arrText = sectorText[i].split('');
for(var j=0;j<arrText.length;j++){
//-8 是为了让文字向左偏移半个字的宽度(大概是 8px)
ctx1.fillText(arrText[j], -8, 20*j-(canvasWidth/2-35), 20);
}
ctx1.closePath();
ctx1.restore();
}
}
//初始化指针
function initPoint(){
//画转盘最外边边框
ctx2.beginPath();
ctx2.strokeStyle = colors[5];
ctx2.arc(canvasWidth/2,canvasWidth/2,canvasWidth/2-2, 0, Math.PI*2, false);
ctx2.lineWidth = 3;
ctx2.stroke();
ctx2.closePath();
//箭头指针
ctx2.beginPath();
ctx2.moveTo(canvasWidth/2,canvasWidth*(3/10));
ctx2.lineTo(canvasWidth/2-9,canvasWidth/2);
ctx2.lineTo(canvasWidth/2+9,canvasWidth/2);
ctx2.lineTo(canvasWidth/2,canvasWidth*(3/10));
ctx2.fillStyle = colors[5];
ctx2.fill();
ctx2.closePath();
//中间小圆
ctx2.beginPath();
ctx2.arc(canvasWidth/2,canvasWidth/2,canvasWidth/10-3,0,Math.PI*2,false);
ctx2.fillStyle = colors[5];
ctx2.fill();
ctx2.closePath();
//小圆文字
ctx2.font = "Bold 16px Microsoft YaHei";
ctx2.textAlign='start';
ctx2.textBaseline='middle';
ctx2.fillStyle = colors[4];
ctx2.beginPath();
ctx2.fillText('开始',canvasWidth/2-16,canvasWidth/2-1,40);
ctx2.fill();
ctx2.closePath();
}
}
//转盘旋转
function runCup(){
var degValue = 'rotate('+angles+'deg'+')',
targetCanvas = $("#"+canvas1ID+"");
targetCanvas.css('-o-transform',degValue); //Opera
targetCanvas.css('-ms-transform',degValue); //IE浏览器
targetCanvas.css('-moz-transform',degValue); //Firefox
targetCanvas.css('-webkit-transform',degValue); //Chrome和Safari
targetCanvas.css('transform',degValue);
}
//获取随机数
function rnd(n, m){
return Math.floor(Math.random()*(m-n+1)+n)
}
//判断 str 是否存在于 arrtay 中
function ifRepeat(array,str){
for(var i=0;i<array.length;i++){
if(array[i]==str){
return true;
}
}
return false;
}
}
})(jQuery);
function createCanvasTurntable(cfg) {
return $("#" + cfg.targetNodeId).AddCanvasTurntable(cfg);
}
export default createCanvasTurntable;