canvas学习之API整理笔记(一),这些数量也是储存在对象的1个脾气当中

<input
type=”file”>——在vue中我们可以给input控件壹个ref属性,然后我们得以接纳this.$refs.(前面那东西的属性值,其实就是三个锚点)去得到那些控件,然后去调用这些控件的files属性,大家就可以拿到控件里面获取到的数码了。当然,他是壹个对象,那几个数量也是储存在目标的壹特特性当中,具体什么的亲善去打印看看。然后那个目的有个name属性,顾名思义,就是您拿到的文件名,还有二性格质是length,大家得以应用那一个脾性去判断控件到底里面有没有数据。借使您自个儿去做过,你会发现有上边一种情况。

前边我收拾过一篇文章canvas学习之API整理笔记(一),从那篇小说大家已经足以着力精通到常用绘图的API、不难的转换和动画。而本篇文章的机要内容囊括高级动画、像素操作、质量优化等知识点,讲解各个知识点的还要还会有一部分酷炫的demo,保险看官们全程在线,毫无尿点,看完不会后悔,哈哈,一个纯正的笑^_^。
除却,关于canvas的一文山会海实例即以后袭!欢迎关切!

永利集团娱乐官网,——场景场景场景——–

始发从前

var can = document.getElementById(‘canvas’);
//创建一个画布
var ctx = can.getContext(‘2d’);

下边全数的操作都在画布ctx上进展操作。

1.第4遍用控件获取一张图纸,我们看到控件获取到了数量

高级动画

继上一篇不难介绍了动画(重借使requestAnimationFrame方法),以后咱们来一步步贯彻多少个在画布内滚动的实例。

html代码:

<canvas id="canvas" width="400" height="200" style="background:#fff;"></canvas>

js代码:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var ball = {    //小球属性,原点位置,速度,半径等。
    x: 100,  
    y: 100,
    vx: 4,
    vy: 2,
    radius: 20,
    color: 'blue',
    draw: function() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true);
        ctx.closePath();
        ctx.fillStyle = this.color;
        ctx.fill();
    }
};
function draw() {
    ctx.clearRect(0,0, canvas.width, canvas.height);    //绘制之前清除整个画布
    ball.draw();   //在画布中绘制小球
    ball.x += ball.vx;   //改变小球位置坐标
    ball.y += ball.vy;   //改变小球位置坐标
    if (ball.y + ball.vy > canvas.height-15 || ball.y + ball.vy < 15) {   //边界判断
        ball.vy = -ball.vy;
    }
    if (ball.x + ball.vx > canvas.width-15 || ball.x + ball.vx < 15) {   //边界判断
        ball.vx = -ball.vx;
    }
    window.requestAnimationFrame(draw);   //循环执行
}
draw();

地方代码完毕的功用如下图:

永利集团娱乐官网 1

代码我早就写了基本的诠释,简单精晓,简单概括一下这个实例的实现思想

开创多个小球对象,包括三个制图本人的法门。在方方面面画布中绘制这么些小球,然后在下五回绘制以前,先化解整个画布,改变小球的一一属性(包蕴了逻辑,比如边界的论断),然后重新绘制三回,从而落成了动起来的效劳。

假诺您把地点代码中的ctx.clearRect(0,0, canvas.width, canvas.height);换来了上边那样:

ctx.fillStyle = 'rgba(255,255,255,0.3)';
ctx.fillRect(0, 0, canvas.width, canvas.height);

就足以拿走渐变尾巴的机能:

永利集团娱乐官网 2

2.次之次点开同样的控件,不过…..

像素操作

若果我们想对1个canvas画布举行如下操作:获取每三个点的音信,对每3个坐标点进行操作。那大家就必要驾驭一下ImageData对象了。

ImageData对象(由getImageData方法得到的)中贮存着canvas对象实际的像素数量,它蕴涵以下几个只读属性:

  • width

    图表宽度,单位是像素。

  • height

    图片中度,单位是像素。

  • data

    Uint8ClampedArray类型的一维数组,包涵着RGBA格式的整型数据,范围在0至255时期(包蕴255)。不难讲,就是2个数组,每四个元素存储一个点的颜色信息,这四个元素分别对应为R、G、B、A的值(知道颜色取值的一眼就清楚了,不明了的也没涉及,后边有实例,一看就知晓)。

3.本身什么也不选

