- 外文名
- Canvas
- 制作·发行
- F&C ZEXCS
- 放映日期
- 2005年10月3日
- 日文名
- 虹色のスケッチ
- 国 家
- 日本
- 总共集数
- 24
-
canvas
2018-04-17 15:29:27以canvas画布的左上角为笛卡尔坐标系的原点,且y轴的正方向向下,x轴的正方向向右 二、准备工作:布置画布、获取画布、获取画笔 <canvas id=“canvas”></canvas> var canvas = document....一、规则
以canvas画布的左上角为笛卡尔坐标系的原点,且y轴的正方向向下,x轴的正方向向右
二、准备工作:布置画布、获取画布、获取画笔
<canvas id=“canvas”></canvas> var canvas = document.getElementById("canvas") var context = canvas.getContext("2d")
三、分类
3、1:线条
移动画笔:context.moveTo(100,100),画笔起点
画笔停点:context.linrTo(600,600),画笔终点
画笔粗细的配置:context.lineWidth='5'
画笔颜色的配置:context.strokeStyle="#353537"
绘制类型:fill()填充 、stroke()描边
beginpath()开始绘制,可以使后面的线段的颜色等不覆盖前面的,结束绘制为fill()、stroke()、closePath()
var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); context.beginPath(); context.moveTo(20,20); context.lineTo(30,30); context.lineTo(20,40); context.lineTo(20,20); context.closePath();//不使用closePath结束绘制,左上角的会有缺口,用closePath的时候可以不用进行结尾,即最后一笔可以不画 context.lineWidth = '2'; //线条粗细 context.strokeStyle = ' #228B22';//线条颜色 context.fillStyle = "yellow";//内容填充色 context.stroke();//描边结束 context.fill(); //绘制结束
3、2:矩形,结合上面的知识点,矩形直接上例子就可以了window.onload = function(){ var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); rectfun(context,80,80,100,100,2,'black','white'); rectfun(context,85,85,90,90,2,'black','white'); rectfun(context,87,87,85,85,1,'black','white'); rectfun(context,90,90,80,80,2,'black','white'); rectfun(context,100,100,60,60,2,'black','white'); rectfun(context,110,110,40,40,2,'black','white'); rectfun(context,120,120,20,20,2,'black','white'); rectfun(context,130,130,1,1,2,'black','white'); }
function rectfun(cxt,x,y,width,height,borderwidth,bordercolor,fillcolor){ cxt.beginPath(); cxt.rect(x,y,width,height);//生成矩形 // cxt.closePath() 使用rect的时候,closePath可以不用 cxt.lineWidth = borderwidth;//宽度 cxt.strokeStyle = bordercolor;//颜色 cxt.fillStyle = fillcolor;//填充色 cxt.stroke(); cxt.fill(); }矩形效果图如下:
3、3:线条属性,共有4个属性
3.3.1、lineCap属性(线条的帽子):定义线的终点属性,有3个属性值(这些属性只会在终点起作用,折线处不会起作用)
* butt:默认值,端点是垂直于线段边缘的平直边缘。 * round:端点是在线段边缘处以线宽为直径的半圆。 * square:端点是在选段边缘处以线宽为长、以一半线宽为宽的矩形。
例子:
window.onload = function(){ var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 600; var context = canvas.getContext("2d"); context.lineWidth = 50; context.strokeStyle = "#1BAAAA"; context.beginPath(); context.moveTo(100,100); context.lineTo(700,100); context.lineCap = "butt"; context.stroke(); context.beginPath(); context.moveTo(100,300); context.lineTo(700,300); context.lineCap = "round"; context.stroke(); context.beginPath(); context.moveTo(100,500); context.lineTo(700,500); context.lineCap = "square"; context.stroke(); //下面画两个基准线方便观察 context.lineWidth = 3; context.strokeStyle = "black"; context.beginPath(); context.moveTo(100,0); context.lineTo(100,600); context.moveTo(700,0); context.lineTo(700,600); context.stroke(); }
效果:
3.3.2、lineJoin(线条的连接),定义折线处的属性,直接看代码和效果就可以明白
代码:
window.onload = function(){ var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 600; var context = canvas.getContext("2d"); context.beginPath(); context.moveTo(100,100); context.lineTo(300,300); context.lineTo(100,500); context.lineJoin = "miter"; context.lineWidth = 20; context.strokeStyle = "red"; context.stroke(); context.beginPath(); context.moveTo(300,100); context.lineTo(500,300); context.lineTo(300,500); context.lineJoin = "bevel"; context.lineWidth = 20; context.strokeStyle = "blue"; context.stroke(); context.beginPath(); context.moveTo(500,100); context.lineTo(700,300); context.lineTo(500,500); context.lineJoin = "round"; context.lineWidth = 20; context.strokeStyle = "black"; context.stroke(); }
效果:
3.3.3、当lineJoin设置为miter时(默认),此时可以使用miterLimit属性(不常用)
例子:
window.onload = function(){ var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 600; var context = canvas.getContext("2d"); context.beginPath(); context.moveTo(100,100); context.lineTo(300,300); context.lineTo(100,500); context.lineJoin = "miter"; context.miterLimit = 10; context.lineWidth = 5; context.strokeStyle = "red"; context.stroke(); context.beginPath(); context.moveTo(300,200); context.lineTo(500,300); context.lineTo(300,400); context.lineJoin = "miter"; context.miterLimit = 10; context.lineWidth = 5; context.strokeStyle = "blue"; context.stroke(); context.beginPath(); context.moveTo(500,290); context.lineTo(700,300); context.lineTo(500,310); context.lineJoin = "miter"; context.miterLimit = 10; context.lineWidth = 5; context.strokeStyle = "black"; context.stroke(); }
效果:原理链接:http://7xkcl8.com1.z0.glb.clouddn.com/edu6-4.png
3、4填充颜色
3.4.1填充基本颜色
(1)颜色字符串填充
context.fillStyle = "red";
(2)十六进制字符串
context.fillStyle = "#FF0000";
(3)rgb
context.fillStyle = "rgba(255,0,0,1)";
(4)hsl()
context.fillStyle = "hsl(0,100%,50%)";
(5)hsla()
context.fillStyle = "hsla(0,100%,50%,1)";
3、5填充渐变形状,线性和径向
3.5.1线性渐变
例子:
var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 600; var context = canvas.getContext("2d"); context.rect(200,100,400,400);//x起始坐标 y起始坐标 宽 高 //添加渐变线 var grd = context.createLinearGradient(200,300,600,300); //xstart,ystart,xend,yend 从(200,300)到(600,300)的径向 //添加颜色断点 grd.addColorStop(0,"black"); grd.addColorStop(0.5,"white"); grd.addColorStop(1,"black"); //应用渐变 context.fillStyle = grd; context.fill();
效果:
3.5.2绘制矩形的快捷方式
`fillRect(x,y,width,height)`、`stroke(x,y,width,height)`。这两个函数可以分别看做`rect()`与`fill()`以及`rect()`与`stroke()`的组合。因为`rect()`仅仅只是规划路径而已,而这两个方法确实实实在在的绘制。
例子,直接看例子就可以直接看明白:
window.onload = function(){ var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 600; var context = canvas.getContext("2d"); //添加渐变线 var grd = context.createLinearGradient(100,300,700,300);xstart,ystart,xend,yend 从(100,300)到(700,300)的径向 //添加颜色断点 grd.addColorStop(0,"olive"); grd.addColorStop(0.5,"aqua"); grd.addColorStop(0.75,"fuchsia"); grd.addColorStop(0.25,"teal"); //应用渐变 context.fillStyle = grd; context.strokeStyle = grd; context.strokeRect(200,150,450,50); context.fillRect(200,300,300,50); }
效果:
3、6:填充样式,createPattern()填充图案,需要传递两个参数createPattern(img,repeat-style),第一个对象是img实例,第二个对象是string类型,有4种填充类型,repeat,repeat-x,repeat-y,no-repeat,第一种参数还可以传入一个canvas或者是video对象,这里只说img对象,其余的自己尝试
window.onload = function(){ var canvas = document.getElementById("canvas"); canvas.width = 800; canvas.height = 600; var context = canvas.getContext("2d"); var img = new Image();//创建img对象 img.src = "1.jpg";//为img对象指定图片源 img.onload = function(){ var pattern = context.createPattern(img, "repeat");//指定类型 context.fillStyle = pattern;//纹理填充 context.fillRect(0,0,800,600);//快速制作矩形的方法,xstart,ystrart,width,height }
效果图:(代码里面img使用onload,是对图片进行预加载,)
3、7:绘制标准圆弧arc()函数
arc(x,y,r,startAngle,endAngle,anticlockwise)
x,y圆心坐标,r半径,
startAngle:开始的弧度值,endAngle:结束的弧度值
anticlockwise:表示绘制的方法(用布尔值进行表示),是(false)顺时针还是(true)逆时针,当此值不填写的时候,默认为false,顺时针,弧度值得规则如图:
例子:(我画的准备图的是随便在浏览器的页面上画的,请自动忽略无用的背景)
var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); context.fillStyle = "#FFF"; context.fillRect(0,0,800,600); context.beginPath(); context.arc(150,250,50,Math.PI, Math.PI * 3 / 2); context.lineTo(250,200); context.arc(250,250,50,Math.PI* 3 / 2, Math.PI *2); context.lineTo(300,400); context.arc(250,400,50,0, Math.PI*1/2); context.lineTo(150,450); context.arc(150,400,50,Math.PI*1/2, Math.PI); // context.lineTo(100,250); context.closePath(); context.strokeStyle = "#0078AA"; context.stroke();
(准备图)
(效果图)
3、8:切点绘制圆弧arcTo()
。。。
-
Canvas
2017-06-22 15:45:04canvas.drawLine(0, 0, 100, 100, paint);画多条线: float []pts = {0,0,100,100,200,200,300,300}; canvas.drawLines(pts, paint);// 画虚线–也通过多条线的方式 画点画一个点: canvas.drawPoint(500, 500, ...画线
画一条直线:
canvas.drawLine(0, 0, 100, 100, paint);画多条线:
float []pts = {0,0,100,100,200,200,300,300};
canvas.drawLines(pts, paint);// 画虚线–也通过多条线的方式画点
画一个点:
canvas.drawPoint(500, 500, paint);画多个点:
float []pts = {0,0,100,100,200,200,300,300};
canvas.drawPoints(pts, paint);画矩形
RectF r = new RectF(100, 100, 400, 500);
canvas.drawRect(r, paint);canvas.drawRect(left, top, right, bottom, paint);
画圆角矩形
RectF r = new RectF(100, 100, 200, 200);
//x-radius ,y-radius圆角的半径
canvas.drawRoundRect(r, 10, 10, paint);画圆
canvas.drawCircle(300, 300, 200, paint);
画椭圆
RectF r = new RectF(100, 100, 300, 200);
canvas.drawOval(r, paint);画圆弧
canvas.drawArc(
rect,
startAngle, //其实角度,相对X轴正方向
sweepAngle, //画多少角度的弧度
useCenter, //boolean, false:只有一个纯弧线;true:闭合的边
paint);RectF r = new RectF(100, 100, 400, 400);
canvas.drawArc(r, 0, 90, true, paint);//顺时针旋转90度true:
false:Path
rLineTo,rMoveTo 带r开头基于前一个点的相对位置
LineTo,MovoTo 不带r开头的,传的是我们的绝对位置Path path = new Path();
//移动
path.moveTo(100, 300);//画笔落笔的位置
//连线(100, 300)—(200, 100)
path.lineTo(200, 100);
//连线(200, 100) — (200, 200)
path.lineTo(200, 200);
//拼接
path.cubicTo(250, 200, 350, 300, 450, 400);//连接(200, 200)
//首尾相接
path.close();
canvas.drawPath(path, paint);圆角矩形路径
RectF r = new RectF(100, 100, 200, 200); Path path = new Path(); float radii[] = {10,10,50,50,0,0,10,10}; path.addRoundRect(r, radii, Path.Direction.CW); canvas.drawPath(path, paint);
RectF r = new RectF(100, 100, 200, 200); Path path = new Path(); path.addArc(r, 0, 90); canvas.drawPath(path, paint);
贝塞尔曲线
mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(4); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.BLACK); mStartX = 60; mStartY = 350; mEndX = 450; mEndY = 350; mPath = new Path(); mPath.reset(); mPath.moveTo(mStartX, mStartY); mPath.quadTo(mContorlX, mContorlY, mEndX, mEndY); //mPath.addCircle(); 里面有一个方向值 --顺时针和逆时针 // canvas.drawTextOnPath();---可以去看一下文字的绘制方向 canvas.drawPath(mPath, mPaint); canvas.drawPoint(mContorlX,mContorlY,mPaint);
setFillType
mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setStrokeWidth(2); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true);
Path.FillType.WINDING
WINDING 模式 — 取Path所有所在的区域 – 默认的模式
private void drawWindingType(Canvas canvas) { mPath = new Path(); mPath.offset(100,100); mPath.addCircle(200, 200, 100, Path.Direction.CW); mPath.addCircle(300, 300, 100, Path.Direction.CW); mPath.setFillType(Path.FillType.WINDING); mPaint.setColor(Color.RED); canvas.drawPath(mPath,mPaint); }
Path.FillType.EVEN_ODD
EVEN_ODD 模式 — 取Path所在不相交的区域
private void drawEvenOddType(Canvas canvas) { mPath = new Path(); mPath.offset(100,100); mPath.addCircle(200, 200, 100, Path.Direction.CW); mPath.addCircle(300, 300, 100, Path.Direction.CW); mPath.setFillType(Path.FillType.EVEN_ODD); mPaint.setColor(Color.RED); canvas.drawPath(mPath,mPaint); }
Path.FillType.INVERSE_WINDING
INVERSE_WINDING 模式 – 取path所有未占的区域
private void drawInverseWinding(Canvas canvas) { mPath = new Path(); mPath.offset(100,100); mPath.addCircle(200, 200, 100, Path.Direction.CW); mPath.addCircle(300, 300, 100, Path.Direction.CW); mPath.setFillType(Path.FillType.INVERSE_WINDING); mPaint.setColor(Color.RED); canvas.drawPath(mPath,mPaint); }
Path.FillType.INVERSE_EVEN_ODD
INVERSE_EVEN_ODD 模式 — 取path所有未占和相交的区域
private void drawInverseEvenOdd(Canvas canvas) { mPath = new Path(); mPath.offset(100,100); mPath.addCircle(200, 200, 100, Path.Direction.CW); mPath.addCircle(300, 300, 100, Path.Direction.CW); mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD); mPaint.setColor(Color.RED); canvas.drawPath(mPath,mPaint); }
op(Path path, Op op)
mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setStrokeWidth(8); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true);
Path.Op.DIFFERENCE
DIFFERENCE – 减去Path2后Path1区域剩下的部分
private void drawDifferenceOp(Canvas canvas) { Path path1 = new Path(); path1.addCircle(150, 150, 100, Path.Direction.CW); Path path2 = new Path(); path2.addCircle(200, 200, 100, Path.Direction.CW); path1.op(path2, Path.Op.DIFFERENCE); canvas.drawPath(path1, mPaint); mPaint.setColor(Color.DKGRAY); mPaint.setStrokeWidth(2); canvas.drawCircle(150, 150, 100,mPaint); canvas.drawCircle(200, 200, 100,mPaint); }
Path.Op.INTERSECT
INTERSECT — 保留Path2 和 Path1 共同的部分
private void drawIntersectOp(Canvas canvas) { Path path1 = new Path(); path1.addCircle(150, 150, 100, Path.Direction.CW); Path path2 = new Path(); path2.addCircle(200, 200, 100, Path.Direction.CW); path1.op(path2, Path.Op.INTERSECT); canvas.drawPath(path1, mPaint); mPaint.setColor(Color.DKGRAY); mPaint.setStrokeWidth(2); canvas.drawCircle(150, 150, 100,mPaint); canvas.drawCircle(200, 200, 100,mPaint); }
Path.Op.UNION
UNION – 保留Path1 和 Path 2
private void drawUnionOp(Canvas canvas) { Path path1 = new Path(); path1.addCircle(150, 150, 100, Path.Direction.CW); Path path2 = new Path(); path2.addCircle(200, 200, 100, Path.Direction.CW); path1.op(path2, Path.Op.UNION); canvas.drawPath(path1, mPaint); mPaint.setColor(Color.DKGRAY); mPaint.setStrokeWidth(2); canvas.drawCircle(150, 150, 100,mPaint); canvas.drawCircle(200, 200, 100,mPaint); }
Path.Op.XOR
XOR — 保留Path1 和 Path2 还有共同的部分
private void drawXorOp(Canvas canvas) { Path path1 = new Path(); path1.addCircle(150, 150, 100, Path.Direction.CW); Path path2 = new Path(); path2.addCircle(200, 200, 100, Path.Direction.CW); path1.op(path2, Path.Op.XOR); canvas.drawPath(path1, mPaint); mPaint.setColor(Color.DKGRAY); mPaint.setStrokeWidth(2); canvas.drawCircle(150, 150, 100,mPaint); canvas.drawCircle(200, 200, 100,mPaint); }
Path.Op.REVERSE_DIFFERENCE
REVERSE_DIFFERENCE — 减去Path1后Path2区域剩下的部分
private void drawReverseDifferenceOp(Canvas canvas) { Path path1 = new Path(); path1.addCircle(150, 150, 100, Path.Direction.CW); Path path2 = new Path(); path2.addCircle(200, 200, 100, Path.Direction.CW); path1.op(path2, Path.Op.REVERSE_DIFFERENCE); canvas.drawPath(path1, mPaint); mPaint.setColor(Color.DKGRAY); mPaint.setStrokeWidth(2); canvas.drawCircle(150, 150, 100,mPaint); canvas.drawCircle(200, 200, 100,mPaint); }
Region
RectF r = new RectF(100, 100, 200, 300); Path path = new Path(); path.addOval(r, Path.Direction.CCW); //创建一块矩形的区域 Region region = new Region(100, 100, 200, 250); Region region1 = new Region(); region1.setPath(path, region);//path的椭圆区域和矩形区域进行交集 //结合区域迭代器使用(得到图形里面的所有的矩形区域) RegionIterator iterator = new RegionIterator(region1); Rect rect = new Rect(); while (iterator.next(rect)) { canvas.drawRect(rect, paint); }
合并union:
//合并 Region region = new Region(50, 50, 100, 250); Rect r = new Rect(30, 30, 200, 100); // canvas.drawRect(r, paint); // paint.setColor(Color.BLUE); region.union(r); // region.op(r, Region.Op.INTERSECT);//交集部分 region是调用者A,r是求交集的B RegionIterator iterator = new RegionIterator(region); Rect rect = new Rect(); while (iterator.next(rect)) { canvas.drawRect(rect, paint); }
求交集:
Region region = new Region(50, 50, 100, 250); Rect r = new Rect(30, 30, 200, 100); // canvas.drawRect(r, paint); // paint.setColor(Color.BLUE); // region.union(r); region.op(r, Region.Op.INTERSECT);//交集部分 region是调用者A,r是求交集的B RegionIterator iterator = new RegionIterator(region); Rect rect = new Rect(); while (iterator.next(rect)) { canvas.drawRect(rect, paint); }
Canvas变换
平移
canvas.translate(150, 50);
// 绘制坐标系 // 第一次绘制坐标轴 paint.setColor(Color.GREEN); canvas.drawLine(0,0,canvas.getWidth(),0,paint);// X 轴 paint.setColor(Color.BLUE); canvas.drawLine(0,0,0,canvas.getHeight(),paint);// Y 轴 //平移--即改变坐标原点 canvas.translate(150, 50); // 第二次绘制坐标轴 paint.setColor(Color.GREEN); canvas.drawLine(0,0,canvas.getWidth(),0,paint);// X 轴 paint.setColor(Color.BLUE); canvas.drawLine(0,0,0,canvas.getHeight(),paint);// Y 轴
缩放
//sx,sy:分别对x/y方向的一个缩放系数,画布的缩放会导致里面所有的绘制的东西都会有一个缩放效果
canvas.scale(1.5f, 0.5f);RectF r = new RectF(0, 0, 400, 500); canvas.drawRect(r, paint); paint.setColor(Color.BLUE); //sx,sy:分别对x/y方向的一个缩放系数,画布的缩放会导致里面所有的绘制的东西都会有一个缩放效果 canvas.scale(1.5f, 0.5f); canvas.drawRect(r, paint);
旋转
canvas.rotate(30);
// 绘制坐标系 // 第一次绘制坐标轴 paint.setColor(Color.GREEN); canvas.drawLine(0,0,canvas.getWidth(),0,paint);// X 轴 paint.setColor(Color.BLUE); canvas.drawLine(0,0,0,canvas.getHeight(),paint);// Y 轴 //旋转 canvas.rotate(30); // 第二次绘制坐标轴 paint.setColor(Color.GREEN); canvas.drawLine(0,0,canvas.getWidth(),0,paint);// X 轴 paint.setColor(Color.BLUE); canvas.drawLine(0,0,0,canvas.getHeight(),paint);// Y 轴
斜拉
//sx,sy倾斜度:X轴方向上倾斜60度,tan60=根号3
canvas.skew(1.73f, 0);RectF r = new RectF(100, 100, 200, 200); canvas.drawRect(r, paint); paint.setColor(Color.BLUE); //sx,sy倾斜度:X轴方向上倾斜60度,tan60=根号3 canvas.skew(1.73f, 0); canvas.drawRect(r, paint);
裁剪
canvas.clipRect(new Rect(250, 250, 300, 400));
RectF r = new RectF(200, 200, 400, 500); canvas.drawRect(r, paint); paint.setColor(Color.BLUE); canvas.clipRect(new Rect(250, 250, 300, 400)); canvas.drawBitmap(mBitmap, 250, 250, paint); paint.setColor(Color.GREEN);
save和restore、restoreToCount
private void saveRestore(Canvas canvas, Paint paint) { canvas.translate(50, 50); RectF r = new RectF(0, 0, 200, 100); paint.setColor(Color.GREEN); canvas.drawRect(r, paint); canvas.save(); //平移 canvas.translate(50, 50); paint.setColor(Color.BLUE); canvas.drawRect(r, paint); canvas.restore(); //canvas.rotate(45); paint.setColor(Color.YELLOW); r = new RectF(0, 0, 100, 200); canvas.drawRect(r, paint); }
Paint paint = new Paint(); RectF r = new RectF(50, 50, 150, 150); //当canvas执行saveLayer的时候就会新建一个新的透明画布图层 int layer = canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),null,Canvas.ALL_SAVE_FLAG); canvas.drawColor(Color.YELLOW); canvas.translate(50, 50); paint.setColor(Color.BLUE); canvas.drawRect(r, paint); canvas.restoreToCount(layer); RectF rectF = new RectF(0,0,100,100); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10); paint.setColor(Color.GREEN); canvas.drawRect(rectF, paint); canvas.translate(50,50);
Paint paint = new Paint(); RectF rectF = new RectF(0,0,100,100); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10); paint.setColor(Color.GREEN); canvas.drawRect(rectF, paint); canvas.translate(50,50); int layerid = canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),null,Canvas.ALL_SAVE_FLAG); //canvas.save(); canvas.drawColor(Color.BLUE);// 通过drawColor可以发现saveLayer是新建了一个图层, // 同时结合Lsn5的16种Xfermode叠加形式Demo可以验证是新建的透明图层 paint.setColor(Color.YELLOW); canvas.drawRect(rectF,paint); // canvas.restore(); canvas.restoreToCount(layerid); RectF rectF1 = new RectF(10,10,300,400); paint.setColor(Color.RED); canvas.drawRect(rectF1,paint);
//save restoreToCount mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); Paint mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); mPaint.setStrokeWidth(10); canvas.save();//1 canvas.translate(200, 200); mPaint.setColor(Color.RED); RectF rectF = new RectF(0,0,200,200); canvas.drawRect(rectF,mPaint); canvas.save();//2 canvas.rotate(45); mPaint.setColor(Color.BLUE); canvas.drawRect(rectF,mPaint); canvas.save();//3 canvas.rotate(45); mPaint.setColor(Color.YELLOW); canvas.drawRect(rectF,mPaint); canvas.save();//4 canvas.restoreToCount(1); canvas.translate(20, 100); mPaint.setColor(Color.GREEN); canvas.drawRect(rectF,mPaint);
-
-
炫酷渐变色背景粒子线条折线连接canvas动画
2019-11-28 17:09:391.新建canvas.js // 炫酷渐变色背景粒子线条折线连接canvas动画 export const canvas = (val) => { var requestAnimationFrame = window.requestAnimationFrame || function (callback) { window....博客地址:http://www.globm.top/blog/1/detail/34
效果图:
1.新建canvas.js// 炫酷渐变色背景粒子线条折线连接canvas动画 export const canvas = (val) => { var requestAnimationFrame = window.requestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60) } // var canvas = document.getElementsByTagName("canvas")[0]; let canvas = val let ctx = canvas.getContext('2d') let maximumPossibleDistance let mousePositionX let mousePositionY let mouseElement let lines = 0 let objects = [] var initAnimation = function () { canvas.width = window.innerWidth canvas.height = window.innerHeight maximumPossibleDistance = Math.round(Math.sqrt((canvas.width * canvas.width) + (canvas.height * canvas.height))) Math.floor(canvas.width / 2) Math.floor(canvas.height / 2) objects.length = 0 clearCanvas() createParticles() } window.addEventListener('resize', function () { initAnimation() }, false) // 线条参数配置 var options = { // 初始线条数量 particlesNumber: 80, // 圆点大小 initialSize: 3, moveLimit: 50, durationMin: 50, durationMax: 300, drawConnections: true, mouseInteractionDistance: 150, mouseGravity: true, drawMouseConnections: true, // 图标色彩 red: 25, green: 200, blue: 255, opacity: 1, // 已连接线条 connectionRed: 255, connectionGreen: 255, connectionBlue: 255, connectionOpacity: 0.2, // 鼠标移动线条 mouseConnectionRed: 255, mouseConnectionGreen: 255, mouseConnectionBlue: 255, mouseConnectionOpacity: 0.2 } var getRandomBetween = function (a, b) { return Math.floor(Math.random() * b) + a } var getDistance = function (element1, element2) { var difX = Math.round(Math.abs(element1.positionX - element2.positionX)) var difY = Math.round(Math.abs(element1.positionY - element2.positionY)) return Math.round(Math.sqrt((difX * difX) + (difY * difY))) } function Particle (positionX, positionY, size, red, green, blue, opacity) { this.positionX = positionX this.positionY = positionY this.size = size this.duration = getRandomBetween(options.durationMin, options.durationMax) this.limit = options.moveLimit this.timer = 0 this.red = red this.green = green this.blue = blue this.opacity = opacity this.color = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',+' + this.opacity + ')' } function MouseParticle (positionX, positionY, size, red, green, blue, opacity) { this.positionX = mousePositionX this.positionY = mousePositionY this.size = size this.red = red this.green = green this.blue = blue this.opacity = opacity this.color = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',+' + this.opacity + ')' } Particle.prototype.animateTo = function (newX, newY) { var duration = this.duration var animatePosition = function (newPosition, currentPosition) { if (newPosition > currentPosition) { var step = (newPosition - currentPosition) / duration newPosition = currentPosition + step } else { step = (currentPosition - newPosition) / duration newPosition = currentPosition - step } return newPosition } this.positionX = animatePosition(newX, this.positionX) this.positionY = animatePosition(newY, this.positionY) // generate new vector if (this.timer === this.duration) { this.calculateVector() this.timer = 0 } else { this.timer++ } } Particle.prototype.updateColor = function () { this.color = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',+' + this.opacity + ')' } Particle.prototype.calculateVector = function () { var distance var newPosition = {} var particle = this var getCoordinates = function () { newPosition.positionX = getRandomBetween(0, window.innerWidth) newPosition.positionY = getRandomBetween(0, window.innerHeight) distance = getDistance(particle, newPosition) } // eslint-disable-next-line no-unmodified-loop-condition while ((typeof distance === 'undefined') || (distance > this.limit)) { getCoordinates() } this.vectorX = newPosition.positionX this.vectorY = newPosition.positionY } Particle.prototype.testInteraction = function () { if (!options.drawConnections) return var closestElement var distanceToClosestElement = maximumPossibleDistance for (var x = 0; x < objects.length; x++) { var testedObject = objects[x] var distance = getDistance(this, testedObject) if ((distance < distanceToClosestElement) && (testedObject !== this)) { distanceToClosestElement = distance closestElement = testedObject } } if (closestElement) { ctx.beginPath() ctx.moveTo(this.positionX + this.size / 2, this.positionY + this.size / 2) ctx.lineTo(closestElement.positionX + closestElement.size * 0.5, closestElement.positionY + closestElement.size * 0.5) ctx.strokeStyle = 'rgba(' + options.connectionRed + ',' + options.connectionGreen + ',' + options.connectionBlue + ',' + options.connectionOpacity + ')' ctx.stroke() lines++ } } MouseParticle.prototype.testInteraction = function () { if (options.mouseInteractionDistance === 0) return var closestElements = [] // var distanceToClosestElement = maximumPossibleDistance; for (var x = 0; x < objects.length; x++) { var testedObject = objects[x] var distance = getDistance(this, testedObject) if ((distance < options.mouseInteractionDistance) && (testedObject !== this)) { closestElements.push(objects[x]) } } for (var i = 0; i < closestElements.length; i++) { if (options.drawMouseConnections) { var element = closestElements[i] ctx.beginPath() ctx.moveTo(this.positionX, this.positionY) ctx.lineTo(element.positionX + element.size * 0.5, element.positionY + element.size * 0.5) ctx.strokeStyle = 'rgba(' + options.mouseConnectionRed + ',' + options.mouseConnectionGreen + ',' + options.mouseConnectionBlue + ',' + options.mouseConnectionOpacity + ')' ctx.stroke() lines++ } if (options.mouseGravity) { closestElements[i].vectorX = this.positionX closestElements[i].vectorY = this.positionY } } } Particle.prototype.updateAnimation = function () { this.animateTo(this.vectorX, this.vectorY) this.testInteraction() ctx.fillStyle = this.color ctx.fillRect(this.positionX, this.positionY, this.size, this.size) } MouseParticle.prototype.updateAnimation = function () { this.positionX = mousePositionX this.positionY = mousePositionY this.testInteraction() } var createParticles = function () { // create mouse particle mouseElement = new MouseParticle(0, 0, options.initialSize, 255, 255, 255) for (var x = 0; x < options.particlesNumber; x++) { var randomX = Math.floor((Math.random() * window.innerWidth) + 1) var randomY = Math.floor((Math.random() * window.innerHeight) + 1) var particle = new Particle(randomX, randomY, options.initialSize, options.red, options.green, options.blue, options.opacity) particle.calculateVector() objects.push(particle) } } var updatePosition = function () { for (var x = 0; x < objects.length; x++) { objects[x].updateAnimation() } // handle mouse mouseElement.updateAnimation() } window.onmousemove = function (e) { mousePositionX = e.clientX mousePositionY = e.clientY } var clearCanvas = function () { ctx.clearRect(0, 0, window.innerWidth, window.innerHeight) } var lastCalledTime var fps var averageFps var averageFpsTemp = 0 var averageFpsCounter = 0 function requestFps () { if (!lastCalledTime) { lastCalledTime = Date.now() fps = 0 return } var delta = (new Date().getTime() - lastCalledTime) / 1000 lastCalledTime = Date.now() fps = Math.floor(1 / delta) averageFpsTemp = averageFpsTemp + fps averageFpsCounter++ if (averageFpsCounter === 5) { averageFps = Math.floor(averageFpsTemp / 5) averageFpsCounter = 0 averageFpsTemp = 0 } if (!averageFps) { } else if (averageFps < 10) { } } var loop = function () { clearCanvas() updatePosition() ctx.fillStyle = '#fff' // ctx.fillText("FPS: " + fps + " lines: " + lines + " Average FPS: " + averageFps , 10, 20); lines = 0 requestAnimationFrame(loop) requestFps() } initAnimation() loop() return lines }
2.引入canvas.js,实现效果
<template> <div class="canvas-page"> <canvas></canvas> </div> </template> <script> import { canvas } from '../plugins/canvas' export default { name: 'CanvasPage', mounted () { canvas(document.getElementsByTagName('canvas')[0]) } } </script> <style lang="less" scoped> .canvas-page { height: 100vh; width: 100vw; background-size: cover; position: relative; background-color: #474747; background-image: radial-gradient(circle at 2% 60%, #27278f, transparent 100%), radial-gradient(circle at 98% 70%, #000c91, transparent 100%), radial-gradient(circle at 50% 50%, #ed68ed, transparent 100%); canvas { position: absolute; left: 0; top: 0; background: transparent; z-index: 15; } } </style>
-
js实现截图并保存图片(html转canvas、canvas转image)
2018-07-23 15:16:43js实现截图并保存图片在本地(html转canvas、canvas转image) 一、html转canvas 需要的库html2canvas.js和canvas2image.js 话不多说,直接上代码! html &amp;amp;amp;lt;h2&amp;amp;amp...js实现截图并保存图片在本地(html转canvas、canvas转image)
简介
JavaScript实现网页截图,使用的库有两个:
我主要是做了两个demo和一个npm包:
1. 如何使用简单版
直接打开
index.html
即可2. 如何使用Webpack+Vue+Element版
# 安装依赖 npm install # 在localhost:8080进行热重新加载 npm run dev # 压缩构建为生产环境代码 npm run build # 构建为生产环境代码并查看捆绑分析器报告 npm run build --report
使用示例
原始html是这样的:
这是元素节点:
这是转成canvas之后:
这是元素节点:
这是转成img之后:
这是元素节点:
这是最终截图结果:
3. 使用npm安装js_screen_shots
npm install --save js_screen_shots
详情见README.md
-
canvas绘图工具
2019-01-21 15:34:36关于canvas绘图,在html页面上太方便了。为什么不用SVG呢?SVG大量的操作DOM元素你会发现网页的内存一下就达到几个G非常恐怖,更别说应用到移动端了。百度取了不少经,什么画板涂鸦只是小把戏缺乏实用性,灵活性。... -
学习HTML5 Canvas这一篇文章就够了
2017-06-16 20:57:43一、canvas简介&amp;lt;canvas&amp;gt; 是 HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素。它可以用来制作照片集或者制作简单(也不是那么简单)的动画,甚至可以进行... -
Android Canvas绘图描述Android Canvas 方法总结
2018-04-23 00:17:47Android中使用图形处理引擎,2D部分是android SDK内部自己提供,3D部分是用Open GL ES 1.0。今天我们主要要了解的是2D相关的,如果你想看3D的话那么...他们提供了图形处理相关的: Canvas、ColorFilter、Point(点)和... -
canvas的使用
2020-03-09 14:15:42文章目录一、canvas在移动端自适应大小canvas坑1:设置canvas的css的宽高会导致你的填充内容被拉伸canvas坑1解决办法:解决后的代码与效果如下:canvas坑2:不能设置css属性如何让它自适应?canvas坑2解决办法:二、... -
Canvas线条动画
2020-09-03 19:23:39Canvas线条动画 简单的Canvas动画,代码只有71行,试试吧!没有谁天生就会,用这个动画,做为你的Canvas小结。 如果你觉得我的代码还算有趣,在你的学习中能有所帮助,请查看我的置顶文章,我由衷感谢! <!... -
-
canvas画数字
2017-02-17 16:07:15canvas -
-
-
[Canvas系列]Canvas画布系列教程
2016-12-11 15:13:39一 canvas系列[Canvas系列]Canvas基本概念_01[Canvas系列]Canvas简单线条绘制_02[Canvas系列]Canvas填充与渐变_03[Canvas系列]Canvas绘制圆弧形状_04[Canvas系列]Canvas绘制曲线之ARCTO_05[Canvas系列]Canvas绘制... -
自定义控件之绘图篇(四):canvas变换与操作
2014-09-05 15:05:36前言:前几篇讲解了有关canvas绘图的一些操作,今天更深入一些,讲讲对画布的操作,这篇文章不像前几篇那么容易理解,如果以前没有接触过画布的童鞋可能比较难以理解,为什么会这样。我尽量多画图,让大家更清晰明白... -
将图片画到canvas 上的几种方法
2018-09-22 01:34:13任何的知识体系,都是由小的知识体系构成,你要想成为高手 ...canvas 画图片的 第一种,就是在画布的坐标上,直接将图片画到上面去,此时 假如图片大小超出了画布,图片也不缩放 /*3参数*/ ... -
一个基于canvas开发,封装于Vue组件的通用手写签名板(电子签名板),支持pc端和移动端
2020-05-08 09:35:40sign-canvas 一个基于canvas开发,封装于Vue组件的通用手写签名板(电子签名板),支持pc端和移动端; 同时支持重新签名,覆盖签名,下载,保存等 github地址:https://github.com/mose-x/vue-sign-canvas.git ... -
canvas乱码的处理
2020-05-29 11:18:40用canvas实现图表功能时,如果我们从网上copy别人的demo时,运行发现中文乱码了。 1、当你的页面是.html格式的乱码问题 解决: 将复制的demo内容先通过记事本以utf-8的编码方式保存,然后再粘贴到自己的项目中。 2、... -
微信小程序组件内(component)canvas元素的坑 canvasToTempFilePath: fail canvas is empty
2018-11-08 18:21:37canvasToTempFilePath: fail canvas is empty , 报这个错是因为调取 wx.canvasToTempFilePath 接口获取不到canvas,同样的需要传入上下文的this wx.canvasToTempFilePath({ height: '430', ... -
canvas的drawImage方法参数详解
2017-07-15 17:24:01canvas
-
如何获取b站、YouTube等网站的视频封面
-
findbugs 代码检查 eclipse插件 3.0.0版本
-
Form背景颜色 displayOption.docx
-
攀登人工智能高地,修嗒嗒以AI赋能创新产业资源!
-
FANUC机器人有关动作速度倍率的相关系统变量-解释说明.docx
-
(新)备战2021软考软件设计师顺利通关套餐
-
EIA-364-18B VISUAL AND DIMENSIONAL INSPECTION-英文版
-
面向深度学习模型的对抗攻击与防御方法综述
-
(新)备战2021软考系统集成基础知识套餐
-
Leetcode 145 - Binary Tree Postorder Traversal
-
倾斜haar-like feature计算
-
智联万物,京东IoT技术创新与实践
-
【数据分析-随到随学】机器学习模型及应用
-
【数据分析-随到随学】SPSS调查问卷统计分析
-
Excel高级图表技巧
-
(新)备战2021软考信息安全工程师基础知识套餐
-
oa管理系统项目源码、视频、sql
-
2021-01-18
-
盐城机电高职北大青鸟人才培养实训基地期末考试进行中!
-
单片机完全学习课程全五季套餐