繁体   English   中英

鼠标悬停检测 JS 画布上的不同形状

[英]Mouse over detection for distinct shapes on a JS canvas

我如何获得路径绘制的画布? 通过 JSON 为我绘制超过 30 个矩形,但是我如何在悬停在特定绘制的画布上后吸引以下功能悬停以更改我的背景?

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.globalAlpha = 0.7;
var grd = ctx.createLinearGradient(150, 2, 300, 200);
grd.addColorStop(0, "red");
grd.addColorStop(1, "red");
ctx.fillStyle = grd;
ctx.fillRect(200,200,200,200); 

$(canvas).hover(function() {
  $(this).css("background-color", "yellow");
  console.log(ctx);
},function() {
  $(this).css("background-color", "");
});

在此处输入图片说明

^ 这是它的样子。

当鼠标位于绘制元素上时,我想更改背景

您要么需要对像素进行颜色编码,要么跟踪您绘制的矩形,然后在鼠标移动时执行点到矩形碰撞检查。

也许使用 SVG 而不是画布会使您的任务更容易,因为 SVG 元素可以单独生成事件。

我最近在研究一些与在画布上绘制形状相关的东西。 我希望下面的代码片段可以帮助你! 很抱歉代码中缺少注释。 更多详情可以直接问我

 var CANVAS_FILL_COLOR_ARR = ["blue", "red", "purple", "yellow", "green", "gray", "orange"]; function PositionModel(x, y) { this.x = x; this.y = y; } PositionModel.prototype.fromJson = function (json) { if (Array.isArray(json)) { return new PositionModel(json[0], json[1]); } else { return new PositionModel(json.x, json.y); } }; function RectangleShapeModel(x, y, w, h, fill) { this.x = x; this.y = y; this.w = w; this.h = h; this.fill = fill || "#AAAAAA"; } RectangleShapeModel.prototype.draw = function (ctx) { ctx.fillStyle = this.fill; ctx.fillRect(this.x, this.y, this.w, this.h); }; RectangleShapeModel.prototype.contain = function (point) { return (this.x <= point.x) && (this.x + this.w >= point.x) && (this.y <= point.y) && (this.y + this.h >= point.y); }; RectangleShapeModel.prototype.getInfo = function () { return "x: " + this.x + ", y: " + this.y + ", w: " + this.w + ", h: " + this.h; }; function CanvasStateModel(canvas, shapeData) { this.canvas = canvas; this.width = canvas.width; this.height = canvas.height; this.ctx = canvas.getContext("2d"); this.shapeData = shapeData; var paddingLeft = "paddingLeft"; var paddingTop = "paddingTop"; var borderLeftWidth = "borderLeftWidth"; var borderTopWidth = "borderTopWidth"; if (document.defaultView && document.defaultView.getComputedStyle) { this.stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)[paddingLeft], 10) || 0; this.stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)[paddingTop], 10) || 0; this.styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)[borderLeftWidth], 10) || 0; this.styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)[borderTopWidth], 10) || 0; } // Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page // They will mess up mouse coordinates and this fixes that var html = document.body.parentNode; this.htmlTop = html.offsetTop; this.htmlLeft = html.offsetLeft; // **** Keep track of state! **** this.invalidState(); // when set to false, the canvas will redraw everything this.shapes = []; // the collection of things to be drawn // remove old events canvas.myState = this; canvas.removeEventListener("mousemove", this.mouseMoveListener, true); canvas.addEventListener("mousemove", this.mouseMoveListener, true); // **** Options! **** this.selectionColor = "#CC0000"; this.selectionWidth = 2; this.drawInterval = 30; setInterval(function () { canvas.myState.draw(); }, this.drawInterval); } CanvasStateModel.prototype.mouseMoveListener = function (e) { var myState = e.target.myState; var mouse = myState.getMouse(e); var containShape = myState.pointInShapes(mouse); if (containShape !== null) { $("#result-panel").css('background-color', containShape.fill); } myState.invalidState(); // Something"s dragging so we must redraw }; CanvasStateModel.prototype.pointInShapes = function (point) { for (var i = this.shapes.length - 1; i >= 0; i--) { if (this.shapes[i].contain(new PositionModel(point.x, point.y))) { return this.shapes[i]; } } return null; }; CanvasStateModel.prototype.invalidState = function () { this.valid = false; }; CanvasStateModel.prototype.addShape = function (shape) { this.shapes.push(shape); this.invalidState(); }; CanvasStateModel.prototype.clear = function () { this.ctx.clearRect(0, 0, this.width, this.height); }; CanvasStateModel.prototype.drawShapes = function () { this.shapes = this.constructShapes(); var l = this.shapes.length; for (var i = 0; i < l; i++) { var shape = this.shapes[i]; // We can skip the drawing of elements that have moved off the screen: if (shape.x > this.width || shape.y > this.height || shape.x + shape.w < 0 || shape.y + shape.h < 0) { continue; } this.shapes[i].draw(this.ctx); } }; CanvasStateModel.prototype.draw = function () { // if our state is invalid, redraw and validate! if (!this.valid) { var ctx = this.ctx; // construct shapes from camera zone this.clear(); this.drawShapes(); // right now this is just a stroke along the edge of the selected Shape if (this.selection != null) { ctx.strokeStyle = this.selectionColor; ctx.lineWidth = this.selectionWidth; var mySel = this.selection; ctx.strokeRect(mySel.x, mySel.y, mySel.w, mySel.h); } // ** Add stuff you want drawn on top all the time here ** this.valid = true; } }; CanvasStateModel.prototype.constructShapes = function () { var shapes = []; for (var i = 0; i < this.shapeData.length; i++) { var shapeDataItem = this.shapeData[i]; var fill = CANVAS_FILL_COLOR_ARR[i % CANVAS_FILL_COLOR_ARR.length]; var shape = new RectangleShapeModel(shapeDataItem.x, shapeDataItem.y, shapeDataItem.w, shapeDataItem.h, fill); shapes.push(shape); } return shapes; }; // Creates an object with x and y defined, set to the mouse position relative to the state"s canvas // If you wanna be super-correct this can be tricky, we have to worry about padding and borders CanvasStateModel.prototype.getMouse = function (e) { var element = this.canvas; var offsetX = element.offsetLeft; var offsetY = element.offsetTop; var mx; var my; // Compute the total offset if (element.offsetParent !== undefined) { var parentElement = element.offsetParent; while (parentElement) { offsetX += parentElement.offsetLeft; offsetY += parentElement.offsetTop; parentElement = parentElement.offsetParent; } } // Add padding and border style widths to offset // Also add the <html> offsets in case there"sa position:fixed bar offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft; offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop; mx = e.pageX - offsetX; my = e.pageY - offsetY; return {x: mx, y: my}; }; $(document).ready(function () { var canvas = $("#layout-canvas")[0]; var shapeData = [{ x: 100, y: 100, w: 100, h: 100 }, { x: 300, y: 100, w: 200, h: 100 }, { x: 500, y: 100, w: 50, h: 100 }, { x: 700, y: 100, w: 80, h: 80 }]; function drawCanvas() { canvasState = new CanvasStateModel(canvas, shapeData); canvasState.invalidState(); } drawCanvas(); });
 #layout-canvas-wrapper { display: block; } #result-panel { width: 300px; height: 300px; display: block; border: 1px solid black; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="layout-canvas"> <div id="layout-canvas-wrapper"> <canvas id="layout-canvas" width="900" height="200"></canvas> </div> <div id="result-panel"></div> </div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM