Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught DOMException: Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The canvas width is 0. #1

Open
codeback opened this issue Jul 28, 2017 · 10 comments

Comments

@codeback
Copy link

I'm getting the following error when I'm running 'tns run android | timeline-view':

Uncaught DOMException: Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The canvas width is 0.
    at redrawBackground (file:///home/miguel/workspace/swipe/hoppin-app/nativescript/times.html:163:32)
    at file:///home/miguel/workspace/swipe/hoppin-app/nativescript/times.html:265:1

Here is the generated html file:

<!DOCTYPE html>
<html>
<head>
<title>Profiling</title>
<style>
* {
    margin: 0px;
    padding: 0px;
    overflow: hidden;

    -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
    -khtml-user-select: none; /* Konqueror HTML */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* Internet Explorer/Edge */
    user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */
}

.trace {
    position: absolute;
    border: 1px solid black;
    border-radius: 5px;
    overflow: hidden;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    background-color: #DDD;
    cursor: default;
    line-height: 20px;
    height: 20px;
    text-align: center;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.trace.Modules {
    background-color: #BFF;
}
.trace.Runtime {
    background-color: #FFB;
}
.trace:hover {
    background-color: #FFF;
    border-color: orange;
    z-index: 1;
    box-shadow: 0px 1px 5px black;
}

</style>
</head>
<body>
  <script>
var timeline = [{"from":null,"to":null,"name":"ALL"}];
function orderStackTraces(traces) {
    traces = traces.slice(0).sort(function (a, b) {
        if (a.from < b.from) {
            return -1;
        }
        else if (a.from === b.from) {
            if (a.to > b.to) {
                return -1;
            }
            else if (a.to === b.to) {
                return 0;
            }
            else {
                return 1;
            }
        }
        else {
            return 1;
        }
    });
    var depthTo = [];
    var stackedTraces = traces.map(function (_a) {
        var from = _a.from, to = _a.to, name = _a.name, domain = _a.domain;
        var depth;
        for (var i = 0; i <= depthTo.length; i++) {
            if (depthTo[i] === undefined || depthTo[i] <= from) {
                depth = i;
                depthTo[i] = to;
                break;
            }
        }
        return { from: from, to: to, name: name, domain: domain, depth: depth };
    });
    return stackedTraces;
}
var stackTraces = orderStackTraces(timeline);
var min = stackTraces.reduce(function (min, trace) { return Math.min(min, trace.from); }, Number.POSITIVE_INFINITY);
var max = stackTraces.reduce(function (max, trace) { return Math.max(max, trace.to); }, Number.NEGATIVE_INFINITY);
var left = min;
var pixelPerMs = 0.1;
var stackTraceDivs = [];
function createStackTraces() {
    stackTraces.forEach(function (trace) {
        var div = document.createElement('div');
        div.className = "trace " + trace.domain;
        traces.appendChild(div);
        div.innerText = trace.name + " " + Math.round(trace.to - trace.from) + "ms";
        div.title = trace.name + " " + (trace.to - trace.from) + "ms";
        div.trace = trace;
        stackTraceDivs.push(div);
        div.addEventListener("click", focusTrace);
    });
}
function updateStackTraces() {
    var right = left + (window.innerWidth / pixelPerMs);
    stackTraceDivs.forEach(function (div) {
        var trace = div.trace;
        var leftPx = (trace.from - left) * pixelPerMs;
        var rightPx = window.innerWidth - (trace.to - left) * pixelPerMs;
        div.style.left = Math.max(-5, leftPx) + "px";
        div.style.top = 30 + trace.depth * 21 + "px";
        div.style.right = Math.max(-5, rightPx) + "px";
    });
}
function snap(px) {
    return Math.floor(px) + 0.5;
}
var background = document.createElement('canvas');
var context = background.getContext("2d");
var rulerBackgroundPattern = document.createElement('canvas');
var rulerBackgroundPatternContext = rulerBackgroundPattern.getContext("2d");
var timelineBackgroundPattern = document.createElement('canvas');
var timelineBackgroundPatternContext = timelineBackgroundPattern.getContext("2d");
function redrawBackground() {
    rulerBackgroundPatternContext.fillStyle = "#DDD";
    rulerBackgroundPatternContext.fillRect(0, 0, rulerBackgroundPattern.width, rulerBackgroundPattern.height);
    timelineBackgroundPatternContext.fillStyle = "#FFF";
    timelineBackgroundPatternContext.fillRect(0, 0, timelineBackgroundPattern.width, timelineBackgroundPattern.height);
    rulerBackgroundPatternContext.lineWidth = 1;
    rulerBackgroundPatternContext.strokeStyle = "#BBB";
    rulerBackgroundPatternContext.beginPath();
    rulerBackgroundPatternContext.moveTo(snap(0), 0);
    rulerBackgroundPatternContext.lineTo(snap(0), rulerBackgroundPattern.height);
    rulerBackgroundPatternContext.stroke();
    timelineBackgroundPatternContext.lineWidth = 1;
    timelineBackgroundPatternContext.strokeStyle = "#EEE";
    timelineBackgroundPatternContext.beginPath();
    timelineBackgroundPatternContext.moveTo(snap(0), 0);
    timelineBackgroundPatternContext.lineTo(snap(0), timelineBackgroundPattern.height);
    timelineBackgroundPatternContext.stroke();
    // timeline horizontal lines
    timelineBackgroundPatternContext.lineWidth = 1;
    timelineBackgroundPatternContext.strokeStyle = "#EEE";
    timelineBackgroundPatternContext.beginPath();
    timelineBackgroundPatternContext.moveTo(0, snap(timelineBackgroundPattern.height - 1));
    timelineBackgroundPatternContext.lineTo(timelineBackgroundPattern.width, snap(timelineBackgroundPattern.height - 1));
    timelineBackgroundPatternContext.stroke();
    rulerBackgroundPatternContext.strokeStyle = "#CCC";
    timelineBackgroundPatternContext.strokeStyle = "#EEE";
    for (var i = 1; i < 10; i++) {
        var x = rulerBackgroundPattern.width / 1000 * i * 100;
        rulerBackgroundPatternContext.beginPath();
        rulerBackgroundPatternContext.moveTo(snap(x), rulerBackgroundPattern.height - rulerBackgroundPattern.height * 0.25);
        rulerBackgroundPatternContext.lineTo(snap(x), rulerBackgroundPattern.height);
        rulerBackgroundPatternContext.stroke();
        timelineBackgroundPatternContext.beginPath();
        timelineBackgroundPatternContext.moveTo(snap(x), 0);
        timelineBackgroundPatternContext.lineTo(snap(x), timelineBackgroundPattern.height);
        timelineBackgroundPatternContext.stroke();
    }
    var rulerOffset = -Math.round((left - Math.floor(left / 1000) * 1000) * pixelPerMs);
    var rulerPattern = context.createPattern(rulerBackgroundPattern, "repeat");
    context.fillStyle = rulerPattern;
    context.translate(rulerOffset, 0);
    context.fillRect(-rulerOffset, 0, background.width, 30);
    context.translate(-rulerOffset, 0);
    var timelinePattern = context.createPattern(timelineBackgroundPattern, "repeat");
    context.fillStyle = timelinePattern;
    context.translate(rulerOffset, 31);
    context.fillRect(-rulerOffset, 0, background.width, background.height - 30);
    context.translate(-rulerOffset, -31);
    // Separators
    context.lineWidth = 1;
    context.strokeStyle = "#666";
    context.beginPath();
    context.moveTo(0, snap(30));
    context.lineTo(background.width, snap(30));
    context.stroke();
}
function resize() {
    background.width = window.innerWidth;
    background.height = window.innerHeight;
}
function resizeRulers() {
    // Lets try major rules on seconds and minor rules on 100ms.
    var width = 1000 * pixelPerMs;
    rulerBackgroundPattern.width = width;
    rulerBackgroundPattern.height = 30;
    timelineBackgroundPattern.width = width;
    timelineBackgroundPattern.height = 21;
}
function clampViewPort() {
    pixelPerMs = Math.max(window.innerWidth / (max - min), pixelPerMs);
    left = Math.min(Math.max(min, left), max - window.innerWidth / pixelPerMs);
}
var chart = document.createElement('div');
chart.id = "chart";
chart.appendChild(background);
var traces = document.createElement('div');
traces.id = "traces";
chart.appendChild(traces);
document.body.appendChild(chart);
function focusTrace(ev) {
    if (suspendClicks) {
        return;
    }
    var trace = this.trace;
    pixelPerMs = window.innerWidth / (trace.to - trace.from);
    left = trace.from;
    clampViewPort();
    resizeRulers();
    redrawBackground();
    updateStackTraces();
}
window.addEventListener("resize", function () {
    resize();
    resizeRulers();
    clampViewPort();
    updateStackTraces();
    redrawBackground();
});
window.addEventListener("mousewheel", function (e) {
    var mousePoint = left + e.clientX / pixelPerMs;
    pixelPerMs = Math.pow(2, Math.log2(pixelPerMs) + Math.max(-0.25, Math.min(0.25, e.wheelDelta)));
    left = mousePoint - e.clientX / pixelPerMs;
    clampViewPort();
    resizeRulers();
    redrawBackground();
    updateStackTraces();
});
var dragging = false;
var suspendClicks = false;
var mouseDown = false;
var dragOriginXms; // The millisecond at which the chart was grabbed
var dragOriginXpx;
window.addEventListener("mousedown", function (e) {
    dragOriginXms = left + e.clientX / pixelPerMs;
    dragOriginXpx = e.clientX;
    mouseDown = true;
}, true);
window.addEventListener("mouseup", function (e) {
    if (dragging) {
        dragging = false;
        // Cant find a way to prevent the click action
        suspendClicks = true;
        setTimeout(function () { return suspendClicks = false; }, 1);
    }
    mouseDown = false;
});
window.addEventListener("mousemove", function (e) {
    if (mouseDown && !dragging && Math.abs(e.clientX - dragOriginXpx) > 8) {
        dragging = true;
    }
    if (dragging) {
        left = dragOriginXms - e.clientX / pixelPerMs;
        clampViewPort();
        redrawBackground();
        updateStackTraces();
    }
});
clampViewPort();
resize();
resizeRulers();
redrawBackground();
createStackTraces();
updateStackTraces();

  </script>
</body>
</html>

Thanks in advance.

@codeback
Copy link
Author

Sorry, my fault. I've write the line "profiling": "timeline" in the wrong package.json.

@PanayotCankov
Copy link
Owner

PanayotCankov commented Jul 28, 2017

It's a valid issue, if the tool finds no output, it shouldn't fail.

The resolution for now is:

Put the "profiling": "timeline" in the app/package.json instead the package.json.

@dbenninger
Copy link

dbenninger commented Nov 6, 2017

I get the same error message in the browser, but the output seems to be in the html page.

The problem is reproducible with NS 3.3:

  1. tns create TimelineTest --template ng
  2. cd TimelineTest/
  3. vi app/package.json and add "profiling": "timeline"
  4. tns run android | timeline-view
  5. Ctrl-C after the app has started and open the file in the browser (tested with latest Chrome, FF and Safari)

When running the app, I can see many "Timeline: ..." statements and looking at the html, the variable timeline seems to contain the output.

@buuhuu
Copy link

buuhuu commented Dec 4, 2017

The issue is caused by: https://github.com/PanayotCankov/timeline-view/blob/master/chart.ts#L257
for really small values width is rounded to 0 which causes the error.

@aboganas
Copy link

aboganas commented Dec 8, 2017

I'm also facing the same issue

@aboganas
Copy link

@PanayotCankov I see all the outputs in my html page, however, I still get the same error Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The canvas width is 0.

this only happens in some apps, while it works fine in other apps I tried it on.

I tried to change pixelPerMs but still no luck, any ideas?

@HunterJS-bit
Copy link

You can change pixelPerMs to 1 it should work then.

@mrazahasan
Copy link

mrazahasan commented Jan 4, 2018

Could you please tell which of the version is running fine? I have tested 0.0.5 & 0.0.6. None of them working. getting the same error

Uncaught DOMException: Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The canvas width is 0.

It has been opened since July. is it actively maintained or are there any alternate packages?

@mm-psymbl
Copy link

Bump for this old thread. it is still an issue today. any chance for a fix?

@CoolHenry
Copy link

are you sure this is what's this question of html2canvas? my quesion is appear in html2canvans

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants