cycle.js + emotion + rxjs6でドラッグアンドドロップ(動作するものの欠陥あり)
こういうのをドラッグするのをrxjsで書きたかった。
import { CycleDOMEvent, div, h1, hr, input, label, p, VNode } from "@cycle/dom";
import * as Snabbdom from "snabbdom-pragma";
import { DOMSource, makeDOMDriver } from "@cycle/dom/lib/cjs/rxjs";
import { run } from "@cycle/rxjs-run";
import { Observable, timer, from } from "rxjs";
import "../stylus/style.styl";
import * as Rx from "rxjs";
import {
map,
startWith,
scan,
switchMap,
combineLatest,
takeUntil
} from "rxjs/operators";
type Sources = {
DOM: DOMSource;
};
type Sinks = {
DOM: Observable<VNode>;
};
/**
* アプリケーション
* @param sources
* @returns {{DOM: Observable<VNode>}}
**/
function cardMain(card: string) {
return function main(sources: Sources): Sinks {
// intent部分
const input$: Observable<Event> = sources.DOM.select("#" + card).events(
"mousedown"
);
const mouseMove$: Observable<Event> = sources.DOM.select("#" + card).events(
"mousemove"
);
const mouseUp$: Observable<Event> = sources.DOM.select("#" + card).events(
"mouseup"
);
const mouseLeave$: Observable<Event> = sources.DOM.select(
"#" + card
).events("mouseleave");
const mouseUpLeave$: Observable<Event> = Rx.merge(mouseUp$, mouseLeave$);
const inputGoniMousemomve$: Observable<Event> = input$
.pipe(switchMap( () => mouseMove$.pipe(takeUntil(mouseUpLeave$))))
;
// cssに入れる位置
map( (evt: MouseEvent) => {
return [evt.pageX - 30, evt.pageY - 30];
})
);
color: "hotpink",
fontSize: "3rem",
fontWeight: "bold"
});
// 現在の状態を画面に描画 ( View )
const vdom$: Observable<VNode> = state$.pipe(
console.log(card);
position: "absolute"
});
return (
<div className={myStyle}>
<div id={card} className={styleOfCard}>
{card}
</div>
</div>
);
})
);
// 結果をドライバに出力する ( Sinks )
return {
DOM: vdom$
};
};
}
// // アプリケーションからの戻り値を受け取るドライバ群を定義
const drivers = {
};
// アプリケーションとドライバを結びつける
run(cardMain("裁きの龍"), drivers);
一応、ドラッグアンドドロップにはなる。しかしながら、マウスダウンストリームが生き残り続けて無限増殖するのがとても気持ち悪い。
更にいうと、cycle.jsはrxjs6をあまりサポートしてないみたいでdomdriver辺りを作ろうとするとどうもできないらしい。rxjs4はおそらく使えるとおもっていて、それを使うか素直にxstreamをつかうべきであるらしい。多分、こういうのを作りたいならdomdriver辺りを工夫するべきなんだろうな。
ちなみにバイト先のエンジニアの方はこのプログラムの致命的な欠陥を20秒ほどで見抜いていたのだった。