Canvas实现微信红包照片效果


Posted in Javascript onAugust 21, 2018

本篇文章来源慕课网课程《canvas玩转红包照片》,用canvas及css3结合,实现红包照片的效果,并不做支付过程,代替的是使用2个按钮,显示清晰图片和重置圆圈可见区域。未做移动的屏幕适应

微信红包照片效果图一张模糊图片,只有鱼哥小圆圈的区域是清晰可见

Canvas实现微信红包照片效果

原理分析:

1、先在页面放置一张原图片image,用css3的filter做模糊处理
2、在图片区域上方放置一个与图片image大小一样的canvas,放置整张清晰图片
3、通过canvas的图片剪辑方法,剪辑出一个圆圈区域,就达到了只显示一个圆圈区域的效果

代码及解析

目录结构:

>Canvas实现微信红包照片效果

index.html,blur.js,blur.css

index.htm页面代码

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8" />
 <meta name="viewport" content="height=device-height,width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
 <title>模糊红包效果</title>
 <link rel="stylesheet" href="css/blur.css" rel="external nofollow" />
 <script type="text/javascript" src="js/jquery-2.1.0.js"></script> 
 </head>
 <body>
 <div id="blur-div">
 <img id="blur-image" src="img/gd.jpg" />
 <canvas id="canvas"></canvas><!--大小要在js设置,不要在css设置-->
 <a href="javascript:reset()" rel="external nofollow" class="button" id="reset-button">重置</a>
 <a href="javascript:show()" rel="external nofollow" class="button" id="show-button">显示</a>
 </div>
 <script type="text/javascript" src="js/blur.js"></script>
 </body>
</html>

css代码blur.css

*{
 margin:0px;
 padding: 0px;
}

#blur-div{
 width:350px;
 height:220px;
 margin:0 auto;
 position: relative;

 overflow: hidden;
}

.button{
 display: block;
 position: absolute;
 z-index: 200;/*按钮在最上面*/

 width: 60px;
 height: 30px;

 color: white;
 text-decoration: none;
 text-align: center;
 line-height: 30px;

 border-radius: 2px;
}
#reset-button{
 left: 40px;
 bottom: 20px; 
 background-color: #058;
}
#reset-button:hover{
 background-color: #047;
}
#show-button{
 right: 40px;
 bottom: 20px; 
 background-color: #085;
}
#show-button:hover{
 background-color: #074;
}
#canvas{

 display:block;
 margin:0 auto;

 position: absolute;
 left:0px;
 top:0px;
 /*canvas在image之上,在按钮下,z-index大于image,小于btn*/
 z-index: 100;
}

#blur-image{
 display:block;
 width:350px;
 height:220px;
 margin:0 auto;

 /*模糊效果*/
 filter:blur(20px);
 -webkit-filter: blur(20px);
 -moz-filter:blur(20px);
 -ms-filter: blur(20px);
 -o-filter:blur(20px);

 position: absolute;
 left:0px;
 top:0px;

 z-index: 0;
}

设置canvas大小要和image大小一样

javascript代码,方法将分片段进行讲解:
初始化一些参数

var canvasWidth = window.innerWidth; //最外层div宽=窗口宽高,为了适应
var canvasHeight = window.innerHeight;

var canvas = document.getElementById("canvas");//获取到canvas元素对象
var context = canvas.getContext("2d");//获取2d context

//设置canvas大小和最外层div宽高一样
canvas.width = canvasWidth;
canvas.height = canvasHeight;

//用canvas显示清晰图像
var image = new Image();
image.src = "img/gd.jpg";

//剪辑区域
var radius = 30;//剪辑区域圆的半径
var clippingRegion;//剪辑区域对象

底层图片用css3设置过后就已经可以显示在页面上,是一张模糊过的图片,下一步就是在canvas上绘制剪辑图片

