canvas-isPointPath

2019-07-08  本文已影响0人  我只会吃饭

含义: Canvas中很多交互的行为离不开这个属性,isPointInPath(x , y)是Canvas 2D API用于检测某点是否在路径的描边内(包括路径上)的方法,返回值是布尔值

语法:
isPointInPath(x , y): x代表的横坐标,y代表的纵坐标

注意: 要记住其方法是针对路径的,canvas中绘制路径 arc rect方法都是可以使用该方法,判断鼠标是否位于该路径范围内,包括路径上
isPointInPath()不支持canvas自带的两个方法fillRect(),strokeRect();
可以使用下面两种方法替换

ctx.rect(x,y,w,h);
ctx.stroke(); //替代strokeRect();

ctx.rect(x,y,w,h);
ctx.fill(); //替代fillRect();

栗子:
我们来一个饼状图,每一块都是一个闭合的路径区域,当鼠标移动至某一块区域内则,填充色为红色


isPointPath.gif

JS

  1. 初始
var canvas = document.createElement('canvas');

canvas.width = 500;
canvas.height = 500;
canvas.style.border = '1px solid #ccc';
document.body.appendChild(canvas);

var ctx = canvas.getContext('2d');
  1. 假想一个数据
var data = [1, 2, 3, 4];
var colors = ['green', 'blue', 'orange', 'yellow'];
  1. 预备阶段
// 求和
var sum = data.reduce((pre, cur) => pre + cur);
// 总角度为360
var deg = 2 * Math.PI / sum;
// 默认起始角度为 0 当循环到下一个角时,为前一个区域的结束角度
var beforeDeg = 0;
for (var i = 0; i < data.length; i++) {
    // 开启新路径
    ctx.beginPath();
    // 移动至中心点
    ctx.moveTo(250, 250);
    // 结束角度
    var endDeg = deg * data[i] + beforeDeg;
    // 画路径
    ctx.arc(250, 250, 100, beforeDeg, endDeg);
    // 闭合路径
    ctx.closePath();
    // 设置颜色
    ctx.fillStyle = colors[i];
    // 填充颜色
    ctx.fill();
    // 更新角度
    beforeDeg = endDeg;
}
  1. 监听鼠标移动事件
canvas.addEventListener('mousemove', move);

function move(event) {
    // 获取鼠标位置
    var x = event.clientX - canvas.getBoundingClientRect().x;
    var y = event.clientY - canvas.getBoundingClientRect().y;
    // 清除画布
    ctx.clearRect(0, 0, 500, 500);
    // 默认起始角度为 0 当循环到下一个角时,为前一个区域的结束角度
    var beforeDeg = 0;

    // 重新绘制路径
    for (var i = 0; i < data.length; i++) {
        // 开启新路径
        ctx.beginPath();
        // 移动至中心点
        ctx.moveTo(250, 250);
        // 结束角度
        var endDeg = deg * data[i] + beforeDeg;
        // 画路径
        ctx.arc(250, 250, 100, beforeDeg, endDeg);
        // 闭合路径
        ctx.closePath();
        // 如果鼠标处于当前路径区域 则为红色
        if (ctx.isPointInPath(x, y)) {
            ctx.fillStyle = 'red';
        } else {
            // 否则会原来色
            ctx.fillStyle = colors[i];
        }
        // 填充颜色
        ctx.fill();
        // 更新角度
        beforeDeg = endDeg;
    }
}
上一篇下一篇

猜你喜欢

热点阅读