Меню

Getcontext is not a function ошибка

Sometimes the TypeError: getContext is not a function in JavaScript error will appear when you use canvas to draw shapes, lines, or add motion to images on the web interface. So in this article, we will work with you to find the cause and how to fix the error. Read on for details. 

Why does the TypeError: getContext is not a function in JavaScript occur?

This error appears when you use the getContext() function to access a variable that is not an HTML5 canvas element. See the example below to understand the error better.

Index.html:

<body>
  <main id="app">
    <canvas class="canvas" width="450" height="200"></canvas>
  </main>
  <script src="main.js"></script>
</body>

Main.js:

// The getElementsByClassName() return a HTMLCollection
let canvas = document.getElementsByClassName("canvas");
console.log(canvas); // Output: HTMLCollection
let ctx = canvas.getContext("2d"); // Error here

Error:

Uncaught TypeError: canvas.getContext is not a function.

In the above example, getElementsByClassName() does not return a canvas object but an HTMLCollection object. That’s what caused the error.

Like the getElementsByClassName(), many functions do not return one element but many elements. For example: getElementsByTagName(), querySelectorAll(), and more… We should be careful when using them to get a canvas object.

So, how to fix the error?

Using the index of array

To correct the above example, we will use index 0 to access the first element of the HTMLCollection, which is also our canvas object.

// The getElementsByClassName() return a HTMLCollection
let canvases = document.getElementsByClassName("canvas");

// Use index 0 to get the canvas object
let canvas = canvases[0];
console.log(canvas); // Output: canvas object

// Use getContext() without error
let ctx = canvas.getContext("2d");

// BELOW IS AN EXAMPLE OF FILL GRADIENT FOR THE TEXT

// Set the font
ctx.font = "60px Verdana";

// Create the gradient object
let gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);

// Draw the gradient
gradient.addColorStop("0", " #0F2027");
gradient.addColorStop("0.5", " #203A43");
gradient.addColorStop("1", "#2C5364");

// Fill with gradient
ctx.fillStyle = gradient;
ctx.fillText("LearnShareIT", 20, 100);

Output:

Using getElementById()

We’ve written an article that uses the getElementById() syntax. You can read more if you want.

The best solution for this error is to use methods that only return 1 element, like getElementById(), querySelector(), and more. Here we only show how to use the getElementById() function to fix the problem. The same functions still return the same results.

Before writing JavaScript code, we must add the id attribute to the canvas tag. Like this:

<canvas id="my-canvas" class="canvas" width="450" height="200"></canvas>

In the js file, we need to use getElementById() instead of getElementsByClassName(), and that’s it.

// The getElementById() return a canvas object
let canvas = document.getElementById("my-canvas");
console.log(canvas); // Output: canvas object

// Use getContext() without error
let ctx = canvas.getContext("2d");

// BELOW IS AN EXAMPLE OF FILL GRADIENT FOR THE TEXT

// Set the font
ctx.font = "60px Verdana";

// Create the gradient object
let gradient = ctx.createLinearGradient(0, 0, canvas.width, 0);

// Draw the gradient
gradient.addColorStop("0", " #FC466B");
gradient.addColorStop("1", "#3F5EFB");

// Fill with gradient
ctx.fillStyle = gradient;
ctx.fillText("LearnShareIT", 20, 100);

Output:

Summary

In summary, the TypeError: getContext is not a function in JavaScript is a common error when using canvas. After reading this article, we hope you will not be confused when you see it again.

Have a lucky day!

Maybe you are interested:

  • TypeError: Cannot read property ‘filter’ of Undefined in JavaScript
  • “TypeError: toISOString is not a function” in JavaScript
  • TypeError: createPopper is not a function in Bootstrap

Lopez

Hi, I’m Cora Lopez. I have a passion for teaching programming languages such as Python, Java, Php, Javascript … I’m creating the free python course online. I hope this helps you in your learning journey.


Name of the university: HCMUE
Major: IT
Programming Languages: HTML/CSS/Javascript, PHP/sql/laravel, Python, Java

Вопрос:

Я встречаю ошибку, когда getContext не может быть вызван, хотя элемент является холстом.

var canvas = document.getElementById(id);
console.log(canvas, canvas.nodeName);
var ctx = canvas.getContext('2d');

Благодарю!

Фрагмент его работы изолирован, но не в скрипте

var canvas = document.getElementById( '0_0' );
document.write(canvas.getContext('2d'));
<g class="node" transform="translate(210,330)">
<canvas x="-8" y="-8" id="0_0"></canvas>
</g>
<canvas x=​"-8" y=​"-8" id=​"0_0">​ "canvas"
Uncaught TypeError: canvas.getContext is not a function
at Array.populateNodes (script.js:95)
at Array.Co.call (d3.v3.min.js:3)
at gen_graph (script.js:63)
at Object.success (main.js:16)
at i (jquery.min.js:2)
at Object.fireWith [as resolveWith] (jquery.min.js:2)
at A (jquery.min.js:4)
at XMLHttpRequest.<anonymous> (jquery.min.js:4)

Js, используя d3:

Извиняюсь за то, насколько плох мой JS может или нет, я для меня совершенно новый

Лучший ответ:

Я думаю, что элемент “canvas” рассматривается d3 как неизвестный элемент “canvas” из SVG. Таким образом, элемент “canvas” отображается не на HTMLCanvasElement, а на SVGUnknownElement в дереве документа, поэтому getContext() для SVGUnknownElement – это undefined.

Чтобы решить эту проблему, вы должны обернуть элемент “canvas” элементом foreignObject и добавить пространство имен xhtml к элементу “canvas”.

Я не очень хорош в d3, попробуйте построить эту структуру, используя d3.

<g class="node" transform="translate(210,330)">
  <foreignObject x="-8" y="-8">
    <canvas id="0_0" xmlns="http://www.w3.org/1999/xhtml"></canvas>
  </foreignObject>
</g>

Или используйте элемент изображения вместо элемента canvas, чтобы поместить изображение, созданное (html) элементом canvas.

Структура SVG

<g class="node" transform="translate(210,330)">
  <image x="-8" y="-8" id="0_0"/>
</g>

Javascript код

//create canvas element.
//var canvas = document.getElementById(nodes[i].__data__.name);
var canvas = document.createElement("canvas");
//console.log(canvas, canvas.nodeName);
var ctx = canvas.getContext('2d');

canvas.width = width;
canvas.height = height;

var idata = ctx.createImageData(width, height);
idata.data.set(buffer);
ctx.putImageData(idata, 0, 0);

//set image created by canvas to image element.
var image = document.getElementById(nodes[i].__data__.name);
image.width.baseVal.value = width;
image.height.baseVal.value = height;
image.href.baseVal = canvas.toDataURL();

Ответ №1

Я действительно получил что-то вроде этого, только сейчас, используя d3 v5. Я делаю это в машинописном тексте, так что мне потребовалось определиться.

Одна проблема заключается в том, что если вы просто добавляете элемент обычным способом d3 (selection.append()), вы получаете выделение более общего типа. Вы не можете просто исправить это с помощью кастинга. Что вам нужно сделать, это создать его в DOM, используя document.createElement(), а затем вызвать appendChild() для его размещения. Когда вы это сделаете, вы получите холст, имеющий тип HTMLCanvasElement.

Один трюк, который я не осознал, это то, что вы должны указать размеры как в foreignObject, так и в canvas, или это будет обрезано.

Я нахожусь в angular стране, так что это выглядит так

import * as d3 from 'd3';
...
private svg: d3.Selection<Element, any, any, any>
private canvasNode: HTMLCanvasElement

constructor(private root: ElementRef) {}

let foreigner = this.svg.append("foreignObject")
foreigner.attr("width", "800")
foreigner.attr("height", "600")

let canvas = document.createElement("canvas")
canvas.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')
canvas.textContent = 'Drawing canvas is not supported'

this.canvasNode = foreigner.node().appendChild(canvas)
this.canvasNode.setAttribute("width", "800")
this.canvasNode.setAttribute("height", "600")

Мой компонент реализует AfterViewInit, чтобы я мог отложить фактическое рисование (хотя это не обязательно делать):

ngAfterViewInit(): void {
let ctx: CanvasRenderingContext2D = this.canvasNode.getContext('2d')
this.draw(ctx)
}

Наконец, у вас есть кое-что, на что вы можете нарисовать:

draw(ctx: CanvasRenderingContext2D): void {
ctx.save()

ctx.strokeStyle = "#FF0000"
ctx.fillStyle = "#00FFFF"

ctx.moveTo(0,0)
ctx.lineTo(2000, 1000);
ctx.stroke();

ctx.restore()

console.log("drawn")
}

Я работаю с angular и d3 (в машинописном тексте) уже некоторое время. Иногда получить все правильные типы непросто, но оно того стоит.

Надеюсь, это кому-нибудь пригодится.

Учебное пособие по WebGL 1 — Как инициализировать WebGL за 11 минут

Я столкнулся с ошибкой, когда getContext не может быть вызван, даже если элемент является холстом.

var canvas = document.getElementById(id); console.log(canvas, canvas.nodeName); var ctx = canvas.getContext('2d'); 

