javascript - 从 Canvas 转换后如何将图像作为表单的一部分提交?

标签 javascript jquery html css forms

假设我使用 .todataURL() 将 Canvas 转换为图像,然后我想将此图像作为表单的一部分提交。

我该怎么做?

var url = document.querySelector('canvas').toDataURL();

如何使用 URL 将此图像作为我的表单的一部分提交?

最佳答案

下面的代码片段展示了提交 Canvas 数据的两种不同方式。

  1. 第一个是使用带有 type=hidden 的标准输入元素。我在表单标签中添加了这种输入,并且在处理 Canvas 绘图结束的方法中更新了它的值。您的情况可能有所不同,但请记住在提交表单之前更新隐藏的输入值。
  2. 第二种方式是通过ajax提交。我使用完全相同的隐藏输入及其值,但在您的情况下,您可能不希望有一个输入并像这样直接获取 Canvas 数据:
document.querySelector('#canvas-data').toDataURL();

然后像这样发送:

$.post("https://httpbin.org/post", {
  canvasData: document.querySelector('#canvas-data').toDataURL()
});

这是两种方法的一个工作示例:

// =============
// == Globals ==
// =============
const canvas = document.querySelector('#drawing-area');
const canvasContext = canvas.getContext('2d');
const clearButton = document.querySelector('#clear-button');
const ajaxButton = document.querySelector('#ajax-button');
const canvasData = document.querySelector('#canvas-data');
const state = {
  mousedown: false
};

// ===================
// == Configuration ==
// ===================
const lineWidth = 5;
const strokeStyle = '#333';

// =====================
// == Event Listeners ==
// =====================
canvas.addEventListener('mousedown', handleWritingStart);
canvas.addEventListener('mousemove', handleWritingInProgress);
canvas.addEventListener('mouseup', handleDrawingEnd);
canvas.addEventListener('mouseout', handleDrawingEnd);

canvas.addEventListener('touchstart', handleWritingStart);
canvas.addEventListener('touchmove', handleWritingInProgress);
canvas.addEventListener('touchend', handleDrawingEnd);

clearButton.addEventListener('click', handleClearButtonClick);

ajaxButton.addEventListener('click', handleAjaxButtonClick);

// ====================
// == Event Handlers ==
// ====================
function handleWritingStart(event) {
  event.preventDefault();
  const mousePos = getMousePositionOnCanvas(event);
  canvasContext.beginPath();
  canvasContext.moveTo(mousePos.x, mousePos.y);
  canvasContext.lineWidth = lineWidth;
  canvasContext.strokeStyle = strokeStyle;
  canvasContext.fill();
  state.mousedown = true;
}

function handleWritingInProgress(event) {
  event.preventDefault();
  if (state.mousedown) {
    const mousePos = getMousePositionOnCanvas(event);
    canvasContext.lineTo(mousePos.x, mousePos.y);
    canvasContext.stroke();
  }
}

function handleDrawingEnd(event) {
  event.preventDefault();
  state.mousedown = false;
  canvasData.value = canvas.toDataURL()
}

function handleClearButtonClick(event) {
  event.preventDefault();
  clearCanvas();
}

function handleAjaxButtonClick(event) {
  const posting = $.post("https://httpbin.org/post", {
    canvasData: canvasData.value
  });
  posting.done(function(data) {
    console.log(data);
  });
}

// ======================
// == Helper Functions ==
// ======================
function getMousePositionOnCanvas(event) {
  const clientX = event.clientX || event.touches[0].clientX;
  const clientY = event.clientY || event.touches[0].clientY;
  const {
    offsetLeft,
    offsetTop
  } = event.target;
  const canvasX = clientX - offsetLeft;
  const canvasY = clientY - offsetTop;
  return {
    x: canvasX,
    y: canvasY
  };
}

function clearCanvas() {
  canvasContext.clearRect(0, 0, canvas.width, canvas.height);
}
.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 95vh;
}

.drawing-area {
  box-shadow: 0 0 6px 0 #999;
}

button {
  margin: 2em;
  font-size: 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container" class="container">
  <form action="https://httpbin.org/post" method="post">
    <canvas id="drawing-area" class="drawing-area" height="500" width="500"></canvas>
    <div class="buttons-container">
      <button id="clear-button" type="button">Clear</button>
      <button type="submit">Submit</button>
      <button id="ajax-button" type="button">Submit with ajax</button>
    </div>
    <input id="canvas-data" type="hidden" name="canvas-data" />
  </form>
</div>

旁注:我使用 jQuery 发送异步请求,但您可以 Fetch API也是。

关于javascript - 从 Canvas 转换后如何将图像作为表单的一部分提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51109669/

相关文章:

javascript - 按钮需要点击两次才能折叠 html Angular div

java - 将网络应用程序与 facebook 事件 api 集成

javascript - 如何使用 Javascript 禁用 Chrome 浏览器中的开发者工具

javascript - 如何从对象列表中检索值列表?

javascript - 当数量变化时如何计算表中的行总计

javascript - html5音频多个播放按钮

javascript - 使用 ontouchmove 只触发一次

jquery - 如果元素具有类则切换复选框

c# - jquery e.preventdefault() 触发后,ASP.NET 按钮服务器单击事件未触发

html - Chrome 上的 Canvas drawImage 类型错误