在画布中模拟div行为

时间:2013-12-18 10:16:17

标签: javascript html5 canvas html5-canvas

我有一个dom编辑器,用户可以插入文本框和图像。我的一个要求是将编辑器中的内容快照保存到图像中。我做了一些研究并且有一些解决方案,但它们似乎并非100%万无一失。我自己尝试过实现一个解决方案,在这里和那里破解代码:

function measureText(text, size, font) {
            var lDiv = document.createElement('lDiv');

            document.body.appendChild(lDiv);

            lDiv.style.fontSize = size;
            lDiv.style.fontFamily = font;
            lDiv.style.position = "absolute";
            lDiv.style.left = -1000;
            lDiv.style.top = -1000;

            lDiv.innerHTML = text;

                   var metrics = font.measureText(text, size.slice(0, size.length - 2));
                var lResult = {
                    width: lDiv.clientWidth,
                    height: metrics.height + lDiv.clientHeight
                };

                document.body.removeChild(lDiv);
                lDiv = null;


                return lResult;


        }

        function wrapText(context, item) {

            var words = item.text.split(' ');
            var line = '';
            var x = parseInt(item.x);
            var y = parseInt(item.y);
            var width = parseInt(item.width.slice(0, item.width.length - 2));
            var height = parseInt(item.height.slice(0, item.height.length - 2));
            var fontsize = parseInt(item.size.slice(0, item.size.length - 2));


            var font = new Font();

            font.onload = function () {
                context.save();

                context.beginPath();
                context.rect(x, y, width, height);
                context.clip();
                context.font = item.size + " " + item.font;
                context.textBaseline = "top";
                for (var n = 0; n < words.length; n++) {
                    var testLine = line + words[n] + ' ';

                    var metrics = measureText(testLine, item.size, font);
                    var testWidth = metrics.width;
                    if (testWidth > width && n > 0) {
                        console.log("Drawing '" + line + "' to " +  x + " " + y);

                        context.fillText(line, x, y);
                        line = words[n] + ' ';
                        y += metrics.height
                    }
                    else {
                        line = testLine;
                    }
                }

                context.fillText(line, x, y);
                context.restore();
            }

            font.fontFamily = item.font;
            font.src = font.fontFamily;


        }


        this.toImage = function () {
            console.log("testing");

            var canvas = document.getElementById("testcanvas");
            canvas.width = 400;
            canvas.height = 400;
            var ctx = canvas.getContext("2d");

            var imageObj = new Image();
            var thisService = this;
            imageObj.onload = function () {

                ctx.drawImage(imageObj, 0, 0, 400, 400);


                for (var i = 0; i < thisService.canvasItems.length; i++) {
                    var component = thisService.canvasItems[i];
                    if (component.type == "textbox") {
                        var x = component.x.slice(0, component.x.length - 2);
                        var y = component.y.slice(0, component.y.length - 2);
                        var w = component.width.slice(0, component.width.length - 2);
                        var h = component.height.slice(0, component.height.length - 2);

                        wrapText(ctx, component);



                    }
                }


            };


            imageObj.src = this.base.front_image;

        }

不知怎的,我相信我几乎是从screenshot

开始的

似乎存在一些定位/字体放置问题,仅低几个像素。顶部1是一个没有填充的div,(它的模型可以显示在左边的面板上),而底部的一个是画布。

我希望在这里有一对一的准确映射,任何人都可以启发可能存在的问题吗?

1 个答案:

答案 0 :(得分:0)

据我所知,由于明显的“安全”原因,无法将HTML绘制到画布中,并且准确率达到100%。

您仍然可以使用rasterizeHTML.js库非常接近。 它使用包含要呈现的内容的SVG图像。要绘制HTML内容,您需要使用包含HTML的元素,然后将该SVG图像绘制到画布中。