当前位置: 首页 > news >正文

【第1章 基础知识】1.8 在 Canvas 中使用 HTML 元素

文章目录

  • 前言
  • 示例-橡皮筋式选取框
  • 示例代码


前言

尽管我们可以说 Canvas 是 HTML5 之中最棒的功能,不过在实现网络应用程序时,很少会单独使用它。在绝大多数情况下,你都会将一个或更多的 canvas 元素与其他 HTML 控件结合起来使用,以便让用户可以通过输入数值或其他方式来控制应用程序。

要将其他 HTML 控件与 canvas 结合起来使用,首先想到的办法可能是将控件嵌入到 canvas 元素之中。不过这么多不行,因为任何放入 canvas 元素主体部分的东西,只有在浏览器不支持 canvas 元素时,才会被显示出来。

浏览器要么显示 canvas 元素,要么显示放在元素之中的 HTML 控件,它不会将两者同时显示出来。所以,必须将控件放在 canvas 元素之外。

为了让 HTML 控件看上去好像是出现在 canvas 范围内,可以使用 CSS 将这些控件放置在 canvas 之上。


示例-橡皮筋式选取框

示例采用了一种名为“橡皮筋式”(rubberbanding)选取框的技术来让用户在 canvas 之中选择某个区域。起初,该 canvas 会显示一副图像,然后当选定图像的某一部分时,应用程序会将你所选的这部分区域放大。

在这里插入图片描述
在这里插入图片描述


示例代码

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8" /><title>橡皮筋选框放大器</title><style>body {background: rgba(100, 145, 250, 0.3);}#canvas {margin-left: 20px;margin-right: 0;margin-bottom: 20px;border: thin solid #aaaaaa;/*十字瞄准线*/cursor: crosshair;padding: 0;}#controls {margin: 20px 0px 20px 20px;}#rubberbandDiv {/*绝对定位,方便位置选取*/position: absolute;border: 3px solid yellow;cursor: crosshair;display: none;}</style></head><body><!--控制重置画面的按钮--><div id="controls"><input type="button" id="resetButton" value="Reset" /></div><!--橡皮筋选取狂div--><div id="rubberbandDiv"></div><canvas id="canvas" width="800" height="520">Canvas not supported</canvas><p>拖拽鼠标拉取橡皮筋,选中区域并放大</p></body><script>var canvas = document.getElementById('canvas'),context = canvas.getContext('2d'),rubberbandDiv = document.getElementById('rubberbandDiv'),resetButton = document.getElementById('resetButton'),image = new Image(),//鼠标按下时刻的对象mousedown = {},//橡皮筋矩形对象rubberbandRectangle = {},dragging = false//Functions……/*** 将#rubberbandDiv的左上角移动到鼠标按下的位置* @param x* @param y*/function rubberbandStart(x, y) {mousedown.x = xmousedown.y = yrubberbandRectangle.left = mousedown.xrubberbandRectangle.top = mousedown.ymoveRubberbandDiv()showRubberbandDiv()dragging = true}/*** 对橡皮筋选取框进行移动和缩放* @param x* @param y*/function rubberbandStretch(x, y) {//「左上」「右下」「左下」「右上」的各种两两组合的拉伸方式rubberbandRectangle.left = x < mousedown.x ? x : mousedown.xrubberbandRectangle.top = y < mousedown.y ? y : mousedown.yrubberbandRectangle.width = Math.abs(x - mousedown.x)rubberbandRectangle.height = Math.abs(y - mousedown.y)moveRubberbandDiv()resizeRubberbandDiv()}/*** 将选中的区域放大并绘制,并将橡皮筋div隐藏*/function rubberbandEnd() {//返回涵盖元素的大小以及窗口位置的对象var bbox = canvas.getBoundingClientRect()try {//选区放大context.drawImage(canvas,rubberbandRectangle.left - bbox.left,rubberbandRectangle.top - bbox.top,rubberbandRectangle.width,rubberbandRectangle.height,0,0,canvas.width,canvas.height)} catch (e) {// suppress error message when mouse is released// outside the canvasalert('鼠标释放错误警报!')}resetRubberbandRectangle()rubberbandDiv.style.width = 0rubberbandDiv.style.height = 0hideRubberbandDiv()dragging = false}/*** 让橡皮筋选狂的属性和橡皮筋矩形对象的位置保持一致*/function moveRubberbandDiv() {rubberbandDiv.style.top = rubberbandRectangle.top + 'px'rubberbandDiv.style.left = rubberbandRectangle.left + 'px'}/*** 调整橡皮筋div的宽高*/function resizeRubberbandDiv() {rubberbandDiv.style.width = rubberbandRectangle.width + 'px'rubberbandDiv.style.height = rubberbandRectangle.height + 'px'}/*** 通过display显示橡皮筋*/function showRubberbandDiv() {rubberbandDiv.style.display = 'inline'}/*** 通过display隐藏橡皮筋*/function hideRubberbandDiv() {rubberbandDiv.style.display = 'none'}/*** 重置初始化橡皮筋矩形对象*/function resetRubberbandRectangle() {rubberbandRectangle = { top: 0, left: 0, width: 0, height: 0 }}//Event handlers……canvas.onmousedown = function (ev) {var x = ev.x || ev.clientX,y = ev.y || ev.clientYev.preventDefault()rubberbandStart(x, y)}window.onmousemove = function (ev) {var x = ev.x || ev.clientX,y = ev.y || ev.clientYev.preventDefault()if (dragging) {rubberbandStretch(x, y)}}window.onmouseup = function (ev) {ev.preventDefault()rubberbandEnd()}image.onload = function (ev) {context.drawImage(image, 0, 0, canvas.width, canvas.height)}resetButton.onclick = function (ev) {context.clearRect(0, 0, context.canvas.width, context.canvas.height)context.drawImage(image, 0, 0, canvas.width, canvas.height)}//Initialization……image.src = 'arch.png'</script>
</html>

