【问题标题】:HTML5 photoshop like polygonal lasso selectionHTML5 Photoshop 像多边形套索选择
【发布时间】:2012-04-12 07:52:14
【问题描述】:

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

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

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

【问题讨论】:

  • 你试过用谷歌搜索教程吗?从pixlr.com/editor 等现有项目中学习代码?
  • 我一直在谷歌搜索教程,我只找到类似铅笔的绘图材料(不是点对点)。和现有的项目? => 不知道你是否已经检查过这个,但是 pixlr-editor 是一个 FLASH 应用程序?我正在寻找 HTML5 画布解决方案

标签: javascript jquery html5-canvas


【解决方案1】:

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

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

你需要 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

【讨论】:

  • 哇,这是一些非常好的资源,感谢您的回复。我找到了一个插件,可以切出一部分图片并使其透明:useragentman.com/blog/2011/10/29/… 所以根据你的解释,我可能可以构建一个像多边形套索这样的工具并修复这个东西!谢谢!
【解决方案2】:

您应该这样做: 下面的代码在页面顶部添加了一个画布,然后通过单击并拖动选择区域将被突出显示。之后您需要做的是从底层页面制作屏幕截图,并从画布中创建的图像中制作一个遮罩层,并将其应用于屏幕截图,就像它在另一个答案中的显示方式一样。

/* 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);
        });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多