Благодарность!

Фрагмент его работы изолированно, но не в скрипте

var canvas = document.getElementById( '0_0' ); document.write(canvas.getContext('2d'));
  
​ 'canvas' Uncaught TypeError: canvas.getContext is not a function at Array.populateNodes (script.js:95) at Array.Co.call (d3.v3.min.js:3) at gen_graph (script.js:63) at Object.success (main.js:16) at i (jquery.min.js:2) at Object.fireWith [as resolveWith] (jquery.min.js:2) at A (jquery.min.js:4) at XMLHttpRequest. (jquery.min.js:4) 

Js, используя d3:

Извиняюсь за то, насколько плохим мой JS может быть или нет, я новичок в этом

  • Разместите здесь вывод своей консоли. Не ссылайтесь на изображения на SO.
  • @jmargolisvt Я не думаю, что он может публиковать изображения напрямую с такой низкой репутацией. И я думаю, что размещение вывода в виде текста будет трудом!
  • Вы используете jQuery для получения элемента холста? Или вы используете getElementById?
  • @ibrahimmahrir я использую getElementById, однако использование jQ дало тот же результат
  • Вы можете опубликовать все script.js?

Я думаю, что элемент «холст» обрабатывается d3 как неизвестный элемент «холст» в SVG. Таким образом, элемент «холст» не отображается на HTMLCanvasElement но SVGUnknownElement в domtree документа, таким образом getContext() из SVGUnknownElement является undefined.

Чтобы решить эту проблему, вы должны обернуть элемент «холст» foreignObject элемент и добавить xhtml пространство имен к элементу «холст».

Я плохо разбираюсь в d3, пожалуйста, попробуйте построить эту структуру, используя d3.

     

Или используйте элемент изображения вместо элемента «холст», чтобы поместить изображение, созданное элементом холста (html).

Структура SVG

   

Код Javascript

//create canvas element. //var canvas = document.getElementById(nodes[i].__data__.name); var canvas = document.createElement('canvas'); //console.log(canvas, canvas.nodeName); var ctx = canvas.getContext('2d'); canvas.width = width; canvas.height = height; var idata = ctx.createImageData(width, height); idata.data.set(buffer); ctx.putImageData(idata, 0, 0); //set image created by canvas to image element. var image = document.getElementById(nodes[i].__data__.name); image.width.baseVal.value = width; image.height.baseVal.value = height; image.href.baseVal = canvas.toDataURL(); 
  • Привет, большое спасибо за ваше сообщение, первый метод дал ту же ошибку. Как вы упомянули, используя тег изображения вместо холста, как бы я это сделал? Я беру массив значений RGB для изображения, которое затем будет отображаться.
  • Вы можете получить изображение холста, вызвав метод toDataURL, и установить созданный им URL-адрес для элемента изображения.
  • Большое спасибо за вашу помощь, я бы проголосовал за вас, но у меня недостаточно высокая репутация.

В D3.js очень важно создать элемент холста в правильном пространстве имен, используя .create('xhtml:canvas') или .append('xhtml:canvas'). В xmlns Приятно иметь атрибут, но он игнорируется большинством современных браузеров HTML5.

Вот полный пример D3.js:

const svg = d3.select('body').append('svg') .style('width', '100%') .style('height', '100%'); const group = svg.append('g') .attr('class', 'node') .attr('transform', 'translate(10,10)'); const foreignObject = group.append('foreignObject') .attr('width', 100) .attr('height', 100); const canvas = foreignObject.append('xhtml:canvas') .attr('xmlns', 'http://www.w3.org/1999/xhtml'); const context = canvas.node().getContext('2d'); console.log(canvas.node().constructor.name); // => HTMLCanvasElement // Draw something context.fillStyle = 'blue'; context.fillRect(0, 0, 100, 100);
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js'></script>

Понятие пространств имен нелегко понять, и в большинстве случаев вам не нужно явно их устанавливать, поскольку они наследуются от родительского элемента. Майк Босток довольно хорошо объясняет эту концепцию в этом выпуске Github.

(Да, я открыл проблему, и она тоже не знала, как использовать пространства имен.)

У меня сейчас что-то вроде этого работает, используя d3 v5. Я делаю это в машинописном тексте, поэтому потребовалось некоторое время.

Одна из проблем заключается в том, что если вы просто добавите элемент обычным способом d3 (selection.append ()), вы получите выбор более общего типа. Вы не можете просто исправить это с помощью кастинга. Вам нужно создать его в DOM с помощью document.createElement (), а затем вызвать appendChild (), чтобы разместить его. Когда вы это сделаете, вы получите холст типа HTMLCanvasElement.

Одна уловка, которую я не осознавал, заключается в том, что вы должны указать размеры как в foreignObject, так и в холсте, иначе он будет обрезан.

Я нахожусь на угловой земле, поэтому это выглядит так

import * as d3 from 'd3'; ... private svg: d3.Selection private canvasNode: HTMLCanvasElement constructor(private root: ElementRef) {} let foreigner = this.svg.append('foreignObject') foreigner.attr('width', '800') foreigner.attr('height', '600') let canvas = document.createElement('canvas') canvas.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml') canvas.textContent = 'Drawing canvas is not supported' this.canvasNode = foreigner.node().appendChild(canvas) this.canvasNode.setAttribute('width', '800') this.canvasNode.setAttribute('height', '600') 

Мой компонент реализует AfterViewInit, чтобы я мог отложить фактическое рисование (хотя вам необязательно это делать):

ngAfterViewInit(): void { let ctx: CanvasRenderingContext2D = this.canvasNode.getContext('2d') this.draw(ctx) } 

Наконец, у вас есть кое-что, на что вы можете опираться:

draw(ctx: CanvasRenderingContext2D): void { ctx.save() ctx.strokeStyle = '#FF0000' ctx.fillStyle = '#00FFFF' ctx.moveTo(0,0) ctx.lineTo(2000, 1000); ctx.stroke(); ctx.restore() console.log('drawn') } 

Я уже некоторое время работаю с angular и d3 (в машинописном тексте). Иногда получить все типы правильно непросто, но это того стоит.

Надеюсь, это кому-то поможет.

Tweet

Share

Link

Plus

Send

Send

Pin

На чтение 3 мин. Просмотров 21 Опубликовано 15.12.2019

I’m working on making a basic web application using canvas that dynamically changes the canvas size when the window resizes. I’ve gotten it to work statically without any flaws but when I create an object to make it dynamically it throws an error

in chrome the error is:

Uncaught TypeError: Object [object Object] has no method ‘getContext’

and in firefox it is:

this.element.getContext is not a function

I’ve searched the web and it seems like a common problem but none of the fixes mentioned make any difference.

Я пытаюсь анимировать шар, который следует за курсором в Javascript, используя элемент canvas. Я передать ссылку на мой объект холста функции с именем followMouse, но когда я пытаюсь получить его контекст, поджигатель дает мне эту ошибку:

TypeError: canvas.getContext is not a function

Когда я вхожу ссылку холст на консоль, он отображает холст элемент. Я не знаю, почему тогда я не могу получить контекст в функции. Кто-нибудь знает, что происходит?

ли элемент с идентификатором ‘main’ действительно холст элемент? Помните, что идентификаторы должны быть уникальными. – Felix Kling 17 окт. 12 2012-10-17 20:23:20

Да, это так. Как я уже сказал, он отображается в консоли при регистрации. – SheedySheedySheedy 17 окт. 12 2012-10-17 20:26:33

Ваше использование window.requestAnimFrame странно. Разве вы не должны устанавливать обратный вызов? Если вы настроили обратный вызов, уверены ли вы, что он предоставляет canvas в качестве первого аргумента? – Denys Séguret 17 окт. 12 2012-10-17 20:28:46

@dystroy Не ‘followMouse’ обратный вызов? – Kendall Frey 17 окт. 12 2012-10-17 20:30:43

@dystoy Действительно: обратный вызов window.requestAnimationFrame [предоставляется временная метка числа] (https://developer.mozilla.org/en-US/docs/DOM/window.requestAnimationFrame#Notes) в качестве первого аргумента. – apsillers 17 окт. 12 2012-10-17 20:33:33

1 ответ

Ваша линия window.requestAnimFrame(followMouse, canvas); называет followMouse(timestamp) , где метка времени является число передается функции обратного вызова, когда он уволен requestAnimationFrame . Это приводит к вызову timestamp.getContext , что явно недействительно.

Вместо этого обернуть вызов внутри анонимной функции:

Создан 17 окт. 12 2012-10-17 20:30:32 apsillers

Это избавляет от ошибки. Благодарю. – SheedySheedySheedy 17 окт. 12 2012-10-17 20:37:06

Сисадмин, программист, делюсь опытом

Проблема «getContext is not a function» наблюдается, если canvas создаётся динамически, или просто сразу не имеет id, когда хотим получить от него getContext (2d).

Рабочее решение при использовании jQuery:

Здесь SomeClass — класс, присвоенный canvas без id, всё отработает без ошибок

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Get contact ошибка 5003 как исправить
  • Get contact ошибка 5001 как избавиться