UNPKG

react-slime-simulation

Version:

A customizable React component for simulating slime mold behavior.

3 lines (2 loc) 13.3 kB
var e=require("react");function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=/*#__PURE__*/t(e);function n(){return n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)({}).hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},n.apply(null,arguments)}var i=["useRandomDefaults","svgShape"];function a(e,t,r){if(!e.s){if(r instanceof o){if(!r.s)return void(r.o=a.bind(null,e,t));1&t&&(t=r.s),r=r.v}if(r&&r.then)return void r.then(a.bind(null,e,t),a.bind(null,e,2));e.s=t,e.v=r;var n=e.o;n&&n(e)}}var o=/*#__PURE__*/function(){function e(){}return e.prototype.then=function(t,r){var n=new e,i=this.s;if(i){var o=1&i?t:r;if(o){try{a(n,1,o(this.v))}catch(e){a(n,2,e)}return n}return this}return this.o=function(e){try{var i=e.v;1&e.s?a(n,1,t?t(i):i):r?a(n,1,r(i)):a(n,2,i)}catch(e){a(n,2,e)}},n},e}();function s(e){return e instanceof o&&1&e.s}function u(e,t){return Math.random()*(t-e)+e}function l(e){for(var t=e.length-1;t>0;t--){var r=Math.floor(Math.random()*(t+1)),n=[e[r],e[t]];e[t]=n[0],e[r]=n[1]}}var h=/*#__PURE__*/function(){function e(e,t){this.settingsRef=e,this.simulationDimensionsRef=t,this.position={x:0,y:0},this.angle=Math.random()*Math.PI*2;var r=e.current.baseHue+u(-20,20);this.color="hsl("+r+", 80%, 60%)",this.escapeThreshold=e.current.escapeThreshold,this.isEscaping=!1,this.escapeTime=0}var t=e.prototype;return t.sense=function(e){var t=this.angle+e*(Math.PI/180),r=this.settingsRef.current.sensorOffset,n=this.simulationDimensionsRef.current.width,i=this.simulationDimensionsRef.current.height,a=Math.cos(t),o=Math.sin(t),s={x:this.position.x+a*r,y:this.position.y+o*r};if(s.x<0||s.x>=n||s.y<0||s.y>=i)return{sum:0,maxDensity:0};var u=0,l=0,h=Math.floor(s.x),c=Math.floor(s.y),f=this.settingsRef.current.trailMap;if(!f)return{sum:0,maxDensity:0};for(var v=-1;v<=1;v++){var d=c+v;if(d>=0&&d<i)for(var m=d*n,g=-1;g<=1;g++){var p=h+g;if(p>=0&&p<n){var M=f[m+p];u+=M,M>l&&(l=M)}}}return{sum:u,maxDensity:l}},t.update=function(){var e,t,r,n,i=this.settingsRef.current,a=this.simulationDimensionsRef.current.width,o=this.simulationDimensionsRef.current.height,s=60*i.deltaTime,l=i.agentSpeed,h=i.edgeThreshold,c=this.sense(0).maxDensity>this.escapeThreshold;if(c&&!this.isEscaping?(this.isEscaping=!0,this.escapeTime=0):!c&&this.isEscaping&&this.escapeTime>1&&(this.isEscaping=!1),this.isEscaping){this.escapeTime+=s;var f=this.sense(45),v=this.sense(-45);f.maxDensity>v.maxDensity?this.angle-=.2*s:this.angle+=.2*s;var d=1.3*l,m={x:Math.cos(this.angle),y:Math.sin(this.angle)};e={x:this.position.x+m.x*d,y:this.position.y+m.y*d}}else{var g=this.position.x<h,p=this.position.x>a-h,M=this.position.y<h,y=this.position.y>o-h;if((g||p||M||y)&&i.edgeAvoidance>0){var x=u(-Math.PI*i.edgeAvoidance,Math.PI*i.edgeAvoidance);g?this.angle=x:p?this.angle=Math.PI+x:M?this.angle=Math.PI/2+x:y&&(this.angle=-Math.PI/2+x)}else{var w=this.sense(0).sum,b=this.sense(45).sum,R=this.sense(-45).sum,S=(r=(r=1234.5678*(t={x:this.position.x+.001*performance.now(),y:this.position.y+.001*performance.now()}).x)*r*r*123456+(n=9012.3456*t.y))*(n=n*n*n*654321+r)%4294967295/4294967295;w>b&&w>R?this.angle+=.1*(S-.5)*s:w<b&&w<R?this.angle+=2*(S-.5)*.5*s:R>b?this.angle-=.5*S*s:b>R&&(this.angle+=.5*S*s)}var T={x:Math.cos(this.angle),y:Math.sin(this.angle)};e={x:this.position.x+T.x*l,y:this.position.y+T.y*l}}(e.x<0||e.x>=a||e.y<0||e.y>=o)&&((e.x<0||e.x>=a)&&(this.angle=Math.PI-this.angle+u(-.2,.2)),(e.y<0||e.y>=o)&&(this.angle=-this.angle+u(-.2,.2)),e.x=Math.max(0,Math.min(a-.01,e.x)),e.y=Math.max(0,Math.min(o-.01,e.y))),this.position=e;var P=Math.floor(this.position.x),I=Math.floor(this.position.y),C=i.trailMap;if(P>=0&&P<a&&I>=0&&I<o&&C){var E=I*a+P;C[E]=Math.min(1,C[E]+i.trailStrength)}},e}();module.exports=function(t){var c=t.useRandomDefaults,f=void 0===c||c,v=t.svgShape,d=void 0===v?'\n <svg id="spawnShape" width="200" height="200" viewBox="0 0 200 200">\n \x3c!-- Remplacez ceci par votre SVG --\x3e\n <path d="M100,20 L180,180 L20,180 Z" fill="white"/>\n </svg>\n':v,m=function(e,t){if(null==e)return{};var r={};for(var n in e)if({}.hasOwnProperty.call(e,n)){if(-1!==t.indexOf(n))continue;r[n]=e[n]}return r}(t,i),g=e.useRef(null),p=e.useRef({}),M=e.useRef([]),y=e.useRef({width:0,height:0}),x=e.useRef(null),w=e.useRef(null),b=e.useRef(null),R=e.useRef(0),S=e.useRef(!1),T=e.useRef(null),P=e.useCallback(function(e,t,r){try{return console.log("Rasterizing SVG string:",(null==e?void 0:e.substring(0,100))+"..."),Promise.resolve(new Promise(function(n){var i=(new DOMParser).parseFromString(e,"image/svg+xml"),a=i.querySelector("parsererror");if(a)return console.error("Error parsing SVG string:",a.textContent),void n([]);var o=i.documentElement;if(!o||"svg"!==o.nodeName)return console.error("Invalid SVG string provided - Could not find root <svg> element."),void n([]);var s=(new XMLSerializer).serializeToString(o),u="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(s),l=new Image;l.onload=function(){var e=document.createElement("canvas");e.width=t,e.height=r;var i,a,o=e.getContext("2d"),s=l.naturalWidth/l.naturalHeight;t/r>s?i=(a=1.6*r)*s:a=(i=1.6*t)/s;var u=(t-i)/2,h=(r-a)/2;o.clearRect(0,0,t,r),o.drawImage(l,u,h,i,a);try{for(var c=o.getImageData(0,0,t,r).data,f=[],v=0;v<r;v++)for(var d=0;d<t;d++)c[4*(v*t+d)+3]>10&&f.push({x:d,y:v});console.log("Rasterized SVG: Found "+f.length+" valid pixels."),n(f)}catch(e){console.error("Error getting ImageData (possible CORS issue if SVG linked external resources, unlikely with data URL):",e),n([])}},l.onerror=function(e){console.error("Error loading SVG image for rasterization. Event:",e),console.error("SVG URL that failed:",u),n([])},l.src=u}))}catch(e){return Promise.reject(e)}},[]),I=e.useCallback(function(){if(w.current&&p.current.trailMap)for(var e=p.current,t=y.current.width,r=y.current.height,n=e.brushSize,i=e.brushStrength,a=Math.floor(w.current.x),o=Math.floor(w.current.y),s=e.trailMap,u=-n;u<=n;u++)for(var l=-n;l<=n;l++)if(l*l+u*u<=n*n){var h=a+l,c=o+u;if(h>=0&&h<t&&c>=0&&c<r){var f=c*t+h,v=Math.sqrt(l*l+u*u),d=Math.max(0,1-v/n);s[f]=Math.min(1,s[f]+i*d)}}},[]),C=e.useCallback(function(){var e=p.current,t=y.current.width,r=y.current.height,n=e.evaporationRate,i=e.trailMap,a=e.processedTrailMap;if(i&&a){I();for(var o=0;o<r;o++)for(var s=0;s<t;s++){var u=o*t+s,l=i[u];if(l<=.001)a[u]=0;else{for(var h=0,c=0,f=-1;f<=1;f++){var v=o+f;if(v>=0&&v<r)for(var d=v*t,m=-1;m<=1;m++){var g=s+m;g>=0&&g<t&&(h+=i[d+g],c++)}}a[u]=Math.max(0,.9*l+.1*(c>0?h/c:0)-n*e.deltaTime*60)}}p.current.trailMap=a,p.current.processedTrailMap=i}},[I]),E=e.useCallback(function(){var e=g.current;if(e){var t=e.getContext("2d");if(t){var r=p.current,n=y.current.width,i=y.current.height,a=r.trailMap;if(a){t.fillStyle="rgba(0, 0, 0, 1)",t.fillRect(0,0,n,i);for(var o=t.createImageData(n,i),s=o.data,u=0;u<i;u++)for(var l=0;l<n;l++){var h=u*n+l,c=a[h];if(c>.01){var f=Math.min(1,c),v=r.baseHue+r.hueRange*(f-.5)*2,d=50+r.lightnessRange*(f-.5)*2,m=Math.min(255,Math.floor(255*f)),M=d/100,x=1*(1-Math.abs(2*M-1)),w=x*(1-Math.abs(v/60%2-1)),b=M-x/2,R=0,S=0,T=0;0<=v&&v<60?(R=x,S=w,T=0):60<=v&&v<120?(R=w,S=x,T=0):120<=v&&v<180?(R=0,S=x,T=w):180<=v&&v<240?(R=0,S=w,T=x):240<=v&&v<300?(R=w,S=0,T=x):300<=v&&v<360&&(R=x,S=0,T=w),R=Math.round(255*(R+b)),S=Math.round(255*(S+b)),T=Math.round(255*(T+b));var P=4*h;s[P]=R,s[P+1]=S,s[P+2]=T,s[P+3]=m}}t.putImageData(o,0,0)}}}},[]),D=e.useCallback(function(){var e=g.current;if(e){var t=e.getContext("2d");if(t){var r=y.current.width,n=y.current.height;M.current.forEach(function(e){var i=Math.floor(e.position.x),a=Math.floor(e.position.y);i>=0&&i<r&&a>=0&&a<n&&(t.fillStyle=e.color,t.fillRect(i,a,1,1))})}}},[]),k=e.useCallback(function(e,t){try{var r=[],n=h;if(t&&0!==t.length){var i=[].concat(t);l(i);for(var a=0,o=0;o<e;o++){a>=i.length&&(l(i),a=0);var s=new n(p,y),c=i[a];s.position={x:c.x,y:c.y},s.angle=Math.random()*Math.PI*2,r.push(s),a++}}else{console.warn("No valid pixels from SVG rasterization or SVG invalid. Spawning agents randomly.");for(var f=y.current.width,v=y.current.height,d=0;d<e;d++){var m=new n(p,y);m.position={x:u(0,f),y:u(0,v)},m.angle=Math.random()*Math.PI*2,r.push(m)}}return M.current=r,Promise.resolve()}catch(e){return Promise.reject(e)}},[]),F=e.useCallback(function(e,t){try{var r=g.current,n=null==r?void 0:r.getContext("2d");if(!n||!p.current.initialAgents)return Promise.resolve();var i=p.current.initialAgents,u=y.current.width,l=y.current.height,h=0,c=function(e,t,r){for(var n;;){var i=e();if(s(i)&&(i=i.v),!i)return u;if(i.then){n=0;break}var u=r();if(u&&u.then){if(!s(u)){n=1;break}u=u.s}if(t){var l=t();if(l&&l.then&&!s(l)){n=2;break}}}var h=new o,c=a.bind(null,h,2);return(0===n?i.then(v):1===n?u.then(f):l.then(d)).then(void 0,c),h;function f(n){u=n;do{if(t&&(l=t())&&l.then&&!s(l))return void l.then(d).then(void 0,c);if(!(i=e())||s(i)&&!i.v)return void a(h,1,u);if(i.then)return void i.then(v).then(void 0,c);s(u=r())&&(u=u.v)}while(!u||!u.then);u.then(f).then(void 0,c)}function v(e){e?(u=r())&&u.then?u.then(f).then(void 0,c):f(u):a(h,1,u)}function d(){(i=e())?i.then?i.then(v).then(void 0,c):v(i):a(h,1,u)}}(function(){return h<e},function(){return h++},function(){return Promise.resolve(k(i,t)).then(function(){n.fillStyle="rgba(0, 0, 0, 1)",n.fillRect(0,0,u,l),D();var t=function(){if(h<e-1)return Promise.resolve(new Promise(function(e){return setTimeout(e,50)})).then(function(){})}();if(t&&t.then)return t.then(function(){})})});return Promise.resolve(c&&c.then?c.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},[k,D]),z=e.useCallback(function(e){g.current&&S.current&&(p.current.deltaTime=R.current>0?Math.min(.1,(e-R.current)/1e3):1/60,R.current=e,C(),E(),M.current.forEach(function(e){return e.update()}),D(),x.current=requestAnimationFrame(z))},[C,E,D]),A=e.useCallback(function(e){if(g.current){clearTimeout(b.current);var t=g.current.getBoundingClientRect();w.current={x:g.current.width/t.width*(e.clientX-t.left),y:g.current.height/t.height*(e.clientY-t.top)},b.current=setTimeout(function(){w.current=null},500)}},[]),L=e.useCallback(function(){clearTimeout(b.current),w.current=null},[]),O=e.useCallback(function(e){void 0===e&&(e=!1);try{if(!g.current)return Promise.resolve();if(!e&&S.current)return console.log("Simulation already initialized."),Promise.resolve();console.log(e?"Re-initializing simulation due to resize...":"Initializing simulation..."),S.current=!1,cancelAnimationFrame(x.current),x.current=null;var t=g.current;if(!t.getContext("2d",{alpha:!1}))return console.error("Failed to get 2D context"),Promise.resolve();var r={initialAgents:Math.floor(501*Math.random())+600,sensorOffset:Math.floor(25*Math.random())+5,edgeAvoidance:parseFloat(Math.random().toFixed(1)),agentSpeed:parseFloat((1.2*Math.random()+.75).toFixed(1)),trailStrength:parseFloat((2.5*Math.random()+.5).toFixed(1)),evaporationRate:parseFloat((.04*Math.random()+.005).toFixed(3)),baseHue:Math.floor(360*Math.random()),hueRange:Math.floor(60*Math.random())+30,lightnessRange:Math.floor(30*Math.random())+20,escapeThreshold:.5+.5*Math.random(),brushSize:4,brushStrength:1.5,pixelScale:6,edgeThreshold:3,reshuffleCount:10,startDelay:500},i=f?r:n({},r,m);Object.keys(r).forEach(function(e){if("number"==typeof r[e]){var t=i[e];if("string"==typeof t){var n=parseFloat(t);isNaN(n)?(console.warn("Invalid numeric value for prop "+e+': "'+t+'". Using default: '+r[e]),i[e]=r[e]):i[e]=n}else"number"!=typeof t&&(i[e]=r[e])}}),p.current=i;var a=p.current.pixelScale,o=Math.max(10,Math.floor(window.innerWidth/a)),s=Math.max(10,Math.floor(window.innerHeight/a));return y.current={width:o,height:s},t.width=o,t.height=s,t.style.width=window.innerWidth+"px",t.style.height=window.innerHeight+"px",t.style.display="block",t.style.background="#111",t.style.imageRendering="pixelated",t.style.cursor="crosshair",p.current.trailMap=new Float32Array(o*s),p.current.processedTrailMap=new Float32Array(o*s),Promise.resolve(P(d,o,s)).then(function(t){return Promise.resolve(F(p.current.reshuffleCount,t)).then(function(){S.current=!0,console.log("Initialization complete. Starting animation soon..."),p.current.startTimeoutId&&clearTimeout(p.current.startTimeoutId),p.current.startTimeoutId=setTimeout(function(){S.current&&!x.current&&(console.log("Starting animation loop."),R.current=performance.now(),x.current=requestAnimationFrame(z))},e?100:p.current.startDelay)})})}catch(e){return Promise.reject(e)}},[f,JSON.stringify(m),d,P,F,z]),G=e.useCallback(function(){clearTimeout(T.current),T.current=setTimeout(function(){O(!0)},250)},[O]);return e.useEffect(function(){console.log("SlimeSimulation component mounted or dependencies changed."),O(!1),window.addEventListener("resize",G);var e=g.current;return e&&(e.addEventListener("mousemove",A),e.addEventListener("mouseleave",L)),function(){console.log("Cleaning up SlimeSimulation..."),S.current=!1,cancelAnimationFrame(x.current),x.current=null,p.current.startTimeoutId&&clearTimeout(p.current.startTimeoutId),clearTimeout(T.current),clearTimeout(b.current),window.removeEventListener("resize",G),e&&(e.removeEventListener("mousemove",A),e.removeEventListener("mouseleave",L))}},[O,G,A,L]),/*#__PURE__*/r.default.createElement("canvas",{ref:g})}; //# sourceMappingURL=index.js.map