Canvas实现微信红包照片效果

来源:互联网 发布:贵金属手机行情软件 编辑:程序博客网 时间:2024/04/29 02:59

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

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

原理分析:

  1. 先在页面放置一张原图片image,用css3的filter做模糊处理
  2. 在图片区域上方放置一个与图片image大小一样的canvas,放置整张清晰图片
  3. 通过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" />        <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()" class="button" id="reset-button">重置</a>            <a href="javascript:show()" 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已经做了随机位置,所以每次点击重置都是随机位置的剪辑区域

//重置,initCanvasfunction 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);}//重置,initCanvasfunction reset() {    initCanvas();}
1 0