Currently, I'm in the process of integrating multiple animations created using Adobe Edge Animate into a single AngularJS application for a project. These animations will serve as the visual elements for a game, with player input controlling the composition. After some trial and error, I've successfully reached this stage.
However, my challenges arise when a player exits the current view and tries to access it again. This seems to trigger an issue with the Adobe Edge Animate Javascript API, causing the composition to fail loading.
In essence, I can load the composition once, but subsequent attempts result in the following Javascript errors...
Uncaught TypeError: Cannot read property 'stage' of undefined edge.5.0.1.js:4872
Uncaught TypeError: Cannot read property 'stage' of undefined edge.5.0.1.js:4519
The composition is currently loaded directly within the controller like so...
.controller('GameTest', function($scope, $state) {
AdobeEdge.loadComposition('edge-animate/GameTest', 'GameTest', {
scaleToFit: "width",
centerStage: "none",
minW: "0",
maxW: "undefined",
width: "2048px",
height: "1134px"
}, {dom: [ ]}, {dom: [ ]});
})
I have also disabled caching for this state...
.state('game-test', {
cache: false,
url: "/games/test",
controller: 'GameTest',
templateUrl: 'templates/games/test.html'
})
Any suggestions or assistance are greatly appreciated!
Thank you
Update: I may have found a solution!
The issue appears to be resolved when the browser reprocesses the contents of the relevant *_edge.js file. Since these files are injected into the <head>
whenever AdobeEdge.loadComposition(...)
is called (via yepnope), and there is no way to force yepnope to reload injected Javascript, I have developed a small Angular service that handles this instead of the standard AdobeEdge.loadComposition(...)
function. It serves as a wrapper that performs necessary checks before execution.
.service('$AdobeEdge', function() {
var head = document.getElementsByTagName('head')[0],
scripts = head.getElementsByTagName('script');
return {
loadComposition: function(projectPrefix, compId, opts, preloaderDOM, downLevelStageDOM) {
// Determine the filename for our project
var projectFile = projectPrefix + '_edge.js';
var newScript = null;
// Iterate through each script tag in the header to search for our file
angular.forEach(scripts, function(script, index, scripts) {
// Does the script src tag end with our project filename?
if (script.src.substr(script.src.length - projectFile.length) == projectFile) {
// It's already loaded! Let's go about removing it and injecting a fresh script tag...
script.remove();
newScript = document.createElement('script');
newScript.setAttribute('type', 'text/javascript');
newScript.setAttribute('src', script.src);
head.insertBefore(newScript, scripts[0]);
// Also delete the composition within the Adobe Edge API to ensure events like 'compositionReady' fire again when we call loadComposition()
delete AdobeEdge.compositions[compId];
}
});
// Regardless, always call loadComposition()
AdobeEdge.loadComposition(projectPrefix, compId, opts, preloaderDOM, downLevelStageDOM);
}
}
})
With this approach, I can simply use this service in the respective controllers to load a composition similarly to before. For instance...
.controller('GameTest', function($scope, $state, $AdobeEdge) {
$AdobeEdge.loadComposition('edge-animate/GameTest', 'GameTest', {
scaleToFit: "width",
centerStage: "none",
minW: "0",
maxW: "undefined",
width: "2048px",
height: "1134px"
}, {dom: [ ]}, {dom: [ ]});
});
Thus far, this method has been successful! I intend to utilize it for other games in our project and will share any issues encountered along the way.
Hopes this spares others from similar frustrations!