javascriptで画像をキャンバスとして使用する方法

roadrunner009

キャンバスに長方形を描くために使用しているスクリプトがあります。ユーザーは、描画された長方形をドラッグ/再配置したり、ダブルクリックして新しい長方形を追加したりできます。ここで、背景に画像を追加します。つまり、プレーンキャンバスを使用するのではなく、長方形を配置できる画像を使用します。

私が構築しようとしているのは、これらの長方形が画像の特定の領域に対応していることです。この画像と長方形が読み込まれた後、領域と長方形が整列されていない場合、ユーザーはそれらを正しく再配置できるはずです。

これが私のコードです:

//Box object to hold data for all drawn rects
function Box() {
  this.x = 0;
  this.y = 0;
  this.w = 1; // default width and height?
  this.h = 1;
  this.fill = '#444444';
}

//Initialize a new Box, add it, and invalidate the canvas
function addRect(x, y, w, h, fill) {
  var rect = new Box;
  rect.x = x;
  rect.y = y;
  rect.w = w
  rect.h = h;
  rect.fill = fill;
  boxes.push(rect);
  invalidate();
}

// holds all our rectangles
var boxes = []; 

var canvas;
var ctx;
var WIDTH;
var HEIGHT;
var INTERVAL = 20;  // how often, in milliseconds, we check to see if a redraw is needed

var isDrag = false;
var mx, my; // mouse coordinates

 // when set to true, the canvas will redraw everything
 // invalidate() just sets this to false right now
 // we want to call invalidate() whenever we make a change
var canvasValid = false;

// The node (if any) being selected.
// If in the future we want to select multiple objects, this will get turned into an array
var mySel; 

// The selection color and width. Right now we have a red selection with a small width
var mySelColor = '#CC0000';
var mySelWidth = 2;

// we use a fake canvas to draw individual shapes for selection testing
var ghostcanvas;
var gctx; // fake canvas context

// since we can drag from anywhere in a node
// instead of just its x/y corner, we need to save
// the offset of the mouse when we start dragging.
var offsetx, offsety;

// Padding and border style widths for mouse offsets
var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop;


// initialize our canvas, add a ghost canvas, set draw loop
// then add everything we want to intially exist on the canvas

function init() {
  // canvas = fill_canvas();
  canvas = document.getElementById('canvas');
  HEIGHT = canvas.height;
  WIDTH = canvas.width;
  ctx = canvas.getContext('2d');
  ghostcanvas = document.createElement('canvas');
  ghostcanvas.height = HEIGHT;
  ghostcanvas.width = WIDTH;
  gctx = ghostcanvas.getContext('2d');
  
  //fixes a problem where double clicking causes text to get selected on the canvas
  canvas.onselectstart = function () { return false; }
  
  // fixes mouse co-ordinate problems when there's a border or padding
  // see getMouse for more detail
  if (document.defaultView && document.defaultView.getComputedStyle) {
    stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10)      || 0;
    stylePaddingTop  = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10)       || 0;
    styleBorderLeft  = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10)  || 0;
    styleBorderTop   = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10)   || 0;
  }
  
  // make draw() fire every INTERVAL milliseconds
  setInterval(draw, INTERVAL);
  
  // set our events. Up and down are for dragging,
  // double click is for making new boxes
  canvas.onmousedown = myDown;
  canvas.onmouseup = myUp;
  canvas.ondblclick = myDblClick;
  
  // add custom initialization here:
  
  // add an orange rectangle
  addRect(200, 200, 200, 200, '#FFC02B');
  
  // add a smaller blue rectangle
  addRect(25, 90, 250, 150  , '#2BB8FF');
}

//wipes the canvas context
function clear(c) {
  c.clearRect(0, 0, WIDTH, HEIGHT);
}

// While draw is called as often as the INTERVAL variable demands,
// It only ever does something if the canvas gets invalidated by our code
function draw() {
  if (canvasValid == false) {
    clear(ctx);
    
    // Add stuff you want drawn in the background all the time here
    
    // draw all boxes
    var l = boxes.length;
    for (var i = 0; i < l; i++) {
        drawshape(ctx, boxes[i], boxes[i].fill);
    }
    
    // draw selection
    // right now this is just a stroke along the edge of the selected box
    if (mySel != null) {
      ctx.strokeStyle = mySelColor;
      ctx.lineWidth = mySelWidth;
      ctx.strokeRect(mySel.x,mySel.y,mySel.w,mySel.h);
    }
    
    // Add stuff you want drawn on top all the time here
    
    
    canvasValid = true;
  }
}

