JS操作canvas

<canvas>元素本身并不可见,它只是创建了一个绘图表面并向客户端js暴露了强大的绘图API。

1  <canvas> 与图形

为优化图片质量,不要在HTML中使用width和height属性设置画布的屏幕大小。而要使用CSS的样式属性width和height来设置画布在屏幕上的预期大小。然后在JS开始绘制前,再将画布对象的width和heigh属性设置为CSS像素乘以window.devicePixelRatio。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<canvas width="100" height="100" id="canvas1"></canvas>
<canvas id="canvas2" style="width: 100px; height: 100px"></canvas>
</body>
</html>
<script>let canvas2 = document.querySelector("#canvas2");canvas2.width = 100 * window.devicePixelRatio;canvas2.height = 100 * window.devicePixelRatio;
</script>

图 代码实现效果

1.1 save()、restore()与beginPath()

beginPath() 开始一条路径或重置当前路径,表示重新开始一个新的路径内容。

<script>
    let context = document.querySelector("#canvasId").getContext("2d");

    context.rect(0,0,30,30);
    context.fillStyle = "green";
    context.fill();
    // 缺失 content.beginPath() 那么上面的矩形fillStyle颜色
    // 始终是在beginPath出现之前设置的fillStyle,即"red";
    context.rect(40,40,30,30);
    context.fillStyle = "red";
    context.fill();

    context.beginPath(); // 重新开始路径内容
    context.rect(80,80,30,30);
    context.fillStyle = "blue";
    context.fill();
</script>

图 beginPath演示效果图

save()方法把当前的图形状态(不包括当前定义的路径和当前的点)推到一个保存到状态栈中,而restore()方法则从该栈中弹出状态。

<script>
  let context = document.querySelector("#canvasId").getContext("2d");
  context.fillStyle = "green";
  context.fillRect(0,0,50,50);
  context.save(); //保存fillStyle等状态信息
  context.fillStyle = "red";
  context.fillRect(60,0,50,50);
  context.save();
  context.restore(); // red
  context.fillRect(120,0,50,50);
  context.restore(); // green
  context.fillRect(180,0,50,50);
</script>

图 store() 演示效果图

1.2 渐变色

需要将fillStyle(或strokeStyle)设置为CanvasGradient对象。上下文有两个方法用于创建这个对象:

1)createLinearGradient(),参数是定义一条直线的两个点的坐标,颜色将在这条直线的方向上渐变。

2)createRadialGradient(),需要指定两个圆心和半径(着两个圆不一定是同心圆),小圆内部区域或大圆外部区域将被实色填充,这两个区域之间的部分则会以渐变色填充。

在创建这个对象后,必须调用该对象的addColorStop()方法定义渐变色。第一个参数是一个介于0.0和1.0之间的数值,第二个参数是一个CSS颜色说明。至少必须调用这个方法两次。

<script>let canvas = document.querySelector("#canvasId");canvas.width = 300 * window.devicePixelRatio;canvas.height = 200 * window.devicePixelRatio;let context = canvas.getContext("2d");context.rect(0,0,130,150);let canvasGradient = context.createLinearGradient(30,20, 130,150);context.fillStyle = canvasGradient;canvasGradient.addColorStop(0,"red");canvasGradient.addColorStop(1,"blue");context.fill();context.beginPath(); // 开始新路径context.rect(140,0,200,200);let radial = context.createRadialGradient(240,100,50,240,100,100);context.fillStyle = radial;radial.addColorStop(0, "yellow");radial.addColorStop(1,"green");context.fill();
</script>

图 渐变色实现效果

1.3 坐标系转换

translate()方法简单地向左、右、上、下移动坐标系原点。rotate()方法按照指定角度旋转坐标轴。scale()方法沿x轴或y轴拉伸或压缩距离(给scale()方法传入一个负缩放因子会围绕原点反转坐标轴,就好像镜子里的倒影一样)。

<script>let context = document.querySelector("#canvasId").getContext("2d");(function scaleTest() {context.translate(100,0);drawTrapezoid("green")context.scale(-1,1);drawTrapezoid("red")}());function drawTrapezoid(color) {context.beginPath();context.moveTo(0,20);context.lineTo(0,170);context.lineTo(-70,150);context.lineTo(-70,70);context.closePath();context.fillStyle = color;context.fill();context.save();}
</script>

图 scale 实现效果图

《JavaScript权威指南》中的科赫雪花代码:

<script>let canvas = document.querySelector("#canvasId");canvas.width = 500 * window.devicePixelRatio;canvas.height = 500 * window.devicePixelRatio;let c = canvas.getContext("2d");let deg = Math.PI / 180;function snowflake(n,x,y,len) {c.save();c.translate(x,y);c.moveTo(0,0);leg(n);c.rotate(-120 * deg);leg(n);c.rotate(-120 * deg);leg(n);c.closePath();c.restore();function leg(n) {c.save();if (n === 0) {c.lineTo(len,0);} else {c.scale(1/3,1/3);leg(n-1);c.rotate(60 * deg);leg(n-1);c.rotate(-120 * deg);leg(n-1);c.rotate(60 * deg);leg(n-1);}c.restore();c.translate(len,0);}}snowflake(0,25,125,125);snowflake(1,175,125,125);snowflake(2,325,125,125);snowflake(3,475,125,125);snowflake(4,625,125,125);c.stroke();
</script>

图 科赫雪花实现效果

1.4 剪切

clip()方法定义一个剪切区域,定义后,这个区域外部将不会被绘制。它的作用是遮罩,用来隐藏没有遮罩的部分。