创建ImageData对象

去创设三个新的,空白的ImageData对像,你应该会使用createImageData()方法

var myImageData = ctx.createImageData(width, height);

地方代码创造了一个新的具体特定尺寸的ImageData对像。全数像素被预设为透明黑。

4.控件里面原来的多少被清空了,貌似向来没来过这些满世界

收获像素数据

为了拿到三个饱含画布场景像素数据的ImageData对像,你可以用getImageData()方法

var myImageData = ctx.getImageData(left, top, width, height);

创建的myImageData对象就有width、height、data几本性格的值了。看上面这一个实例:

html代码:

<div id="color">hover处的颜色</div>

<canvas id="myCanvas" width="300" height="150"></canvas>

js代码:

var can = document.getElementById('myCanvas');
var ctx = can.getContext('2d');
var img = new Image();
    img.src = "img_the_scream.jpg";
ctx.drawImage(img, 0, 0);
var color = document.getElementById('color');
function pick(event) {
    var x = event.layerX;
    var y = event.layerY;
    var area = ctx.getImageData(x, y, 1, 1);  //创建ImageData对象
    var data = area.data;   //获取data属性(一个存储颜色rgba值的数组)
    var rgba = 'rgba(' + data[0] + ',' + data[1] + ',' + data[2] + ',' + data[3] + ')';
    color.style.color =  rgba;
    color.textContent = rgba;
}
can.addEventListener('mousemove', pick);

落到实处的功力如下图:

永利集团娱乐官网 3

注意:
若果略微同学试到那里发现有那一个报错内容Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.,要求检讨那行代码:

img.src = "img_the_scream.jpg";

那里的图片地址不能是跨域地址。网上有一部分化解办法,那里就不开展讲了。

那明明不太协调,于是动动脑子,你可以那样做

写入像素数据

您可以用putImageData()方法去对气象举行像素数据的写入。

ctx.putImageData(myImageData, x, y);  //在画布的(x, y)点开始绘制myImageData所存储的像素信息。

于是我们得以把收获到的像素消息举行拍卖,然后再重新绘制,就获取了新的图纸。看看下边这几个实例:

html代码:

<canvas id="canvas" width="660" height="277"></canvas>

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'img_the_scream.jpg';
ctx.drawImage(img, 0, 0);
var imageData = ctx.getImageData(0,0,canvas.width, canvas.height);  //获取ImageData
var colors = imageData.data;  //获取像素信息
function invert() {
    for (var i = 0; i < colors.length; i += 4) {  //四个为一组
        colors[i]     = 225 - colors[i];     // red
        colors[i+1] = 225 - colors[i+1]; // green
        colors[i+2] = 225 - colors[i+2]; // blue
        colors[i+3] = 255;   //alpha
    }
    ctx.putImageData(imageData, 220, 0);  //从(220, 0)开始绘制改变过的颜色
}
function toGray() {
    for (var i = 0; i < colors.length; i += 4) {
        var avg = (colors[i] + colors[i+1] + colors[i+2]) / 3;  
        colors[i] = avg; // red
        colors[i+1] = avg; // green
        colors[i+2] = avg; // blue
        colors[i+3] = 255;   //alpha
    }
    ctx.putImageData(imageData, 440, 0); //从(440, 0)开始绘制改变过的颜色
} 
invert();   //反转色
toGray();   //变灰色

面面俱到的功效如下图:

永利集团娱乐官网 4

    data () {
       return {
          fileName: null
      }
   }

天性优化


坐标点尽量用整数

浏览器为了完毕抗锯齿的出力会做额外的运算。为了幸免那种情状,请确保使用canvas的绘图函数时,尽量用Math.floor()函数对富有的坐标点取整。比如:

ctx.drawImage(myImage, 0.3, 0.5);  //不提倡这样写,应该像下面这样处理
ctx.drawImage(myImage, Math.floor(0.3), Math.floor(0.5));
if (this.$refs.imgFile.files.length !== 0) {
   this.fileImg = this.$refs.imgFile.files
} else {
   this.$refs.imgFile.files = this.fileImg
   return
 }

动用三个画布绘制复杂气象

例如做2个游戏,有多少个规模:背景层(简单变化)、游戏层(时刻变化)。那一个时候,大家就可以创立三个画布,二个专程用来绘制不变的背景(少量制图),另三个用来绘制游戏动态部分(大批量绘制),就如那样:

