如何在动态上绘制 canvas
how to make drawable on dynamic canvas
我根据数据库中的记录动态显示 canvas。目前我有
数据库中有两条记录,它在 page.Now 中显示了两个 canvas 我应该可以绘制
在两个 cannvas 上,但是我只能在最后一个 canvas 上绘制,而不是在两个 canvas 上绘制。
请查看图片 https://ibb.co/n7rvdk5 了解更多信息。
我得到 id 609,610.It 可以是 1,2 等等。这个 id 传递给 canvas id 以使其唯一。
<div class="snap-field col-sm-12" style="height: 450px;">
loop here
<canvas data-fieldid="{{$draw->id}}"
id="image-canvas-{{$draw->id}}"
width="400" height="200"
class="image-canvas"
style="position:absolute;">
</canvas>
</div>
这是我的 js 部分,在 document.ready 函数中我加载了 canvas 。 initEditableImageCanvas 采用唯一标识。例如,在这种情况下,它需要 609 并且 610.I 可以在 ID 为 610 的 canvas 上绘制,但不能在 609.Maybe 上绘制 我需要在这里进行一些更改,我不确定我应该做什么
<script>
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "red",
y = 2;
function initEditableImageCanvas(fieldId) {
canvas = document.getElementById('image-canvas-' + fieldId);
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
canvas.addEventListener("mousemove", function(e) {
findxy('move', e)
}, false);
canvas.addEventListener("mousedown", function(e) {
findxy('down', e)
}, false);
canvas.addEventListener("mouseup", function(e) {
findxy('up', e)
}, false);
canvas.addEventListener("mouseout", function(e) {
findxy('out', e)
}, false);
}
function draw() {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e) {
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.getBoundingClientRect().left;
currY = e.clientY - canvas.getBoundingClientRect().top;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.getBoundingClientRect().left;
currY = e.clientY - canvas.getBoundingClientRect().top;
draw();
}
}
}
$(document).ready(function() {
$(".image-canvas").each(function(canvas) {
//get id
initEditableImageCanvas($(this).data("fieldid"));
});
});
</script>
我正在寻求帮助来修复它。我要抽取全部 canvas。
有什么帮助吗?谢谢
为了利用 canvas,您可以将其存储在一个变量中,以便能够应用您的逻辑。
let canvas = document.getElementById('canvasId');
let ctx = canvas.getContext('2d')
/*
Logic
*/
但是,在您的情况下,由于 canvas
和 ctx
是全局变量,因此每次在 jQuery 中调用 initEditableImageCanvas()
时都会重新分配它们s each()
.
因此,即使每当一个事件(即 mousemove
)发生时都会调用函数 findxy()
,但仅在正确的位置绘制是不够的。你
必须检查它是否指向右侧 canvas.
这就是说,为了防止意外行为,在处理多个可绘制对象 canvas
时,更喜欢使用用 let
语句定义的局部变量而不是全局变量。一种解决方案如下:
- 更改
var
-> let
- 将第三个参数 (
c
) 添加到 findxy()
- 向
draw()
添加一个参数(ctx
)
// get rid of global canvas and ctx
var flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "red",
y = 2;
function initEditableImageCanvas(fieldId) {
// use let
let canvas = document.getElementById('editable-image-canvas-' + fieldId);
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
/*
Attach this to each findxy
*/
canvas.addEventListener("mousemove", function(e) {
findxy('move', e, this)
}, false);
canvas.addEventListener("mousedown", function(e) {
findxy('down', e, this)
}, false);
canvas.addEventListener("mouseup", function(e) {
findxy('up', e, this)
}, false);
canvas.addEventListener("mouseout", function(e) {
findxy('out', e, this)
}, false);
}
function draw(ctx) {
// added parameter ctx
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e, c) {
// added parameter c and local ctx
let ctx = c.getContext('2d')
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - c.getBoundingClientRect().left;
currY = e.clientY - c.getBoundingClientRect().top;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - c.getBoundingClientRect().left;
currY = e.clientY - c.getBoundingClientRect().top;
draw(ctx); // added argument
}
}
}
$(document).ready(function() {
$(".editable-image-canvas").each(function(canvas) {
// alert($(this).data("fieldid")) //give id 609 and 610
initEditableImageCanvas($(this).data("fieldid"));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="snap-field col-sm-12" style="height: 450px;"> <div style="display:grid;"> <span>609</span> <canvas data-fieldid="609" id="editable-image-canvas-609" width="200" height="150" class="editable-image-canvas" style="position:relative;top:10%;border:1px dotted; margin-bottom:30px;"> </canvas> <span>610</span> <canvas data-fieldid="610" id="editable-image-canvas-610" width="200" height="150" class="editable-image-canvas" style="position:relative;top:10%;border:1px dotted;"> </canvas> </div><input type="hidden" name="field_{{$draw->id}}" id="editable-image-hidden-{{$draw->id}}"></div>
我根据数据库中的记录动态显示 canvas。目前我有 数据库中有两条记录,它在 page.Now 中显示了两个 canvas 我应该可以绘制 在两个 cannvas 上,但是我只能在最后一个 canvas 上绘制,而不是在两个 canvas 上绘制。 请查看图片 https://ibb.co/n7rvdk5 了解更多信息。 我得到 id 609,610.It 可以是 1,2 等等。这个 id 传递给 canvas id 以使其唯一。
<div class="snap-field col-sm-12" style="height: 450px;">
loop here
<canvas data-fieldid="{{$draw->id}}"
id="image-canvas-{{$draw->id}}"
width="400" height="200"
class="image-canvas"
style="position:absolute;">
</canvas>
</div>
这是我的 js 部分,在 document.ready 函数中我加载了 canvas 。 initEditableImageCanvas 采用唯一标识。例如,在这种情况下,它需要 609 并且 610.I 可以在 ID 为 610 的 canvas 上绘制,但不能在 609.Maybe 上绘制 我需要在这里进行一些更改,我不确定我应该做什么
<script>
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "red",
y = 2;
function initEditableImageCanvas(fieldId) {
canvas = document.getElementById('image-canvas-' + fieldId);
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
canvas.addEventListener("mousemove", function(e) {
findxy('move', e)
}, false);
canvas.addEventListener("mousedown", function(e) {
findxy('down', e)
}, false);
canvas.addEventListener("mouseup", function(e) {
findxy('up', e)
}, false);
canvas.addEventListener("mouseout", function(e) {
findxy('out', e)
}, false);
}
function draw() {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e) {
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.getBoundingClientRect().left;
currY = e.clientY - canvas.getBoundingClientRect().top;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.getBoundingClientRect().left;
currY = e.clientY - canvas.getBoundingClientRect().top;
draw();
}
}
}
$(document).ready(function() {
$(".image-canvas").each(function(canvas) {
//get id
initEditableImageCanvas($(this).data("fieldid"));
});
});
</script>
我正在寻求帮助来修复它。我要抽取全部 canvas。 有什么帮助吗?谢谢
为了利用 canvas,您可以将其存储在一个变量中,以便能够应用您的逻辑。
let canvas = document.getElementById('canvasId');
let ctx = canvas.getContext('2d')
/*
Logic
*/
但是,在您的情况下,由于 canvas
和 ctx
是全局变量,因此每次在 jQuery 中调用 initEditableImageCanvas()
时都会重新分配它们s each()
.
因此,即使每当一个事件(即 mousemove
)发生时都会调用函数 findxy()
,但仅在正确的位置绘制是不够的。你
必须检查它是否指向右侧 canvas.
这就是说,为了防止意外行为,在处理多个可绘制对象 canvas
时,更喜欢使用用 let
语句定义的局部变量而不是全局变量。一种解决方案如下:
- 更改
var
->let
- 将第三个参数 (
c
) 添加到findxy()
- 向
draw()
添加一个参数(ctx
)
// get rid of global canvas and ctx
var flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "red",
y = 2;
function initEditableImageCanvas(fieldId) {
// use let
let canvas = document.getElementById('editable-image-canvas-' + fieldId);
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
/*
Attach this to each findxy
*/
canvas.addEventListener("mousemove", function(e) {
findxy('move', e, this)
}, false);
canvas.addEventListener("mousedown", function(e) {
findxy('down', e, this)
}, false);
canvas.addEventListener("mouseup", function(e) {
findxy('up', e, this)
}, false);
canvas.addEventListener("mouseout", function(e) {
findxy('out', e, this)
}, false);
}
function draw(ctx) {
// added parameter ctx
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e, c) {
// added parameter c and local ctx
let ctx = c.getContext('2d')
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - c.getBoundingClientRect().left;
currY = e.clientY - c.getBoundingClientRect().top;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - c.getBoundingClientRect().left;
currY = e.clientY - c.getBoundingClientRect().top;
draw(ctx); // added argument
}
}
}
$(document).ready(function() {
$(".editable-image-canvas").each(function(canvas) {
// alert($(this).data("fieldid")) //give id 609 and 610
initEditableImageCanvas($(this).data("fieldid"));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="snap-field col-sm-12" style="height: 450px;"> <div style="display:grid;"> <span>609</span> <canvas data-fieldid="609" id="editable-image-canvas-609" width="200" height="150" class="editable-image-canvas" style="position:relative;top:10%;border:1px dotted; margin-bottom:30px;"> </canvas> <span>610</span> <canvas data-fieldid="610" id="editable-image-canvas-610" width="200" height="150" class="editable-image-canvas" style="position:relative;top:10%;border:1px dotted;"> </canvas> </div><input type="hidden" name="field_{{$draw->id}}" id="editable-image-hidden-{{$draw->id}}"></div>