Reactãšçµ±åãããã¢ããªãæ§ç¯ããŠããŸãããã®ã¢ããªã¯ãpixi.jsãthree.jsãªã©ãããã€ãã®åå¥ã®å®éšãèªã¿èŸŒã¿ãŸããiframeã䜿çšããŠå®éšãèªã¿èŸŒãããšãã§ããªããããèªåã§ã¯ãªãŒã³ã¢ããããå¿ èŠããããŸãã
æ°ããå®éšãžã®ããã²ãŒã·ã§ã³ããããã³ã«ãã¬ã³ãã©ãŒãååšãããã©ããã確èªããååšããå Žåã¯ç Žæ£ããŸãïŒã
ãããŒã³ãŒã
if renderer
renderer.destroy(true);
renderer = null
renderer = new PIXI.autoDetectRenderer ......
webglã¬ã³ãã©ãŒãæ£ããã¯ãªãŒãã³ã°ããŠããããã§ããã16ããŒãžãèªã¿èŸŒãŸãããšã WARNING: Too many active WebGL contexts. Oldest context will be lost.
ãšããèŠåã衚瀺ãããŸããèŠåãããªãããããã¹ã¯ãããã§ã¯åé¡ã«ãªããŸããããiPadã§ã¯ã¯ã©ãã·ã¥ããŸãããã©ãŠã¶ãšã¡ãã»ãŒãžã衚瀺ãããŸãïŒ X A problem occurred with this web page, so it was reloaded.
ã
ç§ã¯threejsãšãããããããã«å¯Ÿãããœãªã¥ãŒã·ã§ã³ãã©ã®ããã«å®è£ ããããèŠãŠããŸããããããŠåœŒãã¯æ¬¡ã®ã³ãŒããæã£ãŠã
ç§ã¯æããªããšãããŠããŸããïŒ
@andrevenancio
ãã ããæææ¥ãŸãã¯ç«ææ¥ãããã䜿çšããŠããªããããPixiã®å°é家ã§ã¯ãããŸããã äžåºŠã«1ã€ã ãã«ã¢ã¯ã»ã¹ããå¿
èŠããããšããèãã§ãå€ãã®å®éšïŒãã®ãããªïŒã®ããã«è€æ°ã®ã¬ã³ãã©ãŒãšãã£ã³ãã¹ãããå Žåã¯ãã°ããŒãã«ã¬ã³ãã©ãŒãŸãã¯å¥ã®ã¬ã³ãã©ãŒã䜿çšããŠãå®éšãé
åã«ä¿æããŸãã 次ã«ãããã衚瀺ããå¿
èŠãããå Žåã¯ãåå®éšã®ã¹ããŒãžãã¬ã³ãã©ãŒã«æž¡ãã ãã§ãã
var renderer = PIXI.autoDetectRenderer({blah});
var experiments = [];
experiments.push(experiment1);
experiments.push(experiment2);
experiments.push(experiment3);
var currentExperiment = $('#experminetSelector').val();
renderer.render(experiments[currentExperiment]);
ãã®ããã«ããŠãã¬ã³ãã©ãŒã1åã ãäœæããåå®éšã®ã¹ããŒãžã«æž¡ãã ãã§ãã ãã ããããã¯ãå€ãã®ç°ãªãå®éšããŒãžãçšæããã®ã§ã¯ãªãã1ã€ã®ããŒãžã®ã¿ãã¬ã³ããªã³ã°ããŠããã¹ãŠã®å®éšãå®è¡ããããšããŠããå Žåã«ã®ã¿æ©èœããŸãã
å 責äºé ïŒç§ã¯pixiãåããŠäœ¿çšããŸããããããè©ŠããŠããŸããããã€ã¬ãŒãžã¯ç°ãªãå ŽåããããŸãã ãŸããéçºè ã調æ»ããããã¬ã€ãã³ã¹ãæäŸããããããããªãã°ãèŠã€ããããã«ãèãããŸãã
åäžã®ã¬ã³ãã©ãŒãšè€æ°ã®ã·ãŒã³ãããã°åé¡ãããŸããã 1ã€ã®ã¬ã³ãã©ãŒ=== 1ã€ã®ãã£ã³ãã¹èŠçŽ ã
çããããã£ãŒãããã¯ãããããšãããããŸãã @samuraiskirtããªããææ¡ããŠããããšã¯ãŸã£ããã°ãããããšã§ã¯ãªãããããç§ãéåžž1ã€ã®ãã¬ãŒã ã¯ãŒã¯ã§ããã€ãã®å®éšãè¡ãæ¹æ³ã§ã...ããããå®éšã¯pixi.js
ã䜿çšããŠè¡ãããšãã§ããã®ã§ãå¥ã®è§£æ±ºçãäœæããå¿
èŠããããŸãthreejs
ãŸãã¯ãã¬ãŒã³webglã ãŸããããã«å ããŠãreactæ§é ã§ãã§ã«å®çŸ©ãããŠããé·ç§»ã®ã¿ã€ãã«ãããããæç¹ã§å€ãå®éšãšæ°ããå®éšãåæã«ã¬ã³ããªã³ã°ããã1ã€ã®ã¬ã³ãã©ãŒã®ã¢ã€ãã¢ãåã¡ãŸãããåäœããŸãã...
ããã«....ããã¯åé¡ã®åé¿çã§ããã解決çãã®ãã®ã§ã¯ãããŸãã... .destroyïŒïŒã¡ãœãããå®éã«webglã³ã³ããã¹ããžã®åç §ãç Žæ£ããªãå Žå...ãã€ã³ãã¯äœã§ããïŒ :(
ãšããã£ïŒ ã³ã³ããã¹ããç Žæ£ãããŠããªãå Žåãdestroyé¢æ°ãæ³å®ã©ããã«æ©èœããŠããªãããšã«å®å šã«åæããŸã:)
ç§ã¯ããŸãããããªãã¯autodetectRenderer
ã䜿ã£ãŠããŸããïŒ ãã©ãŠã¶ãwebGL察å¿ãã©ãããæ€åºããããã«äœæãããã¹ãã³ã³ããã¹ããç Žæ£ãããŠããªãå¯èœæ§ããããŸãã
ããã€ãã®è¿œå æ å ±ïŒwebglã³ã³ããã¹ããç Žæ£ããããšã¯ã§ããŸããããããã¯ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããŸãïŒäœããå€æŽãããŠããªãéãïŒã
ä¿æããŠããåç §ãåé€ãããªãã·ã§ã³ã§ãã£ã³ãã¹èŠçŽ ïŒã³ã³ããã¹ãã®ã¯ãªãŒã³ã¢ããã«å¿ èŠïŒãåé€ãããšæããŸãããã¯ãªãŒã³ã¢ãããè¡ãã®ã¯ãã©ãŠã¶ãŒã®è²¬ä»»ã§ãã ã³ã³ããã¹ãããªãŒã¯ããŠãããããã©ãŠã¶ãå¿ èŠãšãããããéãäœæãããŠããå¯èœæ§ããããŸãã æ£çŽãªãšããããããŸããã
éçºããŒã«ã¯ããã®ãããªã³ã³ããã¹ãã®åšãã®ãªãŒã¯ã瀺ããŠããŸããïŒ å€åããã¯å©ããããšãã§ããŸããïŒ äœããã³ã³ããã¹ããç¶æããŠããããã«èãããŸã..å€åãã³ã³ããã¹ããžã®js refããåºç€ãšãªããã£ã³ãã¹ãžã®js refã§ããïŒ
ããããç§ãäœããã£ãŠãiframeã倧奜ããªçç±ã§ãã
@GoodBoyDigitalç§ã¯ãã®ããã«autodetectRenderer
ã䜿çšããŠããŸã
<strong i="9">@renderer</strong> = new PIXI.autoDetectRenderer canvas.width, canvas.height, { view: canvas, antialias: false, backgroundColor: 0xffffff }
ç§ã¯ä»ãããé§è»ããŠããŸããç§ããããèŠã€ãããšãã«è§£æ±ºçãäœã§ããããçããã«ç¥ãããŸã..ãã®ã³ã³ããã¹ãã匷å¶çã«å€±ããšãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã«ãããã¯ãªãŒã³ã¢ããããããããããªããšæã£ãŠããŸãã..ãããããã確ãã§ã¯ãããŸãã:)
ç§ã¯åãåé¡ãæ±ããŠããŸãã ç§ãæ§ç¯ããŠãããã®ã§ã¯ãPixiãé »ç¹ã«ç Žæ£ããŠåæ§ç¯ããå¿ èŠããããã¡ã¢ãªãžã®åœ±é¿ãå¿é ã§ãã çŸæç¹ã§ã¯ãåWebGLã€ã³ã¹ã¿ã³ã¹ã¯éåžžã«å°ããã§ããããããæ§ç¯ãç¶ãããšãã¯ããã«å€§ãããªããŸãã
äœãé²å±ã¯ãããŸããïŒ
æ確ã«ããããã«ãç§ã¯Phaserã䜿çšããŠããŸãããPixiã®renderer.destroyã¡ãœãããåŒã³åºããŠããããã§ãã
ãŸã éããªãã 1ã€ã®ã°ããŒãã«ã¬ã³ãã©ãŒã䜿çšããŠããŸããŸãªã·ãŒã³ãã¬ã³ããªã³ã°ããããiframeãä»ããŠã³ã³ãã³ããããŒãããã ãã§ãã¶ãäžãã£ãŠãããã®ãé©åã«åŠçã§ããŸãã
ã¡ãã£ãšèŠããŠãã¯ããããã¯æ¬åœã«å°ãããªãããŒãªãã®ã§ãã ç§ãèŠãéããã³ã³ããã¹ããç Žå£ããããã«ã§ããéãã®ããšãããŸãã ãããã£ãŠããã¹ãŠã®ãã¯ã¹ãã£/ããã°ã©ã ã®arraybuffersectã¯ç Žæ£ãããŸãã ç§ãã¡ã«ã§ããããšã¯ãã³ã³ããã¹ããç Žæ£ããããããŒã«ããŠãæ¯åæ°ããã³ã³ããã¹ããäœæããã®ã§ã¯ãªããåå©çšã§ããããã«ããããšã§ãã
ã¡ãã£ãš@GoodBoyDigitalç§ã®å Žåãç§ã¯ã¢ãã¡ãŒã·ã§ã³ãåºãå ¥ãããŠããã®ã§ãåžžã«2ã€ã®ã³ã³ããã¹ããå¿ èŠã§ãã...ããã¯Reactãšçµ±åããå®å šãªpixiã«ããªãããšã®åé¡ã§ã...ãšã«ããããããä¿®æ£ã§ãããã°ãã©ããã¯ããããŸããèšããŸã§ããªã..ãã©ãŠã¶ãã³ã³ããã¹ãã管çãããããªãã®ã ãšæããŸã... three.jsããã®ãã®ããã¯ãæ©èœãããã©ããããããããŸãã...å€åãããurV4ã§è©ŠããŠãpixiã§16以äžã®ã¿ããéããŠã¿ãŠãã ããhttps://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L289
ãã以å€ã®å Žåã¯å¿é ãããŸãããç§ã¯ãã§ã«ç§ã®ã¢ããªã®ã¢ãŒããã¯ãã£ãå€æŽããŸãã... iframe FTW :)
ãã人ã ïŒ ç§ã¯ééããªãthree.jsããªãã¯ãè¿œå ããããšãæ€èšããŸãã
1ã€ã®ã°ããŒãã«ã¬ã³ããªã³ã°ã䜿çšããããšæããŸãã å®éããããç§ã®ç©¶æ¥µã®ç®æšã§ãã ãã ããã³ãŒããæ¢åã®ã³ã³ããã¹ãã«ã¹ããªãŒãã³ã°ããæ¹æ³ãå¿ èŠã§ãã
èšãæããã°ããŠãŒã¶ãŒã¯ã³ãŒããæžããŠããŸãã äºåã«äœæãããŠããŸããã
ç§ã¯è¯ã解決çãèŠã€ãããšæããŸãã ããã«ããããäºããç¥ãå¿ èŠã®ãªãããããªãŒããŒã¬ã€Reactã³ã³ããŒãã³ããäœæããReactãDOMãææã§ããããã«ãªããŸãã
ãã®ææ³ã䜿çšã
gl.getExtension('WEBGL_lose_context').loseContext();
å®å šãªäŸã次ã«ç€ºããŸãã
var document = require('global/document');
var PIXI = require('pixi.js');
// I want to keep this canvas / renderer around. For example, this might be a bottom layer PIXI / React map overlay.
var canvas1 = document.createElement('canvas');
document.body.appendChild(canvas1);
createRenderer(0xff0000, canvas1);
function createRenderer(color, canvas) {
canvas = canvas || document.createElement('canvas');
var renderer = new PIXI.WebGLRenderer(800, 600, {view: canvas});
var stage = new PIXI.Container();
var graphics = new PIXI.Graphics();
graphics.beginFill(color, 0.5);
graphics.drawCircle(0, 0, 200);
graphics.endFill();
stage.addChild(graphics);
renderer.render(stage);
return {renderer: renderer, stage: stage, graphics: graphics};
}
// Simulate frequent adding / removing of lots of PIXI / React map overlays on top.
for (var i = 0; i < 16; i++) {
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
var scene = createRenderer(0x00ff00, canvas);
// Uncomment to see that the original canvas isn't removed.
/* scene.renderer.currentRenderTarget.gl
.getExtension('WEBGL_lose_context').loseContext(); */
scene.renderer.destroy();
scene.stage.removeChild(scene.graphics);
document.body.removeChild(canvas);
}
ãã¶ããPIXIã¯ãããç¬èªã®ãç Žæ£ãã¡ãœããã«è¿œå ããå¿ èŠããããŸããïŒ
ç§ãã¡ãã³ã³ããã¹ããææããŠããå Žåãããã¯çã«ããªã£ãŠããŸããç§ã¯ä»ãç§ãã¡ãææããŠãããšæ³å®ããŠããŸãïŒv3ïŒã
é¢æ°isWebGLSupportedïŒïŒïŒsource / core / utils / index.jsïŒã§çœ®æreturn !!(gl && gl.getContextAttributes().stencil);
ãš
var success = !!(gl && gl.getContextAttributes().stencil);
gl.getExtension('WEBGL_lose_context').loseContext();
gl = undefined;
return success;
ç§ã®åé¡ãä¿®æ£ããŸããã ããã¯ã°ãŒã°ã«ã¯ããŒã ã§æãé¡èã§ãã-Firefoxã¯ã©ã¡ãã®æ¹æ³ã§ãæ©èœããŸããã ç§ã¯å°ãWebGLã®åå¿è ãªã®ã§ããã®ã¢ãããŒãã«ã€ããŠã³ã¡ã³ãããŠããã ããã°å¹žãã§ãã
ãã§ãã¯æã«ã³ã³ããã¹ãã匷å¶çã«å€±ããšããè¯ãåŒã³ããã§ããã³ã³ããã¹ããææããŠããããšãïŒ100ïŒ ïŒããã£ãŠããã®ã§ãããã¯çŽ æŽãããã¢ã€ãã¢ã§ãã
ããã¯ããŒãžãããŸãããïŒ ç§ãã¡ã¯åãåé¡ãæ±ããŠããŸãã
ping @ englercjããã¯ä»ããéããããšãã§ãããšæããŸã
gl.getExtension('WEBGL_lose_context').loseContext()
ã¯èŠåãæå¶ããå¯èœæ§ããããŸãããä»æ§ã§ã¯ã WEBGL_lose_context.restoreContext()
ãåŒã³åºããããŸã§ãã³ã³ããã¹ãã®åªå€±ãã·ãã¥ã¬ãŒãããã ãã§ãããšãããŠããŸããããã«ãããæåããæ¬åœã«å€±ãããªãã£ãå Žåã«ã®ã¿ã³ã³ããã¹ãã埩å
ã§ããŸãã
ããã¯äŸ¿å©ãããããŸããïŒlose_contextïŒïŒã¯ïŒä»æ§ã«ããïŒåãªãã·ãã¥ã¬ãŒã·ã§ã³ã§ããããã®ã¹ã¬ããïŒãããªãã¯WebGLïŒWEBGL_lose_context ïŒmozillaéçºè
ã®Jeff GilbertããïŒã§ã¯ãFirefoxã§ã¯loseContext()
ãããã®ã³ã³ããã¹ããšãã®ã³ã³ããã¹ãã解æŸããŸããªãœãŒã¹ã ã
åé¡ã¯ãä»ã®ãã©ãŠã¶ããããç°ãªãæ¹æ³ã§åŠçããããšã§ãã Googleéçºè ïŒKen RussellïŒããã®æšå¥šã³ã¡ã³ãããããŸããWebGLRenderingContextã§æ瀺çãªdelete * APIã䜿çšããŠãã¢ããªã±ãŒã·ã§ã³ã䜿çšããªããªã£ãGPUãªãœââãŒã¹ã解æŸããŠãã ããã
ç§ã¯ãããå®éšããããšããªãããšãèªããªããã°ãªããŸããããã©ã®è§£æ±ºçããã©ãŠã¶åºæã«ãªããšæãããŸãã
èå³æ·±ãFFå®è£ ããŒãã 確ãã«ãåã ã®ãªãœãŒã¹ãåé€ããããšã«ã€ããŠã®Kenã®ã¢ããã€ã¹ã¯ãæšæºçãªæ¹æ³ã®ããã«èŠããŸããFFã¯ãå€ãã®äººæ°ã®ãããã©ãŠã¶ãŒã®1ã€ã«ããããFFã®åäœã§ããäºåãªãã«å€æŽãããå¯èœæ§ããããŸãã ãŸããå®è£ ã®è©³çŽ°ãåœã®ãŠãŒã¶ãŒãšãŒãžã§ã³ãæååãŸãã¯ãã©ãŠã¶ã®ã¹ãããã£ã³ã°ãããã³ä»£æ¿æ段ãããå Žåã¯è¿œå ã®ã³ãŒããã¹ã«äŸåããããªãããããã©ãŠã¶ããšã«ãã¹ãããŠããŸããã
ä»æ¥ãiOSã§ã¢ããªã®ãã¹ããè¡ã£ãŠãããšããããã®ãšã©ãŒãçºçããŸããã æ¢ç¥ã®åé¿çã¯ãããŸããïŒ ç§ã®pixiãã¥ãŒã¯ã¢ããªã®ç»é¢ã®ãµãã³ã³ããŒãã³ãã§ããããããŠãŒã¶ãŒããã®ããŒãžãã移åãããšç Žæ£ãããŸãã åé¡ãåé¿ããããã«ããã¥ãŒã®ãã£ã³ãã¹ã«åãã¬ã³ãã©ãŒãäœããã®æ¹æ³ã§ãã¿ãã/åã¢ã¿ããããããšã¯æ©èœããã§ããããïŒ
åé¿çã¯ãè€æ°ã®ã³ã³ããã¹ããäœæããªãããšã§ãã æã£ãŠãããã®ãåå©çšããã ãã§ãã ããŒãžãããã²ãŒãããå Žåãåã®ããŒãžã§äœãäœæããããã¯åé¡ã§ã¯ãããŸããã
ããŒããã§ã¯ãã³ã³ããã¹ããåå©çšããã«ã¯ã©ãããã°ããã§ããïŒ ç§ã¯angularJSã䜿çšããŠããã®ã§ããã³ãã¬ãŒããã¬ãŒã ã¯ãŒã¯å ã§äœæ¥ããŠããŸãã ããšãã°ãcanvasèŠçŽ ãDOMããåãé¢ããŠä¿åãããŠãŒã¶ãŒãããŒãžã«æ»ã£ããšãã«ãããŒãžå ã®ãã®å Žæã«åã¢ã¿ããããããšã¯ã§ããŸããïŒ PIXIå ã«ããã®æ¢åã®ã¬ã³ãã©ãŒãšã³ã³ããã¹ãã䜿çšããŠããã®æ°ãããã£ã³ãã¹ã«ã¢ã¿ããããããšããæ¹æ³ãããã°çŽ æŽãããã®ã§ãããå éšã§ã©ã®ããã«è¡ãããã®ãããããŸããã
ç§ãæ°ã«ããçç±ã¯ãã¢ããªã®èæ¯ãšããŠ1ã€ã®å€§ããªpixiãã¥ãŒã䜿çšããŠããŠãèšå®ããŒãžã§äœ¿çšããå°ããªãã¥ãŒã䜿çšããŠããããã§ãã ãŠãŒã¶ãŒãèšå®ããŒãžã«è€æ°åã¢ã¯ã»ã¹ãããšãæåã«äœæããããããã¡ã€ã³ã®èæ¯ããŒãžã匷å¶çµäºãããŸãã
ããã¯ãã·ã³ã°ã«ããŒãžã¢ããªå ã§PIXIã䜿çšããå Žåã®åé¡ã®ããã§ãã
PIXI.Application / PIXI.WebGLRenderer / PIXI.CanvasRendererã®ã€ã³ã¹ã¿ã³ã¹ãä¿åãããšãcanvasèŠçŽ ã®ã€ã³ã¹ã¿ã³ã¹ãä¿åãããŸãã ããšãã°ãPIXI.Applicationã§ã¯ãHTMLCanvasElementã§ããview
ããããã£ãååŸã§ããŸãã ãã®canvasèŠçŽ ãæ¿å
¥ããŠãAngularJS / Reactã¢ããªããåé€ã§ããŸãã PIXIã§ã¯ããªãã·ã§ã³ãšããŠæž¡ãããšã§ã䜿çšãããã£ã³ãã¹èŠçŽ ãã¬ã³ãã©ãŒã«æ瀺ã§ããŸãããããã¯äœ¿çšããªãã§ãã ããã 代ããã«ãPIXIãç¬èªã®canvasèŠçŽ ãå
éšçã«äœæããDOMã³ã³ããã«addChildãè¿œå ããããšãèš±å¯ããŸãã
<div id="pixi-container"></div>
// maintain the reference to this Application even as your SPA view gets destroyed
const app = new PIXI.Application();
// Insert in the DOM or whatever the equivalent is in Angular
document.querySelector("#pixi-container").appendChild(app.view);
ããããŸãããããããšããç§ã¯ãããè©ŠããŠã¿ãŸãã å®ã¯å šç¶æªããªãã§ãã
äºè§£ããŸããããã¥ãŒãç Žæ£ããã®ã§ã¯ãªããåãé¢ããŠå床远å ããããšã§åé¡ã解決ããŸãããå©ããŠããã人ãã¡ã«æè¬ããŸãã
ãã®ã¹ã¬ããã¯ãéããããåŸã«æè¿ã®ã¢ã¯ãã£ããã£ããªããããèªåçã«ããã¯ãããŠããŸãã é¢é£ãããã°ã«ã€ããŠã¯ãæ°ããåé¡ãéããŠãã ããã
æãåèã«ãªãã³ã¡ã³ã
ç§ã¯è¯ã解決çãèŠã€ãããšæããŸãã ããã«ããããäºããç¥ãå¿ èŠã®ãªãããããªãŒããŒã¬ã€Reactã³ã³ããŒãã³ããäœæããReactãDOMãææã§ããããã«ãªããŸãã
ãã®ææ³ã䜿çšã
å®å šãªäŸã次ã«ç€ºããŸãã
ãã¶ããPIXIã¯ãããç¬èªã®ãç Žæ£ãã¡ãœããã«è¿œå ããå¿ èŠããããŸããïŒ