pirika logo

ホームページ Pirikaで化学 ブログ 業務案内 お問い合わせ
情報化学+教育トップ 情報化学 MAGICIAN MOOC プログラミング
高校生レベルのプログラミングはMAGICIAN-Jrへどうぞ。
フィードバックはお問い合わせフォームからお願いします。

プログラミング・トップ > 化学,薬学系の親子で楽しみながらプログラミング >第2時限:美術

2022.2.27

Pirika.comでプログラミング
山本博志

2-5: 目指せLineスタンプ・メーカー・メーカー

タブレットのタッチイベントを使えるように改造しました。消しゴムボタン、png変換ボタンの反応が悪いです。(枠のあたりをタッチすると上手く行くようです。)

Lineスタンプを作りたいなら、専用のソフトがいくつもあるし高機能なのでそちらを使った方が早いです。
では、なぜ、お絵かき用のプログラムの作成にトライするのでしょうか?

このプログラムを使ってみれば判ります。
何と言っても使いにくいのです。

そこで、どこがどう使いにくいのか考えるようになります。
どうすれば解決できるか調べるのです。

「自ら何かをしたい」と思うためには、不便でないといけない。
線の太さを違うように変えたい。画面の大きさを変えたい。
下書きを読み込みたい。
できた絵を他の用途に使いたい。

ここで、注意です。親子でよく話しましょう。
ネットにある画像は著作権があって、勝手に使ってはいけない事も多いです。
人物には肖像権があるので、これも「有名人だから自由に使っていい」も間違いです。
他の人が見て不快になるような、言葉、画像はだめです。

楽しく創作しましょう。

実際にやってみましょう

PNG画像

書いた絵を送ってください。ここで紹介させていただきます。 ここでできた画像は透過型pngというものです。 自作のハンコを作り、Wordなどにハンコを押してPDF化すれば、偽造は難しいかもしれません。

X320 X320

完成版はこちらになります。コピペして、まずは使いにくさを味わってください。

完成版ソースコード(▶︎をクリックして開く)

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>Draw</title>
    <style>

    </style>
  </head>
  <body>

<div style="text-align:center;">
<canvas id="testCanvas" width="320" height="320" style="border:1px solid #CCC;"></canvas>
</div>
<div style="text-align:center;font-size:12px;">
        <input name="mode" type="radio" value="0" id="rb0" onclick="changeLineL(2)"><label for="rb0">細</label>
        <input name="mode" type="radio" value="1" id="rb1" onclick="changeLineL(4)"><label for="rb1">中</label>
        <input name="mode" type="radio" value="2" id="rb2" onclick="changeLineL(6)"><label for="rb2">太</label>
</div>
<div style="text-align:center;font-size:12px;">
<label><input type="color" id="colorBox" value="#CC0000">色の選択</label>
</div>
<div style="text-align:center;font-size:12px;">
  <input type="checkbox" id="mycheckbox" name="scales" ><label for="scales">消しゴム</label>
</div>


<p style="text-align:center;">
        <input type="button" onclick="addImageData();" value="PNG画像作成">
        <input type="button" onclick="clearCanvas();" value="画面をクリア">
    </p>
<div style="text-align:center;">
        <img src="" alt="PNG画像" width="320" height="320" id="image_png" style="border:1px solid #CCC;">
</div>

<script>

//キャンバスの初期処理
var canvas = document.getElementById('testCanvas');

//2Dコンテキスト
var ctx = canvas.getContext('2d');

init();
addImageData();
    //
var rb = document.getElementById('rb0');
rb.checked = true;

var cW = 320;   //キャンバス横サイズ
var cH = 320;   //キャンバス縦サイズ
var touchM=0;//PC=0
var mouseX = new Array();//finger touch
var mouseY = new Array();
var mouseDownFlag = false;  //マウスダウンフラグ
var lineL = 2;  //線の太さ
var EraserMode=0;

var MyColor;
var colorB = document.getElementById('colorBox');
//colorBox.value = "#F0F0F0";

//colorB.value = "#CC0000";
colorB.addEventListener('change', function(){
  MyColor = this.value;
});
//=colorBox.value;