// Draws a single shape to a single context
// draw() will call this with the normal canvas
// myDown will call this with the ghost canvas
function drawshape(context, shape, fill) {
  context.fillStyle = fill;
  
  // We can skip the drawing of elements that have moved off the screen:
  if (shape.x > WIDTH || shape.y > HEIGHT) return; 
  if (shape.x + shape.w < 0 || shape.y + shape.h < 0) return;
  
  context.fillRect(shape.x,shape.y,shape.w,shape.h);
}

// Happens when the mouse is moving inside the canvas
function myMove(e){
  if (isDrag){
    getMouse(e);
    
    mySel.x = mx - offsetx;
    mySel.y = my - offsety;   
    
    // something is changing position so we better invalidate the canvas!
    invalidate();
  }
}

// Happens when the mouse is clicked in the canvas
function myDown(e){
  getMouse(e);
  clear(gctx);
  var l = boxes.length;
  for (var i = l-1; i >= 0; i--) {
    // draw shape onto ghost context
    drawshape(gctx, boxes[i], 'black');
    
    // get image data at the mouse x,y pixel
    var imageData = gctx.getImageData(mx, my, 1, 1);
    var index = (mx + my * imageData.width) * 4;
    
    // if the mouse pixel exists, select and break
    if (imageData.data[3] > 0) {
      mySel = boxes[i];
      offsetx = mx - mySel.x;
      offsety = my - mySel.y;
      mySel.x = mx - offsetx;
      mySel.y = my - offsety;
      isDrag = true;
      canvas.onmousemove = myMove;
      invalidate();
      clear(gctx);
      return;
    }
    
  }
  // havent returned means we have selected nothing
  mySel = null;
  // clear the ghost canvas for next time
  clear(gctx);
  // invalidate because we might need the selection border to disappear
  invalidate();
}

function myUp(){
  isDrag = false;
  canvas.onmousemove = null;
}

// adds a new node
function myDblClick(e) {
  getMouse(e);
  // for this method width and height determine the starting X and Y, too.
  // so I left them as vars in case someone wanted to make them args for something and copy this code
  var width = 150;
  var height = 100;
  addRect(mx - (width / 2), my - (height / 2), width, height, '#77DD44');
}

function invalidate() {
  canvasValid = false;
}

// Sets mx,my to the mouse position relative to the canvas
// unfortunately this can be tricky, we have to worry about padding and borders
function getMouse(e) {
      var element = canvas, offsetX = 0, offsetY = 0;

      if (element.offsetParent) {
        do {
          offsetX += element.offsetLeft;
          offsetY += element.offsetTop;
        } while ((element = element.offsetParent));
      }

      // Add padding and border style widths to offset
      offsetX += stylePaddingLeft;
      offsetY += stylePaddingTop;

      offsetX += styleBorderLeft;
      offsetY += styleBorderTop;

      mx = e.pageX - offsetX;
      my = e.pageY - offsetY
}

// If you dont want to use <body onLoad='init()'>
// You could uncomment this init() reference and place the script reference inside the body tag
init();
<!DOCTYPE html>
<html>
<head>
  <title>js</title>
</head>
<body>
  <canvas id="canvas" width="400" height="300">
    This text is displayed if your browser does not support HTML5 Canvas.
   </canvas>

</body>
</html>

R.シフィニ

以下のスニペットは、画像がhtmlに読み込まれている場合に機能するはずです。

コードの変更は2つあります。

  • 画像を変数にロードする
  • を使用してキャンバスに画像を描画する ctx.drawImage(im, 0, 0)

//Box object to hold data for all drawn rects
function Box() {
  this.x = 0;
  this.y = 0;
  this.w = 1; // default width and height?
  this.h = 1;
  this.fill = '#444444';
}

