[Dart] Draggable (Movable) Element


This post is Dart version of my previous posts [1] and [2].

If you need draggable element using pure (vanilla) JavaScript, see [1].

If you need draggable element in AngularJS way, see [2].

Dartium is needed for the demo.

Demo

Development Environment: Ubuntu Linux 14.10, Dart 1.8.

Source Code for Demo (HTML):

dart-draggable-element.html | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Dart Draggable (div) Element</title>
  </head>
  <body>

  <div id="dragMe" style="width: 200px; height: 200px; background: yellow;">Drag Me</div>

  <script type='text/javascript'>
  var script = document.createElement('script');
  if (navigator.userAgent.indexOf('(Dart)') === -1) {
    // Browser doesn't support Dart
    script.setAttribute("type","text/javascript");
    script.setAttribute("src", "app.js");
  } else {
    script.setAttribute("type","application/dart");
    script.setAttribute("src", "app.dart");
  }
  document.getElementsByTagName("head")[0].appendChild(script);
  </script>
  </body>
</html>

Source Code for Demo (Dart):

app.dart | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:html.Element
// https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:html.MouseEvent
// https://www.dartlang.org/articles/improving-the-dom/
// http://stackoverflow.com/questions/14476738/remove-event-listener-with-the-new-library
// https://code.google.com/p/dart/issues/detail?id=15216
// https://github.com/threeDart/three.dart/issues/109
import 'dart:html';

void draggable(Element elm) {
  int startX, startY, initialMouseX, initialMouseY;
  var docMouseMoveSub, docMouseUpSub;
  elm.style.position = "absolute";

  void mousemove(e) {
    e.preventDefault();
    // e.clientX works in Dartium, but fails on compiled js
    int dx = e.client.x - initialMouseX;
    // e.clientY works in Dartium, but fails on compiled js
    int dy = e.client.y - initialMouseY;
    elm.style.top = (startY+dy).toString() + 'px';
    elm.style.left = (startX+dx).toString() + 'px';
  }

  void mouseup(e) {
    docMouseMoveSub.cancel();
    docMouseUpSub.cancel();
  }

  elm.onMouseDown.listen((e) {
    e.preventDefault();
    startX = elm.offsetLeft;
    startY = elm.offsetTop;
    // e.clientX works in Dartium, but fails on compiled js
    initialMouseX = e.client.x;
    // e.clientY works in Dartium, but fails on compiled js
    initialMouseY = e.client.y;
    docMouseMoveSub = document.onMouseMove.listen(mousemove);
    docMouseUpSub = document.onMouseUp.listen(mouseup);
  });
}

void main() {
  draggable(querySelector("#dragMe"));
}

Makefile for automating the development:

Makefile | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# path of Dart and utilities
DART_DIR=../../../../../dart
DART_SDK=$(DART_DIR)/dart-sdk
DART_SDK_BIN=$(DART_SDK)/bin
DARTVM=$(DART_SDK_BIN)/dart
DART2JS=$(DART_SDK_BIN)/dart2js
DARTPUB=$(DART_SDK_BIN)/pub
DARTIUM=$(DART_DIR)/chromium/chrome

HTML=dart-draggable-element.html

all: test

# Fix Dartium startup error:
# http://askubuntu.com/questions/369310/how-to-fix-missing-libudev-so-0-for-chrome-to-start-again
test:
	DART_FLAGS='--checked' $(DARTIUM) --user-data-dir=/tmp/data $(HTML) &

demo: js
	chromium-browser $(HTML)

js: app.dart
	$(DART2JS) --minify --out=app.js app.dart

# http://stackoverflow.com/questions/2989465/rm-rf-versus-rm-rf
clean:
	-rm *.js
	-rm *.deps
	-rm *.map

help:
	$(DARTVM) --print-flags

Note

Dart MouseEvent clientX and clientY are deprecated. If you use clientX or clientY, the compiled JavaScript will not work. see [3] for detail.


References:

[1](1, 2) JavaScript Drag and Drop (Draggable, Movable) Element without External Library
[2](1, 2) [AngularJS] Draggable (Movable) Element
[3][Dart] MouseEvent ClientX and ClientY Deprecated
[4][Golang] Draggable (Movable) Element by GopherJS