环形菜单----6个菜单项

这个是用canvas做的, 因为我喜欢那个跟抽奖似的那种效果, 所以每个菜单转的方向都是一样的
不懂得可以在下边评论, 我会回复的

html:

<div class="menu">
	<!-- canvas就是一块画布, 宽度默认是300, 高度是150, 改变不能用CSS -->
	<canvas></canvas>
	<div class="outer">
		<!-- 外面的圆圈 -->
	</div>
	<div class="inner">
		<!-- 里面的圆圈 -->
	</div>
</div>

js

var isToggle = false;				// 标识当前是否处于菜单切换状态
var curDeg = 0;						// 标识menu当前旋转的度数
var menuText = ['神王盖伦', '神王诺手', '黑夜使者亚索', '光明使者瑞文', '青年瑞兹', '吕布', '赵云', '源计划·薇恩']
var menuMapRegion = [0,1,2,3,4,5];	// 将菜单和区域绑定
// 画菜单
var canvas = document.querySelector('canvas')
// 动态设置canvas的大小
canvas.setAttribute('width', canvas.parentNode.offsetWidth);
canvas.setAttribute('height', canvas.parentNode.offsetHeight);
// 算出外圈和内圈的半径
var outerRadius = canvas.width / 2;
var innerRadius = outerRadius / 2;


function drawMenu() {

	console.log(outerRadius, innerRadius)
	// 获取canvas画布画布的上下文对象
	var ctx = canvas.getContext('2d')
	// 平移ctx坐标系, 方便后序的划线操作
	ctx.translate(outerRadius, outerRadius);
	ctx.save(); // 存档, 方便下次获取
	// 画线
	// 进入for循环前, 先让ctx坐标系先旋转30度
	ctx.rotate(Math.PI / 6);
	for (var i = 0; i < 6; i++) {
		ctx.beginPath();
		ctx.moveTo(0, 0);
		ctx.lineTo(outerRadius, 0);
		ctx.strokeStyle = '#0094ff';
		ctx.stroke(); // 对beginPathhe closePath中间的所有操作进行描边
		ctx.closePath();
		ctx.rotate(Math.PI / 3); // 不断旋转ctx坐标系方便画线
	}
	// 画字
	ctx.restore(); // 重置坐标系, 调用存档
	// ctx.rotate(-Math.PI/8)
	var y = innerRadius + (outerRadius - innerRadius) / 2;
	ctx.font = 'normal 16px april';
	ctx.fillStyle = '#0094ff'
	ctx.textAlign = 'center'
	ctx.textBaseline = 'middle'
	ctx.rotate(Math.PI / 6);
	for (var i = 0; i < 6; i++) {
		ctx.fillText(menuText[i], 0, y);
		ctx.rotate(-Math.PI / 3);
	}
	ctx.restore()
}


drawMenu();


document.querySelector('.outer').onclick = function(e) {
	if(isToggle) return;			// 如果当前正在发生切换状态, 点击无效
	// 找出用户点击的是哪个区域
	var regionIndex = getRegionIndex(e.offsetX, e.offsetY);
	if(regionIndex === 0) return;
	isToggle = true;				// 标识进入了菜单切换状态
	toggleMenu(regionIndex);
	// 找出用户点击的 哪个菜单
	console.log('你激活了下标为:' + menuMapRegion[regionIndex] + '的菜单');
	// 调用
	updataMenuMapRegion(regionIndex)
}


function getRegionIndex(x, y) {
	x = x - outerRadius;
	y = y - outerRadius;
	if(Math.abs(y)/Math.abs(x) < Math.tan(Math.PI/6)) {
		return x >0 ? 0 :3;
	} else {
		if(x > 0) return y > 0 ? 5 :1;
		else return y > 0 ? 4 : 2; 
	}
}


function toggleMenu(regionIndex) {
	let deg = 0;
	switch(regionIndex) {
		case 1: deg = curDeg + 60 ;break;
		case 2: deg = curDeg + 60 * 2 ;break;
		case 3: deg = curDeg + 60 * 3;break;
		case 4: deg = curDeg + 60 * 4;break;
		case 5: deg = curDeg + 60 * 5;break;
	}
	curDeg = deg;
	canvas.style.transform = `rotate(${ deg }deg)`;
	setTimeout(function() {
		isToggle = false;
	}, 620);
	
}


function updataMenuMapRegion(regionIndex) {
	var temp = menuMapRegion.slice(0, regionIndex);
	menuMapRegion.splice(0, regionIndex);
	menuMapRegion = menuMapRegion.concat(temp)
}



CSS

* { margin:0; padding:0; }
.menu { width: 600px; height: 600px; position: relative;margin:100px auto; }
.menu>canvas { transition: all .6s ease-out; }
.menu>.outer, .menu>.inner {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	border-radius: 50%;
	box-sizing: border-box;
}
.menu>.outer {
	width: 100%; height: 100%;
	border: 1px solid #0094ff;
	cursor: pointer;
}

.menu>.inner {
	background-color: #0094FF;
	width: 50%; height: 50%;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值