• ベストアンサー

【html5】canvasでの文字の形の透明くりぬ

html5でcanvasを使用した場合に赤い背景に文字の形に透明くり抜きを行いたいです。 ctx.fillStyle = "rgb(200, 0, 0)"; ctx.fillRect(0, 0, 100, 100); ctx.clearRect(20, 30, 60, 40);  ★ここがRectでなく文字の切り抜きにしたい。 イメージ的にはclearText()というのがあればいいのになぁ、という感じです。 パスをmoveToで文字の形にうごかして、clipしなさーい という回答はご勘弁を(^^;)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

.globalCompositeOperationを使ってみてください。 <script> //前略 ctx.fillStyle = "rgb(200, 0, 0)"; ctx.fillRect(0, 0, 100, 100); //マスキング(?)してテキスト描画 ctx.globalCompositeOperation='destination-out'; ctx.fillText('Hello world', 20, 30); ctx.globalCompositeOperation='source-over'; //マスクを戻す ctx.clearRect( 50, 50, 10, 10);//透過確認用 //後略 </script> <p style="background-color:blue;">canvasを透過して背景が見える <canvas id="mycanvas"></canvas> </p> シャギーや半透明を細かく制御したいなら、ブラウザに任せるのではなくNo.1のような方法で自分で作らないとダメだと思います。 >パスをmoveToで文字の形にうごかして、clipしなさーい ある意味そういうことになりますが。(幅1px長さ1pxのパスを1つずつ処理していると考えて)

questionokok
質問者

お礼

