前回の続き。Google Chrome Extensionの習作として、スクリーンショットを撮ってお絵描きするExtensionを作ってみた。とりあえず、ブログにのっけてみる。なお、ライブラリとして、次のものを利用している。
とりあえず、作ってみたものをのせてみる。実際に動かしてみると、色々と動作に怪しさ満載・・・。もう少しキチンをつくり直して、ギャラリーに登録できたらなあと思う。
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
■manifest.json
{ "name": "ScreenShot", "version": "1.0", "description": "ScreenShot", "browser_action": { "default_icon": "camera2.png", "default_title": "ScreenShot", "popup": "popup.html" }, "permissions": [ "tabs" ] }
■image.js
var canvas; var ctx; var image; var scale=1.0; var mx=-1; var my=-1; var doCut=false; var cutoff=false; var pmy=68; var pmx=5; var lines=new Array(); var tmp=null; var mode=0; var color; var stroke=5; function init(){ var options=JSON.parse(localStorage['opt']); image = new Image(); image.src = options.url; image.onload = function() { document.getElementById('canvas').width=image.width; document.getElementById('canvas').height=image.height; canvas=document.getElementById('canvas'); ctx=canvas.getContext('2d'); ctx.drawImage(image,0,0,image.width,image.height); $('canvas').mousedown(function(event) { mx=event.pageX-pmx; my=event.pageY-pmy; if(doCut){ cutoff=true; tmp=new Point(mx,my); }else if(mode==0&&tmp!=null){ var p=new Point(mx,my); color=$('#color').val(); lines[lines.length]=new Line(tmp,p,stroke,color); tmp=p; redraw(); }else if((mode==1||mode==2)&&tmp==null){ tmp=new Point(mx,my); } }); $('canvas').dblclick(function(event){ if(cutoff||mode!=0)return; color=$('#color').val(); mx=event.pageX-pmx; my=event.pageY-pmy; if(tmp==null){ tmp=new Point(mx,my); }else{ var p=new Point(mx,my); lines[lines.length]=new Line(tmp,p,stroke,color); tmp=null; } }); $('canvas').mousemove(function(event) { mx=event.pageX-pmx; my=event.pageY-pmy; if(cutoff){ redraw(); drawRect(); }else if(mode==0&&tmp!=null){ redraw(); color=$('#color').val(); ctx.beginPath(); ctx.strokeStyle=getColor(color); ctx.lineWidth=stroke; ctx.moveTo(tmp.x,tmp.y); ctx.lineTo(mx,my); ctx.stroke(); ctx.closePath(); }else if(mode==1&&tmp!=null){ color=$('#color').val(); var p=new Point(mx,my); lines[lines.length]=new Line(tmp,p,stroke,color); tmp=p; redraw(); }else if(mode==2&&tmp!=null){ redraw(); drawRect(); } }); $('canvas').mouseup(function(event) { mx=event.pageX-pmx; my=event.pageY-pmy; if(cutoff){ cutoffConfirm(); cutoff=false; doCut=false; tmp=null; }else if(mode==1){ tmp=null; }else if(mode==2){ var xx=Math.min(tmp.x,mx); var ww=Math.max(tmp.x,mx)-xx; var yy=Math.min(tmp.y,my); var hh=Math.max(tmp.y,my)-yy; del(xx,yy,ww,hh) tmp=null; redraw(); } }); } $('#dialog').dialog({ autoOpen: false, width: 220, buttons: { "Ok": function() { $(this).dialog("close"); }, "Cancel": function() { $(this).dialog("close"); } } }); $('#dialog_link').click(function(){ $('#dialog').dialog('open'); return false; }); $("#radio").buttonset(); $('#picker').farbtastic('#color'); $("#slider").slider({ animate:true , min:1, max:100, values:5, slide: function(event, ui) { $("#stroke").text(ui.value); stroke=ui.value; } }); } function modeChange(i){ tmp=null; mode=i; } function del(xx,yy,ww,hh){ for(var i=0;i < lines.length;i++){ var l=lines.shift(); if(contain(xx,yy,ww,hh,l.p0))continue; if(contain(xx,yy,ww,hh,l.p1))continue; lines.push(l); } } function contain(xx,yy,ww,hh,p){ if(xx < p.x&&p.x < xx+ww){ return (yy < p.y&&p.y < hh+hh); }else{ return false; } } function drawRect(){ ctx.beginPath(); ctx.strokeStyle="rgb(200,125,125)"; ctx.lineWidth=1.0; var xx=Math.min(tmp.x,mx); var ww=Math.max(tmp.x,mx)-xx; var yy=Math.min(tmp.y,my); var hh=Math.max(tmp.y,my)-yy; ctx.rect(xx, yy, ww, hh); ctx.stroke(); ctx.closePath(); } function redraw(){ ctx.clearRect(0,0,canvas.width,canvas.height); ctx.drawImage(image,0,0,image.width*scale,image.height*scale); ctx.lineCap="round"; ctx.lineJoin="round"; for(var i=0;i < lines.length;i++){ lines[i].draw(ctx); } } function savePNG(){ var s=canvas.toDataURL(); location.href=s; } function resize(val){ ctx.clearRect(0,0,image.width,image.height); scale=val/100.0; document.getElementById('canvas').width=image.width*scale; document.getElementById('canvas').height=image.height*scale; ctx=canvas.getContext('2d'); ctx.drawImage(image,0,0,image.width*scale,image.height*scale); } function cutoffConfirm(){ var xx=Math.min(tmp.x,mx); var ww=Math.max(tmp.x,mx)-xx; var yy=Math.min(tmp.y,my); var hh=Math.max(tmp.y,my)-yy; if(ww==0||hh==0){ redraw(); return; } if(confirm("Cut O.K?")){ redraw(); image=ctx.getImageData(xx, yy, ww, hh); ctx.clearRect(0,0,canvas.width,canvas.height); ctx.putImageData(image,0,0); image = new Image(); image.src = canvas.toDataURL(); image.onload = function() { scale=1.0; lines=new Array(); redraw(); } }else{ redraw(); } } function cut(){ doCut=true; tmp=null; } var Point=function(_x,_y){ this.x=_x; this.y=_y; } var Line=function(_p0,_p1,s,c){ this.p0=_p0; this.p1=_p1; this.size=s; this.color=c; this.draw=function(c){ c.beginPath(); c.strokeStyle=getColor(this.color); c.lineWidth=this.size; c.moveTo(this.p0.x,this.p0.y); c.lineTo(this.p1.x,this.p1.y); c.stroke(); c.closePath(); } } function getColor(str){ var r=eval("0x"+str.substring(1,3)); var g=eval("0x"+str.substring(3,5)); var b=eval("0x"+str.substring(5,7)); r=Math.min(Math.max(0,r),255); g=Math.min(Math.max(0,g),255); b=Math.min(Math.max(0,b),255); var ret="rgb("+r+","+g+","+b+")"; return ret; } function modeLine(){ mode=0; $("#mode").text("Line"); } function modeFree(){ mode=1; $("#mode").text("Free"); } function modeDel(){ mode=2; $("#mode").text("Del "); }
■popup.html
Scan!
■image.html
ScreenShot Save Cut Draw [ 25% 50% 75% 100% 125% 150% 175% ]
Width=5