- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想获取放置在 HTML canvas 标记中的图像的绘制区域的坐标,并将其发送到数据库。并将其填充到另一页中该图像的同一区域。以及如何通过单击重置按钮重置或清除绘制区域?
var canvas = document.getElementById("canvas");
var img = document.getElementById("imagearea"),
ctx = canvas.getContext("2d"),
painting = false,
lastX = 0,
lastY = 0,
lineThickness = 1;
canvas.width = canvas.height = 600;
ctx.fillRect(0, 0, 600, 600);
ctx.drawImage(img, 10, 10);
canvas.onmousedown = function(e) {
painting = true;
ctx.fillStyle = "#ff0000";
lastX = e.pageX - this.offsetLeft;
lastY = e.pageY - this.offsetTop;
};
canvas.onmouseup = function(e){
painting = false;
}
canvas.onmousemove = function(e) {
if (painting) {
mouseX = e.pageX - this.offsetLeft;
mouseY = e.pageY - this.offsetTop;
// find all points between
var x1 = mouseX,
x2 = lastX,
y1 = mouseY,
y2 = lastY;
var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
if (steep){
var x = x1;
x1 = y1;
y1 = x;
var y = y2;
y2 = x2;
x2 = y;
}
if (x1 > x2) {
var x = x1;
x1 = x2;
x2 = x;
var y = y1;
y1 = y2;
y2 = y;
}
var dx = x2 - x1,
dy = Math.abs(y2 - y1),
error = 0,
de = dy / dx,
yStep = -1,
y = y1;
if (y1 < y2) {
yStep = 1;
}
lineThickness = 5 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
if(lineThickness < 1){
lineThickness = 1;
}
for (var x = x1; x < x2; x++) {
if (steep) {
ctx.fillRect(y, x, lineThickness , lineThickness );
} else {
ctx.fillRect(x, y, lineThickness , lineThickness );
}
error += de;
if (error >= 0.5) {
y += yStep;
error -= 1.0;
}
}
lastX = mouseX;
lastY = mouseY;
}
}
<canvas id="canvas">
</canvas>
<img id="imagearea" src="https://media.istockphoto.com/photos/green-apple-with-leaf-and-cut-isolated-on-white-picture-id1141004606?k=6&m=1141004606&s=170667a&w=0&h=zwbN4lLc7MFb6f_aZ4npNL3i4Tgde-yINlYTztlI1QQ=" style="display: none;" />
<button> Reset </button>
最佳答案
为了实现您正在寻找的目标,您需要存储(顶部,左侧)位置的最小(x,y)坐标和(底部,右侧)位置的最大(x,y)坐标,如果您要删除该区域上的绘图,则无法在同一 Canvas 上获取图像。使用相对于 Canvas 具有绝对位置的 HTML 元素作为区域框架,附加一个事件来裁剪,并显示另一个目标区域以将其删除。
这是一个有很多注释的工作示例,应该很清楚。点击显示预览的区域,“x”上的去掉随图一起画,可以处理多个区域。
const source = "https://media.istockphoto.com/photos/green-apple-with-leaf-and-cut-isolated-on-white-picture-id1141004606?k=6&m=1141004606&s=170667a&w=0&h=zwbN4lLc7MFb6f_aZ4npNL3i4Tgde-yINlYTztlI1QQ=";
const container = document.querySelector("#container");
const canvas = container.querySelector("canvas");
const ctx = canvas.getContext("2d");
const resetButton = document.querySelector("button");
let lastDrawnArea = [[Infinity, Infinity], [0, 0]];
let image;
let painting = false;
let lastX = 0;
let lastY = 0;
let lineThickness = 1;
init();
async function init() {
await loadDrawImage();
// Start Event Listening
canvas.onmousedown = function(e) {
painting = true;
ctx.fillStyle = "#ff0000";
lastX = e.pageX - this.offsetLeft;
lastY = e.pageY - this.offsetTop;
};
canvas.onmouseup = function(e){
painting = false;
// Set the drawing area
setDrawingArea();
}
canvas.onmousemove = function(e) {
if (painting) {
mouseX = e.pageX - this.offsetLeft;
mouseY = e.pageY - this.offsetTop;
// find all points between
var x1 = mouseX,
x2 = lastX,
y1 = mouseY,
y2 = lastY;
var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
if (steep){
var x = x1;
x1 = y1;
y1 = x;
var y = y2;
y2 = x2;
x2 = y;
}
if (x1 > x2) {
var x = x1;
x1 = x2;
x2 = x;
var y = y1;
y1 = y2;
y2 = y;
}
var dx = x2 - x1,
dy = Math.abs(y2 - y1),
error = 0,
de = dy / dx,
yStep = -1,
y = y1;
if (y1 < y2) {
yStep = 1;
}
lineThickness = 5 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
if(lineThickness < 1){
lineThickness = 1;
}
for (var x = x1; x < x2; x++) {
if (steep) {
ctx.fillRect(y, x, lineThickness , lineThickness );
} else {
ctx.fillRect(x, y, lineThickness , lineThickness );
}
error += de;
if (error >= 0.5) {
y += yStep;
error -= 1.0;
}
}
lastX = mouseX;
lastY = mouseY;
// Set The min, max coordinate of the current drawing
// to define the current drawing area
lastDrawnArea = [
[// Top left min([x, y]) coords
Math.min(lastDrawnArea[0][0], mouseX),
Math.min(lastDrawnArea[0][1], mouseY)
],
[// Bottom right max([x, y]) coords
Math.max(lastDrawnArea[1][0], mouseX),
Math.max(lastDrawnArea[1][1], mouseY)
]
]
}
}
}
async function loadDrawImage() {
image = new Image();
// Load the image
await new Promise(resolve => {
image.onload = resolve;
image.src = source;
});
const [width, height] = [image.naturalWidth, image.naturalHeight];
// Set the container and canvas size
container.style.width = `${width}px`;
container.style.height = `${height}px`;
canvas.width = width;
canvas.height = height;
// Set the container in the background
container.style.background = `url(${image.src})`;
}
function setDrawingArea(){
const [TOP_LEFT, BOTTOM_RIGHT, X, Y] = [0, 1, 0, 1];
const container = document.querySelector("#container");
const template = document.querySelector("#areaTemplate");
const area = template.content.firstElementChild.cloneNode(true);
// You should replace this with the lineThickness
const offset = 10;
// Get the area size
const width = lastDrawnArea[BOTTOM_RIGHT][X] - lastDrawnArea[TOP_LEFT][X];
const height = lastDrawnArea[BOTTOM_RIGHT][Y] - lastDrawnArea[TOP_LEFT][Y];
area.style.left = `${lastDrawnArea[TOP_LEFT][X] - offset}px`;
area.style.top = `${lastDrawnArea[TOP_LEFT][Y] - offset}px`;
area.style.width = `${width + (offset * 2)}px`;
area.style.height = `${height + (offset * 2)}px`;
// Draw the template
container.append(area);
// Add the events
area.onclick = previewArea; // Preveiw event
area.querySelector("b").onclick = removeArea; // Remove event
// Reset "lastDrawnArea" value
lastDrawnArea = [[Infinity, Infinity], [0, 0]];
}
function previewArea(e) {
const preview = document.querySelector("#preview");
const previewCanvas = preview.querySelector("canvas");
const previewCtx = previewCanvas.getContext("2d");
// Get the drawing area coords
const area = e.target;
const [x, y, width, height] = [
parseFloat(area.style.left),
parseFloat(area.style.top),
parseFloat(area.style.width),
parseFloat(area.style.height)
];
// Draw the preview area
previewCanvas.width = width;
previewCanvas.height = height;
previewCtx.drawImage(image,
x, y, width, height,
0, 0, width, height);
}
function removeArea(e) {
const area = e.target.parentElement;
const [x, y, width, height] = [
parseFloat(area.style.left),
parseFloat(area.style.top),
parseFloat(area.style.width),
parseFloat(area.style.height)
];
ctx.clearRect(x, y, width, height);
area.remove();
}
resetButton.onclick = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
document.querySelectorAll('.area').forEach(el => el.remove());
}
body {
display: flex;
}
#container {
position: relative;
}
.area {
position: absolute;
border: 2px solid #333;
color: #333;
cursor: pointer;
}
.area b {
position: absolute;
right: 0;
top: 0;
transform: translate(100%, -100%);
color: red;
cursor: pointer;
}
<div id="container">
<canvas></canvas>
</div>
<div id="preview">
<canvas></canvas>
</div>
<template id="areaTemplate">
<div class="area">
<b>x</b>
</div>
</template>
<button> Reset All </button>
如果两个区域重叠,则此示例存在一个问题,绘图将在两个区域的交集处被删除,要解决此问题,您需要将每个绘图保留在自己的 Canvas 上(...需要大量工作)。
最后但同样重要的是,如果您使用 fabric js 这样的库,您可以轻松获得相同的结果并更好地控制 Canvas 及其元素。 ,看看这个 freedrawing 的例子,您将免费获得绘图坐标,并且您仍然可以在同一 Canvas 上拥有所有内容(图像或您需要添加到 Canvas 的任何内容以及所有没有重叠的绘图......),初始学习曲线可能需要一些时间时间,但到一天结束时,您将对 HTML canvas 有一个整体的更好的理解。
旁注:您使用的图像有跨源限制,您应该使用来自同一域或允许跨源的域的图像。
关于javascript - 如何获取html canvas标签的坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65810478/
我有一个点(粉色圆圈),它有一个已知的 X 坐标和一个已知的 Y 坐标,但 Y 坐标> 坐标不正确。它当前位于目标贝塞尔曲线(部分位于白色正方形中的曲线)所在的点(如果它是两点之间的一条线)。我需要为
有一个基于QML 和QWT 的代码,一种具有更多可能性的图形生成器。技术要求之一是根据某个 X 坐标获得绘图曲线的 Y 坐标。 有一种不准确的方法 - 获取 QwtPlotCurve 的 QPoint
我目前正在将对象的 3D 坐标转换为 2D 坐标,然后在其上绘制 2D 文本(目前是对象名称): public static int[] getScreenCoords(double x, doubl
首先,我创建一个元组列表(要绘制的点)。每个元组由 3 个数字组成(x - 坐标,y - 坐标,c - 点的颜色) import random import matplotlib.pyplot as
我正在制作一个 2 人 Java 游戏,但我需要确保坐标保留在板上。 addPiece(1, 1, "X"); addPiece(8, 8, "O"); showBoard(); Scanner my
我想检查我是否正确使用了 scipy 的 KD 树,因为它看起来比简单的暴力破解要慢。 关于这个我有三个问题: Q1. 如果我创建以下测试数据: nplen = 1000000 # WGS84 lat
我有一个 GeoJSON 文件,我正在尝试处理它以便在谷歌地图上绘制一些功能。然而,问题在于坐标不是传统的纬度/经度表示法,而是一些大的六位/七位数字。示例: { "type":
我在使用坐标时遇到格式化问题。 public class Coordinate { public int x; public int y; public Coordinate( int x
我正在尝试获取当前位置的经度和纬度坐标。这是到目前为止我的代码: public class MainActivity extends AppCompatActivity { @Override pro
基本上,我需要获取从 OpenGL 中的贝塞尔曲线实现绘制的所有坐标。具体来说,我需要坐标来沿着弯曲的轨迹路径移动场景中的球体对象(棒球)。这是我用来绘制曲线的: GL2 gl = drawable.
现在我用 JAVA 遇到了一些问题,但不记得如何获取坐标系之间的长度。 例如。A 点 (3,7)B点(7,59) 我想知道如何计算a点和b点之间的距离。非常感谢您的回答。 :-) 最佳答案 A = (
我正在用 Pi2Go 机器人制作一个小项目,它将从超声波传感器获取数据,然后如果它看到一个物体,则放置一个 X,并放置 O 它当前所在的位置,我有两个问题:如何在 tkinter 上设置坐标位置?例如
如何在 pygame 中存储对象的先前坐标?我的问题可能有点难以解释,但我会尽力,如果您自己尝试我的代码以理解我的意思可能会有所帮助。 这就是我的游戏的内容。我希望这能让我的问题更容易理解。 我正在创
如何存储用户的当前位置并在 map 上显示该位置? 我能够在 map 上显示预定义的坐标,只是不知道如何从设备接收信息。 此外,我知道我必须将一些项目添加到 Plist 中。我怎样才能做到这一点? 最
我在 android 应用程序开发方面不是很熟练,我正在开发一个测试应用程序。我检测到了脸和眼睛,现在我要根据眼睛的坐标在脸上画一些像粉刺或疤痕的东西(例如脸颊上的眼睛下方)。稍后,我会把眼镜或帽子放
所以我正在使用 API 来检测图像中的人脸,到目前为止它对我来说效果很好。然而,我一直无法弄清楚如何将图像裁剪到脸上。我知道如何裁剪位图,但它需要获取位图中脸部的左上角位置以及宽度和高度。当我使用 查
我有 2 个表。第一个表包含以下列:Start_latitude、start_longitude、end_latitude、end_longitude、sum。 sum 列为空,需要根据第二张表进行填
有没有办法给 Google Maps API 或类似的 API 一个城镇名称,并让它返回城镇内的随机地址?我希望能够将数据作为 JSON 获取,以便我可以在 XCode 中使用 SwiftyJSON
我将坐标保存在 numpy 数组 x 和 y 中。现在我想要的只是获得一个多边形(分别是点数组),它用给定的宽度参数定义周围区域。 我遇到的问题是我需要一个没有(!)交叉点的多边形。但是,当曲线很窄时
我正在开发井字游戏 (3x3),所以我有 9 个按钮,我想做的是获取用户按下的按钮的坐标,并在按钮的位置插入图像。 例子: @IBOutlet weak var button1Outlet: UIBu
我是一名优秀的程序员,十分优秀!