まさにやりたい通りのことができました!! globalCompositeOperationですかぁ~ 勉強するようにします!!o(`・д・´)o

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.2

>パスをmoveToで文字の形にうごかして、clipしなさーい  それが本来の方法であることはご理解されているようです。  inkscapeなどで画像をトレースしたり、直接SVGにするのが良いと思いますけど・・・  SVGからHTML5のcanvasにコンバートする Ink2canvas, a new SVG to HTML5 Canvas converter | Libre Graphics World ( http://libregraphicsworld.org/blog/entry/ink2canvas-a-new-svg-to-html5-canvas-converter4 )  もあります。

questionokok
質問者

お礼

こんなツールがあるんですね!! 画像をトレースする際には役立たせていただきます。

全文を見る
すると、全ての回答が全文表示されます。
  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.1

canvasは使ったことがほとんどありませんが、単純に背景色と文字色とで構成されているものなら、描いた後でcanvasを走査して、色によって透明にするという案ではどうでしょうか? 参考にしたサイト  http://www.html5.jp/canvas/index.html (全角空白は半角に) <!DOCTYPE HTML> <html lang="ja"> <head> <title>sample</title> </head> <body> <canvas id="canvas" width="500" height="300"></canvas> <script> var canvas = document.getElementById("canvas"); if(canvas && canvas.getContext){  var ctx = canvas.getContext("2d");  testDraw();  transparent(0, 100, 260, 120); } //矩形と文字を書いてみる function testDraw(){  ctx.fillStyle = "rgb(200, 0, 0)";  ctx.fillRect(0, 0, 500, 300);  ctx.font = "100px 'MS Pゴシック'";  ctx.fillStyle = "rgb(0, 0, 0)";  ctx.fillText("テストText", 20, 200); } //矩形範囲を指定:(背景色以外の色を透明にする) // // 指定色だけ透明にしてみたら、エッジの中間色が残るようだ // それなので、背景色以外は透明に→エッジが少々ジャギる // エッジを半透明にするとか滑らかにするのは適当に修正してちょ function transparent(x, y, w, h){  var imageData = ctx.getImageData(x, y, w, h);  var d = imageData.data, i;  for(i=0; i<d.length; i+=4)   if(d[i]!=200 || d[i+1]!=0 || d[i+2]!=0) d[i+3] = 0;  ctx.putImageData(imageData, x, y);  } </script> </body> </html>

questionokok
質問者

お礼

ご指定の方法でうまくいきました(p゜∀゜q) 今回はNo3さんの方法でやってみますが、この方法もその内役立たせていただきますm(。v_v。)m

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • javascript 配列について

    HTML5のcanvasにjsで描画する場合、 下記のように複数の図形を描く場合、 配列を用いて表記するにはどのようにすればよろしいでしょうか。 なお、図形の数は決まっていない、また、x,y,width,heightに規則性はないものとします。 ctx.fillStyle = "rgba(0,0,0,1)"; ctx.fillRect(20,10,10,10); ctx.fillStyle = "rgba(0,0,0,1)"; ctx.fillRect(30,10,10,10); ctx.fillStyle = "rgba(64,64,64,1)"; ctx.fillRect(10,20,10,10); ctx.fillStyle = "rgba(64,64,64,1)"; ctx.fillRect(40,20,10,10); … 以上、ご教授いただきたく何卒よろしくお願い致します。

  • html5canvasの文字枠のずれ

    html5のcanvasで、枠付きの文字列を描画しようとしたら、表示がおかしくなったのですが、理由がわかりません。ブラウザはchromeです。 一部のフォントとサイズのときだけ起きるのですが、それ以外で作れば問題ないのでしょうか。 <canvas id="canvas" width="500" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext('2d'); ctx.lineWidth=2; ctx.font = "bold 22px 'MS P明朝'" ctx.strokeStyle = 'rgba(255, 0, 0, 1)'; ctx.fillStyle = 'rgba(0, 0, 0, 1)'; ctx.strokeText("aa0.3", 10, 25); ctx.fillText("aa0.3", 10, 25); </script>

  • Chromeで文字コード(UTF-8)の設定

    ●質問の主旨 文字コードを常時、"utf-8"に設定したいと考えています。 どのように設定すればよいでしょうか? ご存知の方ご教示願います ●質問の補足 下記コードにて、ファイルを実行し、 "Canvasの練習"という文字列と、 青色の正方形をはさんだ黄色の正方形2つが、 表示させるつもりです。 しかし、実際に実行すると、 図形は意図通り描画されますが、文字列が文字化けします。 HTML5のコードにおいて、 <meta charset="utf-8">を <meta charset="s-jis"> に変更すると、文字化けもなくなります。 "utf-8"のコードがすでに大量に用意されているので、 PCの方の認識を"s-jis"から"utf-8"に替えるためにはどうすればよいでしょうか? PCはWindowsVistaで、ブラウザはGoogleChromeです。 ●コード ・HTML5 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Canvasの練習</title> </head> <body> <h1>Canvasの練習</h1> <canvas id="mycanvas" width="400" height="200"> Canvasに対応したブラウザを使ってください。 </canvas> <script src="mycss.js"></script> </body> </html> ・JavaScript // myscript.js window.onload = function() { draw(); } function draw() { var canvas = document.getElementById('mycanvas'); if (!canvas || !canvas.getContext) return false; var ctx = canvas.getContext('2d'); 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); }

    • ベストアンサー
    • HTML
  • マウスの座標を表示しようとしたのですが、できません

    //マウス座標の表示・・・ができない? ctx.fillStyle="rgb(0, 0, 0)"; ctx.font = "18px Arial"; //Hello Worldは表示できる ctx.fillText("Hello World!", 20, 250); //この書き方が、おかしい? ctx.fillText("mouseX =" + mouseX, 50, 50); ctx.fillText("mouseY =" + mouseY, 50, 75); Hello World!のようにcanvas上に座標を表示するには、どうすればいいのでしょうか? ちなみに、マウス座標そのものは alert("mouseX = "+mouseX+"\n"+"mouseY = "+mouseY); で確認できたので取得できてます。(添付画像有)

  • javascriptで困ってます

    下記のスクリプトでcanvas上で四角を動かすアニメーションをさせたのですが、andoroidに標準のブラウザで見ると、最初の位置に四角が残ってしまいます。この残ってしまう四角を消したたいのですが、どのようにしたらよいのでしょうか、教えてください。よろしくお願いします。 <!doctype html> <html> <head> <meta charset="UTF-8"> <title>canvasアニメーション</title> <script type="text/javascript"> // <![CDATA[ window.onload = function(){ var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "#ffffff"; var point = {x:0,y:0}; var par = {x:3,y:3}; var timer; var delay = 100; function draw(x,y){ ctx.clearRect(0,0,600,600); ctx.fillRect(x,y,50,50); } var loop = function(){ point.x = point.x + par.x; point.y = point.y + par.y; draw(point.x,point.y); clearTimeout(timer); timer = setTimeout(loop,delay); } loop(); } // ]]> </script> <style type="text/css" media="screen"> /* <![CDATA[ */ body{ background-color:#000000; } /* ]]> */ </style> </head> <body> <canvas id="canvas" width="600" height="600"></canvas> </body> </html>

  • Javaの質問です

    <!DOCTYPE html> <meta charset = utf-8> <title>ゲーム</title> <!-- スマートフォン対応・ C55 --> <style> * {margin:0; padding:0;} html {text-align:center;} canvas{border:1px solid gray;} </style> <!-- canvasの設定 --> <canvas id="canvas" width=320 height=480> HTML5の扱えるブラウザでご覧下さい。 </canvas> <!-- JavaScriptの設定 --> <script> var canvas = document.getElementById("canvas"); var c = canvas.getContext("2d"); //変数の設定と初期化 var frame = 0; //全体のフレーム数のカウント var target = {x:250, y:100, dir:2}; //ターゲット(x位置と移動方向) var target2 = {x:150, y:150, dir:5}; var player = {x:250, y:400}; //プレイヤー(x位置) var ball = {x:-10, y:-10}; //ボール(x位置とy位置) var point = 0; var point2 = 0; var point3 = 0 //得点 var timer = setInterval(anime,50); //anime関数を50ミリ秒毎に起動 //アニメ関数 function anime(){ frame++; //アニメ関数が実行されるたびごとにframeカウントを1上げる //画面をクリア c.clearRect(0,0,320,480);//canvas上の指定された矩形のすべてのピクセルを、透明な黒にクリア //targetを描画 c.fillStyle = "black"; c.fillRect(target.x-25,target.y-5,50,10); c.fillStyle = "black"; c.fillRect(target2.x-25,target2.y-5,50,10); //得点表示 c.fillStyle = "black"; c.font = "20px sans-serif "; c.fillText(point,target.x,target.y-5); //playerを描画 c.fillStyle = "blue"; c.fillRect(player.x-25,player.y-5,50,10); //ballを描画 c.fillStyle = "red"; c.fillRect(ball.x-5,ball.y-5,10,10); //移動計算 target.x += target.dir; //targetのx座標がdir(1)増加 target2.x += target2.dir; ball.y = ball.y - 5; //ballのy座標が5減少 //壁衝突計算 if(target.x < 25 || 295 < target.x)target.dir *= -1; if(target2.x < 25 || 295 < target2.x)target2.dir *= -1; //得点ゲット if ((100 == ball.y) && (Math.abs(target.x - ball.x)<25)){ point2++; } if ((100 == ball.y) && (Math.abs(target2.x - ball.x)<25)){ point3++; } if (point2 > 0 && point3 > 0 ){ point++; } } //シュートする関数 //シュートする関数 canvas.addEventListener("mousedown",function(e){ ball.x = player.x; ball.y = player.y; }); canvas.addEventListener("mousemove",function(e){ var rect = e.target.getBoundingClientRect(); player.x = e.clientX - rect.left; // player.y = e.clientY- rect.top; }); </script> このプログラミングで下段のバーに通って上段のバーに通った時のみにポイントが追加される風にしたいのですがこの状態だと両方通った時にポイント数が上がり続けますどうすればいいでしょうか

  • 複数canvasを表示状態のまま一つの画像に

    先だってchart.js4.2でカラー設定をする方法(https://okwave.jp/qa/q10117946.html)で複数グラフを上1、下3できれいに配置する方法を教えてもらいました。そのコードに今まで2.9系で上下2個づつの配置表示したものを一つの画像にする下記のコードを加え試しましたが使えませんでした。 function imageDownload() { var chartWidth = 350; var chartHeight = 242; var imageType = "image/png" var imageFileName = "chart.png"; var bufferCanvas = document.createElement("canvas") bufferCanvas.width = chartWidth * 1.82; bufferCanvas.height = chartHeight * 2.2; bufferCanvas.style.display = "none"; document.body.appendChild(bufferCanvas); var ctx = bufferCanvas.getContext("2d"); // 背景色を設定(しない場合は透過) ctx.fillStyle = "rgb(255, 255, 255)"; ctx.fillRect(0, 0, bufferCanvas.width, bufferCanvas.height); // グラフを貼り付け for (i = 1; i <= 4; i++) { ctx.drawImage( document.getElementById("myChart" + i), i % 2 == 1 ? 0 : chartWidth, i <= 2 ? 0 : chartHeight ); } var imageURL = bufferCanvas.toDataURL(imageType); そこで、スタイル設定のボックスを無くし下記のように配置するようにしました。 <div class="row" style="width:100%;" > <div class="chart1" style="position: relative; top: 0; right: 0; left: 0; margin:0;" >c <canvas id="myChart1" width="400px" height="230px"></canvas></div> <div class="chart2" style="position: absolute; top: 300px; right: 0; left: 0; margin:0;" > <canvas id="myChart2" width="210px" height="210px"></canvas></div> <div class="chart3" style="position: absolute; top: 300px; right: 0; left:215px; margin:0;"> <canvas id="myChart3" width="210px" height="210px"></canvas></div> <div class="chart4" style="position: absolute; top: 300px; right: 0; left:430px; margin:0;"> <canvas id="myChart4" width="210px" height="210px"></canvas></div> </div> しかしながらこの画像化コードでは上下に2個配置するようになっているため大きさの違う上のグラフと下の最初のグラフが左右に一部重なって描画される結果となりました。 そこで、任意の配置状態を保ったまま一つの画像とする方法をお教えください。

  • javascriptのタイプミス

    javascript初心者です。以下のコードでどこにミスがあるのか 解りません。どこにあるのでしょうか? このソースをエディタに 貼ると見やすくなると思います。 <!DOCTYPE html> <html> <head> <title>SnakeBite</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <script type="text/javascript"> var W, H, S = 20; var snake = [ ], foods = [ ]; var keyCode = 0; var point = 0; var timer = NaN; var ctx; // pointオブジェクト function Point(x,y) { this.x = x; this.y = y; } //初期関数 function init() { var canvas = document.getElementById('field'); W = canvas.width / S; H = canvas.height / S; ctx = canvas.getContext('2d'); ctx.font = "20px sans-serif"; //蚊の初期化 snake.push(new Point(W / 2, H / 2)); //餌の初期化 for (var i = 0 ; i < 10 ; i++) { addFood(); } timer = setInterval("tick()", 200); window.onkeydown = keydown; } //餌の追加 function addFood() { while (true) { var x = Math.floor(Math.random() * W); var y = Math.floor(Math.random() * H); if (isHit(foods, x, y) || isHit(snake, x, y)) { continue; } foods.push(new Point(x, y)); break; } } //衝突判定 function isHit(data, x, y) { for (var i = 0 ; i < data.length ; i++) { if (data[i].x==x && data[i].y==Y) { return true; } } return false; } function moveFood(x, y) { foods =foods. filter(function (p){return (p.x !=x || p.y !=y);}); addFood(); } function tick() { var x = snake[0].x; var y = snake[0].y; switch (keyCode) { case 37: x--; break; //左 case 38: y--; break; //上 case 39: x++; break; //右 case 40: y++; break; //下 default: paint(); return; } //自分or壁に衝突 if(isHit(snake,x,y) || x<0 || x>=W || y<0 || y>=H ) clearInterval(timer); paint(); return; } //頭を先頭に追加 snake.unshift(new Point(x,y)); if(isHit(foods, x, y)) { point +=10; //餌を食べた moveFood(x,y); }else{ snake.pop(); //食べていない→しっぽを解除 } paint(); } function paint() { ctx.clearRect(0,0,W * S, H * S); ctx.fillStyle = "rgb(256,0,0)"; ctx.fillText(point, S, S * 2); ctx.fillStyle = "rgb(0,0,255)"; foods.forEach(function (p) { ctx.fillText("+", p.x * S, (p.y + 1) * S);}); snake.forEach(function (p) { ctx.fillText("*", p.x * S, (p.y + 1) * S); }); } function keydown(event) { keyCode = event.keyCode; } </script> </head> <body onload="init()"> <canvas id="field" width="400" height="400" style="background:#cccccc"> </canvas> </body> </html>

  • JavaScriptについて

    本を読みながら勉強しているのですが解説が乗っていなくてわからない部分があるので教えてください <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,user-scalable=yes,initial-scale=1.0,maximum-scale=3.0"> <script src="plugins/plugin-loader.js"></script> <link rel="stylesheet" href="plugins/plugin-loader.css"> </head> <body> <canvas id="canvas" width="300" height="300"></canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); //ランダムに50個多角形の表示 for (var i = 0; i < 50; i++) { randomDraw(); } //指定範囲のランダムな整数を返す関数 function randomI(nFrom,nTo) { var f = nTo - nFrom + 1; return Math.floor(Math.random() * f) + nFrom; } //ランダムに多角形を描画する関数 function randomDraw() { //パス指定 ctx.beginPath(); //点をランダムに決定 var n = randomI(2,7); ctx.moveTo(randomI(0,canvas.width),randomI(0,canvas.hright)); for (var i = 0; i < n; i++) { ctx.lineTo(randomI(0,canvas.width),randomI(0,canvas.height)); } ctx.closePath(); //描画 ctx.fillStyle = "#" + randomI(0,0xFFFFFF).toString(16); ctx.fill(); } </script> </body> </html> というコードでランダムに50個多角形を描画するというものです function randomI(nFrom,nTo) { var f = nTo - nFrom + 1; return Math.floor(Math.random() * f) + nFrom; ここのrandomIとnToとnFromというのは変数名ですか?これはいったい何者ですか? var n = randomI(2,7); ここの数字を変更すると何かが変わるのですがうまく言葉にできません 何がどう変わるのか教えてください

  • javascriptの打ちミスしてる所を知りたい。

    参考書の通り打ちました。参考書では、蛇を上下左右キーで操作し、餌を食べさせるゲームと書いておりましたが、灰色のイメージが出るだけで、蛇っぽいのは出ません。 たぶんどっかでタイプミスしてると思うのですが、どこだかわかりません。 教えてください。 <!DOCTYPE html> <html> <head> <title>SnakeBite</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <script type="text/javascript"> var W,H,S=20; var snake=[],foods=[]; var keyCode=0; var point=0; var timer=NaN; var ctx; function Point(x,y){ this.x=x; this.y=y; } function init(){ var canvas = document.getElementById('field'); W=canvas.width/S; H=canvas.height/S; ctx =canvas.getContext('2d'); ctx.font ="20px sans-serif"; snake.push(new Point(W/2,H/2)); for(var i=0; i<10;i++){ addFood(); } timer=setInterval("tick()",200); window.onkeydown =keydown; } function addFood(){ while(true){ var x =Math.floor(Math.random()*W); var y =Math.floor(Math.random()*H); if(isHit(foods,x,y)|| isHit(snake.x,y)){ continue; } foods.push(new point(x,y)); break; } function isHit(data,x,y){ for(var i=0;i<data.lenght;i++){ if(data[i].x==x && data[i].y==y){ return true; } } return false; } function moveFood(x,y){ foods =foods.filter(function(p){ return(p.x !=x || p.y !=y); }); addFood(); } function tick(){ var x=snake[0].x; var y=snake[0].y; switch(keyCode){ case 37:x--;break; case 38:y--;break; case 39:x++;break; case 40:y++;break; defaule:paint(); return; } if(isHit(snake,x,y) || x<0 ||x>=W || y<0||y>=H) { clearInterval(timer); paint(); return; } snake.unshift(new Point(x,y)); if(isHit(foods,x,y)){ point+=10; moveFood(x,y); }else{ snake.pop(); } paint(); } function paint(){ ctx.clearRect(0,0,W*S,H*S); ctx.fillStyle="rgb(256,0,0)"; ctx.fillText(point,S,S*2); ctx.fillStyle="rgb(0,0,255)"; foods.forEach(function(p){ ctx.fillText("+",p.x*S,(p.y+1)*S); }); snake.forEach(function(p){ ctx.fillText("*",p.x*S,(p.y+1)*S); }); } function keydown(event){ keyCode=event.keyCode; } </script> </head> <body onload="init()"> <canvas id="field" width="400" height="400" style="background:#cccccc"> </canvas> </body> </html>

このQ&Aのポイント
  • ソフトウェアアップデート時にパスワードがわからない場合、ブラザー製品のMFC-L3770CDWを使用している方への質問です。
  • 質問内容は、パスワードが不明なためにソフトウェアアップデートができない状況にあることです。
  • お使いの環境はWindows10で無線LAN接続をしており、Wi-Fiルーターの機種名はバッファロー製です。電話回線の種類はひかり回線です。
回答を見る