123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- <!DOCTYPE html>
- <html>
- <head>
- <!-- 必须强制指定页面编码为 UTF-8 -->
- <meta charset="utf-8">
- <!-- Demo 的简要说明,必须要填写 -->
- <meta name="description" content="Kity 实现模拟光标输入">
-
- <!-- Demo 的作者,建议填写 -->
- <meta name="author" content="kity@baidu.com">
-
- <!-- Demo 的标题,必须填写 -->
- <title>模拟光标</title>
-
- <!-- Demo 开发过程中使用 CMD 引入 Kity 源码,方便调试 -->
- <!-- dev start -->
- <!-- 目录型的 Demo 注意修正源码引用路径 -->
- <script src="../dev-lib/sea.js"></script>
- <script>
- // 设置好 kity 源代码目录
- seajs.config( { base: '../src'} );
- // 定义 Demo 模块
- define('demo', function(require) { require('kity'); });
- </script>
- <script>
- // 启动 Demo 模块
- seajs.use('demo');
- </script>
- <!-- dev 版本 示例所需脚本文件 end -->
- <script src="public/jquery.js"></script>
- <style>
- .editor-container{
- }
- .receiver{
- position:absolute;
- padding:0;
- margin:0;
- word-wrap:break-word;
- clip:rect(1em 1em 1em 1em);
- }
- </style>
- </head>
- <body>
- <script>
- var Cursor = kity.createClass('Cursor',{
- base: kity.Line,
- constructor: function(height, color, width) {
- this.callBase();
- this.height = height || 20;
- this.stroke(color || 'blue', width || 1);
- this.setHide();
- this.timer = null;
- },
- setPosition: function(offset) {
- try{
- this.setPoint1(offset.x,offset.y);
- this.setPoint2(offset.x,offset.y + this.height);
- }catch(e){
- debugger
- }
- return this;
- },
- setHeight:function(height){
- this.height = height;
- },
- setHide:function(){
- clearInterval(this.timer);
- this.setStyle('display','none');
- return this;
- },
- setShowHold : function(){
- clearInterval(this.timer);
- this.setStyle('display','');
- return this;
- },
- setShow:function(){
- clearInterval(this.timer);
- var me = this,
- state = '';
- this.timer = setInterval(function(){
- me.setStyle('display',state);
- state = state ? '' : 'none';
- },300);
- return this;
- },
- setTextShape:function(text){
- if(!text){
- this.text = new kity.Text();
- }else{
- this.text = text;
- }
- return this
- },
- getTextShape:function(){
- return this.text
- },
- setTxtContent : function(text){
- this.text.setContent(text)
- },
- updatePosition:function(index){
- }
- });
- var Receiver = kity.createClass('Receiver',{
- clear : function(){
- this.$container.html('');
- this.index = 0;
- return this;
- },
- constructor : function(){
- this.$container = $('<div contenteditable="true" class="receiver"></div>');
- this.$container.appendTo(document.body);
- this.$container.on('keydown keypress keyup', $.proxy(this.keyboardEvents,this));
- this.timer = null;
- this.index = 0;
- },
- setPosition : function(textShapeOffset){
- this.$container.css({
- top:textShapeOffset.x,
- left:textShapeOffset.y
- });
- this.textShape.setPosition(textShapeOffset.x, textShapeOffset.y);
- return this;
- },
- setRange : function(range,index){
- this.index = index || this.index;
- var text = this.$container[0].firstChild;
- console.log(text)
- console.log(this.index)
- range.setStart(text || this.$container[0], this.index).collapse(true);
- setTimeout(function(){
- range.select()
- });
- return this;
- },
- setTextShape:function(textShape){
- if(!textShape){
- textShape = new kity.Text();
- }
- this.textShape = textShape;
- return this;
- },
- setTextShapeSize:function(size){
- this.textShape.setSize(size);
- return this;
- },
- getTextShapeHeight:function(){
- return this.textShape.getRenderBox().height;
- },
- appendTextShapeToPaper:function(paper){
- paper.addShape(this.textShape);
- return this;
- },
- keyboardEvents : function(e){
- clearTimeout(this.timer);
- var me = this;
- switch(e.type){
- case 'keyup':
- this.textShape.setContent(this.$container.text().replace(/\u200b/g,''));
- this.updateTextData();
- this.updateCursor();
- this.timer = setTimeout(function(){
- me.cursor.setShow()
- },500);
- break;
- case 'keypress':
- case 'keyup':
- }
- },
- updateTextData : function(){
- this.textShape.textData = this.getTextOffsetData();
- this.index = this.index + 1;
- },
- setCursor : function(cursor){
- this.cursor = cursor;
- return this;
- },
- updateCursor : function(){
- this.cursor.setShowHold();
- if(this.index == this.textData.length){
- this.cursor.setPosition({
- x : this.textData[this.index-1].x + this.textData[this.index-1].width,
- y : this.textData[this.index-1].y
- })
- }else if(this.index == 0){
- this.cursor.setPosition({
- x : this.textShape.getX(),
- y : this.textData.getY()
- })
- }else{
- if(this.index + 1 == this.textData.length){
- var lastChar = this.textData[this.index];
- this.cursor.setPosition({
- x : lastChar.x + lastChar.width,
- y : lastChar.y
- })
- }else{
- this.cursor.setPosition(this.textData[this.index])
- }
- }
- return this;
- },
- getTextOffsetData:function(){
- var text = this.textShape.getContent();
- this.textData = [];
- // this.textShape.clearContent();
- for(var i= 0,l = text.length;i<l;i++){
- var box = this.textShape.getExtentOfChar(i);
- this.textData.push({
- x:box.x,
- y:box.y,
- width:box.width,
- height:box.height
- })
- }
- return this;
- },
- setCurrentIndex:function(offset){
- var me = this;
- this.getTextOffsetData();
- var hadChanged = false;
- $.each(this.textData,function(i,v){
- if(offset.x >= v.x && offset.x <= v.x + v.width){
- if(offset.x - v.x > v.width/2){
- me.index = i + 1;
- }else {
- me.index = i
- }
- hadChanged = true;
- return false;
- }
- })
- return this;
- },
- setCursorHeight:function(){
- this.cursor.setHeight(this.getTextShapeHeight())
- return this;
- }
- });
- var Range = kity.createClass('Range',{
- constructor : function(){
- this.nativeRange = document.createRange();
- this.nativeSel = window.getSelection();
- },
- select:function(){
- var start = this.nativeRange.startContainer;
- if(start.nodeType == 1 && start.childNodes.length == 0){
- var char = document.createTextNode('\u200b');
- start.appendChild(char);
- this.nativeRange.setStart(char,1);
- this.nativeRange.collapse(true);
- }
- this.nativeSel.removeAllRanges();
- this.nativeSel.addRange(this.nativeRange);
- return this;
- },
- setStart:function(node,index){
- this.nativeRange.setStart(node,index);
- return this;
- },
- setEnd:function(node,index){
- this.nativeRange.setEnd(node,index);
- return this;
- },
- collapse:function(toStart){
- this.nativeRange.collapse(toStart === true);
- return this;
- },
- insertNode:function(node){
- this.nativeRange.insertNode(node);
- return this;
- }
- });
- var cursor = new Cursor();
- var receiver = new Receiver();
- var range = new Range();
- var paper = new kity.Paper(document.body).setHeight(500);
- paper.addShape(cursor)
- .setStyle('border','1px solid #ccc')
- .setStyle('cursor','text')
- .on('click',function(e){
- var originEvent = e.originEvent;
- var position = e.getPosition('top');
- if(e.targetShape.getType() != 'Text'){
- var offset = e.getPosition('top');
- cursor.setShow().setPosition(offset);
- receiver.clear()
- .setTextShape()
- .setTextShapeSize(cursor.height)
- .appendTextShapeToPaper(paper)
- .setPosition(position)
- .setRange(range,0)
- .setCursor(cursor)
- }else{
- receiver.setCursor(cursor)
- .setTextShape(e.targetShape)
- .setCursorHeight()
- .setCurrentIndex(position)
- .updateCursor()
- .setRange(range)
- }
- })
- </script>
- </body>
- </html>
|