image.onload = function(e) {
 //此处js代码设置blur-div 和canvas宽高调整
 $('#blur-div').css("width", canvasWidth + "px");
 $('#blur-div').css("height", canvasHeight + "px");
 $('#blur-image').css("width", image.width + "px");//因为图像大小变化,所以重新设置
 $('#blur-image').css("height", image.height + "px");

 initCanvas();//这是初始化canvas的方法
}
function initCanvas() {
 //重置剪辑区域,归位,随机
 clippingRegion = { //保证剪辑区域一定在有图像的地方
 x: Math.random() * (canvas.width - 2 * radius) + radius, 
 y: Math.random() * (canvas.height - 2 * radius) + radius,
 r: radius
 };
 draw(image, clippingRegion);//这是绘制image的方法
}
//设置剪辑区域
function setClippingRegion(clippingRegion) {
 context.beginPath(); //创建路径
 context.arc(clippingRegion.x, clippingRegion.y, clippingRegion.r, 0, Math.PI * 2, false); //画圆形
 context.clip();
}
function draw(image, clippingRegion) {
 context.clearRect(0, 0, canvas.width, canvas.height);
 context.save();
 //图像绘制前,确定剪辑区域
 setClippingRegion(clippingRegion);
 context.drawImage(image, 0, 0);

 context.restore();
}

点击显示按钮show,完全显示清晰图像,复用draw函数,将剪辑区域变大

function show() {
 //添加动画
 var theAnimation = setInterval(function() {
 clippingRegion.r += 20; //慢慢扩大显示
 //边界条件
 if (clippingRegion.r > 2 * Math.max(canvas.width, canvas.height)) { //停止动画,否则函数执行不停止
  clearInterval(theAnimation);
 }
 draw(image, clippingRegion);//循环执行draw方法,慢慢将剪辑区域的半径扩大,实现动画效果
 }, 30);//bug,显示之后立即点击重置,还是会打开图片,可能是因为定时器还没结束
}

重置则再次初始化canvas就行了,在initCanvas已经做了随机位置,所以每次点击重置都是随机位置的剪辑区域

//重置,initCanvas
function reset() {
 initCanvas();
}

完整blur.js代码

var canvasWidth = window.innerWidth; //最外层div宽=窗口宽高,为了适应
var canvasHeight = window.innerHeight;

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

//设置canvas大小和最外层div宽高一样
canvas.width = canvasWidth;
canvas.height = canvasHeight;

//用canvas显示清晰图像
var image = new Image();
var radius = 30;
//剪辑区域
var clippingRegion;
image.src = "img/gd.jpg";


//因为图像加载需要时间,所以用onload方法,等待图片加载完成后再执行函数
image.onload = function(e) {
 //blur-div 和canvas宽高调整
 $('#blur-div').css("width", canvasWidth + "px");
 $('#blur-div').css("height", canvasHeight + "px");

 $('#blur-image').css("width", image.width + "px");
 $('#blur-image').css("height", image.height + "px");

 initCanvas();
}

function initCanvas() {
 //重置剪辑区域,归位,随机

 clippingRegion = { //保证剪辑区域一定在有图像的地方
 x: Math.random() * (canvas.width - 2 * radius) + radius, //30-320 0-width 减掉半径30 350-30*2
 y: Math.random() * (canvas.height - 2 * radius) + radius, //30-190 0-height 减掉半径30 220-30*2
 r: radius
 };
 draw(image, clippingRegion);
}

//设置剪辑区域
function setClippingRegion(clippingRegion) {
 context.beginPath(); //创建路径
 context.arc(clippingRegion.x, clippingRegion.y, clippingRegion.r, 0, Math.PI * 2, false); //画圆形
 context.clip();
}

function draw(image, clippingRegion) {
 context.clearRect(0, 0, canvas.width, canvas.height);

 context.save();
 //图像绘制前,确定剪辑区域
 setClippingRegion(clippingRegion);

 context.drawImage(image, 0, 0); //图片大于canvas

 context.restore();
}

//完全显示清晰图像,复用draw函数,将剪辑区域变大
function show() {
 //添加动画,此函数有缺点
 clippingRegion.r=radius;//给半径归位
 var theAnimation = setInterval(function() {
 console.log("anima");
 clippingRegion.r += 20; //慢慢扩大显示
 //边界条件
 if (clippingRegion.r > 2 * Math.max(canvas.width, canvas.height)) { //停止动画,否则函数执行不停止1000
  clearInterval(theAnimation);
 }
 draw(image, clippingRegion);
 }, 30);
}