function init() {

    canvas.addEventListener('mousedown', function(e) {

        mDown(pos(e));
    });
    canvas.addEventListener('mouseup', function(e) {
        mUp(pos(e));
    });

    canvas.addEventListener('mousemove', function(e) {

        mMove(pos(e));
    });
    canvas.addEventListener('touchstart', function(e) {
        if (e.changedTouches.length == 1) {
            mDown(pos(e.changedTouches[0]));
        }
    });

    canvas.addEventListener('touchend', function(e) {
        if (e.changedTouches.length == 1) {
            mUp(pos(e.changedTouches[0]));
        }
    });
    canvas.addEventListener('touchmove', function(e) {
        e.preventDefault();
        if (e.changedTouches.length == 1) {
            mMove(pos(e.changedTouches[0]));
        }
    });
    canvas.addEventListener('touchcancel', function(e) {
        mOut();
    });
}




function mOut(e) {
    mouseDownFlag=false;
}


//座標調整

function pos(e) {
    var x, y;

        x = e.clientX - canvas.getBoundingClientRect().left;
        y = e.clientY - canvas.getBoundingClientRect().top;

    
    mouseX[0] =x;
    mouseY[0] =y;
    return [x, y];
}





function mUp(pos) {
    mouseDownFlag =false;
    
    
    
        
}




function mDown(pos) {

    mouseDownFlag = true;
    
    MyColor=colorBox.value;
            var element = document.getElementById('mycheckbox');
                if(element.checked){
                    EraserMode=1;
                }
                else{
                    EraserMode=0;
             }
  
    
}



function mMove(pos) {
    if (mouseDownFlag) {

            //座標調整
            //adjustXY(e);
            //円を描く
            ctx.beginPath();
            
            if(EraserMode==0){
                ctx.fillStyle = MyColor;
                ctx.arc(pos[0],pos[1], lineL , 0, Math.PI * 2, false);
            }
            else{
                ctx.clearRect(pos[0],pos[1], lineL ,lineL);
            }
            ctx.fill();
        }

}

//画像変換
function addImageData() {
    //キャンバスの初期処理
    var canvas = document.getElementById('testCanvas');
    if ( ! canvas || ! canvas.getContext ) return false;
    try {
        var img_png_src = canvas.toDataURL();
        document.getElementById("image_png").src = img_png_src;
    } catch(e) {
        document.getElementById("image_png").alt = "未対応";
    }
}
//線の太さ
function changeLineL(n) {
    lineL = n;
}

//クリア
function clearCanvas() {
    //キャンバスの初期処理
    var canvas = document.getElementById('testCanvas');
    if ( ! canvas || ! canvas.getContext ) return false;
    //2Dコンテキスト
    var ctx = canvas.getContext('2d');
    
    ctx.clearRect(0, 0, cW, cH);
    //画像描画
    addImageData();
}


</script>
  </body>
</html>

どんな改良したら、もっと使いやすくなるか考えて送ってください。
例えば、「下絵が読み込めるともっと上手く描ける」とか

質問:

下絵って何?

おおー!!!
いきなり、「下絵」が通じない!
昔、コピーなどまだ無かった頃、例えば写真を下において、上にトレーシングペーパーという半透明の紙をおいて、下にある絵をなぞって絵を描くことが行われていた。
それを下絵と読んでいた。
イラストの練習とか必須の技術。

最初にキャンバス(絵を描く領域)にpngファイルを読みこむ(これが下絵)
(場合によって薄く読み込んだりする)

提案

線の太さがもう少し太いのが欲しいな
後消しゴムの太さをペンの太さに合わせて欲しい

次のところを修正する。
changeLineLの2, 4, 6を自分の好みの太さにする。

<div style="text-align:center;font-size:12px;">
        <input name="mode" type="radio" value="0" id="rb0" onclick="changeLineL(2)"><label for="rb0">細</label>
        <input name="mode" type="radio" value="1" id="rb1" onclick="changeLineL(4)"><label for="rb1">中</label>
        <input name="mode" type="radio" value="2" id="rb2" onclick="changeLineL(6)"><label for="rb2">太</label>
</div>

提案

もうちょいディティール細かくしたいから、描画範囲広くしてそれを縮小して表示したい(画質重くなる?)

キャンバスのサイズを、例えば640*640にすれば描画範囲は広がる。
ここでは、iPhoneでも使えるように320*320に設定している。

<div style="text-align:center;">
<canvas id="testCanvas" width="320" height="320" style="border:1px solid #CCC;"></canvas>
</div>


2-5-1: ゼロからお絵描きが大変なら

のページが作成されて公開されていきます。

このページのプログラムは少し大きいので、プログラムの説明は、No2-5-2で行います。

プログラミング・トップ > 化学,薬学系の親子で楽しみながらプログラミング


Copyright pirika.com since 1999-
Mail: yamahiroXpirika.com (Xを@に置き換えてください) メールの件名は[pirika]で始めてください。