canvas实现圆框图片
作者:issac_宝华
链接:http://www.jianshu.com/p/9a6ee2648d6f
來源:简书
在html中做圆框图片很容易,只需要简单的 border-radius: 50%; 当然,为了兼容性,还有必要做带前缀的兼容性写法。但总的来说还是很简单。
<style>
img{
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
}
</style>
但是在canvas上做起来就有点麻烦了,在canvas画布上画图片,可以使用canvas的 drawImage接口,但是这个接口也仅仅是将图片画在画布上,并没有如css那样提供做圆角的接口。
网上常看到这样的做法(最先是在张鑫旭的blog上看到的):
通过纹理实现
<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 = 'images.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 = 'image.jpg'; // 首先是先画一个圆形,因为现在我们不是画圆角矩形,所以就不用“张鑫旭”画圆的做法,我们直接使用 `arc` 接口
context.save();
context.arc(100, 100, 50, 0, 2 * Math.PI); // 从画布上裁剪出这个圆形
context.clip();
context.drawImage(img, 50, 50, 100, 100);
</script>
两个值得注意的点,比较容易让误解的API:
- clip()
这是w3c的例子,或许有部分人(在说自己),会误以为,在使用clip以后,接下来的操作都是相对于这个被剪切出来的部分做定位,特别是下面这张图:
- arcTo()
一个用来画弧线的api
关于这个API的参数说明是这样的:[传送门]
上面的参数说明中的起点和终点,比较容易让人误以为是下面两个点:
然而上面的(x1,y1)和(x2,y2)其实是分别指下图上的上面一点和下面一点:
继续看下图:
顺道说一下,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。
[传送门:demo]
/*
* 圆角矩形
* @parama int/float x 矩形位置x坐标
* @parama int/float y 矩形位置y坐标
* @parama int/float w 矩形宽度
* @parama int/float h 矩形高度
* @parama int/float r 圆角半径
* @parama object <img> 矩形背景图
*/
function drawRoundedImg(x,y,w,h,r,bgimg){
ctx.save();
ctx.beginPath();
ctx.moveTo(x+r,y);
ctx.arcTo(x+w,y,x+w,y+h,r);
ctx.arcTo(x+w,y+h,x,y+h,r);
ctx.arcTo(x,y+h,x,y,r);
ctx.arcTo(x,y,x+w,y,r);
ctx.stroke();
ctx.clip();
ctx.drawImage(bgimg, x, y, w, h);
ctx.restore();
ctx.closePath();
}
canvas实现圆框图片的更多相关文章
- canvas实现圆角、圆框图片
参考资料: http://www.zhangxinxu.com/study/201406/image-border-radius-canvas.html https://www.jianshu.com ...
- Canvas 画圆
原文地址:http://hi.baidu.com/lj2tj/item/557d8d1a65adfa721009b58b --------------------------------------- ...
- canvas代替img渲染图片
移动端用canvas代替img渲染图片,可以提高性能 var oImg = new Image(); oImg.src = url; oImg.onload = function(){ var cvs ...
- canvas 绘圆加边框
HTML5中canvas元素,绘制圆形需要使用路径,开始时要取得图形上下文,首先使用路径来勾勒图形的轮廓,然后设置颜色,进行绘制. arc(cx,cy,radius,start_angle,end_a ...
- 解决html5 canvas 绘制字体、图片与图形模糊问题
html5 canvas 绘制字体.图片与图形模糊问题 发生情况 多出现在高dpi设备,这意味着每平方英寸有更多的像素,如手机,平板电脑.当然很多高端台式电脑也有高分辨率高dpi的显示器. canva ...
- canvas绘制圆图输出图片格式
function drawCircleImage(url, callback) { const canvas = document.createElement('canvas'); const img ...
- html5 canvas从圆开始
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- canvas练习 - 圆
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js使用canvas在前端压缩图片
HTML代码: <input id="file" type="file"> JS代码: var eleFile = document.querySe ...
随机推荐
- uiautomator +python 安卓UI自动化尝试
使用方法基本说明:https://www.cnblogs.com/mliangchen/p/5114149.html,https://blog.csdn.net/Eugene_3972/article ...
- eclipse添加插件、删除插件 示例: eclipse marketplace
在有些版本的eclips上并没有eclipse marketplace ,这让eclipse添加插件变得比较玛法,传统的办法都是通过自行下载插件或者用 help->install new sof ...
- WPF学习笔记——没有前途的WPF
看上去,WPF比silverlight有前途一点.毕竟,微软还没有宣布,WPF停止更新. 但我怀疑,不久的将来,WPF也会步其子集silverlight的后尘,要么不再出后续版本,要么向HTML5 + ...
- arm下用shell控制gpio
创建脚本gpio.sh #!/bin/sh PIN=$ VALUE=$ if test -d /sys/class/gpio/gpio$PIN/ then echo $VALUE > /sys/ ...
- diaowen Maven Webapp
五月 , :: 上午 org.apache.catalina.startup.VersionLoggerListener log INFO: Server version: Apache Tomcat ...
- PCB决策引擎:多维决策表转决策树
准备设计一个PCB使用的决策引擎,需要用到决策表,而单维决策表不能满足业务要求, 这里主要是为了实现:用户编辑的是决策表,实际底层存储的是树结构,树的的各个节点挂上业务决策逻辑. 这里将多维决策表转决 ...
- JS代码放在哪里比较好!
在页面上加上<script></script>只有2个地方:head中,body体中 如果外部的JS文件,在head中加,写页面特效js放在body后面. <html&g ...
- My97DatePicker 动态设置有效/无效日期
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...
- SharedPreferences用法
SharedPreferences是Android四种数据存储技术中的一种,它是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信 息,其对 ...
- 联想笋尖S90(S90-t 、S90-u)解锁BootLoader
工具下载链接: http://pan.baidu.com/s/1eSgZuka 备用下载链接: http://pan.baidu.com/s/1dFKqSId 本篇教程,仅限于联想笋尖S90(S90- ...