Canvas 中 isPointInPath

Canvas的isPointInPath方法用于检测点击或触摸位置是否在路径区域内,对于复杂形状如月牙形,该方法能解决数学判断的难题。在多条路径的情况下,可以通过保存和恢复绘图状态,结合触摸坐标的获取,实现交互效果,如鼠标悬停变色和点击事件处理。在最新的H5标准中,isPointInPath有更多的应用价值。

canvas 中的交互很多都可以用isPointInPath来完成
isPointInPath –就是一个检测你的点击或者触摸下是否在这个区域内。
有人会说 很简单啊 在一个区域内 四个点的坐标就可以判断 数学方式不难的
这时候要是来一个月牙形 而且在月弯的空白处点击,我 想你也会感叹 真是扯犊子般的难过了。
首先 大家都知道 canvas 是基于状态绘图的 就是先声明路径 样式 最后保存 绘画状态
说到 isPointInPath 它也是路径的 还是当前的 你之前绘制了 十条之后
突然的去判断是否在这个区域内那就 抓瞎了 那就先附上月牙的检测吧

        var canvas=document.getElementById('canvas_point');
        var context=canvas.getContext('2d');
        //加载完成就添加触摸事件
        window.onload=function()
        {           
            canvas.addEventListener('touchstart',cheeckIsPointInPath,false);            
        }
        // 接着就是检测是否在这个区域内的函数了
        function cheeckIsPointInPath(event)
            {
                var e_X=event.touches[0].clientX-canvas.getBoundingClientRect().left;
                var e_Y=event.touches[0].clientY-canvas.getBoundingClientRect().top;
                Draw();
                if(context.isPointInPath(e_X,e_Y))
                {
                    alert('在区域内');
                }else
                {
                    alert('不在区域');
                }
                context.fill();
            }
            //绘制方法 
                function  Draw()
            {
                  context.fillStyle = 'rgb(174,237,249)';
                  context.lineJoin='round';
                  context.lineWidth=50;
                  context.beginPath();
                  context.moveTo(170,516);                
                  context.lineTo(141,249);
                  context.lineTo(367,114);
                  context.lineTo(559,223);
                  context.lineTo(529,303);
                  context.lineTo(358,191);
                  context.lineTo(254,266);
                  context.lineTo(258,529);
                  context.lineTo(170,516);            
                  context.closePath();                              
            }

月牙

其实你会发现上面就只有单条绘制的状态 在判断内部几乎不用那么多 只要 获取 触摸时的坐标就好了
但是当你有多条的时候你就会想怎么办呢 ?
我用了很傻的办法 :

function Draw_img1()
            {
                                context.beginPath();
                                context.rect(0,410,199,100);    
                                context.fillStyle='#005580';
                                context.closePath();
            }
            function Draw_img2()
            {
                                context.beginPath();
                                context.fillStyle='#005580';
                                context.rect(200,410,199,100);  
                                context.closePath();
            }
            function Draw_img3()
            {
                                context.beginPath();
                                context.fillStyle='#1B6D85';
                                context.rect(400,410,199,100);  
                                context.closePath();
            }
            var  draw=[Draw_img1,Draw_img2,Draw_img3];
//你肯定想说 javascript 的对象 你倒是用啊  存放 x y 坐标多好 。。
//奈何我才疏学浅 暂时还没有玩转canvas 只能慢慢的先摸着石头过河。
            function bet(event)
            {
                    var e_X=event.touches[0].clientX-canvas.getBoundingClientRect().left;
                    var e_Y=event.touches[0].clientY-canvas.getBoundingClientRect().top;
                    for(var i=draw.length;i--;)
                    {   
                            draw[i]();
                            if(context.isPointInPath(e_X,e_Y))
                            {                               
                                if(bet_State==true)
                                {                                   
                                    console.log(" 点击了矩形区域"+i);
                                    bet_State=false;
                                }                                           
                            }
                            //这里可以根据你的想法来的  填充不填充随你的
                            context.fill();
                    }   
                }

