3

我希望通过让用户创建一个封闭的形状来构建一个工具来剪切照片的一部分。用户应该能够开始画线。从a点到b点,再到c、e、d、e、f ....到最后再点a来闭合形状。

我想为此使用 HTML5 画布。我认为这可能很合适,我正在考虑使用 flashcanvas 之类的东西作为 IE/旧浏览器的后备?

是否有任何教程/开源应用程序可以用来构建这种东西?这是我第一次使用 HTML5 画布构建应用程序,所以我应该担心哪些陷阱?

4

2 回答 2

4

我认为这是画布的高级用法。您必须了解基础知识,如何绘制,如何使用图层,如何操作像素。只需向谷歌寻求教程。

假设你知道以前的,我会试一试。我以前从未这样做过,但我有一个想法:

你需要 3 个画布:

  • 包含您的图片的那个(图片的大小)
  • 用户绘制选择形状的图层(图片大小,在第一个画布的顶部)
  • 结果画布,将包含您裁剪的图片(大小相同,不需要显示)

当用户点击你的图片时:实际上,他点击了图层,图层被清除并开始新的一行。

当他再次单击它时,将绘制上一条开始的线并开始另一条线,等等...您继续这样做,直到您单击一个非空白像素(这意味着您关闭了形状)。

如果您希望用户预览线条,则需要另一个画布(此处解释为http://dev.opera.com/articles/view/html5-canvas-painting/#line

当形状闭合时,用户必须在形状内部或外部单击以确定他想要选择的部分。例如,您用半透明灰色填充该部分(洪水填充在这里解释http://www.williammalone.com/articles/html5-canvas-javascript-paint-bucket-tool/

现在图层画布包含与用户选择相对应的彩色形状。

从图层获取像素数据并读取数组,每次在索引i处找到非空白像素时,将此像素从主画布复制到结果画布:

/* 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

于 2012-04-12T12:41:06.263 回答
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);
        });
}
于 2013-01-29T05:20:11.583 回答