画像作成アプリ

canvasで、ctx.moveTo(startX, startY);ctx.lineTo(x, y);ctx.stroke();で線を描画します。canvas.toDataURL().replace(‘image/png’,’application/octet-stream’)で、画像をダウンロードします。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Canvas</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <style>
    #mycanvas{
      border: 10px solid #999;
      cursor: crosshair;
    }
    .thumbnail{
      border: 2px solid #999;
      margin-right: 5px;
    }
    </style>
  </head>
  <body>
    <h1>Canvas</h1>
    <p>
      <select id="penColor">
        <option value="black">黒</option>
        <option value="red">赤</option>
        <option value="blue">青</option>
        <option value="white">白</option>
      </select>
      <select id="penWidth">
        <option value="1">細</option>
        <option value="3">中</option>
        <option value="5">太</option>
      </select>
        <input type="button" id="erase" value="消去">
        <input type="button" id="save" value="ギャラリーに追加">
    </p>
    <canvas id="mycanvas" width="400" height="200">
    Canvasの対応ブラウザを使用ください。</canvas>
    <div id="gallery"></div>
    <p>
    </p>
    <script>
      $(function(){
        var canvas = document.getElementById('mycanvas');
        if (!canvas || !canvas.getContext) return false;
        var ctx = canvas.getContext('2d');
        var startX,
            startY,
            x,
            y,
            borderWidth = 10,
            isDrawing = false;

        $('#mycanvas').mousedown(function(e){
            isDrawing = true;
            startX = e.pageX - $(this).offset().left - borderWidth;
            startY = e.pageY - $(this).offset().top - borderWidth;
        })
        .mousemove(function(e){
            if (!isDrawing) return;
            x = e.pageX - $(this).offset().left - borderWidth;
            y = e.pageY - $(this).offset().top - borderWidth;
            ctx.beginPath();
            ctx.moveTo(startX, startY);
            ctx.lineTo(x, y);
            ctx.stroke();
            startX = x;
            startY = y;
        })
        .mouseup(function() {
           isDrawing = false;
        })
        .mouseleave(function(){
           isDrawing = false;
        });

        $('#penColor').change(function(){
          ctx.strokeStyle = $(this).val();
        });
        $('#penWidth').change(function(){
          ctx.lineWidth = $(this).val();
        });
        $('#erase').click(function(){
            if(!confirm('本当に消去しますか?')) return;
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        });
        $('#save').click(function(){
            var img = $('<img>').attr({
              width: 100,
              height: 50,
              src: canvas.toDataURL()
            });
            var link = $('<a>').attr({
              href: canvas.toDataURL().replace('image/png','application/octet-stream'),
              download: new Date().getTime() + '.png'
            });
            $('#gallery').append(link.append(img.addClass('thumbnail')));
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        });

      });
    </script>
  </body>
</html>

落下するアニメーション

window.onload = function(){
  draw();
}
function draw(){
  var canvas = document.getElementById('mycanvas');
  if (!canvas || !canvas.getContext)return false;
  var ctx = canvas.getContext('2d');

  ctx.fillStyle = "red"
  var y = 0;

  (function loop(){
    ctx.clearRect(0,0,canvas.width, canvas.height);
    if (y > canvas.height) y = -50;
    y++;
    ctx.fillRect(0,y,50,50);
    setTimeout(loop,10);
  })();
}

Canvasで遊ぼう

%e7%84%a1%e9%a1%8c

  ctx.shadowColor = "#ccc";
  ctx.shadowOffsetX = 5;
  ctx.shadowOffsetY = 5;
  ctx.shadowBlur = 5;

  ctx.globalAlpha = 0.5;

  ctx.fillRect(0, 0, 100, 100);

図形の変形

  ctx.scale(0.8,0.8);  
  ctx.rotate(30/180*Math.PI);
  ctx.translate(100, 10);

  ctx.fillRect(0, 0, 100, 100);

stroke

ctx.beginPath();
  ctx.moveTo(20, 20);
  ctx.lineTo(120,20);
  ctx.lineTo(120,120);
  ctx.stroke();

円形・曲線:round,butt,square

ctx.beginPath();
  ctx.arc(100,100,50,10/180*Math.PI,210/180*Math.PI);
  ctx.lineWidth = 15;
  ctx.lineCap = "round";
  ctx.stroke();

テキスト描画

  ctx.font = 'bold 20px Verdana';
  ctx.textAlign = 'left';
  ctx.fillStyle = 'red';

  ctx.fillText('Google', 20, 20, 40);
  ctx.strokeText('Google', 20, 120, 200);

画像表示

  var img = new Image();
  img.src = 'baby.jpg';
  img.onload = function(){
    ctx.drawImage(img, 10, 10);
  }

