You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Two.js实现图像多边形点击拖动时遇TypeError问题求助

Troubleshooting "TypeError: Cannot read property 'elem' of undefined" in AngularJS + Two.js Polygon Drag

Hey there, let's break down this error you're facing when trying to add drag functionality to your Two.js polygons in AngularJS. This error almost always means you're trying to access the elem property of an object that's undefined—so let's track down why that's happening and fix it.

1. Fix Scope/Lifetime Issues for Two.js Instances & Polygons

Chances are, your two instance or polygon object is only defined inside the DrawPolygon function, so when you try to access it later during drag events, it's already out of scope or destroyed.

Fix: Store your Two.js instances and polygons in a persistent scope (like $scope) so they're accessible when drag events fire:

// Initialize a storage object in your controller to track instances by camera ID
$scope.twoInstances = {};

$scope.DrawPolygon = function (id, json) {
  var elem = document.getElementById('ImgCamera' + id);
  if (elem != null) {
    elem.innerHTML = "";
    var two = new Two({
      type: Two.Types.canvas,
      fullscreen: false,
      width: 640,
      height: 480,
    }).appendTo(elem);
    
    // Store the Two.js instance and polygon in the scope storage
    $scope.twoInstances[id] = {
      two: two,
      polygon: null // We'll set this when creating the polygon
    };

    // ... Your existing code to create the polygon
    var polygon = two.makePolygon(/* your polygon coordinates */);
    $scope.twoInstances[id].polygon = polygon;

    // Now bind drag events using the stored instance
    bindDragEvents(id);
  }
};

function bindDragEvents(id) {
  var instance = $scope.twoInstances[id];
  if (!instance || !instance.polygon) return;

  var polygonElem = instance.polygon._renderer.elem;
  polygonElem.addEventListener('mousedown', function(e) {
    // Your drag start logic here—you can safely access instance.two and instance.polygon
  });
}

2. Ensure Event Binding Happens After Polygon Creation

If you're binding drag events before the polygon is fully rendered by Two.js, you might be trying to access an elem property that doesn't exist yet.

Fix: Always bind drag events right after creating the polygon (like in the example above), or use Two.js's render event to ensure the element exists:

instance.two.bind('render', function() {
  if (!instance.polygon._renderer.elem) return;
  // Bind events once the polygon's DOM element is ready
  instance.polygon._renderer.elem.addEventListener('mousedown', onDragStart);
  // Unbind the render event after setup to avoid duplicates
  instance.two.unbind('render', arguments.callee);
});

3. Handle AngularJS's Digest Cycle for Dynamic DOM

If your ImgCamera elements are generated dynamically (e.g., with ng-repeat), document.getElementById might return null if you call DrawPolygon before Angular finishes rendering the DOM.

Fix: Use $timeout to delay execution until Angular's digest cycle completes:

$scope.DrawPolygon = function (id, json) {
  $timeout(function() {
    var elem = document.getElementById('ImgCamera' + id);
    // Rest of your DrawPolygon code here
  }, 0);
};

This ensures the DOM element exists before you try to initialize Two.js on it.

4. Debug to Pinpoint the Undefined Object

If you're still stuck, add console logs to identify exactly which object is undefined when the error hits. For example, in your drag event handler:

function onDragStart(e) {
  console.log('Current polygon object:', this); // Check if the polygon is defined
  console.log('Renderer object:', this._renderer); // Check if the renderer exists
}

The console output will tell you exactly where the chain breaks—whether it's the polygon itself, the renderer, or something else.


内容的提问来源于stack exchange,提问作者sani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:35:36