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 相关文章推荐
jQuery读取XML文件内容的方法
Mar 09 Javascript
对于jQuery性能的一些优化建议
Aug 13 Javascript
使用jQuery判断Div是否在可视区域的方法 判断div是否可见
Feb 17 Javascript
JS中的数组方法笔记整理
Jul 26 Javascript
JS中的两种数据类型及实现引用类型的深拷贝的方法
Aug 12 Javascript
基于Angular中ng-controller父子级嵌套的相关属性详解
Oct 08 Javascript
Vue自定义指令写法与个人理解
Feb 09 Javascript
vue中组件的3种使用方式详解
Mar 23 Javascript
vue自定义指令directive的使用方法
Apr 07 Javascript
vue的列表交错过渡实现代码示例
May 05 Javascript
微信小程序select下拉框实现效果
May 15 Javascript
解决vue v-for src 图片路径问题 404
Nov 12 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 adodb连接mssql解决乱码问题
2009/06/12 PHP
php+mysqli预处理技术实现添加、修改及删除多条数据的方法
2015/01/30 PHP
Yii2增加验证码步骤详解
2016/04/25 PHP
PHP hebrev()函数用法讲解
2019/02/21 PHP
JS option location 页面跳转实现代码
2008/12/27 Javascript
javascript的console.log()用法小结
2012/05/31 Javascript
JQuery给元素添加/删除节点比如select
2013/04/02 Javascript
JS延迟加载加快页面打开速度示例代码
2013/12/30 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
2015/11/30 Javascript
JS中split()用法(将字符串按指定符号分割成数组)
2016/10/24 Javascript
JS动态修改网页body的背景色实例代码
2017/10/07 Javascript
AngularJS创建一个上传照片的指令实例代码
2018/02/24 Javascript
Vue中this.$router.push参数获取方法
2018/02/27 Javascript
vue-cli3.0配置及使用注意事项详解
2018/09/05 Javascript
vue和better-scroll实现列表左右联动效果详解
2019/04/29 Javascript
vue+elementUI动态生成面包屑导航教程
2019/11/04 Javascript
js实现select下拉框选择
2020/01/11 Javascript
解决新建一个vue项目过程中遇到的问题
2020/10/22 Javascript
利用Python画ROC曲线和AUC值计算
2016/09/19 Python
python安装numpy&amp;安装matplotlib&amp; scipy的教程
2017/11/02 Python
Python基于生成器迭代实现的八皇后问题示例
2018/05/23 Python
pandas 对日期类型数据的处理方法详解
2019/08/08 Python
Python使用APScheduler实现定时任务过程解析
2019/09/11 Python
python 实现二维字典的键值合并等函数
2019/12/06 Python
python实现监控阿里云账户余额功能
2019/12/16 Python
Python实现搜索算法的实例代码
2020/01/02 Python
基于python实现图片转字符画代码实例
2020/09/04 Python
pycharm 代码自动补全的实现方法(图文)
2020/09/18 Python
Ticketmaster德国票务网站:购买音乐会和体育等门票
2016/11/14 全球购物
开展党的群众路线教育实践活动方案
2014/02/05 职场文书
鉴史问廉观后感
2015/06/10 职场文书
CSS3鼠标悬浮过渡缩放效果
2021/04/17 HTML / CSS
Matplotlib可视化之添加让统计图变得简单易懂的注释
2021/06/11 Python
JS封装cavans多种滤镜组件
2022/02/15 Javascript
nginx sticky实现基于cookie负载均衡示例详解
2022/12/24 Servers
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS