canvas - 圆圈内 hover效果

各种计算还挺繁琐的, 关键点在角度的计算, 根据鼠标位置, 利用atan(y/x) 得到反正切值 , 角度  (tan输入的是r和x围成的那个角,输出的是y/x。反tan就是输入y/x输出角。)

<!DOCTYPE html>
<html>
<body>

<canvas id="canvas" width="800" height="950" style="border:1px solid #d3d3d3;margin-top:10px">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>

const canvas = document.getElementById(‘canvas‘);
const ctx = canvas.getContext(‘2d‘);
const PI = Math.PI;

const number = 4;//画4个外圆;
const reduceRadio = 15;//递减半径;

const maxRadius = 80;//最大半径
const minRadio = maxRadius-number*reduceRadio;

const translateX = 100;//canvas移动位置
const translateY = 100;

//canvas移动位置
ctx.translate(translateX,translateY);

//画所有圆
function drawAllOuterCircle(number,reduceRadio,maxRadius){

//画虚线
ctx.setLineDash([2,2]);

for(let i=0;i<number;i++){

ctx.beginPath();

//半径递减
ctx.arc(0,0, maxRadius-i*reduceRadio, 0, 2*PI);

if(i+n == 4){
ctx.strokeStyle = ‘red‘;
}else{
ctx.strokeStyle = ‘black‘;
}

ctx.stroke();
ctx.closePath();

}

//重置
ctx.restore();

//最里面小圆
ctx.beginPath();
ctx.arc(0,0,maxRadius-number*reduceRadio,0,2*PI);
ctx.fillStyle="red";
ctx.fill();
ctx.closePath();

ctx.restore();
}

drawAllOuterCircle(number,reduceRadio,maxRadius);

//画分割直线
const lineNum = 8;//分割线条数
const minAngel = 2*PI/lineNum;//最小角度

function drawSplitLine(lineNum,maxRadius){
for(let i=0;i<lineNum;i++){
ctx.setLineDash([]);

ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(0,maxRadius);
ctx.strokeStyle = ‘black‘;
ctx.stroke();

//旋转
ctx.rotate(2*PI/lineNum);
ctx.closePath();
}
}

drawSplitLine(lineNum,maxRadius);

//画阴影部分
function drawShadowPanel(ceilMouseRadio,floorMouseRadio,ceilMouseAngel,floorMouseAngel){

//清屏
ctx.beginPath();
ctx.moveTo(0,0);
ctx.arc(0,0,ceilMouseRadio+reduceRadio,0,2*PI);
ctx.fillStyle = "white";
ctx.fill();
ctx.closePath();

//调试: 先画一个大的绿色扇形
ctx.beginPath();
ctx.moveTo(0,0);
ctx.arc(0,0,ceilMouseRadio,floorMouseAngel,ceilMouseAngel);
ctx.fillStyle = "green";
ctx.fill();
ctx.closePath();

//再画一个小的白色扇形 覆盖 大的扇形, 视觉上形成一个弧形
ctx.beginPath();
ctx.moveTo(0,0);
ctx.arc(0,0,floorMouseRadio,floorMouseAngel,ceilMouseAngel);
ctx.fillStyle = "white";
ctx.fill();
ctx.closePath();
}

const maxN = (maxRadius-minRadio)/reduceRadio;
var n;

//获取ceilMouseRadio,floorMouseAngel,ceilMouseAngel

//获取canvas 的 位移
const canvasX = canvas.getBoundingClientRect().left + document.documentElement.scrollLeft +translateX;
const canvasY = canvas.getBoundingClientRect().top + document.documentElement.scrollTop +translateY;

function getMouseDetail(mouseX,mouseY){

//利用勾股定理 算出鼠标 离 canvas原点的距离
let mouseRadio = Math.sqrt( Math.pow(mouseX-canvasX, 2) + Math.pow(mouseY-canvasY, 2));

//因为 cavas原点已经移动到 100 100, 判断鼠标是否在圆圈内
if(mouseRadio>maxRadius||mouseRadio<=minRadio){
return {ceilMouseRadio:0,floorMouseRadio:0,floorMouseAngel:0,ceilMouseAngel:0};
}

//计算鼠标半径和最小半径的比例,画阴影块的大小半径 reduceRadio:15
n = Math.ceil((mouseRadio-minRadio)/reduceRadio);

let ceilMouseRadio = minRadio+n*reduceRadio;
let floorMouseRadio = minRadio+(n-1)*reduceRadio;

//角度
let mouseAngel;

if(mouseX-canvasX<0){
//计算当前鼠标 相对原点的的弧度值 , x轴 顺时针

// 比如 Math.atan(1)/Math.PI*180 是 45度
mouseAngel = Math.atan((mouseY-canvasY)/(mouseX-canvasX)) + PI;
}else{
mouseAngel = Math.atan((mouseY-canvasY)/(mouseX-canvasX));
}

// 计算当前鼠标 有多少个象限
let m = Math.ceil(mouseAngel/minAngel);

let floorMouseAngel = (m-1)*minAngel;
let ceilMouseAngel = m*minAngel;

return {ceilMouseRadio,floorMouseRadio,floorMouseAngel,ceilMouseAngel};
}