<canvas id="background-can" width="480" height="320"></canvas>
<canvas id="game-can" width="480" height="320"></canvas>

地点是vue的写法,因为近期用vue写项目,所以偷个懒。用原生的话做的措施同样

用CSS设置静态大图

设若有一层是永久不变的,比如一王海鸰态的背景图,最好使用div+css的方法去替代ctx.drawimage(),这么做可以幸免在每一帧在画布上绘制大图。不难讲,dom渲染肯定比canvas的操作质量更高。

好了,将来你会意识,不会再有上面那种非友好的用户体验了,当然这些不分厚薄,有人说那是个fetch,我觉着它很多时候是个bug…..

尽量少操作canvas的缩放

如若要对一个画布进行缩放,假如得以的话,尽量采纳CSS3的transform来兑现。不言而喻,记住一个尺码,能用html+div完结的尽心不要js对canvas进行操作。

作者们跟着唠

更多

  • 将画布的函数调用集合到一同(例如,画一条折线,而不要画多条分开的直线)
  • 行使不一样的主意去破除画布(clearRect()、fillRect()、调整canvas大小)
  • 尽量防止 shadowBlur天性
  • 有动画,请使用window.requestAnimationFrame()
    而非window.setInterval()

接下去,大家会转变三个图形对象,你可以用createElement的方法可能用new
Image的法子,那些不纠结

结语

OK,canvas常用的API就主旨计算完了,靠这几个API已经够用开发一些不大不小游戏了。比如前边本身写的实例demo之小游戏tinyHeart,就是用那一个函数画出来的。关键是这么些函数的三结合使用,多多联系就好了。

一经您把小编事先的两篇作品都看了的话,相信您会对canvas越来越感兴趣。所以为了做三个持久的人,小编继续还会出一层层的有关canvas的实例,注意,是一多样!敬请期待!

请看那里

let imgRender = new FileReader()//用来把文件读入内存,并且读取文件中的数据。FileReader接口提供了一个异步API,使用该API可以在浏览器主线程中异步访问文件系统,读取文件中的数据
imgRender.readAsDataURL(file)//将文件读取为DataURL

 具体文献链接:http://blog.csdn.net/zk437092645/article/details/8745647

若是你问怎么是dataurl,我提议您自个儿先去找文章看看啊,小编那有一篇不错的篇章链接你可以看看:http://www.webhek.com/post/data-url.html

接下来,我们利用canvas,先安装大小,于是可以那样做

let canvas = document.createElement('canvas')
canvas.width = targetWidth
canvas.height = targetHeight

本人纪念canvas对象默许的涨幅是300,中度是150,你协调可以打印看看

下一场我们做上边一件事

let canvasCtx = canvas.getContext('2d')

为了省去有个别同学去翻资料,小编表明下啥意思===>指定了你想要在画布上制图的品类。当前唯一的官方值是
“2d”,它内定了二维绘图,并且导致那些点子重返三个条件目的,该对象导出1个二维绘图
API(那是网上的演说,作者只是个搬运工)。

然后大家用那么些目的的fillRect方法,可以设定那些环境目的的横坐标、纵坐标、宽度、中度。然后是终极一步,用drawImage方法向画布上制图图像、画布或录像。如同上面

canvasCtx.fillStyle = '#fff'
canvasCtx.fillRect(0, 0, canvas.width, canvas.height)// set the default background color of png  to white
canvasCtx.drawImage(图片对象files[0], 0, 0, targetWidth, targetHeight)

OK,那面的步子很简短有木有。总的来说,大家依然用canvasCtx环境目的做一些’动作’

接下去的动作就很简单了,我们看下边

let picBase64 = canvas.toDataURL('image/jpeg', 1)//canvas里面是二进制二进制2222222222222
let fd = new FormData()
let blob = ImgUtil.base64ToBlob(picBase64)//不是blob,你传不了,这里不多解释这个,网上解释很多----你可以用atob()这个方法来,但是这个方法有挺大的缺陷,不过兼容性很好了,而且
你要对它进行切割切割,因为前面会有些emmit----》九九归一,来个new Blob()统统搞定
fd.append('pic', blob)

 OK,到此处,你可以拿上你的接口,把那东西甩过去了。当然,并不是装有意况都以那样子,你得和你的后端小伙伴协定好,到底要什么的数额。

相关文章