<script>const context = document.querySelector("#canvasId").getContext("2d");context.fillStyle = "red";context.arc(100,100,100,0,Math.PI * 2,true);context.fill();context.clip();context.beginPath();context.fillStyle = "blue";context.arc(200,100,100,0,Math.PI * 2, true);context.fill();context.beginPath();context.fillStyle = "green";context.arc(100,200,100,0,Math.PI * 2, true);context.fill();;
</script>

图 clip()演示效果图

1.5 像素操作

context的getImageDate()方法返回一个ImageData对象,表示画布中某矩形区域中包含的原始像素(包括R、G、B和A组件)。createImageData()创建空的ImageData对象,ImageData对象中的像素是可写的。putImageData()方法则是把像素复制到画布中。

<script>let canvas = document.querySelector("#canvasId");canvas.width = 300 * window.devicePixelRatio;canvas.height = 300 * window.devicePixelRatio;let context = canvas.getContext("2d");context.fillStyle = "#008000";context.arc(100,100,100,0,Math.PI,true);context.fill();let imageData = context.getImageData(0,0,200,200);let width = imageData.width,height = imageData.height;let data = imageData.data; // 每个像素占用4个连续字节,分别是R、G、B和Afor (let pos = 0; pos < data.length; pos+=4) {if (data[pos + 1] === 128) {data[pos] = 255;data[pos + 1] = 0; //Gdata[pos + 2] = 0; // Bdata[pos + 3] = 255; // A}}context.putImageData(imageData,210,0);
</script>

图 像素操作演示效果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/175927.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HBase学习笔记(3)—— HBase整合Phoenix

目录 Phoenix Shell 操作 Phoenix JDBC 操作 Phoenix 二级索引 HBase整合Phoenix Phoenix 简介 Phoenix 是 HBase 的开源 SQL 皮肤。可以使用标准 JDBC API 代替 HBase 客户端 API来创建表&#xff0c;插入数据和查询 HBase 数据 使用Phoenix的优点 在 Client 和 HBase …

Spring 6 资源Resources 相关操作

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 1、Spring Resources概述 Java的标准java.net.URL类和各种URL前缀的标准处理程序无法满足所有对low-level资源的访问&#xff0c;比如&#xff1a;没有标准化的 URL 实现可用于访问需要从类路径或相对于 ServletCont…

ubuntu20安装opencv4和opencv_contrib 多版本共存

openCV 卸载 openCV 安装后的源码尽可能保留&#xff0c;因为可以直接从build文件夹下卸载已经安装的openCV. 参考链接&#xff1a;视觉学习笔记10——opencv的卸载、安装与多版本管理 如果已经安装完openCV,后续想重新装&#xff0c;需要先卸载掉安装的openCV. 在ubuntu终端…

量化交易:使用 python 进行股票交易回测

执行环境: Google Colab 1. 下载数据 import yfinance as yfticker ZM df yf.download(ticker) df2. 数据预处理 df df.loc[2020-01-01:].copy()使用了 .loc 方法来选择索引为 ‘2020-01-01’ 以后的所有行数据。通过 .copy() 方法创建了一个这些数据的副本&#xff0c;确…

Nginx 版本信息泄露解决方案

Nginx 【CVE-2021-23017;CVE-2022-41742】 【影响】 攻击者可能使用泄露的版本信息来确定该版本服务器有哪些安全漏洞&#xff0c;据此展开进一步的攻击。以下是百度的请求示例&#xff0c;也是有版本泄露&#xff1a; 【解决方案】 在Server节点增加以下配置&#xff1a; #…

SDL2 播放视频文件(MP4)

1.简介 这里引入FFmpeg库&#xff0c;获取视频流数据&#xff0c;然后通过FFmpeg将视频流解码成YUV原始数据&#xff0c;再将YUV数据送入到SDL库中实现视频播放。 2.FFmpeg的操作流程 注册API&#xff1a;av_register_all()构建输入AVFormatContext上下文&#xff1a;avform…

【原创课设】java+swing+mysql选课管理系统设计与实现

摘要&#xff1a; 随着学校规模的扩大和课程设置的多样化&#xff0c;传统的手工选课管理方式已经无法满足现代教育的需求。因此&#xff0c;开发一款高效、便捷的选课管理系统变得尤为重要。该系统可以提高选课工作的效率&#xff0c;减少人为错误&#xff0c;同时也能为学生…

verdi merge fsdb出现信号冲突的解决办法

前段时间介绍了verdi用 Edit Virtual File的方式把几个fsdb文件merge起来的方法 由于当时实验的时候只用了两个小的fsdb文件&#xff0c;每个fsdb文件中包含的信号量也比较少&#xff0c;所以并没有发现问题 我是用 Edit Virtual FIle把dump不同hier的fsdb文件merge到一起&am…

【Linux】:静动态库

静动态库 一.静态库1.设计静态库2.生成静态库3.发布静态库4.使用静态库 二.动态库1.设计动态库2.生成和发布动态库3.使用 三.进程地址空间1.程序在加载前的地址2.程序在加载后的地址3.动态库的地址 一.静态库 程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候…

【算法练习Day48】回文子串最长回文子序列

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 回文子串最长回文子序列总结…

【文章学习系列之模型】DAGMM

本章内容 文章概况模型结构损失函数实验结果实验分析总结 文章概况 《Deep Autoencoding Gaussian Mixture Model for Unsupervised Anomaly Detection》是2018年发表于ICLR的一篇论文&#xff0c;该论文提出一种端到端的无监督异常检测方法DAGMM&#xff0c;取得了不错的效果…

数据结构-散列表

列表&#xff08;Hash Table&#xff09;&#xff0c;又称哈希表&#xff0c;是一种数据结构&#xff0c;特点是&#xff1a;数据元素的关键字与其存储地址直接相关 例&#xff1a;有一堆数据元素&#xff0c;关键字分别为&#xff5b;19&#xff0c;14&#xff0c;23&#xff…