//监听事件画图
canvas.addEventListener(‘mousemove‘, (e)=>{

let mouseX = e.pageX;
let mouseY = e.pageY;

getMouseDetail(mouseX,mouseY);

let mouseDetail = getMouseDetail(mouseX,mouseY);
let {ceilMouseRadio,floorMouseRadio,floorMouseAngel,ceilMouseAngel} = mouseDetail;

if(ceilMouseRadio){
//先画阴影,
drawShadowPanel(ceilMouseRadio,floorMouseRadio,ceilMouseAngel,floorMouseAngel);
//再画圆圈
drawAllOuterCircle(number,reduceRadio,maxRadius);
drawSplitLine(lineNum,maxRadius);
}
});

</script>

</body>
</html>

链接

时间: 2024-10-08 19:33:06

canvas - 圆圈内 hover效果的相关文章

画线缩放、瞳距缩放、Line延长到指定长度,内附效果,源码供应,解压就跑

原文:画线缩放.瞳距缩放.Line延长到指定长度,内附效果,源码供应,解压就跑 前言 公司项目需要做个画线缩放,我司称之为瞳距缩放,简而言之就是:2张图,从第一张图画一条线,再从第二个图画一条线,第二条线以第一条为基准,延长到一致的长度,并同比缩放图片:文字太枯燥,请先实例图 例子1:以皮卡丘为例,我要把路飞的拳头缩放到皮卡丘头那么大 例子2:以皮卡丘的基准,缩小路飞,与其身高一致 好了,相比看了上面的2个效果图,就明白了大致意思,这个demo可以获得,Canvas里面的Line如何顺着线条方向

必备的Canvas接口和动画效果大全

1.概述 <canvas>元素用于生成图像.它本身就像一个画布,JavaScript 通过操作它的 API,在上面生成图像.它的底层是一个个像素,基本上<canvas>是一个可以用 JavaScript 操作的位图(bitmap).它与 SVG 图像的区别在于,<canvas>是脚本调用各种方法生成图像,SVG 则是一个 XML 文件,通过各种子元素生成图像.使用 Canvas API 之前,需要在网页里面新建一个<canvas>元素. <canvas

如何使用 HTML5 Canvas 制作水波纹效果

原文:如何使用 HTML5 Canvas 制作水波纹效果 今天,我们继续分享 JavaScript 实现的效果例子,这篇文章会介绍使用 JavaScript 实现水波纹效果.水波效果以图片为背景,点击图片任意位置都会触发.有时候,我们使用普通的 Javascript 就可以创建一个很有趣的解决功能. 在线演示      源码下载 Step 1. HTML 和以前一样,首先是 HTML 代码: <!DOCTYPE html> <html> <head> <meta

css3 hover效果

html代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> * { margin: 0; padding: 0; } a { text-decoration: none; color: #

一个简单的tr:hover效果

昨天,搞项目的时候,在一个小问题上卡了40分钟,现在想想,还是平时比较少去注意一些细节,经过这次,一定要去多注意细节了. 好了废话不多说,我现在说明下遇到的问题,一个表格中,要求是当鼠标滑过每一行时,该行就有高亮显示,前天写的时候感觉比较简单啊,就是在表格里面的tr加上一个hover样式就行,即是 tr:hover {...} ,这样就行了,当时也成功了.但是昨天项目又有调整,就是要给td一个背景色,我加上了背景色,当时没发现这个高亮的效果已经没了,晚上回来调试的时候老不行当时的想法是样式的优先

酷!使用 jQuery &amp; Canvas 制作相机快门效果

在今天的教程中,我们将使用 HTML5 的 Canvas 元素来创建一个简单的摄影作品集,它显示了一组精选照片与相机快门的效果.此功能会以一个简单的 jQuery 插件形式使用,你可以很容易地整合到任何网站. 效果演示     插件下载 您可能感兴趣的相关文章 Web 开发中很实用的10个效果[源码下载] 精心挑选的优秀jQuery Ajax分页插件和教程 12个让人惊叹的的创意的 404 错误页面设计 让网站动起来!12款优秀的 jQuery 动画插件 十分惊艳的8个 HTML5 & Java

Canvas之动态波浪效果_陈在真Sunny_chen_新浪博客

Canvas之动态波浪效果_陈在真Sunny_chen_新浪博客 Canvas之动态波浪效果 (2012-04-26 09:04:51) 转载▼

手机网页中的hover效果实现

js文件 function mouseout(obj) { var className ="hover"; var _ecname = obj.className; if (_ecname.length == 0) return; if (_ecname == className) { obj.className ="";return; } if (_ecname.match(new RegExp("(^|\s)"+ className +&qu

hover效果加边框不抖动

前两天遇到一个hover效果给整个div加边框的问题. html 如下  <div class="hot-recommend">         <div class="wrapper">             <div class="offer-list">                 <ul class='underline'>                     <li cla