å¤ãè¯ãã¤ã³ã¿ã¼ãããã¢ããªã±ã¼ã·ã§ã³ã§ãããã¦ã¹ã¹ãã¼ã«ã¼*1ããªã¢ã¯ãã£ãããã°ã©ãã³ã°ã®æè¡ãæ´»ç¨ãã¦å®è£ ãã¦ã¿ãã¨ããåãçµã¿ããã¾ããã®ã§ãç´¹ä»ãã¾ãããªã¢ã¯ãã£ãããã°ã©ãã³ã°ã¨ããã¨ä¸»èªã大ããã§ãããããã§ã¯bacon.jsã使ã£ã¦ããããã®æå³ã§ãã
ã§ãããã®
ã¾ãã¯å®æãããã¦ã¹ã¹ãã¼ã«ã¼ãç´¹ä»ãã¾ãããã§ã¼ã³ã®ããã«é£ãªã£ãæããã¦ã¹ã«ã¼ã½ã«ã®è»è·¡ã辿ã£ã¦ã¤ãã¦ãã¾ãã工夫ãã¦ããããã¨ãªããªã綺éºã§ããä¸ã®ãã¿ã³ãæ¼ãã¨å®éã«ãã®ç»é¢ã§ãã¦ã¹ã¹ãã¼ã«ã¼ãæå¹ã«ãããã¨ãã§ãã¾ã(requestAnimationFrameã«å¯¾å¿ããPCãã©ã¦ã¶ã®ã¿)ãããããåããã¦éãã§ã¿ã¦ãã ããã
 
å®è£
ãã®ãã¦ã¹ã¹ãã¼ã«ã¼ãã©ã®ããã«å®è£
ããã¦ãããç´¹ä»ãã¾ããソースコードはGitHubに公開していますã®ã§ãé©å®ãåç
§ãã ãããæå
ã§ãã«ããã¦è©¦ãå ´åã«ã¯ãREADMEã®éãã«ãã«ããã¦ãexample.htmlã表示ãã¦ã¿ã¦ãã ããã
ã§ã¯é çªã«è¦ã¦ããã¾ãã
ãã¦ã¹ã«ã¼ã½ã«ã®ä½ç½®ã®å¤åãEventStreamã«å¤æãã
ã¾ãã¯å»ã
ã¨å¤åãããã¦ã¹ã«ã¼ã½ã«ã®ä½ç½®å¤åããåãæ±ããããããã«bacon.jsã®EventStreamã«å¤æãã¾ããããdocumentè¦ç´ ã«å¯¾ãã¦çºçããmousemoveã¤ãã³ããEventStreamã«å¤æããã«ã¯ä»¥ä¸ã®ããã«ãã¾ãã
var mouseCursorStream = Bacon.fromEventTarget(document, 'mousemove').map(function(me) { return { x: me.pageX, y: me.pageY }; });
ããã§ãã¦ã¹ã«ã¼ã½ã«ã®å¤åãï¼ã¤ã®ãªãã¸ã§ã¯ãã¨ãã¦é¢æ°ã«æ¸¡ããããããã¨ãã§ããããã«ãªãã¾ããã(pageX/pageYã¯æ¨æºåããã¦ããªããã£ã¼ã«ãã§ãããpolyfillã®ããã®ã³ã¼ããæ¸ããã¨ã¯æ¬é¡ã§ã¯ãªãã®ã§ãããã§ã¯éã«ä½¿ã£ã¦ãã¾ãã)
å»ã ã¨å¤åããä½ç½®ãç®æãã¦åããªãã¸ã§ã¯ããä½ã
次ã¯ãã¦ã¹ã«ã¼ã½ã«è¿½ããããæã«ç¸å½ããStalkerãªãã¸ã§ã¯ããä½ãã¾ãã
ãã®ãªãã¸ã§ã¯ãã¯åæåæã«ä¸ããããEventStreamã«ãã£ã¦è¡¨ãããå»ã
ã¨å¤åããä½ç½®ã«åãã£ã¦ãæã®ç»åãç§»åããã¾ããä¾ãã°æ¬¡ã®ããã«Stalkerãªãã¸ã§ã¯ããä½ãã¨ããã¦ã¹ã«ã¼ã½ã«ãï¼ã¤ã®æã追ãããã¾ãã
new Stalker(mouseCursorStream); // ãã¦ã¹ã«ã¼ã½ã«ãç®æãã¦åãStalkerãä½ã

