javascript - otherwise - Uso de Adobe Edge Animate con AngularJS y Router AngularUI
ui view angular js (1)
Estoy trabajando en un proyecto en este momento que incorporará múltiples animaciones creadas con Adobe Edge Animate en una única aplicación AngularJS. La idea es que estas animaciones actúen como imágenes para un juego y controlaré la composición en función de la información del jugador. Se requiere algo de experimentación para llegar a esta etapa, pero todo eso está funcionando perfectamente.
Mis problemas comienzan cada vez que el jugador elige salir de la vista actual y acceder a ella por segunda vez. Por alguna razón, esto causa un problema con la API Adobe Edge Animate Javascript y la composición no se carga.
Esencialmente, puedo cargar una composición una vez pero no más. Cada vez que intento cargar la composición por segunda vez obtengo los siguientes errores de Javascript ...
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
Actualmente estoy cargando la composición directamente desde el controlador de la siguiente manera ...
.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: [ ]});
})
También he desactivado el almacenamiento en caché para este estado ...
.state(''game-test'', {
cache: false,
url: "/games/test",
controller: ''GameTest'',
templateUrl: ''templates/games/test.html''
})
Todas las sugerencias son bienvenidas y agradezco cualquier ayuda!
Gracias
Actualización: ¡he encontrado una solución! Ojalá...
El problema parece resolverse si el navegador maneja los contenidos del * _edge.js relevante de nuevo. Dado que estos se inyectan en <head>
cada vez que se AdobeEdge.loadComposition(...)
(a través de yepnope), y no parece haber ningún método para pedirle a yepnope que vuelva a cargar el Javascript inyectado, he escrito un pequeño servicio para Angular que puedo usar para manejar esto en lugar de la función estándar AdobeEdge.loadComposition(...)
. Es esencialmente un contenedor que hará los controles pertinentes de antemano.
.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]);
// Let''s also delete the composition within the Adobe Edge API so that events
// like ''compositionReady'' are fired again when we call loadComposition()
delete AdobeEdge.compositions[compId];
}
});
// Ultimately we always need to call loadComposition() no matter what
AdobeEdge.loadComposition(projectPrefix, compId, opts, preloaderDOM, downLevelStageDOM);
}
}
})
Usando este método, puedo invocar este servicio en los controladores relevantes y cargar una composición de una manera similar a la normal. En este caso particular ...
.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: [ ]});
});
¡Hasta ahora ha estado funcionando genial! Lo usaré para construir el resto de los juegos en nuestro proyecto y publicar cualquier problema que encuentre.
¡Ojalá esto le ahorre a alguien más mucho dolor!
Respuesta de Rob Sinton :
El problema parece resolverse si el navegador maneja los contenidos del * _edge.js relevante de nuevo. Dado que estos se inyectan en <head>
cada vez que se AdobeEdge.loadComposition(...)
(a través de yepnope), y no parece haber ningún método para pedirle a yepnope que vuelva a cargar el Javascript inyectado, he escrito un pequeño servicio para Angular que puedo usar para manejar esto en lugar de la función estándar AdobeEdge.loadComposition(...)
. Es esencialmente un contenedor que hará los controles pertinentes de antemano.
.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]);
// Let''s also delete the composition within the Adobe Edge API so that events
// like ''compositionReady'' are fired again when we call loadComposition()
delete AdobeEdge.compositions[compId];
}
});
// Ultimately we always need to call loadComposition() no matter what
AdobeEdge.loadComposition(projectPrefix, compId, opts, preloaderDOM, downLevelStageDOM);
}
}
})
Usando este método, puedo invocar este servicio en los controladores relevantes y cargar una composición de una manera similar a la normal. En este caso particular ...
.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: [ ]});
});
¡Hasta ahora ha estado funcionando genial! Lo usaré para construir el resto de los juegos en nuestro proyecto y publicar cualquier problema que encuentre.
¡Ojalá esto le ahorre a alguien más mucho dolor!