背景パターン

  var img = new Image();
  img.src = 'google.png';
  im.onload = function(){
    var patter = ctx.createPattern(img, 'repeat');
    ctx.fillStyle = pattern;
    ctx.fillRect(20, 20, 100, 100);
  }

設定の保存、復元

  ctx.fillStyle = "yellow";
  ctx.save();

  ctx.fillRect(0, 0, 50, 50);

  ctx.fillStyle= "blue";
  ctx.fillRect(100, 0, 50, 50);

  ctx.restore();
  ctx.fillRect(200, 0, 50, 50);
window.onload = function(){
  draw();
}
function draw(){
  var canvas = document.getElementById('mycanvas');
  if (!canvas || !canvas.getContext)return false;
  var ctx = canvas.getContext('2d');

  ctx.globalAlpha = 0.5;

  for (var i = 0; i < 100; i++){
    var x = Math.floor(Math.random() * 400);
    var y = Math.floor(Math.random() * 200);
    var r = Math.floor(Math.random() * 200);

    ctx.fillStyle = "rgb("+rgb()+","+rgb()+","+rgb()+")";
    ctx.beginPath();
    ctx.arc(x,y,r,0,2*Math.PI);
    ctx.stroke();
    ctx.fill();
  }

  function rgb(){
    return Math.floor(Math.random() * 255);
  }
}

Canvas

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Canvas</title>
  </head>
  <body>
    <h1>Canvas</h1>
    <canvas id="mycanvas" width="800" height="800">
    対応ブラウザを使用ください。</canvas>
    <p>
    </p>
  <script src="myscript.js"></script>
  </body>
</html>
window.onload = function(){
  draw();
}
function draw(){
  var canvas = document.getElementById('mycanvas');
  if (!canvas || !canvas.getContext)return false;
  var ctx = canvas.getContext('2d');

  //ctx.strokeRect(50, 10, 50, 150);
  ctx.fillRect(10, 10, 50, 50);
  ctx.clearRect(15, 15, 20, 20);
}

線の塗りやスタイル

  ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
  ctx.lineWidth = 15;
  ctx.lineJoin = "bevel";//"round";

  ctx.fillStyle = "rgba(255, 0, 0, 0.5)";
  ctx.strokeRect(10, 10, 50, 50);
  ctx.fillRect(100, 10, 50, 50);

%e7%84%a1%e9%a1%8c

  var g = ctx.createLinearGradient(0, 0, 0, 100);
  g.addColorStop(0.0, "red");
  g.addColorStop(0.5, "yellow");
  g.addColorStop(1.0, "blue");
  ctx.fillStyle = g;

  ctx.fillRect(0, 0, 100, 100);

円形
var g = ctx.createRadialGradient(50, 50, 0, 50, 50, 80);

日付カウントダウン

setTimeoutは、一定時間後に特定の処理をおこなう(繰り返さずに一度だけ)処理です。setTimeout(function(){
getResult();},200);で、0.2秒ごとに処理を繰り返します。new Date().getTime();から、Date.now()を引いた秒数で表示しています。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/css?family=Bilbo" rel="stylesheet">
    <title>Web font</title>
    <style>
    body {
      font-family: 'Bilbo', cursive;
      background: #000;
      text-align: center;
      font-size:36px;
      color:red;
    }
    h1 {
      color: #fff;
      font-size: 128px;
      margin:0;
    }
    #remainingDays, #remainingTime {
      font-size: 64px;
    }
    </style>
  </head>
  <body>
    <h1>Q</h1>
    <p>
      <span id="remainingDays"></span>days <span id="remainingTime"></span> to go
    </p>
  <script>
  function getResult(){
    var target = new Date(2020, 04, 01, 10, 0, 0).getTime();
    var now = Date.now();
    var diff = (target - now) /1000;
    var d = Math.floor(diff / 60 / 60/ 24);
    diff = diff - 60 * 60 * 24 * d;
    var h = Math.floor(diff / 60 / 60);
    diff = diff - 60 * 60 * h;
    var m = Math.floor(diff / 60);
    diff = diff - 60 * m;
    var s = Math.floor(diff);

    document.getElementById('remainingDays').innerHTML = d;
    document.getElementById('remainingTime').innerHTML = padZero(h)  + ':' + padZero(m) + ':' + padZero(s);
    setTimeout(function(){
    getResult();
  },200);
  }
  getResult();

  function padZero(n){
    return (n < 10) ? '0'+n : n;
  }

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

二次元バーコード生成

jQuery doc
.attr()
Get the value of an attribute for the first element in the set of matched elements or set one or more attributes for every matched element.

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二次元バーコード</title>
    <style>
    body {

    }
    </style>
  </head>
  <body>
    <h1>二次元バーコード</h1>
    <p>
      <input type="text" id="msg">
      <input type="button" value="変換" id="button">
    </p>
    <div id="barCode"></div>
  <script>
    $(function(){
      $('#button').click(function(){
          var msg = encodeURIComponent($('#msg').val());
          var img = $('<img>').attr('src', 'http://chart.apis.google.com/chart?cht=qr&chs=150x150&choe=Shift_JIS&chl='+msg);
          $('#barCode').html(img);
      });
    });
  </script>
  </body>
</html>

Redisの操作


127.0.0.1:6379> rpush mycolor pink
(integer) 1
127.0.0.1:6379> rpush mycolor green
(integer) 2
127.0.0.1:6379> rpush mycolor red
(integer) 3
127.0.0.1:6379> rpush mycolor yellow
(integer) 4
127.0.0.1:6379> rpush mycolor blue
(integer) 5
127.0.0.1:6379> rpush myclolor purple
(integer) 1
127.0.0.1:6379> lrange mycolor 0 5
1) "pink"
2) "green"
3) "red"
4) "yellow"
5) "blue"
127.0.0.1:6379> lrange mycolor 0 -1
1) "pink"
2) "green"
3) "red"
4) "yellow"
5) "blue"

リスト操作

127.0.0.1:6379> rpop mycolor
"blue"
127.0.0.1:6379> lrange mycolor 0 -1
1) "pink"
2) "green"
3) "red"
4) "yellow"
127.0.0.1:6379> lpop mycolor
"pink"
127.0.0.1:6379> lrange mycolor 0 -1
1) "green"
2) "red"
3) "yellow"
127.0.0.1:6379> lindex mycolor 2
"yellow"
127.0.0.1:6379> llen mycolor
(integer) 3
127.0.0.1:6379> ltrim mycolor 0 2
OK
127.0.0.1:6379> lrange mycolor 0 -1
1) "green"
2) "red"
3) "yellow"

セット型の計算

127.0.0.1:6379> sadd myset1 a
(integer) 1
127.0.0.1:6379> sadd myset1 b
(integer) 1
127.0.0.1:6379> sadd myset1 c
(integer) 1
127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> sadd myset1 d
(integer) 1
127.0.0.1:6379> smembers myset1
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> srem myset1 d
(integer) 1
127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> sadd myset2 b
(integer) 1
127.0.0.1:6379> sadd myset2 c
(integer) 1
127.0.0.1:6379> sadd myset2 e
(integer) 1
127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> smembers myset2
1) "c"
2) "b"
3) "e"
127.0.0.1:6379> sunion myset1 myset2
1) "b"
2) "c"
3) "e"
4) "a"
127.0.0.1:6379> sinter mysete1 myset2
(empty list or set)
127.0.0.1:6379> sdiff myset1 myset2
1) "a"

ソート済みの集合

127.0.0.1:6379> zadd hs 22 yamada
(integer) 1
127.0.0.1:6379> zadd hs 50 tanaka
(integer) 1
127.0.0.1:6379> zadd hs 80 yasuda
(integer) 1
127.0.0.1:6379> zadd hs 21 okamoto
(integer) 1
127.0.0.1:6379> zrange hs 0 -1
1) "okamoto"
2) "yamada"
3) "tanaka"
4) "yasuda"
127.0.0.1:6379> zrevrange hs 0 -1
1) "yasuda"
2) "tanaka"
3) "yamada"
4) "okamoto"
127.0.0.1:6379> zrank hs yamada
(integer) 1
127.0.0.1:6379> zrevrank hs yamada
(integer) 2

Redis

永続化の機能があるインメモリデータベースです。高速処理用に部分的に使われるなどのケースが多いようです。

http://redis.io/commands

インストールして、サーバーを立ち上げます。

[vagrant@localhost redis]$ redis-server
[14193] 12 Nov 04:58:10.521 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
[14193] 12 Nov 04:58:10.522 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
[14193] 12 Nov 04:58:10.522 # Redis can't set maximum open files to 10032 because of OS error: Operation not permitted.
[14193] 12 Nov 04:58:10.522 # Current maximum open files is 1024. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 2.8.12 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in stand alone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 14193
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[14193] 12 Nov 04:58:10.524 # Server started, Redis version 2.8.12
[14193] 12 Nov 04:58:10.525 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[14193] 12 Nov 04:58:10.526 * The server is now ready to accept connections on port 6379

cliからのアクセス, exit, shutdouwn

[vagrant@localhost redis]$ redis-cli

データベースの選択
> select

データの保存
> bgsave
bgsaveでデータベースを保存すると、redis-serverを立ち上げたディレクトリに、dump.rdbが作成されます。

データの設定

127.0.0.1:6379> set name yamada
OK
127.0.0.1:6379> get name
"yamada"
127.0.0.1:6379> mset email yamada@gmail.com score 120
OK
127.0.0.1:6379> get name email score
(error) ERR wrong number of arguments for 'get' command
127.0.0.1:6379> mget name email score
1) "yamada"
2) "yamada@gmail.com"
3) "120"

incr score

127.0.0.1:6379> incr score
(integer) 121
127.0.0.1:6379> get score
"121"
127.0.0.1:6379> decrby score 10
(integer) 111
127.0.0.1:6379> get score
"111"

keyの操作

127.0.0.1:6379> keys *
1) "name"
2) "score"
3) "email"
127.0.0.1:6379> keys *m*
1) "name"
2) "email"
127.0.0.1:6379> exists score
(integer) 1
127.0.0.1:6379> exists age
(integer) 0
127.0.0.1:6379> set age 14
OK
127.0.0.1:6379> rename age nenrei
OK
127.0.0.1:6379> keys *
1) "nenrei"
2) "email"
3) "score"
4) "name"
127.0.0.1:6379> del nenrei
(integer) 1
127.0.0.1:6379> keys *
1) "email"
2) "score"
3) "name"
127.0.0.1:6379> set age 14
OK
127.0.0.1:6379> expire age 5
(integer) 1
127.0.0.1:6379> get age
(nil)

psql document

Postgresには独自の命令文が多数用意されています。

PostgreSQL document

blogapp=# select name, length(name) from users;
  name  | length
--------+--------
 yamada |      6
 satou  |      5
 sasaki |      6
 yamada |      6
 satou  |      5
 sasaki |      6
 yamada |      6
(7 行)

抽選システム

blogapp=# select * from users order by random() limit 1;
 id |  name  | score | team
----+--------+-------+-------
  6 | sasaki |   7.6 | green
(1 行)

更新

blogapp=# update users set score = 5.8 where name = 'yamada';
UPDATE 3

削除

blogapp=# delete from users where id = 7;
DELETE 1

テーブルの変更

blogapp=# alter table users add fullname varchar(255);
ALTER TABLE
blogapp=# select * from users;
 id |  name  | score | team  | fullname
----+--------+-------+-------+----------
  2 | satou  |   4.3 | green |
  3 | sasaki |   8.2 | green |
  5 | satou  |   4.2 | blue  |
  6 | sasaki |   7.6 | green |
  1 | yamada |   5.8 | red   |
  4 | yamada |   5.8 | red   |
(6 行)

blogapp=# alter table users alter name type varchar(32);
ALTER TABLE

複数のユーザを突き合わせ

select users.name, post.title from users, posts wher users.id = posts.id;

複雑なselect文はviewを作成

blogapp=# create view yamada_posts as
blogapp-# select users.name, post.title from users, posts wher users.id = posts.id;

beginとcommitで囲むと、トランザクションという処理ができるようになります。変更の取り消しはrollbackです。

psql 

条件検索

blogapp=# select * from users where score > 4.0;
 id |  name  | score |  team
----+--------+-------+--------
  1 | yamada |   6.5 | red
  2 | satou  |   4.3 | green
  3 | sasaki |   8.2 | green
  5 | satou  |   4.2 | blue
  6 | sasaki |   7.6 | green
  7 | yamada |   5.7 | yellow
(6 行)
blogapp=# select * from users where name = 'yamada';
 id |  name  | score |  team
----+--------+-------+--------
  1 | yamada |   6.5 | red
  4 | yamada |   3.6 | red
  7 | yamada |   5.7 | yellow
(3 行)

並び順

blogapp=# select * from users order by score;
 id |  name  | score |  team
----+--------+-------+--------
  4 | yamada |   3.6 | red
  5 | satou  |   4.2 | blue
  2 | satou  |   4.3 | green
  7 | yamada |   5.7 | yellow
  1 | yamada |   6.5 | red
  6 | sasaki |   7.6 | green
  3 | sasaki |   8.2 | green
(7 行)

blogapp=# select * from users order by score desc;
 id |  name  | score |  team
----+--------+-------+--------
  3 | sasaki |   8.2 | green
  6 | sasaki |   7.6 | green
  1 | yamada |   6.5 | red
  7 | yamada |   5.7 | yellow
  2 | satou  |   4.3 | green
  5 | satou  |   4.2 | blue
  4 | yamada |   3.6 | red

offset

blogapp=# select * from users limit3 offset 3;
 id |  name  | score |  team
----+--------+-------+--------
  4 | yamada |   3.6 | red
  5 | satou  |   4.2 | blue
  6 | sasaki |   7.6 | green
  7 | yamada |   5.7 | yellow
(4 行)

レコード集計

blogapp=# select count(*) from users;
 count
-------
     7
(1 行)