在html中做圆框图片很容易,只需要简单的 border-radius: 50%; 当然,为了兼容性,还有必要做带前缀的兼容性写法。但总的来说还是很简单。
- <style>
- img{
- -webkit-border-radius: 50%;
- -moz-border-radius: 50%;
- border-radius: 50%;
- }
- </style>
- 
-
但是在canvas上做起来就有点麻烦了,在canvas画布上画图片,可以使用canvas的 drawImage 接口,但是这个接口也仅仅是将图片画在画布上,并没有如css那样提供做圆角的接口。
网上google过一下,常看到这样的做法:
- <canvas id="canvas"></canvas>
- <script>
- CanvasRenderingContext2D.prototype.roundRect = function (x, y, w, h, r) {
- var min_size = Math.min(w, h);
- if (r > min_size / 2) r = min_size / 2;
- // 开始绘制
- this.beginPath();
- this.moveTo(x + r, y);
- this.arcTo(x + w, y, x + w, y + h, r);
- this.arcTo(x + w, y + h, x, y + h, r);
- this.arcTo(x, y + h, x, y, r);
- this.arcTo(x, y, x + w, y, r);
- this.stroke();
- this.closePath();
- return this;
- }
-
- var canvas = document.querySelector("#canvas");
- var context = canvas.getContext("2d");
- var img = new Image();
- img.src = 'https://pbs.twimg.com/profile_images/588883654157291520/4DBMn6_A.jpg';
- var pattern = context.createPattern(img, "no-repeat");
- context.roundRect(0, 0, img.width, img.height, 0);
- context.fillStyle = pattern;
- context.fill();
- </script>
-
这样做是可以的,这个做法的关键道具是createPattern 这是一个专门用来作纹理的API:
但是,如果你将该形状右移50px就会发现问题所在,图片没有跟着形状(圆框)一起移动:
其实,看第二个画布应该可以看出图片是对画布的左上角做定位的。如果图片没有移动,那么想办法移动图片就好啦!然而,可悲的是没有方法。因此,这是一种比较鸡肋的做法。
这是我最后使用的方法,这个方法的关键道具是clip()API,这个API,可以用你指定的形状在画布上裁剪一部分出来,然后,接下来你在画布上的操作只有在该形状区域内可见,如果还有后续还有对画布的其他地方有操作,可以使用restore()接口恢复,但是必须在使用clip接口前用 save() 接口保存canvas的状态。
- <canvas id="canvas" style="border: 1px solid;"></canvas>
- <script>
- var canvas = document.querySelector("#canvas");
- var context = canvas.getContext("2d");
- var img = new Image();
- img.src = 'https://pbs.twimg.com/profile_images/588883654157291520/4DBMn6_A.jpg';
- // 首先是先画一个圆形,因为现在我们不是画圆角矩形,所以就不用“张鑫旭”画圆
- // 的做法,我们直接使用 `arc` 接口
- context.save();
- context.arc(100, 100, 50, 0, 2 * Math.PI);
- // 从画布上裁剪出这个圆形
- context.clip();
- context.drawImage(img, 50, 50, 100, 100);
- </script>
-
为此,还封装了个简单的方法:
- <canvas id="canvas" style="border: 1px solid;"></canvas>
- <script>
- // 封装了一个简单的方法
- function circleImg(ctx, img, x, y, r) {
- ctx.save();
- var d =2 * r;
- var cx = x + r;
- var cy = y + r;
- ctx.arc(cx, cy, r, 0, 2 * Math.PI);
- ctx.clip();
- ctx.drawImage(img, x, y, d, d);
- ctx.restore();
- }
-
- var img = new Image();
- img.src = 'https://pbs.twimg.com/profile_images/588883654157291520/4DBMn6_A.jpg';
- var canvas1 = document.querySelector("#canvas1");
- var context1 = canvas1.getContext("2d");
- circleImg(context1, img, 100, 20, 50);
- </script>
-
正如你所见,这个做法可以随意移动圆框和图片的。
顺道说一下,canvas的坐标,x轴由原点左到右从0开始递增,y轴由原点上到下,从0开始递增。
A点是直线的末点,这个点一般是有lineTo接口写出,或者moveTo接口,比如moveTo(50,50),而B点则是arcTo中的x1,x2,B(100, 50), C点则是arcTo中的x2,y2,C(100, 100),而arcTo中的r则是AB或者CD。