//Initialize a new Box, add it, and invalidate the canvas
function addRect(x, y, w, h, fill) {
  var rect = new Box;
  rect.x = x;
  rect.y = y;
  rect.w = w
  rect.h = h;
  rect.fill = fill;
  boxes.push(rect);
  invalidate();
}

//***************************
// This will load the image into the variable "im"
var im = document.getElementById("myImage");
//***************************

// holds all our rectangles
var boxes = []; 

var canvas;
var ctx;
var WIDTH;
var HEIGHT;
var INTERVAL = 20;  // how often, in milliseconds, we check to see if a redraw is needed

var isDrag = false;
var mx, my; // mouse coordinates

 // when set to true, the canvas will redraw everything
 // invalidate() just sets this to false right now
 // we want to call invalidate() whenever we make a change
var canvasValid = false;

// The node (if any) being selected.
// If in the future we want to select multiple objects, this will get turned into an array
var mySel; 

// The selection color and width. Right now we have a red selection with a small width
var mySelColor = '#CC0000';
var mySelWidth = 2;

// we use a fake canvas to draw individual shapes for selection testing
var ghostcanvas;
var gctx; // fake canvas context

// since we can drag from anywhere in a node
// instead of just its x/y corner, we need to save
// the offset of the mouse when we start dragging.
var offsetx, offsety;

// Padding and border style widths for mouse offsets
var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop;


// initialize our canvas, add a ghost canvas, set draw loop
// then add everything we want to intially exist on the canvas

function init() {
  // canvas = fill_canvas();
  canvas = document.getElementById('canvas');
  HEIGHT = canvas.height;
  WIDTH = canvas.width;
  ctx = canvas.getContext('2d');
  ghostcanvas = document.createElement('canvas');
  ghostcanvas.height = HEIGHT;
  ghostcanvas.width = WIDTH;
  gctx = ghostcanvas.getContext('2d');
  
  //fixes a problem where double clicking causes text to get selected on the canvas
  canvas.onselectstart = function () { return false; }
  
  // fixes mouse co-ordinate problems when there's a border or padding
  // see getMouse for more detail
  if (document.defaultView && document.defaultView.getComputedStyle) {
    stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10)      || 0;
    stylePaddingTop  = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10)       || 0;
    styleBorderLeft  = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10)  || 0;
    styleBorderTop   = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10)   || 0;
  }
  
  // make draw() fire every INTERVAL milliseconds
  setInterval(draw, INTERVAL);
  
  // set our events. Up and down are for dragging,
  // double click is for making new boxes
  canvas.onmousedown = myDown;
  canvas.onmouseup = myUp;
  canvas.ondblclick = myDblClick;
  
  // add custom initialization here:
  
  // add an orange rectangle
  addRect(200, 200, 200, 200, '#FFC02B');
  
  // add a smaller blue rectangle
  addRect(25, 90, 250, 150  , '#2BB8FF');
}

//wipes the canvas context
function clear(c) {
  c.clearRect(0, 0, WIDTH, HEIGHT);
}

// While draw is called as often as the INTERVAL variable demands,
// It only ever does something if the canvas gets invalidated by our code
function draw() {
  if (canvasValid == false) {
    clear(ctx);
    
    // Add stuff you want drawn in the background all the time here
    
    // draw all boxes
    var l = boxes.length;
    for (var i = 0; i < l; i++) {
        drawshape(ctx, boxes[i], boxes[i].fill);
    }
    
    // draw selection
    // right now this is just a stroke along the edge of the selected box
    if (mySel != null) {
      ctx.strokeStyle = mySelColor;
      ctx.lineWidth = mySelWidth;
      ctx.strokeRect(mySel.x,mySel.y,mySel.w,mySel.h);
    }
    
    // Add stuff you want drawn on top all the time here
    //You might want to change the size of the image
    //In that case use ctx.drawImage(im,0,0,width,height);
    //***************************
    ctx.drawImage(im,0,0);
    //***************************
    
    canvasValid = true;
  }
}

// Draws a single shape to a single context
// draw() will call this with the normal canvas
// myDown will call this with the ghost canvas
function drawshape(context, shape, fill) {
  context.fillStyle = fill;
  
  // We can skip the drawing of elements that have moved off the screen:
  if (shape.x > WIDTH || shape.y > HEIGHT) return; 
  if (shape.x + shape.w < 0 || shape.y + shape.h < 0) return;
  
  context.fillRect(shape.x,shape.y,shape.w,shape.h);
}

// Happens when the mouse is moving inside the canvas
function myMove(e){
  if (isDrag){
    getMouse(e);
    
    mySel.x = mx - offsetx;
    mySel.y = my - offsety;   
    
    // something is changing position so we better invalidate the canvas!
    invalidate();
  }
}

// Happens when the mouse is clicked in the canvas
function myDown(e){
  getMouse(e);
  clear(gctx);
  var l = boxes.length;
  for (var i = l-1; i >= 0; i--) {
    // draw shape onto ghost context
    drawshape(gctx, boxes[i], 'black');
    
    // get image data at the mouse x,y pixel
    var imageData = gctx.getImageData(mx, my, 1, 1);
    var index = (mx + my * imageData.width) * 4;
    
    // if the mouse pixel exists, select and break
    if (imageData.data[3] > 0) {
      mySel = boxes[i];
      offsetx = mx - mySel.x;
      offsety = my - mySel.y;
      mySel.x = mx - offsetx;
      mySel.y = my - offsety;
      isDrag = true;
      canvas.onmousemove = myMove;
      invalidate();
      clear(gctx);
      return;
    }
    
  }
  // havent returned means we have selected nothing
  mySel = null;
  // clear the ghost canvas for next time
  clear(gctx);
  // invalidate because we might need the selection border to disappear
  invalidate();
}

function myUp(){
  isDrag = false;
  canvas.onmousemove = null;
}

// adds a new node
function myDblClick(e) {
  getMouse(e);
  // for this method width and height determine the starting X and Y, too.
  // so I left them as vars in case someone wanted to make them args for something and copy this code
  var width = 150;
  var height = 100;
  addRect(mx - (width / 2), my - (height / 2), width, height, '#77DD44');
}

function invalidate() {
  canvasValid = false;
}

// Sets mx,my to the mouse position relative to the canvas
// unfortunately this can be tricky, we have to worry about padding and borders
function getMouse(e) {
      var element = canvas, offsetX = 0, offsetY = 0;

      if (element.offsetParent) {
        do {
          offsetX += element.offsetLeft;
          offsetY += element.offsetTop;
        } while ((element = element.offsetParent));
      }

      // Add padding and border style widths to offset
      offsetX += stylePaddingLeft;
      offsetY += stylePaddingTop;

      offsetX += styleBorderLeft;
      offsetY += styleBorderTop;

      mx = e.pageX - offsetX;
      my = e.pageY - offsetY
}

// If you dont want to use <body onLoad='init()'>
// You could uncomment this init() reference and place the script reference inside the body tag
init();
<!DOCTYPE html>
<html>
<head>
  <title>js</title>
</head>
<body>
  <canvas id="canvas" width="400" height="300">
    This text is displayed if your browser does not support HTML5 Canvas.
   </canvas>
   
<!-- This image will be displayed on the canvas -->   
<img id="myImage" src="image.jpg" style = "display: none">


</body>
</html>

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

javascriptを使用してキャンバスの画像を印刷する

分類Dev

FlutterWebでキャンバスを画像としてキャプチャする

分類Dev

キャンバスに複数の画像を描画し、キャンバスをpng画像として保存する方法

分類Dev

外部Javascriptを使用してHTMLキャンバスに画像を追加する

分類Dev

JavaFXでMouseEventとMouseClickedを使用してキャンバス画像を選択して移動する

分類Dev

キャンバスを使用して画像を並べて表示する最も効率的な方法は何ですか?

分類Dev

Fabricjsを使用してキャンバスに複数の画像を追加する方法

分類Dev

toDataURLを使用してキャンバスからphpに画像を送信する方法

分類Dev

キャンバスとJavaScriptを使用してSpralingテキストを描画する方法は?

分類Dev

キャンバスを使用して画像を表示する

分類Dev

キャンバスを画像としてUWPに保存する

分類Dev

Reactjsを使用して新しいタブでキャンバスを画像として開く方法

分類Dev

キャンバスとJavaScriptを使用して変数パスを編集する方法は?

