65.9K
CodeProject 正在变化。 阅读更多。
Home

使用JavaScript和HTML5绘制橡皮筋线

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (6投票s)

2014 年 5 月 22 日

CPOL

2分钟阅读

viewsIcon

20678

downloadIcon

441

除了绘制橡皮筋线条,你还可以了解自定义光标和数组存储。

引言

我的主要目标是解决在画布上绘制橡皮筋线条的问题。我使用了位于原始画布之上(z-index!)的透明副本画布。副本画布仅在输入过程中“可见”,否则 <display:"none">。

我的程序是一个类似于 CAD 的 2D 绘图解决方案,具有重力(吸附)功能。你可以绘制线条、多线、圆形和弧线。智能(自定义)光标反映了几何元素和光标位置之间的关系。

元素数据存储在 sessionStorage 中。如何存储和检索对象数组并不显而易见:我使用了 JSON 函数来实现。

所使用的工具提示解决方案并非我创建的。

你可以在 此页面 上试用此应用程序。

使用代码

我附上了一个 htm 文件,js 文件夹中的三个 js 文件,以及光标文件夹中的自定义光标图像文件。

现在我分享一些代码文件中的重要细节

如何创建副本画布?

htm 文件中的原始画布

<div id = "canvasId">
    <canvas id="myCanvas" width=...; z-index: 1;">
        Your browser does not support the HTML5 canvas tag.
    </canvas>
</div> 

副本 JavaScript 函数

function SetCanvasLayer (p_canvas, p_divId, p_moveFunc, p_cancelFunc) {
    var rubberDiv = document.getElementById(p_divId);
    var layer = document.getElementById(canvasRubber);
    if (layer == null) {
        canvasRubber = document.createElement('canvas');
        rubberDiv.appendChild(canvasRubber);
        ctxRubber = canvasRubber.getContext("2d");

        canvasRubber.width = p_canvas.width;
        canvasRubber.height = p_canvas.height;
        canvasRubber.setAttribute("style", p_canvas.getAttribute("style"));
        canvasRubber.style.backgroundColor = "transparent";
        canvasRubber.style.zIndex = parseInt(p_canvas.style.zIndex) + 1;
        canvasRubber.style.cursor = "url(Cursors/pencil.png) 6 28, crosshair";
        canvasRubber.style.display = "none";
        canvasRubber.innerHTML = "Your browser does not support the HTML5 canvas tag.";
        canvasRubber.onclick = LayerClick;
        canvasRubber.onmousemove = LayerMouseMove;

        window.addEventListener("keydown", LayerKeyDown, false);
        moveFunction = p_moveFunc;
        cancelFunction = p_cancelFunc;
    }
}

第一次点击事件由原始画布处理。根据单选按钮,它的函数必须调用 StartRubberLine 函数,例如。之后,副本画布变得“可见”,并接收鼠标事件。

LayerMouseMove 函数在 mousemove 事件时被调用。此函数调用 - 除其他外 - DrawRubberLine 函数

function DrawRubberLine(pos, clear) {
    if (clear == true) {
        ClearCanvas();
    }

    ctxRubber.strokeStyle = colorRubber;
    ctxRubber.beginPath();
    ctxRubber.moveTo(startx, starty);
    ctxRubber.lineTo(pos.x, pos.y);
    ctxRubber.stroke();
}

通常,我们必须在绘制之前清除画布

function ClearCanvas() {
    ctxRubber.clearRect(0, 0, canvasRubber.width, canvasRubber.height);
    var w = canvasRubber.width;
    canvasRubber.width = 1;
    canvasRubber.width = w;
}

StoreGeomElemObj 函数将数据存储到 sessionStorage 中。存储的数据是一个数组。数组中的一个项目是一个包含数字、字符串和坐标数组的对象。

function StoreGeomElemObj(p_elem, p_storageId) {
    var store = sessionStorage.getItem(p_storageId);
    if (store == null) {
        store = new Array(0);
    }
    else {
        store = JSON.parse(store);
    }
    store.push(p_elem);
    sessionStorage.setItem(p_storageId, JSON.stringify(store));
}

要检索原始对象项,请使用以下函数

function GetGeomElemObj(p_index, p_storageId) {
    var store = sessionStorage.getItem(p_storageId)
    if (store == null) {
        return null;
    }
    else {
        store = JSON.parse(store);
        return store[p_index];
    }
}

要获取对象数组中的元素数量,请使用以下函数

function GetArrayLength (obj) {
    var i = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) {
            i++;
        }
    }
    return i;
};

重力系统是一个包含几何计算的复杂代码。例如,如果光标靠近一条线段的端点,光标会改变其形状:在输入过程中显示管道或条纹铅笔。

var CursorPencilStriped = "url(cursors/pencilstriped.png) 6 28, crosshair";
 canvasRubber.style.cursor = CursorPencilStriped ;

重力系统还可以帮助你绘制垂直线。弧线的重力是你的任务 :) 我可以做到:请参阅 此页面。

最后,这里有一个提示:你可以通过返回弧线的起始点来改变弧线的方向。

© . All rights reserved.