Stalkerãªãã¸ã§ã¯ãã®ä¸ã§ã¯ç®æãä½ç½®ã®EventStream( = targetStream)ã®å¤åããããã¨ã«ãèªåã®ç¾å¨ã®ç®çå°ãæ´æ°ãã¾ãã
function Stalker(targetStream) { // ... var targetPosition = {x: 0, y:0}; targetStream.onValue(function(p) { targetPosition.x = p.x; targetPosition.y = p.y; }); // ... }
ããã§åºã¦ããtargetPositionãç®æãã¦æãä¸å®é度ã§ç§»åãããã¢ãã¡ã¼ã·ã§ã³ã®ã³ã¼ãã¯ã以ä¸ã®ãããªé°å²æ°ãªãã¾ããã詳細ã¯çç¥ãã¾ã*2ã
// Stalker ã®ã³ã³ã¹ãã©ã¯ã¿å ã«ã¦ // animationFrameãã¨ã«Stalkerã®positionãæ´æ°ãã animationFrame.onValue(function() { position = next(); elem.style.left = position.x + 'px'; elem.style.top = position.y + 'px'; } });
å»ã ã¨å¤åããStalkerã®ä½ç½®ãEventStreamã«ãã
ããã¾ã§ã§æãï¼ã¤è¿½ãããããããã¨ã¯ã§ããããã«ãªãã¾ãããããã¾ããããããããã¾ããããã¾ã£ãããªã¢ã¯ãã£ãæãããã¾ãããããã§å°ã工夫ãã¦ã¿ã¾ãã
Stalkerãªãã¸ã§ã¯ãã¯targetPositionãç®æãã¦ä¸å®é度ã§ç§»åãã¾ãããã®ç§»åä¸ã®Stalkerãªãã¸ã§ã¯ãèªèº«ã®ä½ç½®ãEventStreamã¨ãã¦åãæ±ããããã«ãã¦ã¿ã¾ãã
bacon.jsã®Busã¨ãããªãã¸ã§ã¯ãã使ãã¨èªåã§å¤ãpushã§ãããããªEventStreamãä½ãäºãã§ãã¾ããStalkerãæã®ä½ç½®ãæ´æ°ããç®æã§Busã¨ãã¦ä½ã£ãEventStreamã«å¤ãpushãã¾ããpushãããå¤ãæå¾ã«pushãããå¤ã¨åãå ´åã¯ç¡è¦ãããã®ã§ãskipDuplicatesã¡ã½ããã«ãã£ã¦ä½ãããæ°ããEventStreamãStalkerãªãã¸ã§ã¯ãã®positionStreamãã£ã¼ã«ãã«ã»ãããã¦ããã¾ãã
// Stalker ã®ã³ã³ã¹ãã©ã¯ã¿å ã«ã¦ // animationFrameãã¨ã«Stalkerã®positionãæ´æ°ãã var ps = new Bacon.Bus(); this.positionStream = ps.skipDuplicates(); // Busã«åãå¤ãpushããã¦ãç¡è¦ãã animationFrame.onValue(function() { position = next(); ps.push(position); // ä½ç½®ã®å¤åãStreamã«pushãã elem.style.left = position.x + 'px'; elem.style.top = position.y + 'px'; });
ããã«ãããç§»åä¸ã®Stalkerã®ä½ç½®ãmouseCursorStreamã¨åãå½¢å¼ã®EventStreamã¨ãã¦åãæ±ããããã«ãªãã¾ãããã¤ã¾ããStalkerã¯ãã¦ã¹ã«ã¼ã½ã«ã ãã§ã¯ãªãå¥ã®Stalkerã追ããããããããã«ãªãã¾ããã
Stalker ãã¤ãªãã
ãè³ç«ã¦ã¯æ¸ãã ã®ã§Stalkerãªãã¸ã§ã¯ããããããä½ã£ã¦ããå°ãããããããã¦ã¹ã¹ãã¼ã«ã¼ãä½ãã¾ãã
ä¾ãã°ã1ã¤ç®ã®Stalkerããã¦ã¹ã«ã¼ã½ã«ã追ããããããã«ãã3ã¤ç®ã®Stalkerã1ã¤ç®ã®Stalkerãã3ã¤ç®ã®Stalkerã2ã¤ç®ã®Stalkerã追ããããããã«ãã¦ã¿ã¾ãããã
var one = new Stalker(mouseCursorStream); var two = new Stalker(one.positionStream.delay(100)); var three = new Stalker(two.positionStream.delay(100));

ãã¾ãããã¾ãããpositionStreamã§çºçããã¤ãã³ãã100msã»ã©delayãã¦ããã®ããã¤ã³ãã§ããpositionStreamã®æ´æ°ã¯é »ç¹ã«è¡ã£ã¦ãããããdelayããªãã¨ï¼ã¤ã®æãã»ã¼åãä½ç½®ã«è¡¨ç¤ºããã¦é¢ç½ã¿ãããã¾ããã
ã¯ããã«ç´¹ä»ãããã¦ã¹ã¹ãã¼ã«ã¼ã§ã¯ä»¥ä¸ã®ããã«30åã®æãéã®ããã«ã¤ãªãã¦ãèªåããåã«ãªããã æã追ããããããã«è¨å®ãã¦ãã¾ãã
var cur = new Stalker(mouseCursorStream); for (var i = 0; i < 30; i++) { cur = new Stalker(cur.positionStream.delay(100)); }
ææ³
ãªã¢ã¯ãã£ãããã°ã©ãã³ã°ã®æè¡ãæ´»ç¨ãããã¦ã¹ã¹ãã¼ã«ã¼ãå®è£
ãã¦ã¿ã¾ãããå»ã
ã¨å¤åããä½ç½®ã®å¤åãEventStreamã®ãªãã¸ã§ã¯ãã¨ã¿ãªããã¨ã§ãStalkerãå»ã
ã¨å¤ããç®çå°( = targetStream)ãç®æãã¦åããªãã¸ã§ã¯ãã§ãããã¨ããããªãã§ããããããã¢ãã«ã«ãããã¨ãã§ãã¾ããã
ä¾ãã°ãEventStreamã«é ¼ããã«mousemoveã¤ãã³ãã®ãã³ãã©ã§ç®çã®ä½ç½®ãæ´æ°ããã³ã¼ããStalkerã®å¤ã«å®è£
ãããã¨ãã§ããã§ãããã
var s = new Stalker(mouseCursorStream); document.addEventListener('mousemove', function(e) { s.updateCurrentTargetPosition({x: e.pageX, y: e:pageY}); });
ã§ãããç®çã®ä½ç½®ãå¤åããæã«ã©ã®ãããªåå¿ããããã¯Stalkerã§ããéãã¯ããã»ã©å¤ããããªã(ç¾å¨ã®ç®çä½ç½®ãæ´æ°ãã)ã¨èããããã®ã§ãã³ã¼ãã®éè¤ãæ
å ±é è½ã®è¦³ç¹ããStalkerå
ã«å®è£
ããã¦ããã®ãè¯ãããã«æãã¾ãããã¨ãã£ã¦ãmousemoveã®ãã³ãã©ã®ç»é²ãç´æ¥Stalkerå
ã«å®è£
ããã°ããã¦ã¹ã«ã¼ã½ã«ã§ã¯ãªãå¥ã®Stalkerã®ä½ç½®ããã¤ãã³ããåãåã£ã¦æãé£ãããã¨ãã£ãæè»æ§ãå®ç¾ã§ããªãã£ãã§ãããã
EventStreamã¨ããæ½è±¡åã¯å¤§å¤ä¾¿å©ã§ããEventStreamã使ããã¨ã§skipDuplicatesãdelayã®ãããªä¾¿å©ãªã¡ã½ãããå©ç¨åºæ¥ã¾ããã
ãã¦ã¹ã¹ãã¼ã«ã¼ããªã¢ã¯ãã£ãããã°ã©ãã³ã°ãå¦ã¶æé©ãªèª²é¡ã¨ããããã§ã¯ãªãããã«ã¯æãã¾ãããä»åã¯å¤åããã¤ãã³ãããªãã¸ã§ã¯ãã¨ãã¦æ±ãçµã¿åããããããã¨ã®ä¾¿å©ããå°ãã¯æããããã¨æãã¾ãã
ãã¾ã: http://mouse-stalkers.github.io/ã¸ã®å¯ç¨¿ãåéãã¦ãã¾ã
ãã¦ã¹ã¹ãã¼ã«ã¼ã®å®è£ ãéããåãçµã¿ãå§ãã¾ãããã¿ãªããä½ãããã®ãã¦ã¹ã¹ãã¼ã«ã¼ãå®è£ ããããã¨ããããã¨æãã¾ããããããããã¦ã¹ã¹ãã¼ã«ã¼ãåããã¦ãã¾ãã®ã¯æ®å¿µãªã®ã§ããã²mouse-stalkers.github.ioã«PullRequestãã¦ãã ããã
- Webãµã¤ã http://mouse-stalkers.github.io/
- GitHubã®ãªãã¸ã㪠https://github.com/mouse-stalkers/mouse-stalkers.github.io