相关文章:

  • WPF【11_3】WPF实战-重构与美化(可复用的UI组件)
  • 【AI工具应用】使用 trae 实现 word 转成 html
  • PH热榜 | 2025-05-24
  • 【Linux】shell脚本的常用命令
  • winform LiveCharts2的使用--图表的使用
  • Linux 使用 Docker 安装 Milvus的两种方式
  • 微信小程序的软件测试用例编写指南及示例--性能测试用例
  • 【CSS】CSS 和 SASS 的区别
  • 【平面波导外腔激光器专题系列】用于光纤传感的低噪声PLC外腔窄线宽激光器
  • 【IOS】【OC】【应用内打印功能的实现】如何在APP内实现打印功能,连接本地打印机,把想要打印的界面打印成图片
  • 理解 Kubernetes 的架构与控制平面组件运行机制
  • 【洛谷P9303题解】AC- [CCC 2023 J5] CCC Word Hunt
  • word批量导出visio图
  • Nginx--手写脚本压缩和切分日志(也适用于docker)
  • 【Java实战】集合排序方法与长度获取方法辨析(易懂版)
  • Python实现VTK-自学笔记(5):在三维世界里自由舞蹈——高级交互与动态可视化
  • 得物Java开发面试题及参考答案(下)
  • 力扣面试150题--完全二叉树的节点个数
  • 【数据结构】单链表练习
  • openresty+lua+redis把非正常访问的域名加入黑名单
  • 苏州360推广网站建设/线上宣传渠道
  • 深圳做网站的/长春seo整站优化
  • 网站开发建设专业的公司/网络营销的基本功能
  • 石家庄网站制作福州/html网页制作软件有哪些
  • 郑州做网站制作的公司/俄罗斯搜索引擎yandex推广入口
  • wordpress点击跳转/聊城网站seo