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 相关文章推荐
浅谈Javascript鼠标和滚轮事件
Jun 27 Javascript
Javascript表单验证要注意的事项
Sep 29 Javascript
jQuery晃动层特效实现方法
Mar 09 Javascript
使用AngularJS实现表单向导的方法
Jun 19 Javascript
JS获取数组最大值、最小值及长度的方法
Nov 24 Javascript
JavaScript:Date类型全面解析
May 19 Javascript
JS中Array数组学习总结
Jan 18 Javascript
Jquery获取radio选中的值
May 05 jQuery
JavaScript模块模式实例详解
Oct 25 Javascript
JS简单获得节点元素的方法示例
Feb 10 Javascript
微信小程序实现的3d轮播图效果示例【基于swiper组件】
Dec 11 Javascript
在vue中使用Echarts利用watch做动态数据渲染操作
Jul 20 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 allow_url_include的应用和解释
2010/04/22 PHP
Zend的AutoLoad机制介绍
2012/09/27 PHP
解析php二分法查找数组是否包含某一元素
2013/05/23 PHP
Thinkphp中Create方法深入探究
2014/06/16 PHP
php可应用于面包屑导航的迭代寻找家谱树实现方法
2015/02/02 PHP
PHP树-不需要递归的实现方法
2016/06/21 PHP
javascipt匹配单行和多行注释的正则表达式
2013/11/20 Javascript
当达到输入长度时表单自动切换焦点
2014/04/06 Javascript
js调试工具Console命令详解
2014/10/21 Javascript
js捕捉键盘事件和按键键值的方法
2016/10/10 Javascript
js实现获取鼠标当前的位置
2016/12/14 Javascript
HTML页面定时跳转方法解析(2种任选)
2016/12/22 Javascript
正则表达式基本语法及表单验证操作详解【基于JS】
2017/04/07 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
2017/04/18 Javascript
Vue props用法详解(小结)
2018/07/03 Javascript
对Vue- 动态元素属性及v-bind和v-model的区别详解
2018/08/27 Javascript
详解Vue路由自动注入实践
2019/04/17 Javascript
JS实现灯泡开关特效
2020/03/30 Javascript
如何在vue项目中嵌入jsp页面的方法(2种)
2020/02/06 Javascript
Python中字符串格式化str.format的详细介绍
2017/02/17 Python
python WindowsError的错误代码详解
2017/07/23 Python
对DJango视图(views)和模版(templates)的使用详解
2019/07/17 Python
python画微信表情符的实例代码
2019/10/09 Python
Pycharm无法打开双击没反应的问题及解决方案
2020/08/17 Python
TripAdvisor斯洛伐克:阅读评论、比较价格和酒店预订
2018/04/25 全球购物
英国网上购买肉类网站:Great British Meat
2018/10/17 全球购物
美国按摩椅批发网站:Titan Chair
2018/12/27 全球购物
成教自我鉴定
2013/10/27 职场文书
2014年高三毕业生自我评价
2014/01/11 职场文书
绿化先进工作者事迹材料
2014/01/30 职场文书
海飞丝广告词
2014/03/20 职场文书
门市房租房协议书
2014/12/04 职场文书
2015感人爱情寄语
2015/02/26 职场文书
2019新员工心得体会
2019/06/25 职场文书
Python使用华为API为图像设置多个锚点标签
2022/04/12 Python
PHP 时间处理类Carbon
2022/05/20 PHP