2018年10月13日 星期六

寫一個簡單在 HTML canvas 裡繪圖的 Javascript 程式

<html><head></head><body><script>
// 存成 draw.html 檔案後, 用支援 ES6 的瀏覽器開啟
class myCanvas{
    constructor(name,maxx,maxy){
        let div     = document.createElement('div');   
        let canvas     = document.createElement('canvas');   
        let ctx     = canvas.getContext("2d");   
        let textnode= document.createTextNode(name);
        document.body.appendChild(textnode);
        document.body.appendChild(div);
        div.appendChild(canvas);                               
        div.align="center";
        canvas.style.border = "1px solid";//外框 1 點
        canvas.width = maxx;     //{0 < x < maxx}
        canvas.height = maxy;    //{-maxy < y < maxy}
        this.context = ctx;        // must init first, will be used later
        this._ispaint = false;    // must init second
        this.limitx = canvas.width;
        this.limity = canvas.height;
        this.yscale = 95/100; // 95%
        this.color = "green";   
        this.dashline = [4,1]; // 4px solid, 1px space
        this.drawline(0,     0, maxx, 0);   
        this.drawline(0, -maxy,    0, maxy);
        this.color = "red";       
        this.dashline = [1,4]; // 1px solid, 4px space
        this.drawline(0, -maxy, maxx, -maxy);
        this.drawline(0 , maxy, maxx,  maxy);           
        this.dashline = [5,0]; // 5px solid
        this.drawtext("0",0,0);
        this.drawtext( "x="+maxx, maxx, 0);
        this.drawtext( "+"+maxy, 0,-maxy);
        this.drawtext( "-"+maxy, 0, maxy);   
    } // object create complete
    // following method need object to be created first   
    set start(ispaint) { // keep track of the paint state
        if( ispaint )    {
            if( ! this.start ) this.context.beginPath();
            this._ispaint = true;
        } else {
            this.move(0,0);// back to the origin   
            if( this.start ) this.context.stroke();
            this._ispaint = false;
        }
    }
    get start()    { return this._ispaint;     }
    set color(c){ this.context.strokeStyle=c;}
    set dashline(x){this.context.setLineDash(x); }
    close()        { this.start = false;          }
    move(x,y)    { this.context.moveTo(x,y);     }
    rescale(sx,sy){ this.context.scale(sx, sy); }
    mirror()    { this.context.scale(1, -1); }   
    set yscale(sy){
        // 先移動原點至中心, y 再縮小比例並鏡射
        this.context.lineWidth = 1; // 線寬 1 點
        this.context.translate(0, this.limity/2); // y center
        this.rescale(1, -sy/2); //
        //ctx.rotate(5*Math.PI/180);// 座標旋轉角度
    }
    drawline(x1,y1,x2,y2){
        if( ! this.start ) this.start = true
        this.context.moveTo(x1,y1);
        this.context.lineTo(x2,y2);
        this.start = false; // auto offline
    }
    lineto(x, y){
        if( ! this.start ) this.start = true
        this.context.lineTo(x,y);
    }
    drawtext(msg, x, y, align){
        this.rescale(1, -1);// text force y mirror back
        let fontpx=24;   
        if( (x + msg.length * fontpx) >= this.limitx )  {
                  this.context.textAlign="right";
        } else  this.context.textAlign="left";
        if( y<=0 ) y = y + fontpx;   
        this.context.font=fontpx + "px Comic Sans MS";
        this.context.fillText(msg, x, y);// 充實字體
        this.rescale(1, -1);// mirror back again
    }
};
let pen    = new myCanvas("Sin",600,300);
pen.color="blue";
for (let x=0; x < pen.limitx; x++) {
    pen.lineto(x, pen.limity * Math.sin(2*Math.PI*x*4/pen.limitx));       
}
pen.close();
</script></body></html>

沒有留言: