質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Q&A

解決済

5回答

6616閲覧

html5のcanvasで絵を描くとき、太くすると線が粗くなってしまう【参考画像あり】

sanset

総合スコア186

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

0グッド

1クリップ

投稿2015/08/01 14:33

編集2015/08/01 17:22

イメージ説明

【追記】

hirohiroさん、edo_m18さんのコードで、斜めに線を引くとこうなります。
たしかに修正前のようにスカスカはしませんが、きれいに描画されてないように思います。

イメージ説明

【追記終】

上のイメージのように、線を太い設定のまま書くとこのように粗く表示されてしまいます。
下記が上記のようになってしまうcanvasの設定です。

html

1<canvas width="780" height="400"></canvas>

javascript

1 2 var borderWidth = 5; 3 var fromX; 4 var fromY; 5 var drawFlag = false; 6 var context = $("canvas").get(0).getContext('2d'); 7 var pale = '#ff25a8'; //色 8 var penWidth = 2; //太さ 9 10 $('canvas').mousedown(function(e) { 11 drawFlag = true; 12 fromX = e.pageX - $(this).offset().left - borderWidth; 13 fromY = e.pageY - $(this).offset().top - borderWidth; 14 return false; // for chrome 15 }); 16 17 $('canvas').mousemove(function(e) { 18 if (drawFlag) { 19 draw(e); 20 } 21 }); 22 23 $('canvas').on('mouseup', function() { 24 drawFlag = false; 25 }); 26 27 $('canvas').on('mouseleave', function() { 28 drawFlag = false; 29 }); 30 31 function draw(e) { 32 var toX = e.pageX - $('canvas').offset().left - borderWidth; 33 var toY = e.pageY - $('canvas').offset().top - borderWidth; 34 context.strokeStyle = pale; //色の設定 paleという変数に入れてます。 35 context.lineWidth = penWidth; //太さの設定 上記の画像は30 36 context.beginPath(); 37 context.moveTo(fromX, fromY); 38 context.lineTo(toX, toY); 39 context.stroke(); 40 context.closePath(); 41 42 fromX = toX; //追記 43 fromY = toY; //追記 44 }

どなたか対処法など、ご教示お願いいたします。
コードで書いて説明していただけるとうれしいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

beginPathclosePathを実行しちゃってるからな気がします。
つまり、パスを毎回切っちゃってるためにガタガタしているんですね。

draw関数内ではlineToのみを行い、moveTobeginPathclosePathmousedownmouseup時に行うようにすると綺麗につながると思いますよ。

投稿2015/08/01 16:26

edo_m18

総合スコア2283

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2015/08/01 17:24

ありがとうございます。 試してみて、上記の画像のように別の問題が出てきてしまいました。
edo_m18

2015/08/02 07:31 編集

書かれているコードは最新版ですかね? 指摘の点が反映されていないようです。 こちらに上記コードを少し修正して意図した動作になるようにしたものをあげてみました。 http://jsdo.it/edo_m18/jfjA JSであればこうした動くものを提示しやすいので、こうしたサイトを利用して動かないコードを共有するとより早く回答が得られると思いますよ。 ※ ちなみに変更点は、上記指摘の通り、mouseup、mousedownにbeginPath、closePathを移動したものになります。
sanset

2015/08/13 13:58

ご連絡遅れて申し訳ありません。 サンプルのコードまで頂き、とても助かりました。 何度もご協力頂きありがとうございます。
guest

0

直線ではなく曲線で書くようにすれば改善されます。
http://jsdo.it/oao_oao/sRaI

投稿2015/08/08 07:39

jser

総合スコア100

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2015/08/13 13:59

ご連絡遅れて申し訳ありません。 サンプルのコードまで頂き、とても助かりました。 非常に心苦しいですが、 先に同じようにして解説頂いた方がいらっしゃったので、そちらの方をベストアンサーにさせていただきました。申し訳ございません。 また何かございましたらよろしくお願い致します。
guest

0

ごり押し。非推奨。

javascript

1 var borderWidth = 5; 2 var fromX; 3 var fromY; 4 var drawFlag = false; 5 var context = $("canvas").get(0).getContext('2d'); 6 var pale = '#ff25a8'; //色 7 var penWidth = 30; //太さ 8 9 $('canvas').mousedown(function(e) { 10 drawFlag = true; 11 fromX = e.pageX - $(this).offset().left - borderWidth; 12 fromY = e.pageY - $(this).offset().top - borderWidth; 13 return false; // for chrome 14 }); 15 16 $('canvas').mousemove(function(e) { 17 if(!drawFlag)return 18 setTimeout(function (){draw(e)},0); 19 setTimeout(function (){draw(e)},10); 20 setTimeout(function (){draw(e)},20); 21 setTimeout(function (){draw(e)},30); 22 setTimeout(function (){draw(e)},40); 23 setTimeout(function (){draw(e)},50); 24 }); 25 26 $('canvas').on('mouseup', function() { 27 drawFlag = false; 28 }); 29 30 $('canvas').on('mouseleave', function() { 31 drawFlag = false; 32 }); 33 34 function draw(e) { 35 var toX = e.pageX - $('canvas').offset().left - borderWidth; 36 var toY = e.pageY - $('canvas').offset().top - borderWidth; 37 context.strokeStyle = pale; //色の設定 paleという変数に入れてます。 38 context.lineWidth = penWidth; //太さの設定 上記の画像は30 39 context.beginPath(); 40 /* 41 context.fillStyle=pale; 42 context.arc(toX,toY,(penWidth/10)|0,0,Math.PI*2,false); 43 context.fill(); 44 */ 45 context.moveTo(fromX, fromY); 46 context.lineTo(toX, toY); 47 context.stroke(); 48 context.closePath(); 49 fromX=toX; 50 fromY=toY; 51 }

