arc(x, y, r, start, stop)
moveTo(x, y) 定义线条开始坐标lineTo(x, y) 定义线条结束坐标
fill()
stroke()
<canvas id="canvas" width="700" height="600">
浏览器不支持canvas!
</canvas>
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
// 坐标(x, y)、半径、开始角度、结束角度、顺时针(逆时针)
ctx.arc(70, 80, 30, 0, Math.PI * 2, false);
//生成点
for (let i = 0; i < dotsNum; i ++) {
x = Math.random() * canvas.width;
y = Math.random() * canvas.height;
r = Math.random() * 4; // 随机生成 <4 的半径值
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(0,0,0,.8)";
ctx.fill();
ctx.closePath();
}
确定两个点的坐标 + lineTo 、moveTo
for (let i = 0; i < 2; i++) {
ctx.beginPath()
// 设置原点位置为(100,100),半径为10
ctx.arc(100 + i * 150, 100 + i * 250, 10, 0, Math.PI * 2, false)
// 两个点进行画线
ctx.moveTo(100, 100)
ctx.lineTo(100 + i * 150, 100 + i * 250)
// 设置线的宽度,单位是像素
ctx.lineWidth = 2
ctx.stroke()
// 实心圆 - 填充颜色,默认是黑色
// 实心圆 - 画实心圆
ctx.fill()
ctx.closePath()
}
当点很多、元素很多的时候再进行画线操作会很繁琐,对于多元素的情况,创建实例对象,把变量存储在实例对象上。
var Dots = function () {
// 画布
this.canvas;
this.ctx;
// 画点
this.x;
this.y;
this.r;
};
Dots.prototype = {
// 初始化点的方法
init: function (canvas) {
this.canvas = canvas;
this.ctx = this.canvas.getContext('2d');
this.x = Math.random() * this.canvas.width;
this.y = Math.random() * this.canvas.height;
this.r = Math.random() * 4; // 随机生成 <4 的半径值
this.ctx.beginPath();
this.ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
this.ctx.fillStyle = "black";
this.ctx.fill();
this.ctx.closePath();
}
};
// 绘制连线
for (var i = 0; i < dotsNum; i ++) {
for (var j = i + 1; j < dotsNum; j ++) {
var tx = dotsArr[i].x - dotsArr[j].x,
ty = dotsArr[i].y - dotsArr[j].y,
// 三角形斜边长
s = Math.sqrt(Math.pow(tx, 2) + Math.pow(ty, 2));
if (s < dotsDistance) {
ctx.beginPath();
ctx.moveTo(dotsArr[i].x, dotsArr[i].y);
ctx.lineTo(dotsArr[j].x, dotsArr[j].y);
ctx.strokeStyle = 'rgba(0,0,0,'+(dotsDistance-s)/dotsDistance+')';
ctx.strokeWidth = 1;
ctx.stroke();
ctx.closePath();
}
}
}
点与点之间连线
优化点:
限定点与点的连线距离(优化:根据点之间的距离添加连线颜色透明度)
Canvas 画布的工作原理和显示器工作原理一样,都是通过不断的刷新绘制。浏览器的刷新是实时的,而 Canvas 的刷新是手动触发的,如果我们只想在 Canvas 上实现静态的效果,就没必不断刷新。
requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘。requestAnimationFrame不是自己指定回调函数运行的时间,而是跟着浏览器内建的刷新频率来执行回调。
浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果,一旦页面不处于浏览器的当前标签,就会自动停止刷新。
持续调用 requestAnimFrame清除动画调用 cancelAnimationFrame
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
// 画布渲染
var render = function () {
// 清除画布
context.clearRect(0, 0, canvas.width, canvas.height);
// 绘制(在canvas画布上绘制图形的代码)
draw();
// 继续渲染
requestAnimationFrame(render);
};
render();
上面的draw()就是在 canvas 画布上绘制图形的代码,但是如果仅仅有上面代码还不够,如果是同一个位置不断刷新,我们看到的还是静止不动的效果,所以还需要一个运动变量。
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
// 坐标变量
var x = 0;
// 绘制方法
var draw = function () {
ball.x = x;
};
// 画布渲染
var render = function () {
// 清除画布
context.clearRect(0, 0, canvas.width, canvas.height);
// 位置变化
x++;
// 绘制
draw();
// 继续渲染
requestAnimationFrame(render);
};
render();
动的是点,画的是线
let Dots = function () {
// 画布
this.canvas;
this.ctx;
// 画点
this.x;
this.y;
this.r;
// 移动
// 随机确定点的移动速度与方向 速度值在 [-2, 2) 之间 提高数值可加快速度
//(Math.random() 随机返回[0,1)的数)
this.sx = Math.random() * 4 - 2;
this.sy = Math.random() * 4 - 2;
};
// 更新点位置
update: function () {
this.x = this.x + this.sx;
this.y = this.y + this.sy;
// 点超出 canvas 范围时重新初始化
if (this.x < 0 || this.x > this.canvas.width) {
this.init(this.canvas);
}
if (this.y < 0 || this.y > this.canvas.height) {
this.init(this.canvas);
}
this.ctx.beginPath();
this.ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
this.ctx.fillStyle = "rgba(0,0,0,.6)";
this.ctx.fill();
this.ctx.closePath();
}
兼容 requestAnimationFrame
let requestAnimFrame = requestAnimationFrame || webkitRequestAnimationFrame || oRequestAnimationFrame || msRequestAnimationFrame;
requestAnimFrame(animateUpdate); // 兼容不同浏览器的 requestAnimationFrame
或者使用 setTimeout 向下兼容:
// requestAnimationFrame的向下兼容处理
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(fn) {
setTimeout(fn, 17);
};
}
由于点的位置不断变换,因此需要将画线的操作放在动画内执行,点的位置 update 一次就执行一次连线。
function animateUpdate() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空canvas中原有的内容
for (let i = 0; i < dotsNum; i ++) {
dotsArr[i].update();
}
// 绘制连线
for (let i = 0; i < dotsNum; i ++) {
for (let j = i + 1; j < dotsNum; j ++) {
let tx = dotsArr[i].x - dotsArr[j].x,
ty = dotsArr[i].y - dotsArr[j].y,
// 三角形斜边长
s = Math.sqrt(Math.pow(tx, 2) + Math.pow(ty, 2));
if (s < dotsDistance) {
ctx.beginPath();
ctx.moveTo(dotsArr[i].x, dotsArr[i].y);
ctx.lineTo(dotsArr[j].x, dotsArr[j].y);
ctx.strokeStyle = 'rgba(0,0,0,'+(dotsDistance-s)/dotsDistance+')';
ctx.strokeWidth = 1;
ctx.stroke();
ctx.closePath();
}
}
}
// 继续渲染
requestAnimFrame(animateUpdate);
}
星空效果、下雨效果等
不要在style里指定 Canvas 的宽度,Canvas 画布的尺寸的大小和显示的大小是有很大的区别的,在 canvas 里面设置的是才是 Canvas 本身的大小。
如果不给<canvas>设置 width、height 属性时,则默认 width 为 300、height 为 150, 单位都是 px。也可以使用 css 属性来设置宽高,但是如宽高属性和初始比例不一致,他会出现扭曲。所以,建议永远不要使用css属性来设置<canvas>的宽高。
画新元素前记得要 beginPath()
来自:https://segmentfault.com/a/1190000018488327
Canvas 是H5的一部分,允许脚本语言动态渲染图像。Canvas 定义一个区域,可以由html属性定义该区域的宽高,javascript代码可以访问该区域,通过一整套完整的绘图功能(API),在网页上渲染动态效果图。
上传截图很多做法是把图像发送到后端,把裁剪后的结果发送给浏览器,这种方式会增加处理时延。用canvas提供的API实现纯前端的剪切:这里头关键有三步:显示未经处理的图片,得到裁剪区域,显示裁剪后的区域。
javascript完成图片格式转换: 通过input上传图片,使用FileReader将文件读取到内存中。将图片转换为canvas,canvas.toDataURL()方法设置为我们需要的格式,最后将canvas转换为图片。
现在因为有了离屏Canvas,你可以不用在你的主线程中绘制图像了!Canvas 是一个非常受欢迎的表现方式,同时也是WebGL的入口。它能绘制图形,图片,展示动画,甚至是处理视频内容
最近的一个客户项目中,简化的需求是绘制按照行列绘制很多个圆圈。需求看起来不难,上手就可以做,写两个for循环。,IT行业的知识更新越来越快,能够以不变应万变的人,就是拥有良好的学习力、创造力、判断力和思考力的人。这些能力会让你在变换万千的技术海洋中,屹立不倒,不被淹没。
利用canvas将网页元素生成图片并保存在本地,首先引入三个文件,createElementNS() 方法可创建带有指定命名空间的元素节点。 createElementNS(ns,name) > createElementNS() 方法与 createElement() 方法相似
随着大数据时代的来临,物联网的日益发展,原先的 SCADA 系统本身也在求新求变,从最开始的专业计算机和操作系统,到通用计算机和相关软件,再到现在基于 HTML5 Canvas 的新型组态开发,其应用的范围也从最初的电力
在写下合格粒子运动时要先清楚你的思路,不能一开始就盲目的开始写,首先先要确定思路然后在去一步步的实现,在写的过程要注意细节,要思考js有些知识是跟数学知识相关的要注意观察
由于一些移动端的兼容性原因,我们某个项目需要前端将pdf转换成在移动端页面可直接观看的界面。为了方便解决,我们采用了pdf.js这个插件,该插件可以将pdf转换成canvas绘制在页面上
熟悉 canvas 的朋友想必都使用或者听说过 Fabric.js,Fabric 算是一个元老级的 canvas 库了,从第一个版本发布到现在,已经有 8 年时间了。我近一年时间也在项目中使用,作为用户简单说说感受:
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!