//重置,initCanvas
function reset() {
 initCanvas();
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS启动应用程序的一个简单例子
May 11 Javascript
ASP Json Parser修正版
Dec 06 Javascript
JS 遮照层实现代码
Mar 31 Javascript
jQuery中调用WebService方法小结
Mar 28 Javascript
document节点对象的获取方式示例介绍
Dec 24 Javascript
对比分析json及XML
Nov 28 Javascript
javascript截图 jQuery插件imgAreaSelect使用详解
May 04 Javascript
网络传输协议(http协议)
Nov 18 Javascript
原生javascript实现的全屏滚动功能示例
Sep 19 Javascript
基于vue.js 2.x的虚拟滚动条的示例代码
Jan 23 Javascript
angularjs实现table表格td单元格单击变输入框/可编辑状态示例
Feb 21 Javascript
vue实现点击按钮切换背景颜色的示例代码
Jun 23 Javascript
Vue开发实现吸顶效果的示例代码
Aug 21 #Javascript
js canvas实现红包照片效果
Aug 21 #Javascript
js实现简单选项卡功能
Mar 23 #Javascript
js实现轮播图的完整代码
Oct 26 #Javascript
JQuery扩展对象方法操作示例
Aug 21 #jQuery
详解Vue结合后台的列表增删改案例
Aug 21 #Javascript
JavaScript事件发布/订阅模式原理与用法分析
Aug 21 #Javascript
You might like
PHP加密解密实例分析
2015/12/25 PHP
PHP编写RESTful接口
2016/02/23 PHP
如何创建一个JavaScript弹出DIV窗口层的效果
2013/09/25 Javascript
让table变成exls的示例代码
2014/03/24 Javascript
node.js入门教程迷你书、node.js入门web应用开发完全示例
2014/04/06 Javascript
在JavaScript中重写jQuery对象的方法实例教程
2014/08/25 Javascript
jQuery中:nth-child选择器用法实例
2014/12/31 Javascript
在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)
2016/01/20 Javascript
window.open不被拦截的简单实现代码(推荐)
2016/08/04 Javascript
JavaScript 动态三角函数实例详解
2017/01/08 Javascript
Node.js开发第三方微信公众平台
2017/06/05 Javascript
ReactJs实现树形结构的数据显示的组件的示例
2017/08/18 Javascript
对于js垃圾回收机制的理解
2017/09/14 Javascript
在Angular中使用JWT认证方法示例
2018/09/10 Javascript
Angularjs之ngModel中的值验证绑定方法
2018/09/13 Javascript
js限制输入框只能输入数字(onkeyup触发)
2018/09/28 Javascript
使用vue打包进行云服务器上传的问题
2020/03/02 Javascript
Python中用于转换字母为小写的lower()方法使用简介
2015/05/19 Python
将Emacs打造成强大的Python代码编辑工具
2015/11/20 Python
利用Python暴力破解zip文件口令的方法详解
2017/12/21 Python
Python中列表与元组的乘法操作示例
2018/02/10 Python
python实现控制台打印的方法
2019/01/12 Python
Python3中函数参数传递方式实例详解
2019/05/05 Python
django使用admin站点上传图片的实例
2019/07/28 Python
利用css3如何设置没有上下边的列表间隔线
2017/07/03 HTML / CSS
详解HTML5通讯录获取指定多个人的信息
2016/12/20 HTML / CSS
乐天旅游香港网站:日本饭店预订
2017/11/29 全球购物
与C++相比,Java中的数组有什么不同
2014/03/25 面试题
竞选部门副经理的自荐书范文
2014/02/11 职场文书
测量员岗位职责
2015/02/14 职场文书
《曾国藩家书》读后感——读家书,立家风
2019/08/21 职场文书
python某漫画app逆向
2021/03/31 Python
解决MySQL存储时间出现不一致的问题
2021/04/28 MySQL
Golang表示枚举类型的详细讲解
2021/09/04 Golang
Win11怎么添加用户?Win11添加用户账户的方法
2022/07/15 数码科技
python中使用redis用法详解
2022/12/24 Redis