isPointInPath 你可以用来做 鼠标挪上去 变颜色 移走又变颜色 点击做什么事情啊
看看最新版的H5标准的 值得一瞅

### 在 Canvas 中添加地图并实现地图经纬度的显示或交互 在 HTML5 Canvas 中加载地图并处理地图的经纬度坐标,主要涉及以下几个关键步骤: #### 1. 加载并解析 GeoJSON 地图数据 地图数据通常以 GeoJSON 格式提供,可通过 `fetch()` 方法异步加载并解析: ```javascript fetch('map.geojson') .then(response => response.json()) .then(geojsonData => { // 解析 GeoJSON 数据并进行绘制 }); ``` 在解析完成后,需要遍历所有坐标点,计算地图的最大和最小经纬度值,以确定地图的包围盒范围。需要注意的是,GeoJSON 数据中可能包含多面和洞的结构,因此必须确保所有坐标点都被正确遍历[^1]。 #### 2. 地理坐标到屏幕坐标的转换 由于 Canvas 使用的是像素坐标系,而地图数据是以经纬度表示的地理坐标系,因此需要将经纬度转换为屏幕坐标。通常使用线性变换方法进行映射,并结合画布尺寸和地图包围盒进行比例缩放: ```javascript function latLngToScreen(lat, lon, bounds, canvasSize) { const { minLat, maxLat, minLon, maxLon } = bounds; const { width, height } = canvasSize; const x = ((lon - minLon) / (maxLon - minLon)) * width; const y = height - ((lat - minLat) / (maxLat - minLat)) * height; return { x, y }; } ``` 为了使地图完整显示在画布中,需计算合适的缩放比例。通过比较宽度和高度方向的比例,选择较小的比例值进行等比缩放: ```javascript var xScale = width / Math.abs(bounds.xMax - bounds.xMin); var yScale = height / Math.abs(bounds.yMax - bounds.yMin); var scale = xScale < yScale ? xScale : yScale; ``` #### 3. 绘制地图并标注经纬度坐标 使用 Canvas 的 `beginPath()`、`moveTo()`、`lineTo()` 等方法绘制地图轮廓。遍历 GeoJSON 数据中的多边形要素,并将每个坐标点转换为屏幕坐标后绘制: ```javascript ctx.beginPath(); geojsonData.features.forEach(feature => { feature.geometry.coordinates[0].forEach(coord => { const { x, y } = latLngToScreen(coord[1], coord[0], bounds, { width, height }); ctx.lineTo(x, y); }); ctx.stroke(); }); ``` 若需在地图上标注经纬度坐标,可以在绘制过程中添加文本标签: ```javascript ctx.fillStyle = 'red'; ctx.font = '12px Arial'; ctx.fillText(`Lat: ${lat}, Lon: ${lon}`, x, y); ``` #### 4. 实现地图交互功能 Canvas 的交互主要依赖鼠标事件。例如,可以通过点击事件判断用户是否点击了地图的某个区域: ```javascript canvas.addEventListener('click', function (e) { const rect = canvas.getBoundingClientRect(); const mouseX = e.clientX - rect.left; const mouseY = e.clientY - rect.top; geojsonData.features.forEach(feature => { ctx.beginPath(); feature.geometry.coordinates[0].forEach(coord => { const { x, y } = latLngToScreen(coord[1], coord[0], bounds, { width, height }); ctx.lineTo(x, y); }); if (ctx.isPointInPath(mouseX, mouseY)) { alert(`您点击了:${feature.properties.name}`); } }); }); ``` 此外,还可以通过 `isPointInStroke()` 方法检测鼠标是否位于地图边线上,实现更精细的交互控制。 #### 5. 地图状态变化时的坐标重绘 当地图状态发生变化(如缩放、平移)时,需要重新计算坐标并重绘地图。可以通过监听事件(如按钮点击、滚轮事件)来触发重绘逻辑,并根据新的缩放和平移参数更新绘制函数。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值