使用Two.js实现图像多边形点击拖动时遇TypeError问题求助
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

