Home Reference Source

src/layers/canvasUtil.js


function drawDashLine(ctx, line) {
    if (ctx instanceof CanvasRenderingContext2D && line instanceof Array) {
        ctx.setLineDash([10, 5]);
        ctx.strokeStyle = 'rgba(0,252,100,0.6)';
        ctx.lineWidth = 6;
        
        ctx.beginPath();
        ctx.moveTo(line[0][0], line[0][1]);
        for (let i = 1; i < line.length; i += 1) {
            ctx.lineTo(line[i][0], line[i][1]);
        }
        ctx.stroke();
        ctx.closePath();
    }
}

function drawGradientLine(ctx, line, shadow = false) {
    if (ctx instanceof CanvasRenderingContext2D && line instanceof Array) {
        // build gradient style
        var gradient = ctx.createLinearGradient(0, 0, 600, 0);
        gradient.addColorStop(0, "rgba(0,255,100,0.9)");
        gradient.addColorStop(1, "rgba(255,255,255,0.1)");

        if (shadow) {
            console.warn(`enabling line shadowBlur`);
            ctx.shadowBlur = 4;
            ctx.shadowColor = '#0f0';
        }

        ctx.strokeStyle = gradient;
        ctx.setLineDash([]);
        ctx.globalAlpha = 0.9;
        ctx.globalCompositeOperation = 'source-over';

        // ctx.strokeStyle = 'green';
        ctx.lineCap = "round";  // square
        ctx.lineJoin = 'round'; // bevel
        ctx.lineWidth = 6;

        ctx.beginPath();
        ctx.moveTo(line[0][0], line[0][1]);
        for (let i = 1; i < line.length; i += 1) {
            ctx.lineTo(line[i][0], line[i][1]);
        }
        ctx.stroke();
        ctx.closePath();
    }
}

function drawArrowLine(ctx, line, enableAni = false) {
    if (ctx instanceof CanvasRenderingContext2D && line instanceof Array) {
        
            // ctx.fillRect(0, 0, 600, 400);
            setLineStyle(ctx);

            ctx.beginPath();
            ctx.moveTo(line[0][0], line[0][1]);
            for (let i = 1; i < line.length; i += 1) {
                ctx.lineTo(line[i][0], line[i][1]);
            }
            ctx.stroke();
            ctx.closePath();

        function drawArrows() {
            let aniOffset = .2;        
            aniOffset = aniOffset < 1 ? aniOffset + .01 : .2;
            for (let i = 1; i < line.length; i += 1) {
                drawArrow(ctx, line[i-1], line[i], aniOffset); // one segment.
            }
            if (enableAni) requestAnimationFrame(drawArrows);
        }
        drawArrows();
    }
}

function setLineStyle(ctx, shadow = false) {
    ctx.strokeStyle = 'green';
    ctx.setLineDash([]);
    ctx.globalAlpha = 0.95;
    ctx.globalCompositeOperation = 'source-over';
    if (shadow) {
        console.warn(`enabling line shadowBlur`);
        ctx.shadowBlur = 4;
        ctx.shadowColor = '#0f0';
    } else {
        ctx.shadowBlur = 0;
    }

    // ctx.strokeStyle = 'green';
    ctx.lineCap = "round";  // square
    ctx.lineJoin = 'round'; // bevel
    ctx.lineWidth = 12;
}

function drawArrow(ctx, startPoint, endPoint, aniOffset) {
    ctx.beginPath();
    ctx.strokeStyle = 'white';
    ctx.lineWidth = 2;
    
    // arrow img: assets/up.png
    var points = generatePoints(startPoint, endPoint, 30, ctx, aniOffset);
    // console.warn(`draw segment arrows done... from ${startPoint.join()} to ${endPoint.join()}`);
    // // calc left/right point.
    // var lrPoints = calcLRPoints(point, rotate);   

    ctx.closePath();
}

function generatePoints(startP, endP, stepSize = 20, ctx, aniOffset = 0.5) {
    const radA = Math.atan((endP[1] - startP[1]) / (endP[0] - startP[0]));  // k should be transform to a in Rad.
    const dist = calcDist(startP, endP);
    let points = [];
    const steps = dist / stepSize;

    const drawImg = (pX, pY) => {
        if (img && ctx) {
            ctx.save();
            // ctx.beginPath();
            ctx.translate(pX , pY);  // consider img position and imgWidth/Height.
            const rotateAng = 180 * radA / Math.PI; 
            ctx.rotate(radA);
            // ctx.arc(0, 0, 2, 0, 2 * Math.PI);
            ctx.drawImage(img, -img.width / 2,  -img.width/2);
            // ctx.stroke();
            console.warn(`drawIcon at ${pX}, ${pY}, with angle rad: ${radA}`);
            // ctx.closePath();
            ctx.restore();
        }
    }

    // gen points by stepSize.. if enable corner arrow, start s with (0~1) float number.
    for (let s = aniOffset; s <= steps; s += 1) {
        const pX = startP[0] + s * stepSize * Math.cos(radA);
        const pY = startP[1] + s * stepSize * Math.sin(radA);
        points.push([pX, pY]);
        if (ctx) {
            var img = new Image();
            img.src = '../../assets/arrow.png';
            img.onload = function() {
                drawImg(pX, pY);
            }
        }
    }
    return points;
}

function calcDist(startP, endP) {
    return Math.sqrt((endP[1] - startP[1]) ** 2 + (endP[0] - startP[0]) ** 2);
}

/**
 *      . <-- center coordinate [x, y].
 *     / \
 *    `   ` 
 * 
 */
function calcLRPoints(center, rotate) {
    const arrawRadius = 3;
    return center;
}

function drawGradientRect(ctx, line) {
    
}