2012-04-12 35 views
3

我正在建立一個工具,通過讓用戶創建一個封閉的形狀來剪出一張照片的一部分。用戶應該能夠開始繪製線條。從a點到b點,再到c,e,d,e,f ....最終再次指向a來關閉形狀。HTML5 photoshop喜歡多邊形套索的選擇

我想爲此使用HTML5畫布。我認爲這可能是一個不錯的選擇,我正在考慮使用類似flashcanvas的作爲IE /舊版瀏覽器的後備版本嗎?

是否有任何教程/開源應用程序,我可以用來建立這樣的事情? 這是我第一次使用HTML5 canvas創建應用程序,所以我應該擔心哪些缺陷?

+1

你有沒有試過只是谷歌的教程?學習來自現有項目的代碼,如http://pixlr.com/editor/? – kirilloid 2012-04-12 08:00:07

+0

我一直在搜索教程,我只找到鉛筆畫的東西(不是點對點)。和現有的項目? =>不知道你是否已經檢查過這個,但是pixlr-editor是一個FLASH應用程序?我正在尋找一個HTML5帆布解決方案 – 2012-04-12 12:26:20

回答

4

我認爲這是帆布的高級用法。你必須知道基礎知識,如何繪製,如何使用圖層,如何操作像素。只需向谷歌尋求教程。

假設你知道以前,我會試試看。我從來沒有這麼做過,但我有一個想法:

您需要3個帆布:

  • 包含您的圖片(您的圖片尺寸)
  • 一個層,其中用戶繪製選擇一個形狀(您的圖片大小,在第一畫布的頂部)
  • 結果畫布上,將包含您裁剪圖片(大小相同,這其中並不需要顯示)

當用戶點擊在y上我們的圖片:實際上,他點擊圖層,圖層被清除並開始一條新線。

當他再次點擊它時,先前啓動的線條被繪製,另一個線條開始,等等......您繼續這樣做直到您單擊非空白像素(這意味着您關閉了形狀)。

