Skip to content
Snippets Groups Projects
index.html 7.33 KiB
Newer Older
Andreas Horn's avatar
Andreas Horn committed
<!DOCTYPE html>
<html>

<head>
    <style type="text/css">
        #board {
            touch-action: none;
            border: 0.5px solid rgba(0, 0, 0, 0.1);
            box-shadow: 1px 1px 1px 0.5px rgba(0, 0, 0, 0.1);
            cursor: crosshair;
        }
    </style>

    <script type="application/javascript" src="js/main.js"></script>
    <script type="application/javascript" src="js/Board.js"></script>
    <script type="application/javascript" src="js/Pen.js"></script>
    <script type="application/javascript" src="js/Pointer.js"></script>

    <script type="application/javascript">
        let strokeData = [];

Andreas Horn's avatar
Andreas Horn committed
        function init() {
            Board.init("board");
            Pen.init(Board.ctx);

            //Pointer.onEmpty = _.debounce(Board.storeMemory.bind(Board), 1500);

            // Attach event listener
            var pointerDown = function pointerDown(e) {
                if (e.pointerType == "pen") {
                    // Initialise pointer
                    var pointer = new Pointer(e.pointerId);
                    pointer.set(Board.getPointerPos(e));

                    // Get function type
                    Pen.setFuncType(e);
                    if (Pen.funcType === Pen.funcTypes.menu) Board.clearMemory();
                    else drawOnCanvas(e, pointer, Pen);
                }
            }
            var pointerMove = function pointerMove(e) {
                if (Pen.funcType && (Pen.funcType.indexOf(Pen.funcTypes.draw) !== -1)) {

                    var pointer = Pointer.get(e.pointerId);
                    drawOnCanvas(e, pointer, Pen);
                }
            }
            var pointerCancel = function pointerLeave(e) {
                var tension = 0.5;

                drawCurve(Board.ctx, strokeData, tension);

Andreas Horn's avatar
Andreas Horn committed
                Pointer.destruct(e.pointerId);
            }
            Board.dom.addEventListener('pointerdown', pointerDown);
            Board.dom.addEventListener('pointermove', pointerMove);
            Board.dom.addEventListener('pointerup', pointerCancel);
            Board.dom.addEventListener('pointerleave', pointerCancel);

            // Draw method
            function drawOnCanvas(e, pointerObj, Pen) {
                if (pointerObj) {
                    pointerObj.set(Board.getPointerPos(e));
                    Pen.setPen(Board.ctx, e);

                    if (pointerObj.pos0.x < 0) {
                        pointerObj.pos0.x = pointerObj.pos1.x - 1;
                        pointerObj.pos0.y = pointerObj.pos1.y - 1;
                    }
                    Board.ctx.beginPath();
                    Board.ctx.moveTo(pointerObj.pos0.x, pointerObj.pos0.y)
                    Board.ctx.lineTo(pointerObj.pos1.x, pointerObj.pos1.y);
                    Board.ctx.closePath();
                    Board.ctx.stroke();

                    strokeData.push({x: pointerObj.pos1.x, y: pointerObj.pos1.y});
Andreas Horn's avatar
Andreas Horn committed
                    pointerObj.pos0.x = pointerObj.pos1.x;
                    pointerObj.pos0.y = pointerObj.pos1.y;
                }
            }

            function drawCurve(ctx, ptsa, tension, isClosed, numOfSegments, showPoints) {
                ctx.beginPath();

                var oldStyle = ctx.strokeStyle;
                ctx.strokeStyle = "#FF0000";
                ctx.lineWidth = 5;

                drawLines(ctx, getCurvePoints(ptsa, tension, isClosed, numOfSegments));

                if (showPoints) {
                    ctx.beginPath();
                    for (var i = 0; i < ptsa.length - 1; i += 2)
                        ctx.rect(ptsa[i] - 2, ptsa[i + 1] - 2, 4, 4);
                }

                ctx.stroke();

                ctx.strokeStyle = oldStyle;
            }

            function getCurvePoints(pts, tension, isClosed, numOfSegments) {
                // use input value if provided, or use a default value	 
                tension = (typeof tension != 'undefined') ? tension : 0.5;
                isClosed = isClosed ? isClosed : false;
                numOfSegments = numOfSegments ? numOfSegments : 16;

                var _pts = [], res = [],    // clone array
                    x, y,                   // our x,y coords
                    t1x, t2x, t1y, t2y,     // tension vectors
                    c1, c2, c3, c4,         // cardinal points
                    st, t, i;               // steps based on num. of segments

                // clone array so we don't change the original
                _pts = pts.slice(0);

                // The algorithm require a previous and next point to the actual point array.
                // Check if we will draw closed or open curve.
                // If closed, copy end points to beginning and first points to end
                // If open, duplicate first points to befinning, end points to end
                if (isClosed) {
                    _pts.unshift(pts[pts.length - 1]);
                    _pts.unshift(pts[pts.length - 1]);
                    _pts.push(pts[0]);
                }
                else {
                    _pts.unshift(pts[0]);	//copy 1. point and insert at beginning
                    _pts.push(pts[pts.length - 1]);	//copy last point and append
                }

                // ok, lets start..

                // 1. loop goes through point array
                // 2. loop goes through each segment between the 2 pts + 1e point before and after
                for (var i = 1; i < (_pts.length - 2); i++) {
                    for (var t = 0; t <= numOfSegments; t++) {
                        // calc tension vectors
                        t1x = (_pts[i + 1].x - _pts[i - 1].x) * tension;
                        t2x = (_pts[i + 2].x - _pts[i].x) * tension;
                        t1y = (_pts[i + 1].y - _pts[i - 1].y) * tension;
                        t2y = (_pts[i + 2].y - _pts[i].y) * tension;

                        // calc step
                        st = t / numOfSegments;

                        // calc cardinals
                        c1 = 2 * Math.pow(st, 3) - 3 * Math.pow(st, 2) + 1;
                        c2 = -(2 * Math.pow(st, 3)) + 3 * Math.pow(st, 2);
                        c3 = Math.pow(st, 3) - 2 * Math.pow(st, 2) + st;
                        c4 = Math.pow(st, 3) - Math.pow(st, 2);

                        // calc x and y cords with common control vectors
                        x = c1 * _pts[i].x + c2 * _pts[i + 1].x + c3 * t1x + c4 * t2x;
                        y = c1 * _pts[i].y + c2 * _pts[i + 1].y + c3 * t1y + c4 * t2y;

                        //store points in array
                    }
                }

                return res;
            }

            function drawLines(ctx, pts) {
                ctx.moveTo(pts[0].x, pts[0].y);
                for (i = 1; i < pts.length - 1; i++) {
                    ctx.lineTo(pts[i].x, pts[i].y);
                }
Andreas Horn's avatar
Andreas Horn committed
        }
    </script>
</head>

<body onload="init();">
    <canvas touch-action="none" id="board" width="640" height="640" style="width:320px; height:320px;">
        Opps, you cannot play draw N guess with this browser!
    </canvas>
    <button style="z-index: 9001; position:absolute; top:100px; left: 100px; width: 200px;"
        onclick="Board.storeMemory();">save</button>
    <button style="z-index: 9001; position:absolute; top:100px; left: 320px; width: 200px;"
        onclick="Board.clearMemory();">clear</button>
Andreas Horn's avatar
Andreas Horn committed
</body>

</html>