博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AlloyRenderingEngine文本框组件
阅读量:4611 次
发布时间:2019-06-09

本文共 4941 字,大约阅读时间需要 16 分钟。

写在前面

Github:

在dom元素里,自带了input标签,设置其type为text,它就是一个文本框。

那么在Canvas中模拟input文本框是不是闲的没事找事?绝对不是!

因为在游戏当中可以统一化像素管理,具体统一化像素管理有什么好处,以后新开文章详细讨论。

演示

上面的文本框就是使用AlloyRenderingEngine渲染出来的。

使用

; (function () {    var Stage = ARE.Stage, Textbox = ARE.Textbox;    var stage = new Stage("#ourCanvas", true);    var textbox = new ARE.Textbox({        fontSize: 22,        color: "red",        width: 200,        height: 26    });    textbox.x = 50;    textbox.y = 50;    textbox.focus();    stage.add(textbox);})();

原理(都在注释里)

; (function () {    //先把要使用类的赋给临时变量,以后就不用打点了:)    var Stage = ARE.Stage, Container = ARE.Container, Graphics = ARE.Graphics, Text = ARE.Text;    //文本框集成自容器    ARE.Textbox = Container.extend({        //构造函数        ctor: function (option) {            //把容器的属性和方法搞给自己            this._super();            //鼠标移上去指针的形状,AlloyRenderingEngine会自动帮你显示鼠标移上去时候的形状            this.cursor = "text";            //文本框的边框            this.box = new Graphics()            //直接根据传进的宽和高画个矩形            this.box.strokeRect(0, 0, option.width, option.height);            //文本框的背景,这里接近透明,为什么要设置背景是因为鼠标一上去要触发一个事件,            //而AlloyRenderingEngine的默认触发是像素级别,            //会根据getImageData得到该点的rgba的a是否为0去判断是否触发事件            //所以铺一个接近透明的背景            //主要是为了触发的事件是:鼠标移到文本框上面,鼠标形状要变成cursor:text            this.box.fillStyle("rgba(255,255,255,0.1)").fillRect(0, 0, option.width, option.height);            //把边框添加到自身(因为自身就是容器,继承自Container,所以有了add方法)            this.add(this.box);            //绑定事件            this._bindEvent();            //合并默认配置            this.option = {                fontSize: option.fontSize || 12,                fontFamily: option.fontFamily || "arial",                color: option.color || "black",                width: option.width            };                       //cursorText代表文本框中闪烁的光标,自己用黑色的Text去模拟            this.cursorText = new Text("|", this.option.fontSize + "px " + this.option.fontFamily, "black");            //真正的input!!!!哈哈,玄机就在于此 =   =!            this.realTextbox = document.createElement("input");            this.realTextbox.type = "text";            this.realTextbox.style.position = "fixed";            this.realTextbox.style.left= "-200px"            this.realTextbox.style.top= "0px"            document.body.appendChild(this.realTextbox);            //canvas中显示的文本            this.text = new Text("", this.option.fontSize + "px " + this.option.fontFamily, this.option.color);            //measureCtx是专门用于测量canvas中文本宽度的            this.measureCtx = document.createElement("canvas").getContext("2d");            this.measureCtx.font = this.option.fontSize + "px " + this.option.fontFamily;            this.add(this.text, this.cursorText);            //tickFPS是该容器tick执行的频率,AlloyRenderingEngine会自动帮你执行tick方法            this.tickFPS = 20;        },        //获取焦点        focus: function () {            var self = this;            //真正的input也同时获取焦点            this.realTextbox.focus();            //Canvas中的光标闪烁            this.loop = setInterval(function () {                self.cursorText.visible = !self.cursorText.visible;            }, 500);        },        //失去焦点        blur: function () {            clearInterval(this.loop);            //真正的input也同时失去焦点            this.realTextbox.blur();            //隐藏Canvas中的光标            this.cursorText.visible = false;        },        _bindEvent: function () {            var self = this;            this.onClick(function (evt) {                //真正的input也同时获取焦点                self.realTextbox.focus();                //显示光标                self.cursorText.visible = true;                //自己也假装获取焦点                self.focus();                //阻止冒泡                evt.stopPropagation();            });            //点击文本框的其他区域触发失去焦点            document.addEventListener("mousedown", function () {                //失去焦点                self.blur();            }, false);        },        //计算合适的显示文本,这主要是解决文本超出了文本框的宽度时候的显示问题        getFitStr: function (str, index) {            //利用measureText计算文本宽度            var width = this.measureCtx.measureText(str.substring(index, str.length - 1)).width;            if (width < this.option.width - this.option.fontSize) {                return this.getFitStr(str, --index);            } else {                return str.substring(index++, str.length - 1)            }        },        tick: function () {            //利用measureText计算文本宽度,并把该宽度赋值给光标的偏移            this.cursorText.x = this.measureCtx.measureText(this.realTextbox.value).width;            //如果宽度超了            if (this.cursorText.x > this.option.width) {                this.text.value = this.getFitStr(this.realTextbox.value, this.realTextbox.value.length - 2);                this.cursorText.x = this.measureCtx.measureText(this.text.value).width;            } else {//如果宽度没超                this.text.value = this.realTextbox.value;            }        }    });})();

大部分代码都做了解释,不再重复阐述。

Github:

转载于:https://www.cnblogs.com/iamzhanglei/p/4516337.html

你可能感兴趣的文章
python的沙盒环境--virtualenv
查看>>
软件自动化测试——入门、进阶与实战
查看>>
BZOJ1878 [SDOI2009]HH的项链 树状数组 或 莫队
查看>>
BZOJ3675 [Apio2014]序列分割 动态规划 斜率优化
查看>>
2016.10.24 继续学习
查看>>
产品功能对标 - 服务授权管理
查看>>
各地IT薪资待遇讨论
查看>>
splay入门
查看>>
带CookieContainer进行post
查看>>
C语言学习笔记--字符串
查看>>
CSS-上下文选择器
查看>>
ionic repeat 重复最后一个时要执行某个函数
查看>>
1.初识代码审计-基础
查看>>
[Vue-rx] Stream an API using RxJS into a Vue.js Template
查看>>
解决VC几个编译问题的方法——好用
查看>>
SPOJ #11 Factorial
查看>>
City Upgrades
查看>>
“人少也能办大事”---K2 BPM老客户交流会
查看>>
关于七牛进行图片添加文字水印操作小计
查看>>
DataSource数据库的使用
查看>>