zoukankan      html  css  js  c++  java
  • 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以后,接下来的操作都是相对于这个被剪切出来的部分做定位,特别是下面这张图:


    灰色框是画布
    更加容易让人误以为真是如此,其实不然,其实还是相对画布的左上角做定位,用了clip后只是变成,只有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();
                }
  • 相关阅读:
    解决PLSQL Developer中文横着显示的问题
    品优购_day06
    品优购_day05
    品优购_day04
    品优购_day03
    品优购_day02
    java 学习中遇到的问题(二)泛型中<? extends T>和<? super T>的区别
    java 学习中遇到的问题(一)方法调用中的值传递和引用传递
    java中的字符串比较
    自学java 第十一章持有对象
  • 原文地址:https://www.cnblogs.com/yiven/p/7551535.html
Copyright © 2011-2022 走看看