javascript - 如何在表单上使用画布保存/下载绘图
问题描述
我正在尝试使用一个框制作一个表单,用户可以在其中用鼠标绘制一些东西。保存表格时,必须将绘制的文件存储起来,并将其名称链接到数据库中。
我不习惯画布,我有点挣扎。这是js代码部分:
$(document).ready(() => {
var canvasDiv = document.getElementById('canvasDiv');
var canvas = document.createElement('canvas');
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
$("#canvas").attr('height', $("#canvasDiv").outerHeight());
$("#canvas").attr('width', $("#canvasDiv").width());
if (typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d");
$('#canvas').mousedown(function(e) {
var offset = $(this).offset()
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - offset.left, e.pageY - offset.top);
redraw();
});
$('#canvas').mousemove(function(e) {
if (paint) {
var offset = $(this).offset()
//addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
addClick(e.pageX - offset.left, e.pageY - offset.top, true);
console.log(e.pageX, offset.left, e.pageY, offset.top);
redraw();
}
});
$('#canvas').mouseup(function(e) {
paint = false;
});
$('#canvas').mouseleave(function(e) {
paint = false;
});
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
function addClick(x, y, dragging) {
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
$("#reset-btn").click(function() {
context.clearRect(0, 0, window.innerWidth, window.innerWidth);
clickX = [];
clickY = [];
clickDrag = [];
});
$(document).on('click', '#btn-save', function() {
var mycanvas = document.getElementById('canvas');
var img = mycanvas.toDataURL("image");
window.location.assign=img;
anchor = $("#signature");
anchor.val(img);
img.download = 'image.png';
$("#signatureform").submit();
});
var drawing = false;
var mousePos = {
x: 0,
y: 0
};
var lastPos = mousePos;
canvas.addEventListener("touchstart", function(e) {
mousePos = getTouchPos(canvas, e);
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousedown", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
canvas.addEventListener("touchend", function(e) {
var mouseEvent = new MouseEvent("mouseup", {});
canvas.dispatchEvent(mouseEvent);
}, false);
canvas.addEventListener("touchmove", function(e) {
var touch = e.touches[0];
var offset = $('#canvas').offset();
var mouseEvent = new MouseEvent("mousemove", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
// Get the position of a touch relative to the canvas
function getTouchPos(canvasDiv, touchEvent) {
var rect = canvasDiv.getBoundingClientRect();
return {
x: touchEvent.touches[0].clientX - rect.left,
y: touchEvent.touches[0].clientY - rect.top
};
}
var elem = document.getElementById("canvas");
var defaultPrevent = function(e) {
e.preventDefault();
}
elem.addEventListener("touchstart", defaultPrevent);
elem.addEventListener("touchmove", defaultPrevent);
function redraw() {
//
lastPos = mousePos;
for (var i = 0; i < clickX.length; i++) {
context.beginPath();
if (clickDrag[i] && i) {
context.moveTo(clickX[i - 1], clickY[i - 1]);
} else {
context.moveTo(clickX[i] - 1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
})
这是我的表格:
{% extends '@!EasyAdmin/layout.html.twig' %}
{% block content %}
{% for flashError in app.flashes('verify_email_error') %}
<div class="alert alert-danger" role="alert">{{ flashError }}</div>
{% endfor %}
{{ form_start(formWithElectroSignature) }}
<div class="form-control js-user-autocomplete" autocomplete="on">
{{ form_label(formWithElectroSignature.personnel) }}<br>
{{ form_widget(formWithElectroSignature.personnel) }}
</div>
<div class="form-control">
<i class="fa fa-calendar"></i> {{ form_label(formWithElectroSignature.dateDebut) }}<br>
{{ form_widget(formWithElectroSignature.dateDebut) }}
</div>
<div class="form-control">
{{ form_label(formWithElectroSignature.cle) }}<br>
{{ form_widget(formWithElectroSignature.cle) }}
</div>
<div class="form-control">
{{ form_label(formWithElectroSignature.document) }}<br>
{{ form_widget(formWithElectroSignature.document) }}
</div>
<div class="form-control">
<div class="col-md-8 col-md-offset-2">
<br>
<?php echo isset($msg)?$msg:''; ?>
<h2>Signature Electronique !</h2>
<hr>
<div id="canvasDiv"></div>
<br>
<button type="button" class="btn btn-danger" id="reset-btn">Clear</button>
<button type="button" class="btn btn-success" id="btn-save">Save</button>
</div>
<form id="signatureform" action="" style="display:none" method="post">
<input type="hidden" id="signature" name="signature">
<input type="hidden" name="signaturesubmit" value="1">
</form>
</div>
</div>
<div class="row">
{{ form_end(formWithElectroSignature) }}
{% endblock %}
{% block body_javascript %}
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8=" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-beta4/html2canvas.min.js"></script>
<script src="/signatures/Signature.js"></script>
{% endblock %}
在当前状态下,我可以在控制台中看到绘图。但它没有保存在服务器上。我缺少什么,我是否朝着正确的方向去做?
解决方案
Canvas.toDataUrl
返回一个base64编码的字符串,如果你想使用/保存它作为一个文件,你首先必须将base64字符串转换为一个blob。然后这个 blob 可以通过 xml 或 Ajax 请求发送给您的后端处理。
您可以在类似问题的答案中找到带有示例的过程:https ://stackoverflow.com/a/50538148/15282066
推荐阅读
- javascript - 如何使用 javascript 推送评论?
- r - 选择另一个标记后,如何清除已添加到传单地图的标记?
- iis - 诊断在 IIS 上运行的网站中的零星锁定
- java - 当我尝试在 JPQL 中使用 Case 语句时出现问题
- python - 比较不同 pandas 数据集中的 2 列,如果值存在于第二个数据集中,则替换值
- javascript - 如何与 momentjs 约会?
- c++ - 插入 unordered_map 时的 bad_alloc
- automated-tests - 如何使用绝对路径而不是类路径来读取文件
- c# - 在 Jpath 中转义单引号
- python-3.x - 无法从命令行运行 tensorboard 来评估我的模型的效率