基于HTML5(canvas)、JavaScript实现画布的填充功能

基于HTML5(canvas)、JavaScript实现画布的填充功能

最近由于需求,在canvas画布绘图功能上实现一个填充功能。记录下实现方法,用到了种子填充算法,是基于JavaScript实现的。

一、种子填充算法

网上可以找到很多关于种子填充算法的内容,这里不进行表述。这里借鉴的是“4-联通非递归”方式的一种。

二、逻辑思路

步骤一:
比对鼠标选中的种子点颜色是否与要填充的颜色相同,相同则不进 行填充,直接结束;
步骤二:
使用“‘种子4-联通非递归"算法实现 选中区域的填充

三、代码实现

一. function getDataByCanvasData(cas, ctx, startX, startY, newColor)
其中: cas是画布对象, ctx是cas.getContext(‘2d’) , startX,startY是鼠标选中要填充区域内部的某一点坐标, newColor是要填充的颜色。调用该函数就会将cas画布上选中的区域填充成newColor颜色。

/**
 *  使用 漫水填充的种子填充非递归算法((堆的4领域填充)),填充封闭区域
 * @param cas 目标画布
 * @param ctx 目标画布操作对象
 * @param startX 横坐标
 * @param startY 纵坐标
 * @param newColor 填充的颜色
 */
function getDataByCanvasData(cas, ctx, startX, startY, newColor) {

    //获取画布的宽(列数)高(行数)
    var width = cas.width;
    var height = cas.height;

    //获取画布像素信息
    var casData = ctx.getImageData(0, 0, width, height);

    //第 startY行 第 startX 列的像素所在 ImageData 坐标
    var i = startY * width + startX;
    //获取原图的种子点颜色值
    var colorR = casData.data[4*i];
    var colorG = casData.data[4*i+1];
    var colorB = casData.data[4*i+2];

    //获取填充颜色的RGB数组
    var fillingColor = colorHexToRGB(newColor);
    //如果当前指定颜色等于要填充的颜色 则直接返回
    if(colorR==fillingColor[0] && colorG==fillingColor[1] && colorB==fillingColor[2]){
        return ;
    }

    /** 堆栈 数组使用 push进 Pop出 **/
        //列数的堆栈
    var stackColumn = new Array();
    //行数的堆栈
    var stackRow = new Array();

    //存储种子点
    stackColumn.push(startX);
    stackRow.push(startY);

    /**
     * 检验该点是否是同色点,是的话就将其作为种子点
     * @param r 行数
     * @param c 列数
     * @constructor 返回布尔值
     */
    function CheckNewSeed(r, c){
        //获取
        let n = r * width + c;
        //获取原图的 r 行 c列 的RGB像素值
        let needColorR = casData.data[4*n+0];
        let needColorG = casData.data[4*n+1];
        let needColorB = casData.data[4*n+2];
        //判断颜色 + 存储种子点://在判断 颜色 是否是 种子点的颜色
        if( c>=0 && c <= width && r>=0 && r<= height
            && needColorR == colorR && needColorG== colorG && needColorB ==colorB){
            // 若 符合情况 则将该店改颜色
            casData.data[4*n] = fillingColor[0];
            casData.data[4*n+1] = fillingColor[1];
            casData.data[4*n+2] = fillingColor[2];
            //并且将其作为种子点
            stackRow.push(r);
            stackColumn.push(c);
        }
    }

    var c;
    var r;

    //非递归种子算法
    while(true){
        //当堆栈中的元素为零时,即 无种子元素 则 退出循环
        if(stackColumn.length <= 0){
            break;
        }
        c = stackColumn.pop();
        r = stackRow.pop();
        CheckNewSeed(r, c);
        CheckNewSeed(r + 1, c);
        CheckNewSeed(r - 1, c);
        CheckNewSeed(r, c + 1);
        CheckNewSeed(r, c - 1);
    }

    ctx.putImageData(casData, 0, 0);
}

二. colorHexToRGB(hex)函数
用于将 16进制颜色值(例 ”#FFFFFF“)转换成RGB的颜色值(例: [255,255,255])。

//十六进制颜色值的正则表达式
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;

/**
 * 颜色的 16进制值 转换成 RGB值
 * @param hex 颜色的16进制值
 * @returns {string|[]} 转成RGB值
 */
function colorHexToRGB(hex){
    var that = hex;
    var sColor = that.toLowerCase();
    //处理六位的颜色值
    var sColorChange = [];
    if(sColor && reg.test(sColor)){
        if(sColor.length === 4){
            var sColorNew = "#";
            for(var i=1; i<4; i+=1){
                sColorNew += sColor.slice(i,i+1).concat(sColor.slice(i,i+1));
            }
            sColor = sColorNew;
        }

        for(var i=1; i<7; i+=2){
            sColorChange.push(parseInt("0x"+sColor.slice(i,i+2)));
        }
        return sColorChange;
    }else{
        return sColorChange;
    }
}


四、效果

填充前:
在这里插入图片描述

填充后:在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
html5 canvas填色画游戏代码是一款适合儿童玩的益智类填色游戏,通过选中色块,来给模型填充颜色。支持多种模型选择填色效果。 function extend(O1,O2){     for(var i in O2){         O1[i]=O2[i];     } } function each(arr,f){     for(var i = 0;i<arr.length;i ){         f.call(arr[i],i,arr[i]);     } } function dataInfo(Obj,x,y){     var c=document.createElement("canvas");     var txt= c.getContext("2d");     c.width=Obj.img.width;     c.height=Obj.img.height;     txt.drawImage(Obj.img,0,0);     var data=txt.getImageData(x-1,y-1,3,3);     var num=0;     for(var q=0;q<data.data.length;q =4){         num =data.data[q 3];     }     num=num/9;     return parseInt(num); } var HGAME=new Object(); HGAME.event=new Object();//事件对象 HGAME.event.clickBuffer=new Array();//缓存要添加事件的节点 click buffer HGAME.animate=function(Obj){     var defaultObj={         time:30,//动画间隔         frequency:-1,//动画次数 -1表示无限制         action:function(){},//动画每一帧的动作         lastAction:function(){}//最后一次动画执行完成触发函数     };     extend(defaultObj,Obj);     var oldTime=new Date();     var newTime=null;     this.time=defaultObj.time;     this.frequency=defaultObj.frequency;     this.action=defaultObj.action;     this.lastAction=defaultObj.lastAction;     this.stop=function(){         cancelAnimationFrame(this.INT_BUFFER);     };

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值