簡體   English   中英

HTML5畫布的適合和居中內容

[英]HTML5 Fit and Center Content of a Canvas

我想創建一個畫布,該畫布可自動擬合並自動居中繪制在其上的形狀。

我有:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />

    <title>Fit Canvas Content</title>

</head>

<body>
    <canvas id="myCanvas" width="500" height="500" style="border:1px solid #000000;">
        Your browser doesn't support the HTML5 canvas.
    </canvas>
    <script>
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        ctx.fillStyle = "black";
        ctx.fillRect(-5, -50, 10, 100);
        ctx.fillRect(-50, -5, 100, 10);
    </script>
</body>
</html>

請記住,畫布內容是動態的,形狀可以在任何位置並且可以具有任何大小。

畫布上的形狀集合

我猜你想要這樣的東西: http : //jsfiddle.net/e3qSP/1/

這是用於繪制包含JSDoc的加號的函數:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "black";
drawPlus(20, c);

/**
 * Draws plus in the middle of the canvas with specified width
 *
 * @public
 * @param {number} plusWidth The width of the plus
 * @param {canvas} canvas The canvas on which the plus should be drawn
 */
function drawPlus(plusWidth, canvas) {
    var height = parseInt(canvas.height),
        width = parseInt(canvas.width),
        size = Math.min(height, width);
    ctx.fillRect((width - plusWidth) / 2, (height - size) / 2, plusWidth, size);
    ctx.fillRect((width - size) / 2, (height - plusWidth) / 2, size, plusWidth);
}

這將適合並縮放到畫布。 請注意,沒有填充,但這很容易添加

首先,您需要設置一些東西來跟蹤轉換。

this.trackTransforms = function (ctx) {
    var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
    var xform = svg.createSVGMatrix();
    ctx.getTransform = function () { return xform; };

    var savedTransforms = [];
    var save = ctx.save;

    ctx.save = function () {
        savedTransforms.push(xform.translate(0, 0));
        return save.call(ctx);
    };

    var restore = ctx.restore;
    ctx.restore = function () {
        xform = savedTransforms.pop();
        return restore.call(ctx);
    };

    var scale = ctx.scale;
    ctx.scale = function (sx, sy) {
        xform = xform.scaleNonUniform(sx, sy);
        return scale.call(ctx, sx, sy);
    };

    var rotate = ctx.rotate;
    ctx.rotate = function (radians) {
        xform = xform.rotate(radians * 180 / Math.PI);
        return rotate.call(ctx, radians);
    };

    var translate = ctx.translate;
    ctx.translate = function (dx, dy) {
        xform = xform.translate(dx, dy);
        return translate.call(ctx, dx, dy);
    };

    var transform = ctx.transform;
    ctx.transform = function (a, b, c, d, e, f) {
        var m2 = svg.createSVGMatrix();
        m2.a = a; m2.b = b; m2.c = c; m2.d = d; m2.e = e; m2.f = f;
        xform = xform.multiply(m2);
        return transform.call(ctx, a, b, c, d, e, f);
    };

    var setTransform = ctx.setTransform;
    ctx.setTransform = function (a, b, c, d, e, f) {
        xform.a = a;
        xform.b = b;
        xform.c = c;
        xform.d = d;
        xform.e = e;
        xform.f = f;
        return setTransform.call(ctx, a, b, c, d, e, f);
    };

    var pt = svg.createSVGPoint();
    ctx.transformedPoint = function (x, y) {
        pt.x = x; pt.y = y;
        return pt.matrixTransform(xform.inverse());
    }
}

接下來,您需要能夠實際容納其中的內容。 我的函數假定您知道內容的絕對寬度和高度,您必須自己弄清楚這點,但應該相當簡單。 請注意,如果某些內容從-150開始並變為+150,則其寬度為300。

this.fitToContents = function (widthOfContents, heightOfContents) {

    var p1 = this.context.transformedPoint(0, 0);
    var p2 = this.context.transformedPoint(this.canvas.width, this.canvas.height);

    var centerX = (p2.x - p1.x) / 2;
    var centerY = (p2.y - p1.y) / 2;

    centerX -= widthOfContents / 2;
    centerY -= heightOfContents / 2;

    this.context.translate(centerX, centerY);

    var lastX = this.canvas.width / 2,
        lastY = this.canvas.height / 2;

    var scaleFactorX = this.canvas.width / widthOfContents;
    var scaleFactorY = this.canvas.height / heightOfContents;

    var scaleFactorToUse = Math.abs(scaleFactorX) < Math.abs(scaleFactorY) ? scaleFactorX : scaleFactorY;

    var pt = this.context.transformedPoint(lastX, lastY);
    this.context.translate(pt.x, pt.y);
    this.context.scale(scaleFactorToUse, scaleFactorToUse);
    this.context.translate(-pt.x, -pt.y);
}

放在一起看起來像這樣:

this.init = function (elementId) {
    this.canvas = document.getElementById(elementId);
    this.context = this.canvas.getContext('2d');

    this.trackTransforms(this.context);

    this.context.canvas.width = this.canvas.offsetWidth;
    this.context.canvas.height = this.canvas.offsetHeight;

    this.draw();
}

this.draw = function () {

    this.fitToContents(300,300);

    // you can now draw other stuff
    // you can probably only fit to contents once, 
    // in the init function, if their positions don't change
    this.drawStuff();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM