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

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

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

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

HTML5

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

10540閲覧

toDataURL()が上手く動作しない。

yoshiz

総合スコア7

canvas

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

HTML5

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2017/10/02 23:36

###前提・実現したいこと
HTML5 Canvasで背景設定した画像に対して、
上から画像スタンプのように載せて保存するWebページを作っています。
色々なページを見ながらやり始めたばかりですが、一番最初の段階である、
背景画像に1つ目のスタンプを載せ、ドラッグで移動させる所までは、一応作ることができました。
しかし、そのスタンプを載せた状態のキャンバスをDLすることができません。

###発生している問題・エラーメッセージ

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

###該当のソースコード

html

1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="UTF-8" /> 5 <title>Drag</title> 6 <style>#canvas {background: #666;}</style> 7</head> 8<body> 9<div> 10 <canvas id="canvas" width="600" height="900"></canvas> 11</div> 12<script> 13(function() { 14 var canvas = document.getElementById('canvas'); 15 var context = canvas.getContext('2d'); 16 var isDragging = false; 17 var dragTarget = null; // ドラッグ対象の画像の添え字 18 19 var srcs = ['b.png','1.png']; 20 var images = []; 21 for (var i in srcs) { 22 images[i] = new Image(); 23 24 images[i].src = srcs[i]; 25 } 26 27 var loadedCount = 0; 28 for (var i in images) { 29 images[i].addEventListener('load', function() { 30 if (++loadedCount == images.length) { 31 for (var j in images) { 32 // 画像を描画した時の情報を記憶 33 images[j].drawOffsetX = 0; 34 images[j].drawOffsetY = 0; 35 images[j].drawWidth = images[j].width; 36 images[j].drawHeight = images[j].height; 37 38 // 画像を描画 39 context.drawImage(images[j], 0, 0, images[j].width, images[j].height); 40 } 41 } 42 }, false); 43 } 44 45 // ドラッグ開始 46 var mouseDown = function(e) { 47 // ドラッグ開始位置 48 var posX = parseInt(e.clientX - canvas.offsetLeft); 49 var posY = parseInt(e.clientY - canvas.offsetTop); 50 51 // 当たり判定(ドラッグした位置が画像の範囲内に収まっているか) 52 if (posX >= images[1].drawOffsetX && posX <= (images[1].drawOffsetX + images[1].drawWidth) && 53 posY >= images[1].drawOffsetY && posY <= (images[1].drawOffsetY + images[1].drawHeight)) { 54 dragTarget = 1; 55 isDragging = true; 56 } 57 } 58 59 // ドラッグ終了 60 var mouseUp = function(e) { 61 isDragging = false; 62 }; 63 64 // canvasの枠から外れた 65 var mouseOut = function(e) { 66 // canvas外にマウスカーソルが移動した場合に、ドラッグ終了としたい場合はコメントインする 67 // mouseUp(e); 68 } 69 70 // ドラッグ中 71 var mouseMove = function(e) { 72 // ドラッグ終了位置 73 var posX = parseInt(e.clientX - canvas.offsetLeft); 74 var posY = parseInt(e.clientY - canvas.offsetTop); 75 76 if (isDragging) { 77 // canvas内を一旦クリア 78 context.clearRect(0, 0, canvas.width, canvas.height); 79 80 for (var i in images) { 81 if (i == dragTarget) { 82 x = posX - images[i].drawWidth / 2; 83 y = posY - images[i].drawHeight / 2; 84 85 // ドラッグが終了した時の情報を記憶 86 images[i].drawOffsetX = x; 87 images[i].drawOffsetY = y; 88 } else { 89 x = images[i].drawOffsetX; 90 y = images[i].drawOffsetY; 91 } 92 w = images[i].drawWidth; 93 h = images[i].drawHeight; 94 95 // 画像を描画 96 context.drawImage(images[i], x, y, w, h); 97 } 98 } 99 } 100 101 // canvasにイベント登録 102 canvas.addEventListener('mousedown', function(e){mouseDown(e);}, false); 103 canvas.addEventListener('mousemove', function(e){mouseMove(e);}, false); 104 canvas.addEventListener('mouseup', function(e){mouseUp(e);}, false); 105 canvas.addEventListener('mouseout', function(e){mouseOut(e);}, false); 106})(); 107function screenshot() 108{ 109 var canvas = document.getElementById("canvas"); 110 var base64 = canvas.toDataURL(); 111 var blob = Base64toBlob(base64); 112 saveBlob(blob,"default.png"); 113} 114</script> 115<a href="#" onclick="screenshot();">screenshot</a> 116<script type="text/javascript" src="blob.js"></script> 117</body> 118</html>

JavaScript

1function Base64toBlob(_base64) 2{ 3 var i; 4 var tmp = _base64.split(','); 5 var data = atob(tmp[1]); 6 var mime = tmp[0].split(':')[1].split(';')[0]; 7 var arr = new Uint8Array(data.length); 8 for (i = 0; i < data.length; i++) {arr[i] = data.charCodeAt(i);} 9 var blob = new Blob([arr], { type: mime }); 10 return blob; 11} 12function saveBlob(_blob,_file) 13{ 14 if (false) 15 { 16 window.navigator.msSaveBlob(_blob, _file); 17 } 18 else 19 { 20 var url = (window.URL || window.webkitURL); 21 var data = url.createObjectURL(_blob); 22 var e = document.createEvent("MouseEvents"); 23 e.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 24 var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); 25 a.href = data; 26 a.download = _file; 27 a.dispatchEvent(e); 28 } 29} 30function ArraytoBlob(_mime,_array) 31{ 32 var arr = new Uint8Array(_array.length); 33 for (var i = 0; i < _array.length; i++) {arr[i] = _array[i];} 34 var blob = new Blob([arr], { type: _mime }); 35 return blob; 36}

###試したこと
元々試作として、それぞれ別のHTMLとして一度作りましたが、DLの単体では問題ありませんでした。
また、ネットで『img.crossOrigin = "Anonymous";』と入れると解消するという情報があったので、images[i].crossOrigin = "Anonymous";という風に入れてみましたが、別のエラーコードが出た為、解決には至らず、質問させて頂きました。
どうかよろしくお願いいたします。

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

guest

回答1

0

ベストアンサー

HTMLをローカルファイル(file://...)として開いていませんか?
http(s)://... (例えばlocalhost)でサーバ経由で開いて実行してみると、問題なく動作しました。

投稿2017/10/03 00:24

othersight

総合スコア356

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

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

yoshiz

2017/10/03 01:37

ああ、なるほど! サーバの環境が既にあるPCが別のPCのため、これが上手く行ったらサーバ経由に移行させようと思っていたのですが、このエラーで止めてしまっていました。 うっかりしていました。ご回答ありがとうございます。
yoshiz

2017/10/03 01:41

ああ、なるほど! サーバ環境が既にあるPCが別のPCのため、この動作が上手く行ったらそろそろ必要になるから移行させようと思っていたのですが、そこが問題だったのですね… この問題が解決したら…と思っていたので、永遠に解決に辿り着かない所でした。 迅速な回答ありがとうございます。本当に助かりました。
yoshiz

2017/10/03 01:42

投稿できていないと思って二重で投稿してしまいました。 申し訳ありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問