🗂
Chromeで別小窓に手書きメモを表示するブックマークレット
同じようなネタばかり、書いていますが、シロウトなので単にITリテラシーが無いからです…
0.初めに
-
以前にマウス、タッチパネル両対応の手書きメモみたいなJavaScriptアプリをCodePenで見つけた
-
記憶があいまいだが、多分、JavaScriptアプリを少し直して、メモの画像保存、UNDO、REDO、線の太さ変更を、できるようにして、使っていた
-
Chromeでウェブサイトを見ながらメモ帳にメモすることがたまにある
-
タッチパネル対応PCも増えたので、手書きしたいこともある
-
メモを保存したいときもある
⇒こんな感じにしたかった
-
というわけで、簡単に手書きメモできるChromeの小窓が欲しかった
⇒こんな感じにしたかった
-
ブックマークレットなら簡単そうだったので作った
1.作ったもの、使ったもの
- 元々のJavaScript
⇒このやり方だとDOMContentLoadedが発火せず、少しいじりました
⇒長すぎるとブックマーク同期がうまく行かないのでCSSを外部ファイルにしました
var hhh='<html>'+
'<!doctype html>'+
'<html>'+
'<head>'+
' <title>Sketch Pad</title>'+
' <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" />'+
' <link rel="stylesheet" href="https://laboratory.main.jp/fcss/a.css">'+
'<script type="text/javascript">'+
'var ctx, color = "#000"; '+
''+
'function newCanvas(){'+
' document.getElementById("content").style.height = window.innerHeight-90;'+
' var canvas = \'<canvas id="canvas" width="\'+window.innerWidth+\'" height="\'+(window.innerHeight-90)+\'"></canvas>\';'+
' document.getElementById("content").innerHTML = canvas;'+
' ctx=document.getElementById("canvas").getContext("2d");'+
' ctx.strokeStyle = color;'+
' ctx.lineWidth = 5; '+
' beforeDraw();'+
' drawTouch();'+
' drawPointer();'+
' drawMouse();'+
'}'+
''+
'function saveCanvas(){'+
' let canvas = document.getElementById("canvas");'+
' let link = document.createElement("a");'+
' link.href = canvas.toDataURL("image/png");'+
' link.download = "noname.png";'+
' link.click();'+
'}'+
' '+
'function selectColor(el){'+
' for(var i=0;i<document.getElementsByClassName("palette").length;i++){'+
' document.getElementsByClassName("palette")[i].style.borderColor = "#777";'+
' document.getElementsByClassName("palette")[i].style.borderStyle = "solid";'+
' }'+
' el.style.borderColor = "#fff";'+
' el.style.borderStyle = "dashed";'+
' color = window.getComputedStyle(el).backgroundColor;'+
' ctx.beginPath();'+
' ctx.strokeStyle = color;'+
'}'+
''+
'var drawTouch = function() {'+
' var start = function(e) {'+
' ctx.beginPath();'+
' x = e.changedTouches[0].pageX;'+
' y = e.changedTouches[0].pageY-44;'+
' beforeDraw();'+
' ctx.moveTo(x,y);'+
' };'+
' var move = function(e) {'+
' e.preventDefault();'+
' x = e.changedTouches[0].pageX;'+
' y = e.changedTouches[0].pageY-44;'+
' ctx.lineTo(x,y);'+
' ctx.stroke();'+
' };'+
' document.getElementById("canvas").addEventListener("touchstart", start, false);'+
' document.getElementById("canvas").addEventListener("touchmove", move, false);'+
'}; '+
' '+
'var drawPointer = function() {'+
' var start = function(e) {'+
' e = e.originalEvent;'+
' ctx.beginPath();'+
' x = e.pageX;'+
' y = e.pageY-44;'+
' beforeDraw();'+
' ctx.moveTo(x,y);'+
' };'+
' var move = function(e) {'+
' e.preventDefault();'+
' e = e.originalEvent;'+
' x = e.pageX;'+
' y = e.pageY-44;'+
' ctx.lineTo(x,y);'+
' ctx.stroke();'+
' };'+
' document.getElementById("canvas").addEventListener("MSPointerDown", start, false);'+
' document.getElementById("canvas").addEventListener("MSPointerMove", move, false);'+
'}; '+
''+
'var drawMouse = function() {'+
' var clicked = 0;'+
' var start = function(e) {'+
' clicked = 1;'+
' ctx.beginPath();'+
' x = e.pageX;'+
' y = e.pageY-44;'+
' beforeDraw();'+
' ctx.moveTo(x,y);'+
' };'+
' var move = function(e) {'+
' if(clicked){'+
' x = e.pageX;'+
' y = e.pageY-44;'+
' ctx.lineTo(x,y);'+
' ctx.stroke();'+
' }'+
' };'+
' var stop = function(e) {'+
' clicked = 0;'+
' };'+
' document.getElementById("canvas").addEventListener("mousedown", start, false);'+
' document.getElementById("canvas").addEventListener("mousemove", move, false);'+
' document.addEventListener("mouseup", stop, false);'+
'};'+
' </script>'+
'</head>'+
'<body>'+
'<div id="page">'+
' <div class="header">'+
' <a id="new" class="navbtn" onclick="newCanvas()">New</a>'+
' <a id="save" class="navbtn" onclick="saveCanvas()">Save</a>'+
' <a id="undo" class="navbtn" onclick="undo()">Undo</a>'+
' <a id="redo" class="navbtn" onclick="redo()">Redo</a>'+
'<select id="aaa" name="linewidth">'+
'<option value="2">細い</option>'+
'<option value="5" selected>普通</option>'+
'<option value="8">太い</option>'+
'<option value="11">極太</option>'+
'<option value="14">超太</option>'+
'</select>'+
' <div class="title">Sketch Pad</div>'+
' </div>'+
' <div id="content"><p style="text-align:center">NEWボタンを押してください...</p></div>'+
' <div class="footer">'+
' <div class="palette-case">'+
' <div class="palette-box">'+
' <div class="palette white" onclick="selectColor(this)"></div>'+
' </div> '+
' <div class="palette-box">'+
' <div class="palette red" onclick="selectColor(this)"></div>'+
' </div>'+
' <div class="palette-box">'+
' <div class="palette blue" onclick="selectColor(this)"></div>'+
' </div>'+
' <div class="palette-box">'+
' <div class="palette green" onclick="selectColor(this)"></div>'+
' </div>'+
' <div class="palette-box">'+
' <div class="palette black" onclick="selectColor(this)"></div>'+
' </div> '+
' <div style="clear:both"></div>'+
' </div>'+
' </div>'+
'</div>'+
''+
'<script>'+
''+
'function linew() {'+
' ctx.lineWidth = document.getElementById("aaa").value;'+
'}'+
''+
'var el1 = document.getElementById(\'aaa\');'+
'el1.addEventListener(\'change\', linew, false);'+
''+
'const STACK_MAX_SIZE = 5;'+
'let undoDataStack = [];'+
'let redoDataStack = [];'+
''+
'function beforeDraw() {'+
' redoDataStack = [];'+
' if (undoDataStack.length >= STACK_MAX_SIZE) {'+
' undoDataStack.pop();'+
' }'+
' var w=document.getElementById(\'canvas\').width;'+
' var h=document.getElementById(\'canvas\').height;'+
' undoDataStack.unshift(ctx.getImageData(0, 0, w, h));'+
'}'+
''+
'function undo () {'+
' if (undoDataStack.length <= 0) return;'+
' var w=document.getElementById(\'canvas\').width;'+
' var h=document.getElementById(\'canvas\').height;'+
' redoDataStack.unshift(ctx.getImageData(0, 0, w, h));'+
' var imageData = undoDataStack.shift();'+
' ctx.putImageData(imageData, 0, 0);'+
'}'+
''+
'function redo () {'+
' if (redoDataStack.length <= 0) return;'+
' var w=document.getElementById(\'canvas\').width;'+
' var h=document.getElementById(\'canvas\').height;'+
' undoDataStack.unshift(ctx.getImageData(0, 0, w, h));'+
' var imageData = redoDataStack.shift();'+
' ctx.putImageData(imageData, 0, 0);'+
'}'+
'</script>'+
'</body>'+
'</html> ';
var win = window.open('','','width=560,height=440');
win.document.write(hhh);
-
ブックマークレットに変換するためのWEBサービス
-
変換後のJavaScript
javascript:var%20hhh%3D'%3Chtml%3E'%2B%20'%3C!doctype%20html%3E'%2B%20'%3Chtml%3E'%2B%20'%3Chead%3E'%2B%20'%20%3Ctitle%3ESketch%20Pad%3C%2Ftitle%3E'%2B%20'%20%3Cmeta%20name%3D%22viewport%22%20content%3D%22width%3Ddevice-width%2Cinitial-scale%3D1.0%2Cmaximum-scale%3D1.0%2Cminimum-scale%3D1.0%2Cuser-scalable%3D0%22%20%2F%3E'%2B%20'%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A%2F%2Flaboratory.main.jp%2Ffcss%2Fa.css%22%3E'%2B%20'%3Cscript%20type%3D%22text%2Fjavascript%22%3E'%2B%20'var%20ctx%2Ccolor%3D%22%23000%22%3B'%2B%20''%2B%20'function%20newCanvas()%7B'%2B%20'%20document.getElementById(%22content%22).style.height%3Dwindow.innerHeight-90%3B'%2B%20'%20var%20canvas%3D%5C'%3Ccanvas%20id%3D%22canvas%22%20width%3D%22%5C'%2Bwindow.innerWidth%2B%5C'%22%20height%3D%22%5C'%2B(window.innerHeight-90)%2B%5C'%22%3E%3C%2Fcanvas%3E%5C'%3B'%2B%20'%20document.getElementById(%22content%22).innerHTML%3Dcanvas%3B'%2B%20'%20ctx%3Ddocument.getElementById(%22canvas%22).getContext(%222d%22)%3B'%2B%20'%20ctx.strokeStyle%3Dcolor%3B'%2B%20'%20ctx.lineWidth%3D5%3B'%2B%20'%20beforeDraw()%3B'%2B%20'%20drawTouch()%3B'%2B%20'%20drawPointer()%3B'%2B%20'%20drawMouse()%3B'%2B%20'%7D'%2B%20''%2B%20'function%20saveCanvas()%7B'%2B%20'%20let%20canvas%3Ddocument.getElementById(%22canvas%22)%3B'%2B%20'%20let%20link%3Ddocument.createElement(%22a%22)%3B'%2B%20'%20link.href%3Dcanvas.toDataURL(%22image%2Fpng%22)%3B'%2B%20'%20link.download%3D%22noname.png%22%3B'%2B%20'%20link.click()%3B'%2B%20'%7D'%2B%20'%20'%2B%20'function%20selectColor(el)%7B'%2B%20'%20for(var%20i%3D0%3Bi%3Cdocument.getElementsByClassName(%22palette%22).length%3Bi%2B%2B)%7B'%2B%20'%20document.getElementsByClassName(%22palette%22)%5Bi%5D.style.borderColor%3D%22%23777%22%3B'%2B%20'%20document.getElementsByClassName(%22palette%22)%5Bi%5D.style.borderStyle%3D%22solid%22%3B'%2B%20'%7D'%2B%20'%20el.style.borderColor%3D%22%23fff%22%3B'%2B%20'%20el.style.borderStyle%3D%22dashed%22%3B'%2B%20'%20color%3Dwindow.getComputedStyle(el).backgroundColor%3B'%2B%20'%20ctx.beginPath()%3B'%2B%20'%20ctx.strokeStyle%3Dcolor%3B'%2B%20'%7D'%2B%20''%2B%20'var%20drawTouch%3Dfunction()%7B'%2B%20'%20var%20start%3Dfunction(e)%7B'%2B%20'%20ctx.beginPath()%3B'%2B%20'%20x%3De.changedTouches%5B0%5D.pageX%3B'%2B%20'%20y%3De.changedTouches%5B0%5D.pageY-44%3B'%2B%20'%20beforeDraw()%3B'%2B%20'%20ctx.moveTo(x%2Cy)%3B'%2B%20'%7D%3B'%2B%20'%20var%20move%3Dfunction(e)%7B'%2B%20'%20e.preventDefault()%3B'%2B%20'%20x%3De.changedTouches%5B0%5D.pageX%3B'%2B%20'%20y%3De.changedTouches%5B0%5D.pageY-44%3B'%2B%20'%20ctx.lineTo(x%2Cy)%3B'%2B%20'%20ctx.stroke()%3B'%2B%20'%7D%3B'%2B%20'%20document.getElementById(%22canvas%22).addEventListener(%22touchstart%22%2Cstart%2Cfalse)%3B'%2B%20'%20document.getElementById(%22canvas%22).addEventListener(%22touchmove%22%2Cmove%2Cfalse)%3B'%2B%20'%7D%3B'%2B%20'%20'%2B%20'var%20drawPointer%3Dfunction()%7B'%2B%20'%20var%20start%3Dfunction(e)%7B'%2B%20'%20e%3De.originalEvent%3B'%2B%20'%20ctx.beginPath()%3B'%2B%20'%20x%3De.pageX%3B'%2B%20'%20y%3De.pageY-44%3B'%2B%20'%20beforeDraw()%3B'%2B%20'%20ctx.moveTo(x%2Cy)%3B'%2B%20'%7D%3B'%2B%20'%20var%20move%3Dfunction(e)%7B'%2B%20'%20e.preventDefault()%3B'%2B%20'%20e%3De.originalEvent%3B'%2B%20'%20x%3De.pageX%3B'%2B%20'%20y%3De.pageY-44%3B'%2B%20'%20ctx.lineTo(x%2Cy)%3B'%2B%20'%20ctx.stroke()%3B'%2B%20'%7D%3B'%2B%20'%20document.getElementById(%22canvas%22).addEventListener(%22MSPointerDown%22%2Cstart%2Cfalse)%3B'%2B%20'%20document.getElementById(%22canvas%22).addEventListener(%22MSPointerMove%22%2Cmove%2Cfalse)%3B'%2B%20'%7D%3B'%2B%20''%2B%20'var%20drawMouse%3Dfunction()%7B'%2B%20'%20var%20clicked%3D0%3B'%2B%20'%20var%20start%3Dfunction(e)%7B'%2B%20'%20clicked%3D1%3B'%2B%20'%20ctx.beginPath()%3B'%2B%20'%20x%3De.pageX%3B'%2B%20'%20y%3De.pageY-44%3B'%2B%20'%20beforeDraw()%3B'%2B%20'%20ctx.moveTo(x%2Cy)%3B'%2B%20'%7D%3B'%2B%20'%20var%20move%3Dfunction(e)%7B'%2B%20'%20if(clicked)%7B'%2B%20'%20x%3De.pageX%3B'%2B%20'%20y%3De.pageY-44%3B'%2B%20'%20ctx.lineTo(x%2Cy)%3B'%2B%20'%20ctx.stroke()%3B'%2B%20'%7D'%2B%20'%7D%3B'%2B%20'%20var%20stop%3Dfunction(e)%7B'%2B%20'%20clicked%3D0%3B'%2B%20'%7D%3B'%2B%20'%20document.getElementById(%22canvas%22).addEventListener(%22mousedown%22%2Cstart%2Cfalse)%3B'%2B%20'%20document.getElementById(%22canvas%22).addEventListener(%22mousemove%22%2Cmove%2Cfalse)%3B'%2B%20'%20document.addEventListener(%22mouseup%22%2Cstop%2Cfalse)%3B'%2B%20'%7D%3B'%2B%20'%20%3C%2Fscript%3E'%2B%20'%3C%2Fhead%3E'%2B%20'%3Cbody%3E'%2B%20'%3Cdiv%20id%3D%22page%22%3E'%2B%20'%20%3Cdiv%20class%3D%22header%22%3E'%2B%20'%20%3Ca%20id%3D%22new%22%20class%3D%22navbtn%22%20onclick%3D%22newCanvas()%22%3ENew%3C%2Fa%3E'%2B%20'%20%3Ca%20id%3D%22save%22%20class%3D%22navbtn%22%20onclick%3D%22saveCanvas()%22%3ESave%3C%2Fa%3E'%2B%20'%20%3Ca%20id%3D%22undo%22%20class%3D%22navbtn%22%20onclick%3D%22undo()%22%3EUndo%3C%2Fa%3E'%2B%20'%20%3Ca%20id%3D%22redo%22%20class%3D%22navbtn%22%20onclick%3D%22redo()%22%3ERedo%3C%2Fa%3E'%2B%20'%3Cselect%20id%3D%22aaa%22%20name%3D%22linewidth%22%3E'%2B%20'%3Coption%20value%3D%222%22%3E%E7%B4%B0%E3%81%84%3C%2Foption%3E'%2B%20'%3Coption%20value%3D%225%22%20selected%3E%E6%99%AE%E9%80%9A%3C%2Foption%3E'%2B%20'%3Coption%20value%3D%228%22%3E%E5%A4%AA%E3%81%84%3C%2Foption%3E'%2B%20'%3Coption%20value%3D%2211%22%3E%E6%A5%B5%E5%A4%AA%3C%2Foption%3E'%2B%20'%3Coption%20value%3D%2214%22%3E%E8%B6%85%E5%A4%AA%3C%2Foption%3E'%2B%20'%3C%2Fselect%3E'%2B%20'%20%3Cdiv%20class%3D%22title%22%3ESketch%20Pad%3C%2Fdiv%3E'%2B%20'%20%3C%2Fdiv%3E'%2B%20'%20%3Cdiv%20id%3D%22content%22%3E%3Cp%20style%3D%22text-align%3Acenter%22%3ENEW%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%92%E6%8A%BC%E3%81%97%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84...%3C%2Fp%3E%3C%2Fdiv%3E'%2B%20'%20%3Cdiv%20class%3D%22footer%22%3E'%2B%20'%20%3Cdiv%20class%3D%22palette-case%22%3E'%2B%20'%20%3Cdiv%20class%3D%22palette-box%22%3E'%2B%20'%20%3Cdiv%20class%3D%22palette%20white%22%20onclick%3D%22selectColor(this)%22%3E%3C%2Fdiv%3E'%2B%20'%20%3C%2Fdiv%3E%20'%2B%20'%20%3Cdiv%20class%3D%22palette-box%22%3E'%2B%20'%20%3Cdiv%20class%3D%22palette%20red%22%20onclick%3D%22selectColor(this)%22%3E%3C%2Fdiv%3E'%2B%20'%20%3C%2Fdiv%3E'%2B%20'%20%3Cdiv%20class%3D%22palette-box%22%3E'%2B%20'%20%3Cdiv%20class%3D%22palette%20blue%22%20onclick%3D%22selectColor(this)%22%3E%3C%2Fdiv%3E'%2B%20'%20%3C%2Fdiv%3E'%2B%20'%20%3Cdiv%20class%3D%22palette-box%22%3E'%2B%20'%20%3Cdiv%20class%3D%22palette%20green%22%20onclick%3D%22selectColor(this)%22%3E%3C%2Fdiv%3E'%2B%20'%20%3C%2Fdiv%3E'%2B%20'%20%3Cdiv%20class%3D%22palette-box%22%3E'%2B%20'%20%3Cdiv%20class%3D%22palette%20black%22%20onclick%3D%22selectColor(this)%22%3E%3C%2Fdiv%3E'%2B%20'%20%3C%2Fdiv%3E%20'%2B%20'%20%3Cdiv%20style%3D%22clear%3Aboth%22%3E%3C%2Fdiv%3E'%2B%20'%20%3C%2Fdiv%3E'%2B%20'%20%3C%2Fdiv%3E'%2B%20'%3C%2Fdiv%3E'%2B%20''%2B%20'%3Cscript%3E'%2B%20''%2B%20'function%20linew()%7B'%2B%20'%20ctx.lineWidth%3Ddocument.getElementById(%22aaa%22).value%3B'%2B%20'%7D'%2B%20''%2B%20'var%20el1%3Ddocument.getElementById(%5C'aaa%5C')%3B'%2B%20'el1.addEventListener(%5C'change%5C'%2Clinew%2Cfalse)%3B'%2B%20''%2B%20'const%20STACK_MAX_SIZE%3D5%3B'%2B%20'let%20undoDataStack%3D%5B%5D%3B'%2B%20'let%20redoDataStack%3D%5B%5D%3B'%2B%20''%2B%20'function%20beforeDraw()%7B'%2B%20'%20redoDataStack%3D%5B%5D%3B'%2B%20'%20if(undoDataStack.length%20%3E%3DSTACK_MAX_SIZE)%7B'%2B%20'%20undoDataStack.pop()%3B'%2B%20'%7D'%2B%20'%20var%20w%3Ddocument.getElementById(%5C'canvas%5C').width%3B'%2B%20'%20var%20h%3Ddocument.getElementById(%5C'canvas%5C').height%3B'%2B%20'%20undoDataStack.unshift(ctx.getImageData(0%2C0%2Cw%2Ch))%3B'%2B%20'%7D'%2B%20''%2B%20'function%20undo()%7B'%2B%20'%20if(undoDataStack.length%20%3C%3D0)return%3B'%2B%20'%20var%20w%3Ddocument.getElementById(%5C'canvas%5C').width%3B'%2B%20'%20var%20h%3Ddocument.getElementById(%5C'canvas%5C').height%3B'%2B%20'%20redoDataStack.unshift(ctx.getImageData(0%2C0%2Cw%2Ch))%3B'%2B%20'%20var%20imageData%3DundoDataStack.shift()%3B'%2B%20'%20ctx.putImageData(imageData%2C0%2C0)%3B'%2B%20'%7D'%2B%20''%2B%20'function%20redo()%7B'%2B%20'%20if(redoDataStack.length%20%3C%3D0)return%3B'%2B%20'%20var%20w%3Ddocument.getElementById(%5C'canvas%5C').width%3B'%2B%20'%20var%20h%3Ddocument.getElementById(%5C'canvas%5C').height%3B'%2B%20'%20undoDataStack.unshift(ctx.getImageData(0%2C0%2Cw%2Ch))%3B'%2B%20'%20var%20imageData%3DredoDataStack.shift()%3B'%2B%20'%20ctx.putImageData(imageData%2C0%2C0)%3B'%2B%20'%7D'%2B%20'%3C%2Fscript%3E'%2B%20'%3C%2Fbody%3E'%2B%20'%3C%2Fhtml%3E%20'%3Bvar%20win%3Dwindow.open(''%2C''%2C'width%3D560%2Cheight%3D440')%3Bwin.document.write(hhh)%3Bvoid(0);
2.終わりに
- 結構長いHTML+
CSS+JSなのに動いてビックリ! - ブックマークレットは簡単で初心者でも作れる
- ブラウザで同期されるので、他のPCでもすぐ使える
- 中身がわかるので、セキュリティの心配もない
- Chromeのタブで開いているサイト側設定の為に、上手く動かない場合もあります
とても便利だと思います
おしまい
Discussion