分類Dev

HTMLとJavascriptを使用してキャンバスを作成することはできません

分類Dev

JavaScript-キャンバスに描画して、マウスに追従する画像を取得する方法

分類Dev

ダブルバッファリングを使用してキャンバスに画像を描画すると、完全な画像を取得できませんか?

分類Dev

Javascript / JQueryとHTML(キャンバスなし)を使用してノードを線で接続する

分類Dev

キャンバスで画像の一部を抽出し、それをdivの背景画像として使用するにはどうすればよいですか?

分類Dev

javascriptを使用してキャンバスに再描画すると色が変わるのはなぜですか?

分類Dev

キャンバス画像をデータベースとして保存し、URLを生成する方法

分類Dev

toplevel()Tkinterでキャンバスを使用してボタンを作成する方法

分類Dev

javascriptを使用して画像のサイズを変更すると、空白のキャンバス画像が作成されます

分類Dev

FirefoxとMicrosoftEdgeで機能しない画像としてキャンバスをダウンロードする

分類Dev

JavaScriptを使用して要素をキャンバスに配置する

分類Dev

APIを使用してキャンバスからサーバーに画像を送信する方法は?

分類Dev

HTML5キャンバスを画像としてdjangoサーバーに送信する方法

分類Dev

キャンバスを使用して画像にコンテンツを追加する

分類Dev

drawImage()を含むキャンバスを画像としてダウンロードする方法

分類Dev

キャンバスを右クリックすると画像として保存

Related 関連記事

  1. 1

    javascriptを使用してキャンバスの画像を印刷する

  2. 2

    FlutterWebでキャンバスを画像としてキャプチャする

  3. 3

    キャンバスに複数の画像を描画し、キャンバスをpng画像として保存する方法

  4. 4

    外部Javascriptを使用してHTMLキャンバスに画像を追加する

  5. 5

    JavaFXでMouseEventとMouseClickedを使用してキャンバス画像を選択して移動する

  6. 6

    キャンバスを使用して画像を並べて表示する最も効率的な方法は何ですか?

  7. 7

    Fabricjsを使用してキャンバスに複数の画像を追加する方法

  8. 8

    toDataURLを使用してキャンバスからphpに画像を送信する方法

  9. 9

    キャンバスとJavaScriptを使用してSpralingテキストを描画する方法は?

  10. 10

    キャンバスを使用して画像を表示する

  11. 11

    キャンバスを画像としてUWPに保存する

  12. 12

    Reactjsを使用して新しいタブでキャンバスを画像として開く方法

  13. 13

    キャンバスとJavaScriptを使用して変数パスを編集する方法は?

  14. 14

    HTMLとJavascriptを使用してキャンバスを作成することはできません

  15. 15

    JavaScript-キャンバスに描画して、マウスに追従する画像を取得する方法

  16. 16

    ダブルバッファリングを使用してキャンバスに画像を描画すると、完全な画像を取得できませんか?

  17. 17

    Javascript / JQueryとHTML(キャンバスなし)を使用してノードを線で接続する

  18. 18

    キャンバスで画像の一部を抽出し、それをdivの背景画像として使用するにはどうすればよいですか?

  19. 19

    javascriptを使用してキャンバスに再描画すると色が変わるのはなぜですか?

  20. 20

    キャンバス画像をデータベースとして保存し、URLを生成する方法

  21. 21

    toplevel()Tkinterでキャンバスを使用してボタンを作成する方法

  22. 22

    javascriptを使用して画像のサイズを変更すると、空白のキャンバス画像が作成されます

  23. 23

    FirefoxとMicrosoftEdgeで機能しない画像としてキャンバスをダウンロードする

  24. 24

    JavaScriptを使用して要素をキャンバスに配置する

  25. 25

    APIを使用してキャンバスからサーバーに画像を送信する方法は?

  26. 26

    HTML5キャンバスを画像としてdjangoサーバーに送信する方法

  27. 27

    キャンバスを使用して画像にコンテンツを追加する

  28. 28

    drawImage()を含むキャンバスを画像としてダウンロードする方法

  29. 29

    キャンバスを右クリックすると画像として保存

ホットタグ

アーカイブ