最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • canvas

    正文概述 掘金(linda168)   2021-03-18   470

    最近和canvas 杠上了,写一个总结。

    需求: 1、画圆:单纯 点击画固定大小的圆, 鼠标按下a 并且 滑动 鼠标松开b 画 半径 不固定的圆(半径 根据 a b 间距确定 , a 为圆心)。

    canvas 属性

    通过 attr 设置 width, height, 不推荐style/css 设置 width, height 标签中间可以添写 当浏览器不支持 canvas 时显示的内容; 不能写成

    <canvas id="can" width="800px" height="1000px" ></<canvas>

    要在画布上操作需要先获取画布的 上下文 ,可通过 getContext 获取;

    画圆

    canvas

    定义圈的结构

    {
        x:1, // x轴坐标
        y:1, // y轴坐标
        r:20, // 半径
        fontPos: { // 下标的坐标
            x: 1,
            y:2
        }
    }
    

    通过 监听鼠标事件 来判断是否是点击,完整代码如下

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <script type="text/javascript" src="./jquery-1.9.0.min.js" ></script>
    </head>
    <body>
        <div id="box" style="width: 500px;height: 500px;margin: 0 auto;">
            <canvas id="can" width="800px" height="1000px" style="border: 1px solid black;">
        
            </canvas>
        </div>
        <div>
        <input id="num" />
        <button id="btn" οnclick="del()">删除</button>
    
        </div>
    </body>
    <script type="text/javascript" >
        
    
        var canvas_w = 800;
        var canvas_h = 1000;
        var list = [];
        var index = 1;
        var can = document.getElementById('can');
        var ctx = can.getContext("2d");
        //鼠标点击生成圆
        var radius = 40;
        
        
        function mouseCoords(ev){
            var e = event || window.event;
            var x = e.offsetX || e.layerX;
            var y = e.offsetY || e.layerY;
            return {x,y};
        }
        //生成圆
        function makearc(x,y,r,color){
            ctx.beginPath();
            ctx.lineWidth = "2"
            ctx.strokeStyle='red';
            ctx.arc(x,y,r,0,180); // 圆心位置: x,y ; 圆半径:r;  起始角:s;  结束角:e; 
            ctx.stroke();
        }
    
        function getFontPos(x, y, r) {
            return {x: x + r, y: y + r}
        }
    
        function drawFont(x, y, num, color) {
            ctx.font = "16px serif";
            ctx.fillStyle = color;
            ctx.fillText(num, x, y);
        }
        function isPointInRetc(x,y){
            let len=layers.length;
            for(let i=0;i<len;i++){
                if(layers[i].x1<x&&x<layers[i].x2&&layers[i].y1<y&&y<layers[i].y2){
                    return layers[i];
                }
            }
        }
    
        $('#btn').click(function(){
            del();
        })
        function del() {
            var num = document.getElementById('num').value;
            if(!+num) {
                return;
            }
           
            var index  = list.findIndex(val=> val.idx === +num);
            if(index === -1) {
                return;
            }
            list.splice(index, 1);
            
            reDraw();
            
        }
    
        function reDraw () {
            ctx.clearRect( 0, 0, 800, 1000 );  //清除画布
            list.forEach((item)=>{
             makearc(item.x,item.y, item.radius,'red');
             drawFont(item.fontPos.x, item.fontPos.y, item.idx, 'red')
            })
        }
        var isMove = false;
        can.onmousedown = function(oEvent) {
            origin = mouseCoords(oEvent);
            isClick = true;
            isMove = false;
        };
        var movePoint = {x: 0, y : 0, r: 0}, isClick = false, origin;
    
        offset = getOffset(can);
        function getOffset(obj) {
            var x = 0,
              y = 0;
            do {
              x += obj.offsetLeft;
              y += obj.offsetTop;
              obj = obj.offsetParent;
            } while (obj);
            return  Point(x, y);
          }
        function Point(x, y) {
            return  {x:  x || 0, y: y|| 0}
          }
        document.onmousemove = function(oEvent) {
            if (!isClick) {
                return;
            }
            oEvent = oEvent || event;
            pt = Point(oEvent.clientX - offset.x, oEvent.clientY - offset.y);
            r = Math.sqrt(
                (pt.x - origin.x) * (pt.x - origin.x) +
                (pt.y - origin.y) * (pt.y - origin.y)
            );
            if (!posIslegal({ x: origin.x,
                y: origin.y,}, r)) {
                    console.log('超出边界了');
                return;
            }
            movePoint = {
                x: origin.x,
                y: origin.y,
                r
            }
            reDraw();
            makearc(origin.x, origin.y, r, "green");
            isMove = true;
        };
           
    
    
        document.onmouseup = function(oEvent) {
            isClick = false;
            var mousePos = mouseCoords(oEvent);
            if (mousePos.x === origin.x && mousePos.y === origin.y && !isMove) {
                handleClick(mousePos)
                return;
            }
            
           if(movePoint && isMove) {
            var fontPos = getFontPos(movePoint.x, movePoint.y, movePoint.r);
            var idx = index ++;
            list.push({
                x: movePoint.x,
                y: movePoint.y,
                radius: movePoint.r,
                idx,
                fontPos
            })
            reDraw();
            isMove = false;
           }
        };
        
        function handleClick (mousePos) {
            if(!posIslegal(mousePos, radius)) {
                console.log('圆的位置超出边界!');
                return;
            }
            mousePosX = mousePos.x;
            mousePosY = mousePos.y;
            var fontPos = getFontPos(mousePosX, mousePosY, radius);
            var idx = index ++;
            list.push({
                x: mousePosX,
                y: mousePosY,
                radius,
                idx,
                fontPos
            })
            makearc(mousePosX,mousePosY, radius,'red');
            drawFont(fontPos.x, fontPos.y, idx, 'red')
        }
    
        function  posIslegal(pos, r) {
            const x = pos.x + r;
            const y = pos.y + r;
            const left_x = pos.x - r;
            const left_y = pos.y - r;
            console.log('-----', left_x, left_y); // || left_x < canvas_w || left_y < canvas_h
            if(x > canvas_w || y > canvas_h || left_x < 0 || left_y < 0 ) {
                return false;
            }
            return true;
        }
    
        </script>
    </html>
    
    

    阅览

    画每个圆的时间控制在1s, 可使用 setInterval来控制 采取画圆弧的策略; 记录当前的圆的下标 和 当前 圆弧的长度/百分数;

    完整代码:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <script type="text/javascript" src="./jquery-1.9.0.min.js" ></script>
    </head>
    <style>
        #yuan {
            border: 1px solid;
        }
       
        .show {
            display: inline-block;
        }
        .hide {
            display: none;
        }
        
        .zebra {
            width: 700px;
            height: 700px;
            border: 1px solid red;
            position: relative;
        }
    
        
          
    </style>
    
    <body>
        <p>input:<input onclick="circleProgress()" value="画圆" type="button"></p>
        <div>
        <canvas id="yuan" width="500" height="800"></canvas>
        </div>
    
       
    </body>
    <script type="text/javascript" >
        var timer=null, n = 0;
        var canvas = document.getElementById("yuan");
        var context = canvas.getContext('2d');
        var _this = $(canvas),
        maxpercent = 100,//最大百分比,可设置
        c_width = _this.width(),// canvas,宽度
        c_height =_this.height();// canvas,高度
    
    
        list = [{
            x: 100,
            y: 50,
            r: 20,
        }, {
            x: 76,
            y: 177,
            r: 20,
        },
        {
            x: 400,
            y: 280,
            r: 30,
        }, {
            x: 200,
            y: 397,
            r: 40,
        },{
            x: 388,
            y: 140,
            r: 23,
        }, {
            x: 426,
            y: 547,
            r: 45,
        },
        ]
        
        function circleProgress(){
            
            if(timer) {
                clearInterval(timer);
            }
            n = 0;
            index = 0;
            loadCanvas(0);
           
            // 调用定时器实现动态效果
            
        }; 
    
        var index = 0, len = list.length; 
        function loadCanvas(nowT){
            timer = setInterval(function(){
                console.log('----', n, index);
                if(index === (len - 1) && n > 100) {
                    clearInterval(timer);
                    return;
                }
                if(n > 100){
                    // clearInterval(timer);
                    // return;
                    index++;
                    n = 0;
                }
                draw(n / 100);
                n += 1;
                
            },10); // 1000 一秒  
        }
        function draw(cur){
            context.strokeStyle = "#27b5ff";
            context.lineWidth = 2.0;
            context.clearRect(0, 0, c_width, c_height);
        
            for(let i = 0; i < index; i++) {
                context.beginPath();
                const c = list[i];
                context.arc(c.x, c.y, c.r, 0, 180, false);
                context.stroke()
            }
            context.beginPath();
            const curC = list[index];
            // 绘制一个中心点为(c_width/2, c_height/2),半径为c_height/2-5不与外圆重叠,
            // 起始点-(Math.PI/2),终止点为((Math.PI*2)*cur)-Math.PI/2的 整圆cur为每一次绘制的距离
            context.arc(curC.x, curC.y, curC.r, -(Math.PI / 2), ((Math.PI * 2) * cur ) - Math.PI / 2, false);
            context.stroke();
        }
        
    
        </script>
    </html>
    
    

    canvas

    点击画圆,会在画布上顺序画圆;


    起源地下载网 » canvas

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元