美文网首页
HTML5 Canvas笔记——简单文本编辑功能

HTML5 Canvas笔记——简单文本编辑功能

作者: 没昔 | 来源:发表于2020-06-02 23:11 被阅读0次

    编写在canvas环境中具有简单文本编辑功能的程序。

    主要功能:(1)有跟随移动的闪烁的光标;(2)能输入、插入、退格键删除。

    文本编辑.html

    <!DOCTYPE html>
    <html>
        <head>
            <title>简单文本编辑</title>
            <style>
            body {
                background: #eeeeee;
            }
            #canvas {
                background: #fff;
                cursor: pointer;
                margin-left: 10px;
                margin-top: 10px;
                box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
                -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
                -moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            }
            #controls {
                position: absolute;
                left: 25px;
                top: 25px;
        }
            </style>
        </head>
        <body>
            <div id='controls'>
                Font: <select id='fontSelect'>
                    <option value='palatino' select>palatino</option>
                    <option value='lucida'>lucida</option>
                    <option value='fantasy'>fantasy</option>
                    <option value='Arial'>Arial</option>
                    <option value='Comic Sans' selected>Comic Sans</option>
                    <option value='Lucida Sans'>Lucida Sans</option>
                    <option value='Helvetica'>Helvetica</option>
                    <option value='century'>century</option>
                    <option value='tahoma'>tahoma</option>
                    <option value='impact'>impact</option>
                    <option value='copperplate'>copperplate</option>
                </select>
                Size: <select id='sizeSelect'>
                    <option value='20px' select>20px</option>
                    <option value='30px'>30px</option>
                    <option value='32px'>32 px</option>
                    <option value='40px'>40px</option>
                    <option value='48px' selected>48 px</option>
                    <option value='50px'>50px</option>
                    <option value='60px'>60px</option>
                    <option value='64px'>64 px</option>
                    <option value='70px'>70px</option>
                    <option value='128px'>128 px</option>
                </select>
                Text stroke color:<select id='strokeStyleSelect'>
                    <option value='red'>red</option>
                    <option value='green'>green</option>
                    <option value='blue'>blue</option>
                    <option value='orange'>orange</option>
                    <option value='cornflowerblue' selected>cornflowerblue</option>
                    <option value='goldenrod'>goldenrod</option>
                    <option value='navy'>navy</option>
                    <option value='purple'>purple</option>
                </select>
                Text fill color:<select id='fillStyleSelect'>
                    <option value='rgba(255,0,0,0.5)'>semi-transparent red</option>
                    <option value='green'>green</option>
                    <option value='rgba(0,0,255,0.5)'>semi-transparent blue</option>
                    <option value='orange'>orange</option>
                    <option value='rgba(100,140,230,0.5)'>semi-transparent cornflowerblue</option>
                    <option value='rgba(218,165,32,0.5)' selected>semi-transparent goldenrod</option>
                    <option value='goldenrod' selected>goldenrod</option>
                    <option value='navy'>navy</option>
                    <option value='purple'>purple</option>
                </select>       
            </div>
            <canvas id='canvas' width='950' height='550'>
            Canvas not supported
            </canvas>
        </body>
        <script>
            // 光标
            TextCursor = function (width,fillStyle){
                this.width = width || 2;
                this.fillStyle = fillStyle || 'rgba(0,0,0,0.5)';
                this.left = 0;
                this.top = 0;
            }
            TextCursor.prototype = {
                getHeight:function(context){
                    var h = context.measureText('M').width;
                    return h+h/6;
                },            
                creatPath:function(context){
                    context.beginPath();
                    context.rect(this.left,this.top,this.width,this.getHeight(context));
                },            
                draw:function(context,left,bottom){
                    context.save();
                    this.left = left;
                    this.top = bottom - this.getHeight(context);
                    this.creatPath(context);
                    context.fillStyle = this.fillStyle;
                    context.fill();
                    context.restore();
                },            
                erase:function(context,imageData){
                    context.putImageData(imageData,0,0,this.left,this.top,this.width,this.getHeight(context));
                }
            }
        </script>
    
        <script>
            //插入文本行
            //插入字符位置
            TextLine = function(x,y){
                this.left = x;
                this.bottom = y;
                this.text = '';
                this.caret = 0; 
            }
            TextLine.prototype = {
                getHeight:function(context){
                    var h = context.measureText('M').width;
                    return h+h/6;
                },
                getWidth:function(context){
                    return context.measureText(this.text).width;
                }, 
                insert:function(text){
                    this.text = this.text.substr(0,this.caret) + text +this.text.substr(this.caret);
                    this.caret +=text.length;
                },            
                removeCharacterBeforeCaret:function(){
                    if(this.caret===0){
                        return;
                    }
                    this.text = this.text.substr(0,this.caret-1)+this.text.substr(this.caret);
                    this.caret--;
                },            
                draw:function(context){
                    context.save();
                    context.textAlign = 'start';
                    context.textBaseline = 'bottom';
                    context.strokeText(this.text,this.left,this.bottom);
                    context.fillText(this.text,this.left,this.bottom);
                    context.restore();
                },            
                erase:function(context,imageData){
                    context.putImageData(imageData,0,0);
                }
            }
        </script>
        <script src='文本编辑.js'></script>
    </html>
    

    文本编辑.js

    var canvas = document.getElementById('canvas'),
        context = canvas.getContext('2d'),
    
        fontSelect = document.getElementById('fontSelect'),
        sizeSelect = document.getElementById('sizeSelect'),
        strokeStyleSelect = document.getElementById('strokeStyleSelect'),
        fillStyleSelect = document.getElementById('fillStyleSelect'),
        GRID_STROKE_STYLE='lightgray',
        GIRD_HORIZONTAL_SPACING=10,
        GIRD_VERTICAL_SPACING=10,
        cursor=new TextCursor(),
        line,
        blinkingInterval,
        BLINK_TIME=1000,
        BLINK_OFF=300;
    //function........................................
    function drawBackground(){
        var stop_y = 20;
        var left_margin = stop_y*3;
        var top_marigin = stop_y*4;
        var i = canvas.height;
        context.save();
        context.shadowColor = undefined;
        context.shadowOffsetX = 0;
        context.shadowOffsetY = 0;
        context.shadowBlur = 0;
        context.strokeStyle = 'lightgray';
        context.lineWidth = 0.5;
        while(i>top_marigin){
            context.beginPath();
            context.moveTo(left_margin,i);
            context.lineTo(canvas.width,i);
            context.stroke();
            i-=stop_y;
        }
        context.beginPath();
        context.moveTo(left_margin,top_marigin);
        context.lineTo(left_margin,canvas.height);
        context.stroke();
        context.restore();
    }
    function windowToCanvas(x,y){
        var bbox = canvas.getBoundingClientRect();
        return {
            x:x-bbox.left*(canvas.width/bbox.width),
            y:y-bbox.top*(canvas.height/bbox.height)
        };
    };
    //Drawing surface...................................
    function saveDrawingSurface() {
        drawingSurfaceImageData = context.getImageData(0, 0,
                                  canvas.width,
                                  canvas.height);
    }
    //Text................................................
    function setFont(){
        context.font=sizeSelect.value+' '+fontSelect.value;
    }
    function blinkCursor(x,y){
        clearInterval(blinkingInterval);
        blinkingInterval=setInterval(function(e){
            cursor.erase(context,drawingSurfaceImageData);
            setTimeout(function(){
                if(cursor.left==x && cursor.top+cursor.getHeight(context)==y){
                    cursor.draw(context,x,y);
                }
            },300);
        },1000);
    }
    function moveCursor(x,y){
        cursor.erase(context,drawingSurfaceImageData);
        saveDrawingSurface();
        cursor.draw(context,x,y);
        blinkCursor(x,y);
    }
    
    //Event handlers.........................................
    canvas.onmousedown=function(e){
        var loc=windowToCanvas(e.clientX,e.clientY);
        
        moveCursor(loc.x,loc.y);
        line=new TextLine(loc.x,loc.y);
    }
    strokeStyleSelect.onchange=function(e){
        cursor.strokeStyle=strokeStyleSelect.value;
        context.strokeStyle=strokeStyleSelect.value;
    };
    fillStyleSelect.onchange=function(e){
        cursor.fillStyle=fillStyleSelect.value;
        context.fillStyle=fillStyleSelect.value;
    };
    //Key event handlers......................................
    document.onkeydown=function(e){
        if(e.keyCode===8 || e.keyCode===13){
            e.preventDefault();
        }
        if(e.keyCode===8){   //Backspace
            context.save();  
            line.erase(context,drawingSurfaceImageData);
            line.removeCharacterBeforeCaret();
            moveCursor(line.left+line.getWidth(context),line.bottom);
            line.draw(context);
            context.restore();
        }
    }
    document.onkeypress=function(e){
        var key=String.fromCharCode(e.which);
        e.preventDefault();
        context.save();
        line.erase(context,drawingSurfaceImageData);
        line.insert(key);
        moveCursor(line.left+line.getWidth(context),line.bottom);
        context.shadowColor='rgba(0,0,0,0.5)';
        context.shadowOffsetX=1;
        context.shadowOffsetY=1;
        context.shadowBlur=2;
        line.draw(context);
        context.restore();
    }
    //Initialization.....................................
    fontSelect.onchange=setFont;
    sizeSelect.onchange=setFont;
    cursor.fillStyle=fillStyleSelect.value;
    cursor.strokeStyle=strokeStyleSelect.value;
    context.strokeStyle=strokeStyleSelect.value;
    context.fillStyle=fillStyleSelect.value;
    context.lineWidth=2.0;
    setFont();
    drawBackground();
    saveDrawingSurface();
    
    
    

    相关文章

      网友评论

          本文标题:HTML5 Canvas笔记——简单文本编辑功能

          本文链接:https://www.haomeiwen.com/subject/xdrmzhtx.html