如果你希望用戶預覽行,則需要其他畫布(這裏http://dev.opera.com/articles/view/html5-canvas-painting/#line解釋)

當形狀關閉時,用戶必須點擊內部或形狀之外,以確定他想要哪一部分選擇。例如,用半透明灰色填充該部分(此處填充的填充爲http://www.williammalone.com/articles/html5-canvas-javascript-paint-bucket-tool/

現在,圖層畫布包含與用戶選擇對應的彩色形狀。

從層獲取像素數據,並通過陣列讀,每次都發現在指數一個非空白像素,你從你的主畫布這個像素複製到結果帆布:

/* First, get pixel data from your 3 canvas into 
* layerPixData, resultPixData, picturePixData 
*/ 

// read the entire pixel array 
for (var i = 0 ; i < layerPixData.length ; i+=4) { 
    //if the pixel is not blank, ie. it is part of the selected shape 
    if (layerPixData[i] != 255 || layerPixData[i+1] != 255 || layerPixData[i+2] != 255) { 
     // copy the data of the picture to the result 
     resultPixData[i] = picturePixData[i]; //red 
     resultPixData[i+1] = picturePixData[i+1]; //green 
     resultPixData[i+2] = picturePixData[i+2]; //blue 
     resultPixData[i+3] = picturePixData[i+3]; //alpha 

     // here you can put the pixels of your picture to white if you want 

    } 

} 

如果你不知道像素操作是如何工作的,請閱讀本https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas

然後,使用putImageData的像素畫到你的結果畫布。任務完成 !

如果你想將你選擇的線路的路要走:http://simonsarris.com/blog/225-canvas-selecting-resizing-shape

+0

哇,這是一些非常好的資源,謝謝你的迴應。我發現了一個插件,可以切出部分圖片並使其透明:http://www.useragentman.com/blog/2011/10/29/clipping-jpeg-images-into-non-rectangular-polygons-using -polyclip-js /所以你的解釋我可以建立一個像多邊形套索的工具並修復這個問題!謝謝! – 2012-04-12 14:23:53

1

這裏是你應該怎麼做: 在下面的代碼將在你的頁面頂部的帆布,然後通過點擊和拖動選擇區域將被突出顯示。之後您需要做的是從底層頁面製作屏幕截圖,並在畫布中創建一個遮罩層,然後將其應用於屏幕截圖,就像它在另一個答案中的顯示方式一樣。

/* sample css code for the canvas 
#overlay-canvas { 
    position: absolute; 
    top: 0; 
    left: 0; 
    background-color: transparent; 
    opacity: 0.4; 
    -moz-user-select: none; 
    -khtml-user-select: none; 
    -webkit-user-select: none; 
    -o-user-select: none; 
} 
*/ 

function getHighIndex(selector) { 
    if (!selector) { selector = "*" }; 

    var elements = document.querySelectorAll(selector) || 
        oXmlDom.documentElement.selectNodes(selector); 
    var ret = 0; 

    for (var i = 0; i < elements.length; ++i) { 
     if (deepCss(elements[i],"position") === "static") 
      continue; 

     var temp = deepCss(elements[i], "z-index"); 

     if (temp != "auto") 
      temp = parseInt(temp, 10) || 0; 
     else 
      continue; 

     if (temp > ret) 
      ret = temp; 
    } 
    return ret; 
} 

maxZIndex = getHighIndex(); 

$.fn.extend({ 
    lasso: function() { 
     return this 
     .mousedown(function (e) { 
      // left mouse down switches on "capturing mode" 
      if (e.which === 1 && !$(this).is(".lassoRunning")) { 
       var point = [e.offsetX, e.offsetY]; 
       $(this).addClass("lassoRunning"); 
       $(this).data("lassoPoints", [point]); 
       $(this).trigger("lassoStart", [point]); 
      } 
     }) 
     .mouseup(function (e) { 
      // left mouse up ends "capturing mode" + triggers "Done" event 
      if (e.which === 1 && $(this).is(".lassoRunning")) { 
       $(this).removeClass("lassoRunning"); 
       $(this).trigger("lassoDone", [$(this).data("lassoPoints")]); 
      } 
     }) 
     .mousemove(function (e) { 
      // mouse move captures co-ordinates + triggers "Point" event 
      if ($(this).is(".lassoRunning")) { 
       var point = [e.offsetX, e.offsetY]; 
       $(this).data("lassoPoints").push(point); 
       $(this).trigger("lassoPoint", [point]); 
      } 
     }); 
    } 
}); 


function onLassoSelect() { 
    // creating canvas for lasso selection 
    var _canvas = document.createElement('canvas'); 
    _canvas.setAttribute("id", "overlay-canvas"); 
    _canvas.style.zIndex = ++maxZIndex; 
    _canvas.width = document.width 
    _canvas.height = document.height 
    document.body.appendChild(_canvas); 
    ctx = _canvas.getContext('2d'), 
    ctx.strokeStyle = '#0000FF'; 
    ctx.lineWidth = 5; 

    $(_canvas) 
     .lasso() 

     .on("lassoStart", function(e, lassoPoint) { 
      console.log('lasso start'); 

      var pos = lassoPoint; 
      ctx.beginPath(); 
      ctx.moveTo(pos[0], pos[1]); 
      console.log(pos); 
     }) 

     .on("lassoDone", function(e, lassoPoints) { 
      console.log('lasso done'); 

      var pos = lassoPoints[0]; 
      ctx.lineTo(pos[0], pos[1]); 
      ctx.fill(); 
      console.log(pos); 
     }) 

     .bind("lassoPoint", function(e, lassoPoint) { 
      var pos = lassoPoint; 
      ctx.lineTo(pos[0], pos[1]); 
      ctx.fill(); 
      console.log(pos); 
     }); 
}