質問本文のコードで
fromX=toX;
fromY=toY;
が抜けていませんか?
(質問の本題とは関係ないですが挙動が全く違うため念のため)

コードを変えた点としてはsetTimeout()を使い時間差で複数回実行されるようにしているだけです。
円をマウス座標に描画する方法も考えられますが、マウスを高速で動かした場合に円と円の間に隙間が空くため、今回は使用していません。

投稿2015/08/01 16:58

Cf_cwd

総合スコア730

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2015/08/01 17:36

ご丁寧にありがとうございます。 試してみて、すばやく描くと滑らかに描画されますが、ゆっくり描くとやはり上記の画像のようになってしまいます。
guest

0

javascript

1context.beginPath(); 2context.moveTo(fromX, fromY); 3context.lineTo(toX, toY); 4context.closePath(); 5context.stroke();

closePath()の後に,stroke()ではないでしょうか?

投稿2015/08/01 16:45

KenTerada

総合スコア751

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2015/08/01 17:23

ありがとうございます。 直してみましたが改善されませんでした。
guest

0

2はそんなに太くないと思います。
恐らくfromX,Yがmousedownの時の設定で固定されていて、mousemoveイベント時に再設定されていないのが原因ではないでしょうか?
こんな感じ↓

JavaScript

1 $('canvas').mousemove(function(e) { 2 if (drawFlag) { 3 draw(e); 4 fromX = e.pageX - $(this).offset().left - borderWidth; 5 fromY = e.pageY - $(this).offset().top - borderWidth; 6 } 7 });

※何度も同じ記述が出てきて格好は悪いですが、とりあえず動作するのではないかと思います。

修正コードを追記します。これでどうでしょう?

JavaScript

1 var borderWidth = 5; 2 var fromX; 3 var fromY; 4 var drawFlag = false; 5 var context = $("canvas").get(0).getContext('2d'); 6 var pale = '#ff25a8'; //色 7 var penWidth = 20; //太さ 8 9 $('canvas').mousedown(function(e) { 10 drawFlag = true; 11 fromX = e.pageX - $(this).offset().left - borderWidth; 12 fromY = e.pageY - $(this).offset().top - borderWidth; 13 context.beginPath(); //追加 14 context.moveTo(fromX, fromY); //追加 15 context.strokeStyle = pale; //追加 16 context.lineWidth = penWidth; //追加 17 return false; // for chrome 18 }); 19 20 $('canvas').mousemove(function(e) { 21 if (drawFlag) { 22 draw(e); 23 } 24 }); 25 26 $('canvas').on('mouseup', function() { 27 drawFlag = false; 28 context.closePath(); //追加 29 }); 30 31 $('canvas').on('mouseleave', function() { 32 drawFlag = false; 33 context.closePath(); //追加 34 }); 35 36 function draw(e) { 37 var toX = e.pageX - $('canvas').offset().left - borderWidth; 38 var toY = e.pageY - $('canvas').offset().top - borderWidth; 39 // context.strokeStyle = pale; 削除 40 // context.lineWidth = penWidth; 削除 41 // context.beginPath(); 削除 42 // context.moveTo(fromX, fromY); 削除 43 context.lineTo(toX, toY); 44 context.stroke(); 45 fromX = toX; //追加 46 fromY = toY; //追加 47 // context.closePath(); 削除 48 } 49 });

投稿2015/08/01 16:14

編集2015/08/01 17:13
hirohiro

総合スコア2068

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sanset

2015/08/01 16:19

ご回答ありがとうございます。 上記のコードで試してみましたが、改善されませんでした・・・。
hirohiro

2015/08/01 16:57

失礼しました。添付のコードでは直線にならないと思ったのですが、恐らく改修前のコードですね。それでギザギザになるのはmousetoを都度設定してるからのようです。 修正コードを追記します。
Cf_cwd

2015/08/01 17:00

fromX=toX; fromY=toY; のように書いておかないと初期位置から集中線のように描画されていますよね
hirohiro

2015/08/01 17:05

追記しました。まだ開始と終端が少し変になりますが、途中はましになってると思います
sanset

2015/08/01 17:14

引き続き回答いただきありがとうございます。 そうですね、自身が出していたコードに抜けがありましたので修正しました。 そして、頂いたコードも試してみて、線が切れたりはしなくなりましたが、 太さが均一でないジラジラした線?のようになってしまいました。
hirohiro

2015/08/01 17:19

恐らくそれは、linetoを使っているとはいえポイントの集まりにしかならないからです。 本当に滑らかな線にするには、ポイントを一定時間サンプリングして、それらを最小二乗法などで高次関数化し、ベジェやBスプライン曲線なんかに落とし込むしかないと思います。 参考ページ:http://gihyo.jp/design/serial/01/createjs/0010#sec2_pd
hirohiro

2015/08/01 17:27 編集

mousedownのcontext.beginPath();の下に context.lineJoin = "bevel"; を追加すると多少マシになりました
sanset

2015/08/13 14:00

ご連絡遅れて申し訳ありません。 参考URL、とても助かりました。 非常に心苦しいですが、 先に同じようにして解説頂いた方がいらっしゃったので、そちらの方をベストアンサーにさせていただきました。申し訳ございません。 また何かございましたらよろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問