ラベル Dart の投稿を表示しています。 すべての投稿を表示
ラベル Dart の投稿を表示しています。 すべての投稿を表示

2017年2月15日水曜日

Dart x WebDriver Capture webpage

クローラーを作る。
ただ、最近だJavaScriptが動的にデータを読み込むパターンがあるので、
WebDriverを利用して、実際にウェブブラウザーを利用する必要がある。

Dartで試してみた。

Install

brew install selenium-server-standalone
brew install chromedriver

Run

1. Run chromedriver
> chromedriver

2. Write code and capture


import 'package:webdriver/core.dart' as wcore;
import 'package:webdriver/io.dart' as wio;
import 'dart:async';
import 'dart:io' as io;


main() async {
  var uri = Uri.parse('http://127.0.0.1:9515');
  wcore.WebDriver driver = await wio.createDriver(uri: uri);
  await driver.get('http://firefirestyle.net');
  await new Future.delayed(new Duration(seconds: 2));
  wcore.WebElement elm = await driver.activeElement;
  print("${await elm.text}");
  io.File f = new io.File("./out.jpg");
  await f.writeAsBytes(await driver.captureScreenshotAsList());
}
http://firefirestyle.net/




参考

http://qiita.com/isyumi_net/items/49a7e60fed6b39377e6a

2017年2月14日火曜日

Dart x WebGL Spring Mesh

XX-CAKE!(https://www21.atwiki.jp/xxcake/)の影響を受けて、Spring機能付きのMeshを作ってみた。

https://firefirestyle.github.io/nonno/v0_0_1/index.html


とりあえず、バネ機能付のMeshを生成する部分までのコードを書いてみた。
https://github.com/kyorohiro/nonno

実際に書いて動かしてみると、これをぷるんぷるん動画作成に利用するのは、
発想がすごいよなぁ。

真似したくなる。
応用も利くし。
便利


作り込むか決めてない。
Spring Mesh の計算はGPGPU にで書けないか試してみたくはある。

PS
今の所、Dartiumのgl.readPixcel()が不調なので、
WebGLをTextureを利用して、GPGPU化する場合は、
dart2jsを通して、Chromeで確認する必要がある。

まぁ、Dart Dev Compiler  待ちですね。




2017年2月8日水曜日

Dart x AngularDart x GAE x Go で ウェブページを作ってみた

AngularDart x GAE x Go  で ウェブページを作ってみました

http://firefirestyle.net/



Twitterでログインして、投稿ができます。タグ検索をサポートしています。
機能不足ですが、今週中くらいには、現在の提供している
機能で未実装の部分は実装する予定。

ただ、投稿サイトの機能は、外して、http://k07.me の方のみにするかも

フォロー機能、タイムライン機能、メッセージ機能は
k07meには、今年の前半中には
実装する予定です。

ノウハウはあるので

Source
https://github.com/firefirestyle/engine-v01-app
https://github.com/firefirestyle/engine-v01

2017年1月30日月曜日

Dart x WebBluetooth x BLE Peripheral Simulator x Eddystone 's memo (1)

WebBluetoothについて、BLEの学習も兼ねて、アレコレ遊んでみます。
Dartを利用します。

型があるので、保管機能を利用することができます。Crt+Space するだけで、何ができるのかが判断できて便利です。

欠点としては、Dartium のWebBluetoothへの対応が微妙なの事です。dart:jsで変換しないと、動作確認ができません。しかし、Dart DDC対応が完了すれば、この問題もなくなります。なので、今だけの問題といえるでしょう。



# Batteryサービスから、残量を取得してみる

とりあえず、Web Bluetooth x Dart で、HelloWorldをしてみる。

BLE Peripheral Simulator(https://github.com/WebBluetoothCG/ble-test-peripheral-android) は、Web Bluetooth の通信の実験相手をしてくれます。
とっても便利です。
ソースも公開されていますから、中身を見ながら、理解を深める事ができます。

BLE Peripheral Simulator の Batteryサービスから、バッテリー残量を取得して見ましょう。
※ BLE Peripheral Simulator は、GooglePlay からダウンロードできます。
https://play.google.com/store/apps/details?id=io.github.webbluetoothcg.bletestperipheral
※ chrome://flags よりWeb Bluetoothを有効にしてください。

===

Source
https://github.com/firefirestyle/ebook_webbluetooth_with_dart/tree/master/memo/test/hello

import 'package:angular2/core.dart';
import 'dart:html' as html;
import 'bt.dart' as b;
import 'dart:typed_data';


@Component(selector: 'my-app',
    template: """
    <h1>Hello {{name}}</h1>
    <div>
    <div *ngFor='let v of logs'>{{v}}</div>
    </div>
    <button (click)='onClick()'>Click</button>
    """
)
class AppComponent {
  var name = 'Angular';
  List<String> logs = [];

  log(String l) {
    print(l);
    logs.add(l);
  }

  onClick() async {
    b.Bluetooth bluetooth = b.getBluetooth();
    b.BluetoothDevice device = await bluetooth.requestDevice({ "filters": [{ "services": ['battery_service']}]});
    log("name : ${device.name}");
    log("id : ${device.id}");

    b.BluetoothRemoteGATTServer server = await device.gatt.connect();
    log("server.connected : ${server.connected}");

    b.BluetoothRemoteGATTService service = await server.getPrimaryService('battery_service');
    log("service.isPrimary : ${service.isPrimary}");
    log("service.uuid : ${service.uuid}");

    b.BluetoothRemoteGATTCharacteristic chara = await service.getCharacteristic('battery_level');
    log("service.uuid : ${chara.uuid}");

    ByteData buffer = await chara.readValue();
    log("service.value : ${buffer}");
    log("service.value : ${buffer.lengthInBytes}");
    log("service.value : ${buffer.buffer.asUint8List()}");
  }
}

===

参考

Web Bluetooth Draft Community Group Report, 27 January 2017


Implementation Status


LeScanは、これから
https://github.com/WebBluetoothCG/web-bluetooth/pull/239
https://webbluetoothcg.github.io/web-bluetooth/scanning.html



PS

個人的に、ネタを集めて、WebBluetoothについて、まとめる予定
たぶん以下で



2017年1月29日日曜日

AngularDart で Pinterestっぽい、Layout を試して見た。

Angular Dart で Pinterestっぽい、Design を試して見ました。
https://github.com/firefirestyle/ebook_windstyle_markdown/tree/master/angular/tiny-dynamicblock



隙間なく、四角形を詰めていくデモです。

コンストラクターで ElementRef を取得できる事がわかれば
簡単に書けますね!!

コード

main.dart

import 'package:angular2/platform/browser.dart';
import 'package:angular2/core.dart';
import 'dart:async';
import 'dart:html' as html;
import 'dynablock.dart' as dyna;
import 'dart:math';

main() {
  bootstrap(AppComponent);
}

class DynamicItemParam {
  int w;
  int h;

  DynamicItemParam() {
    Random rnd = new Random();
    w = rnd.nextInt(100) + 50;
    h = rnd.nextInt(200) + 100;
  }
}

@Component(
  selector: 'dynamicitem',
  template: """
  xxx
  """,
)
class DynamicItem implements OnInit {
  @Input()
  DynamicComponent parent;

  @Input()
  int width = 100;

  @Input()
  int height = 200;

  final ElementRef element;

  DynamicItem(this.element) {
    (element.nativeElement as html.Element).style.width = "${width}px";
    (element.nativeElement as html.Element).style.height = "${height}px";
    (element.nativeElement as html.Element).style.color = "#FF00";
    (element.nativeElement as html.Element).style.padding = "0px";
    (element.nativeElement as html.Element).style.margin = "0px";
    (element.nativeElement as html.Element).style.backgroundColor = 'yellow';
    (element.nativeElement as html.Element).style.display = 'inline-block';
    (element.nativeElement as html.Element).style.border =
    "medium solid #333333";
  }

  ngOnInit() {
    print("xx1 ${element.nativeElement}");
    (element.nativeElement as html.Element).style.width = "${width}px";
    (element.nativeElement as html.Element).style.height = "${height}px";
    if (parent != null) {
      parent.append(this);
    }
  }
}


@Component(
  selector: 'markdown-component',
  directives: const [DynamicItem],
  template: """
  <div #markdowncontent>
    <dynamicitem  *ngFor='let c of contents' [parent]='own' [width]='c.w' [height]='c.h' ></dynamicitem>
  </div>
  """,
)
class DynamicComponent implements OnInit {
  @Input()
  List<DynamicItemParam> contents;
  List<DynamicItem> items = [];

  html.Element _contentElement;
  dyna.DynaBlockCore dynaCore = new dyna.DynaBlockCore();


  final ElementRef element;
  DynamicComponent own;

  DynamicComponent(this.element) {
    var elm = element.nativeElement;
    elm.style.position = "absolute";
    own = this;
  }

  @ViewChild('markdowncontent')
  set main(ElementRef elementRef) {
    _contentElement = elementRef.nativeElement;
    print("${elementRef} ${elementRef.nativeElement}");
    _contentElement.onChange.listen((e) {
      print("-a");
    });
  }

  append(DynamicItem ap) {
    print("XXS");
    var elm = ap.element.nativeElement;
    int margineW = 10;
    int margineH = 10;
    dyna.FreeSpaceInfo info = dynaCore.addBlock(
        ap.width + margineW, ap.height + margineH);
    elm.style.position = "absolute";
    elm.style.left = "${info.xs}px";
    elm.style.top = "${info.y}px";
  }

  ngOnInit() {
  }
}

@Component(
    selector: 'my-app',
    directives: const [DynamicComponent],
    template: """
    <markdown-component [contents]='contents'></markdown-component>
  """
)
class AppComponent implements OnInit {
  List<DynamicItemParam> contents = [
    new DynamicItemParam(),
    new DynamicItemParam(),
    new DynamicItemParam(),
    new DynamicItemParam(),
  ];

  ngOnInit() async {
    for (int i = 0; i < 10; i++) {
      contents.add(new DynamicItemParam());
      await new Future.delayed(new Duration(milliseconds: 500));
    }
  }
}


四角形を埋め尽くすアルゴ

https://github.com/firefirestyle/ebook_windstyle_markdown/blob/master/angular/tiny-dynamicblock/app/web/dynablock.dart


2017年1月28日土曜日

AngularDart で Markdownを利用してみる

AngularDart で Markdownを利用してみた。
"#" と、@ViewChild を利用の仕方を覚えた!!

https://github.com/firefirestyle/ebook_windstyle_markdown/tree/master/angular/tiny-markdown

import 'package:angular2/platform/browser.dart';
import 'package:angular2/core.dart';
import 'dart:async';
import 'dart:html' as html;
import 'package:markdown/markdown.dart' as mark;

main() {
  bootstrap(AppComponent);
}


@Component(
  selector: 'markdown-component',
  template: """
  <div #markdowncontent></div>
  """,
)
class MarkdownComponent implements OnInit {
  @Input()
  String content;

  html.Element _contentElement;

  @ViewChild('markdowncontent')
  set main(ElementRef elementRef) {
    _contentElement = elementRef.nativeElement;
  }

  ngOnInit() {
    _contentElement.children.clear();
    _contentElement.children.add(new html.Element.html(
        """<div>${mark.markdownToHtml(content)}</div>""",
        treeSanitizer: html.NodeTreeSanitizer.trusted)
    );
    print(">> ${content}");
  }
}

@Component(
    selector: 'my-app',
    directives: const [MarkdownComponent],
    template: """
    <markdown-component [content]='content'></markdown-component>
  """
)
class AppComponent {
  String content = """
# H1
aasasdfa;lklasdf
  """;
}



2017年1月27日金曜日

AngularDart RouteParams.params は UrlEncodeされたまま

OAuthの認証っぽいコードを書いていて、
URLの中にAccessTokenを渡すような書き方をしてみた。

その時に、渡されたパラメータが、UrlEncodeが必要な事に気がついた。


import 'package:angular2/core.dart';
import 'package:angular2/router.dart';
import 'package:cl/config.dart' as config;


@Component(
    selector: "myhome",
    template:  """
    <div class="mybody">
    <h1>Home</h1>
    </div>
  """,
    styles: const[
      """
    .mybody {
      display: block;
      height: 600px;
    }
    """,
    ]
)
class HomeComponent implements OnInit {
  String twitterLoginUrl = "";
  final RouteParams _routeParams;
  HomeComponent(this._routeParams);
  config.AppConfig rootConfig = config.AppConfig.inst;

  ngOnInit() {
    twitterLoginUrl =  config.AppConfig.inst.twitterLoginUrl;
    print(_routeParams.params.toString());
    if(_routeParams.params.containsKey("token")) {
      config.AppConfig.inst.cookie.accessToken = Uri.decodeFull(_routeParams.params["token"]);
      config.AppConfig.inst.cookie.setIsMaster(_routeParams.params["isMaster"]);
      config.AppConfig.inst.cookie.userName = Uri.decodeFull(_routeParams.params["userName"]);
    }
  }
}
===

それは、そうだよなぁ...。
バイナリーデータが渡される事もあるわけだし

と、しかし、
Url.decodeFull()にバイナリデーターが返るような値を渡すと

どんな感じになるのだろうか?



AngularDartを利用して Inputタグで画像を読み込むダイアログ。(2) 関数渡しをしてみる

前回のを、もう少し、賢くしてみました。

関数やパラメータを渡せるようにする
初期化しなくても動作するようにする
エラーメッセージ等を呼び出せるようにする


https://github.com/firefirestyle/ebook_windstyle_markdown/tree/master/angular/image-input-dialog/app


dialog.dart

import 'package:angular2/core.dart';
import 'package:angular2_components/angular2_components.dart';
import 'dart:html' as html;
import 'imageutil.dart' as imgutil;
import 'dart:async';


@Component(
  selector: 'inputimage-dialog',
  styles: const [
    """
    .inputimage-dialog-title {
    }
    .inputimage-dialog-message {
    }
    .inputimage-dialog-errormessage {
    }
    .inputimage-dialog-cancelbutton{
    }
    .inputimage-dialog-okbutton{
    }
    """,
  ],
  template: """
<modal #wrappingModal>
  <material-dialog style='width:80%'>
    <div *ngIf='errorMessage!=""' class='inputimage-dialog-errormessage'>{{errorMessage}}</div>
    <h3 class='inputimage-dialog-title' header>{{param.title}}</h3>
    <p class='inputimage-dialog-message'>{{param.message}}</p>
    <material-spinner *ngIf='isloading'></material-spinner>
    <div #imgc></div><br>
    <input #in *ngIf='isloading==false' type="file" id="upload" (change)='onInput(in,imgc)'>
    <div footer>
      <material-button *ngIf='isloading==false' autoFocus clear-size (click)="onCancel(wrappingModal)" class='inputimage-dialog-cancelbutton'>
        {{param.cancel}}
      </material-button>
      <material-button *ngIf='currentImage!=null||isloading==false' autoFocus clear-size (click)="onFile(wrappingModal)" class='inputimage-dialog-okbutton'>
        {{param.ok}}
      </material-button>
    </div>
  </material-dialog>
</modal>
  """,
  directives: const [materialDirectives],
  providers: const [materialProviders],
)
class InputImageDialog implements OnInit {
  @ViewChild('wrappingModal')
  ModalComponent wrappingModal;

  @Input()
  InputImageDialogParam param;

  bool isloading = false;
  html.ImageElement currentImage = null;
  String errorMessage = "";

  ngOnInit(){
    if(param == null) {
      param = new InputImageDialogParam();
    }
  }

  void open() {
    wrappingModal.open();
  }

  onCancel(ModalComponent comp) {
    wrappingModal.close();
  }

  onFile(ModalComponent comp) async {
    isloading = true;
    try {
      var ret = await param.onFile(this);
      if (ret != "" && ret != null) {
        errorMessage = ret;
      } else {
        errorMessage = "";
        wrappingModal.close();
      }
    } catch (e) {
      errorMessage = "failed to (${e})";
    } finally {
      isloading = false;
    }
  }

  onInput(html.InputElement i,html.DivElement c) async {
    isloading = true;
    try {
      c.children.clear();
      if(i.value.length <= 0) {
        return;
      }
      var img = await imgutil.ImageUtil.loadImage(i.files.first);
      var img1 = await imgutil.ImageUtil.resizeImage(img);
      c.children.add(img1);
      currentImage = img1;
    } catch(e){
      errorMessage = "failed to (${e})";
    } finally{
      isloading = false;
    }
  }
}

typedef Future<String> OnFileFunc(InputImageDialog d);

class InputImageDialogParam {
  String title;
  String message;
  String ok;
  String cancel;
  int get imgWidth => 300;
  int get imgHeight => -1;
  OnFileFunc onFileFunc;

  InputImageDialogParam({this.title:"File",this.message:"select file!!",this.ok:"OK",this.cancel:"Cancel",
  onFileFunc: null}){
  }

  /**
   * if failed to do onFind func, then return error message.
   */
  Future<String> onFile(InputImageDialog d) async {
    if (onFileFunc == null) {
      return "";
    } else {
      return onFileFunc(d);
    }
  }
}

====


main.dart


import 'package:angular2/platform/browser.dart';
import 'package:angular2/core.dart';
import 'dialog.dart';

void main() {
  bootstrap(AppComponent);
}

@Component(
    selector: "my-app",
    directives: const [InputImageDialog],
    template: """
    <div>
    <h1>Dialog Test</h1>
    <div>
    <button (click)='onClick(myDialoga)'>open</button>
    </div>
    <inputimage-dialog #myDialoga [param]='param'>
    </inputimage-dialog>
    </div>
  """
)
class AppComponent implements OnInit {
  final InputImageDialogParam param = new InputImageDialogParam();

  AppComponent();
  ngOnInit() {
  }
  onClick(InputImageDialog _dialog) async {
    _dialog.open();
  }
}

====

InputImageDialogParam を用意して、デフォルト値を持たせるようにして
初期化は必須で無くした。

onFIle()メソッドを追加して、後から機能を拡張できるようにしてみた。


うーむ
徐々に汎用的な部品が作れるようになってきたかな。
まだ、微妙かな



2017年1月26日木曜日

AngularDartを利用して Inputタグで画像を読み込むダイアログ

AngularDart を利用して、Inputタグで画像を読み込むダイアログを作ってみた。



#xxxx で、domを紐づけたりできるのを知った。

https://github.com/firefirestyle/ebook_windstyle_markdown/tree/master/angular/image-input-dialog/app


===
main.dart

import 'package:angular2/platform/browser.dart';
import 'package:angular2/core.dart';
import 'input_img_dialog.dart';
void main() {
  bootstrap(AppComponent);
}

@Component(
    selector: "my-app",
    directives: const [InputImageDialog],
    template: """
    <div>
    <h1>Dialog Test</h1>
    <div>
    <button (click)='onClick(myDialoga)'>open</button>
    </div>

    <input-image-dialog #myDialoga>
    </input-image-dialog>

    </div>
  """
)
class AppComponent implements OnInit {
  AppComponent();
  ngOnInit() {
  }
  onClick(InputImageDialog _dialog) async {
    _dialog.open();
  }
}

===

input_image_dialog.dart


import 'package:angular2/core.dart';
import 'package:angular2_components/angular2_components.dart';
import 'dart:html' as html;
import 'imageutil.dart' as imgutil;
import 'dart:async';

@Component(
  selector: 'input-image-dialog',
  template: """
<modal #wrappingModal>
  <material-dialog style='width:80%'>
    <h3 header> File </h3>
    <material-spinner *ngIf='isloading'></material-spinner>
    <div #imgc></div>
    <div footer>
      <input #in type="file" id="upload" (change)='onInput(in,imgc)'>
      <material-button autoFocus clear-size (click)="onCancel(wrappingModal)">
        Cancel
      </material-button>
      <material-button *ngIf='currentImage!=null' autoFocus clear-size (click)="onFile(wrappingModal)">
        File
      </material-button>
    </div>
  </material-dialog>
</modal>
  """,
  directives: const [materialDirectives],
  providers: const [materialProviders],
)
class InputImageDialog {

  @ViewChild('wrappingModal')
  ModalComponent wrappingModal;

  bool isloading = false;
  html.ImageElement currentImage = null;

  void open() {
    wrappingModal.open();
  }

  onCancel(ModalComponent comp) {
    wrappingModal.close();
  }
  onFile(ModalComponent comp) {
    wrappingModal.close();
  }

  onInput(html.InputElement i,html.DivElement c) async {
    isloading = true;
    try {
      if(i.value.length <= 0) {
        return;
      }
      var img = await imgutil.ImageUtil.loadImage(i.files.first);
      var img1 = await imgutil.ImageUtil.resizeImage(img);
      c.children.add(img1);
      currentImage = img1;
    } catch(e){
    } finally{
      isloading = false;
    }
  }
}

===


2017年1月24日火曜日

AngularDart の Router を使って見た。

AngularDart の Router を使って見た。
Tour of Heros を試してみて。ちょっと躓いたので、記録だけ。

Router機能で、画面を切り替えるだけのコードなら、100行もない。

https://github.com/firefirestyle/ebook_windstyle_markdown/tree/master/angular/tiny-routing

===
main.dart

import 'package:angular2/platform/browser.dart';
import 'package:angular2/core.dart';
import 'package:angular2/router.dart';
import 'package:angular2/platform/common.dart';
import 'dart:async';

void main() {
  bootstrap(AppComponent);
}

@Component(
    selector: 'my-app',
    template: '''
      <h1>{{title}}</h1>
      <nav>
        <a [routerLink]="['XXX']">XXX</a>
        <a [routerLink]="['YYY']">YYY</a>
      </nav>
      <router-outlet></router-outlet>''',
    directives: const [ROUTER_DIRECTIVES],
    providers: const [ROUTER_PROVIDERS])
@RouteConfig(const [
  const Route(
      path: '/xxxx',
      name: 'XXX',
      component: XXXComponent,
      useAsDefault: true),
  const Route(path: '/yyy', name: 'YYY', component: YYYComponent)
])
class AppComponent {
  String title = 'Tour of Heroes';
}


@Component(
  selector: 'yyyy',
  template: """<div>xxx</div> """,
  directives: const [ROUTER_DIRECTIVES],
)
class XXXComponent {
  XXXComponent();
}


@Component(
    selector: 'xxxx',
    directives: const [ROUTER_DIRECTIVES],
    template: """
    <div>yyy {{v}}</div>
    <button (click)="goBack()">Back</button>
    <button (click)="gotoDetail()">View Details</button>""")
class YYYComponent implements OnInit {
  final Router _router;
  final Location _location;
  String v="";
  YYYComponent(this._router,this._location);

  void ngOnInit() {
    v = _location.path();
  }

  void goBack() => _location.back();
  Future<Null> gotoDetail() => _router.navigate([
    'XXX'
  ]);
}
===

index..html
====

<!DOCTYPE html>
<html>
  <head>
    <!-- For testing using pub serve directly use: -->
    <base href="/">
    <title>Hello Angular</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script defer src="main.dart" type="application/dart"></script>
    <script defer src="packages/browser/dart.js"></script>
  </head>
  <body>
  <my-app>Loading AppComponent content here ...</my-app>
  </body>
</html>
====

チュートリアルには書いているのですが、
<base href="/">
を書き忘れて、躓いた。


そこだけ、注意。


2017年1月22日日曜日

Eddystone を試してみた。

Eddystoneを試してみました。
Eddystoneは、Google が勧めている Beaconサービスです。
Beaconといえば、AppleのiBeaonが有名ですが、Google も遅れて参戦してきました。

Chromeブラウザーがすでに、Beaconを発見する機能を持っている事と、
あと、URL(http://www 等をのぞいた17文字)を直接Beaconとして発信できるため、eddysone対応のBeaconを利用すれだけで、WebページをBeacon対応化できます。


Beaconを発信してみる

https://github.com/don/node-eddystone-beacon を利用するとすぐできます。
===
EB = require('eddystone-beacon');

EB.advertiseUrl('https://goo.gl/EmhB38');
===

アドレスは、httpsである必要があります!! ショートURLのリダイレクト先も同様です。
httpsである必要があるようです。
※ 正確には、chromeが受信するためには...


Beaconを受信してみる。

Chromeを設定してください。ちょっと、めんどくさいです。

android 

https://support.google.com/chrome/answer/6239299?co=GENIE.Platform%3DAndroid&hl=en

ios

https://docs.pushmote.com/docs/how-to-enable-chromes-physical-web-extension-on-the-ios


発見すると、通知画面に表示されます。バックグラウンドで実行されているわけではないので、iosでは、Widgetを開く必要があります。Androidも似たような感じでした。



2017年1月20日金曜日

AngularDart のチュートリアルを試してみた。 ngModel

前回の通り、AngularDartだとデータを紐づけるのが簡単。
で、Html側で値を変更するようなシナリオがあった場合は、ngModelを利用すると
良いですよ的な事が、Angular Dart の Tutorial に書かれていた。



import 'package:angular2/platform/browser.dart';
import 'package:angular2/core.dart';

void main() {
  bootstrap(AppComponent);
}

class Monster {
  int id;
  String name;
  int lv;
  Monster({this.id:0,this.name:"slime",this.lv:1});
}

@Component(
    selector: "my-app",
    template: """
      <div>Lv. {{monster.lv}} 's {{monster.name}} </div>
      <div> <label>mode name </label><input value={{monster.name}}></div>
      <div> <label>mode name ngmodel</label><input [(ngModel)]="monster.name"></div>
    """)
class AppComponent {
  Monster monster = new Monster();
}
ngModelを利用しない方は、Input Domで値を変えても、Lv.{{}}.... の部分は変更されない。
しかし、ngModelを利用すると、 Input Domで値を変えると、 Lv{{}}... の部分が変更されます。

便利!!


2017年1月18日水曜日

AngularDart のチュートリアルを試してみた。

この、2年間はDart 向けのフレームワークをアレコレ行ったり来たりしていました。

私の場合だと、Web系では、dart_web_toolkit -> polymer-dart ->フルスクラッチ-> material design lite -> フルスクラッチ
アプリ系では、chrome app -> flutter -> cordova x フルスクラッチ  

しかし、そろそろ、Angular Dart と、Flutter が、そろそろ使えるようになるのではと期待しています。

で、学習を再開しました。ドンドン使ってみる。


まずは、Angular Dart の Tutorial を 試してみました。 良い感じ。とってもコードを書くのが楽になりました。
※ AngularDart 用の componentsも、だいたい揃ってる。


Data Binding とか

例えば、Dartのクラスと、Domが自動で連携してくれて便利!!
一秒ごとに、Counterを増やすような場合、以下のような感じで書ける。
https://github.com/kyorohiro/memo.dart.angular/tree/master/a002

main.dart
import 'package:angular2/platform/browser.dart';
import 'package:angular2/core.dart';
import 'dart:async';

main() {
  bootstrap(AppComponent);
}

@Component(
    selector: 'my-app',
    template: """
  <div>{{counter}}</div>
  """
)
class AppComponent implements OnInit {
  int counter = 0;

  ngOnInit() {
    new Future(() async {
      while (true) {
        await new Future.delayed(new Duration(seconds: 1));
        counter++;
      }
    });
  }
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>a002</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script defer src="main.dart" type="application/dart"></script>
    <script defer src="packages/browser/dart.js"></script>
  </head>
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

Domを検索して、そのドムの値を更新するコードを書くとか。
いらない。


他にも、アレコレと







2017年1月17日火曜日

Dart x Flutter の学習再開 HelloWorld

1.6ヶ年くらいに、、Flutter x Dartの学習をして、Umiuni2dとかつくったり、学習記録を残したり、GooglePlayリリースしたりしていたのですが、ペンドしていました。

実際には、Cordova x Dart を利用する方が多かったからです。
が、しかし、ネイティブ機能を自由に拡張できるようになったので、(以前もコードを直接いじればできたけど)、使いたくなりました。

で、再開します。


HelloWorld

https://github.com/kyorohiro/memo_flutter/blob/master/lib/hello.dart

==

import 'package:flutter/material.dart';

void main() {
  runApp(new Text("Hello World!!"));
}
==

黒の画面に、HelloWorldと白く文字が表示されました。

補足

pubでなくて、
flutter packages get
flutter packages upgrade
を利用する


pubspec.yamlのdependencyは、sdkを使う

name: memo_flutter
description: A new flutter project.
dependencies:
  flutter:
    sdk: flutter


注意

あっという間に、これらの情報は古くなるので、公式サイト(https://flutter.io/)を参考にしてください。


2017年1月15日日曜日

Dart x Flutter 用の iBeaconプラグインを作成してみた。(Android Only 今のところ)

Flutter x Dart を利用して、ネイティブの機能を独自に拡張できるのは、前回解説しました。
実際に使えるアプリを作ってみようと考えています。昔 Chrome Mobile を利用して作った UPnP Port Mapperのコードベースが古くてバグがあるので、新たに作り直そうかなぁとも考えました。
しかし、趣向を変えて、ちょっと要望があったので、位置情報関連を試す事にしました。

とりあえず、iBeaconを探索する機能を追加してみました。

## iBeacon用のプラグイン

以前作成したCordova用のPluginを再利用する事にしました(https://github.com/kyorohiro/umiuni2d_beacon)。 この子はAndroidでも、iOSでも動作します。

## Android用のJarを抜き出す

https://github.com/kyorohiro/android.tinybeacon

Android用の機能だけまずは、抜き出してjar化しました。機能はとても少なく
# void startLescan(Context context)
スキャンを開始する

# void stopLescan()
スキャンを停止する

# getFoundedBeeaconAsJSONText()
発見したBeaconをJSON形式で取得

# List<TinyBeaconInfo> getFoundedBeeacon()
発見したBeacon情報を取得する。

# void clearFoundedBeeacon()
発見したBeacon情報をクリアする

だけです。もちろん距離とかも測定できます。



## Flutter Plugin として組み込む

https://github.com/kyorohiro/dart.flutter.ibeacon

実際に、組み込んでみました。
アプリ部分は、これから作ります。


何を作ろうかなぁ。
Beaconバトラーとか
位置情報系のサービスとか

忘れ物探しツールとか

..


## 前回のは以下

http://kyorohiro.blogspot.jp/2017/01/dart-x-flutter-platform-service-javadart.html

http://qiita.com/kyorohiro/items/fef353c4ff86a665c984



2017年1月13日金曜日

Android上で、Dart x Flutter の platform service で、JavaとDartを連携させてみる

Dart x Flutter の platform service 機能を利用して、JavaとDartを連携させてみました。
公式のサンプルを読むだけだと、具体的に何をしているのかが、しっくりこなかったので、実際にプロジェクトをゼロから作ってみました。

試した結果は以下におきました
公式のサンプルを参考にして、プロジェクトの作成から試してみました。

https://github.com/kyorohiro/dart.flutter.platformservice
https://github.com/kyorohiro/dart.flutter.ibeacon




コード自体はとても少なく済んでいます。
また、AtomなどのIDEからもDartのプロジェクトとして実行できるので、
拡張したとしても、ストレスなく開発を続ける事ができます。

こんな順序で作業してみた



1. まずは、IntelliJ を利用して、Flutterプロジェクトを作る

まずは、Flutterのプロジェクトを作ってみました。
https://github.com/kyorohiro/dart.flutter.ibeacon/tree/8d7bfdc166f6027999c6ca57acfb6a7edfd0bc41



2. android配下を削除して、Android Stdioでプロジェクトを作る

https://github.com/kyorohiro/dart.flutter.ibeacon/tree/5bc3631a5a644753ddcfc8daf9062201248a4d10

https://github.com/kyorohiro/dart.flutter.ibeacon/tree/5ff7facd1a2b8c4f19791a68b754e83e07770fda


3. buildSrcをサンプルから、コピーして、各種設定をする。

GradleのFlutterプラグインを利用します。公式のサンプルコードからコピーしました。
https://github.com/kyorohiro/dart.flutter.ibeacon/tree/8496c634ebb15c7ee6a8855d250627eddcb012b8


3.1 android/app/build.gradleに追加

+apply plugin: 'flutter'

+

+
+flutter {
+ source '../..'
+}


3.2 local.propertiesにパスを追加

+ flutter.sdk=/Users/kyorohiro/tools/git/flutter


4. とりあえず、Dartのコードを動作させてみる

Dartを動作させる環境ができたので、上手く動作するか確認してみした。AndroidManifesrtとActivityを少し変更します。

https://github.com/kyorohiro/dart.flutter.ibeacon/tree/4d09df74bf678d4094c3e56a4f632564f7f0e81e

4.1 Application Name を Dart用に変更する
==

<manifest package="info.kyorohiro.ibeacontest" xmlns:android="http://schemas.android.com/apk/res/android">

    <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:name="org.domokit.sky.shell.SkyApplication" android:supportsrtl="true" android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"></action>
                <category android:name="android.intent.category.LAUNCHER"></category>
            </intent-filter>
        </activity>

    </application>

</manifest>
==

4.2 Dartのコードを読み込むようにする
===

package info.kyorohiro.ibeacontest;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView;

/**
 * Created by kyorohiro on 2017/01/13.
 */

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FlutterMain.ensureInitializationComplete(this,null);
        LinearLayout rootLayout = new LinearLayout(this);
        this.setContentView(rootLayout);

        FlutterView flutterView = new FlutterView(this);
        rootLayout.addView(flutterView);

        flutterView.runFromBundle(FlutterMain.findAppBundlePath(getApplicationContext()), null);
    }
}
===



5 JavaとDart 間で通信するコードを追加する

実際にJavaとDartを連携させてみました。上手く動作した。

https://github.com/kyorohiro/dart.flutter.ibeacon/blob/5995b98e12850f49344bb5f306f0e3273874a805/android/app/src/main/java/info/kyorohiro/ibeacontest/MainActivity.java

====++

package info.kyorohiro.ibeacontest;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Created by kyorohiro on 2017/01/13.
 */

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FlutterMain.ensureInitializationComplete(this,null);
        LinearLayout rootLayout = new LinearLayout(this);
        this.setContentView(rootLayout);

        FlutterView flutterView = new FlutterView(this);
        rootLayout.addView(flutterView);

        flutterView.runFromBundle(FlutterMain.findAppBundlePath(getApplicationContext()), null);

        flutterView.addOnMessageListener("callback_sync", new FlutterView.OnMessageListener(){
            @Override
            public String onMessage(FlutterView flutterView, String message) {
                return "hi sync" + message;
            }
        });

        flutterView.addOnMessageListenerAsync("callback_async", new FlutterView.OnMessageListenerAsync() {
            @Override
            public void onMessage(FlutterView flutterView, String message, FlutterView.MessageResponse messageResponse) {
                messageResponse.send("hi async" + message);
            }
        });

        flutterView.addOnMessageListenerAsync("callback_proc", new FlutterView.OnMessageListenerAsync() {
            @Override
            public void onMessage(FlutterView flutterView, String message, final FlutterView.MessageResponse messageResponse) {
                JSONObject jsonMessage = new JSONObject();
                try {
                    jsonMessage.put("vvv", 100);
                } catch(JSONException e){
                }
                //jsonMessage.put("v",1);
                flutterView.sendToFlutter("hi", jsonMessage.toString(), new FlutterView.MessageReplyCallback() {
                    @Override
                    public void onReply(String s) {
                        messageResponse.send(s);
                    }
                });
            }
        });
    }
}
====++

https://github.com/kyorohiro/dart.flutter.ibeacon/blob/5995b98e12850f49344bb5f306f0e3273874a805/lib/main.dart

====

import 'package:flutter/material.dart';
import 'package:flutter/services.dart' as fsv;
import 'dart:typed_data';
import 'dart:convert';

void main() {
  runApp(new MyApp());

}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    fsv.PlatformMessages.setJSONMessageHandler("hi",(String v) async{
      return v;
    });
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String message = "";

   _incrementCounter() async {
     //
    ByteData buffer0 = await fsv.PlatformMessages.sendBinary("callback_sync", new ByteData.view(
      new Uint8List.fromList([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]).buffer
    ));

    //
    String buffer1 = await fsv.PlatformMessages.sendString("callback_async", JSON.encode({"test":"hello"}));

    //
    String buffer2 = await fsv.PlatformMessages.sendString("callback_proc", "hello");


    //
    message = "${buffer0.buffer.asUint8List()} :: ${buffer1} :: ${buffer2}" ;
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(config.title),
      ),
      body: new Center(
        child: new Text(
          '${message} $_counter time${ _counter == 1 ? '' : 's' }.',
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ), // This trailing comma tells the Dart formatter to use
    );
  }
}
====




mbedtls dart の 開発を始めた web wasm ffi io flutter

C言語 で開発した機能を、Dart をターゲットとして、Web でも サーバーでも、そして Flutter  でも使えるようにしたい。 そこで、mbedtls の 暗号化の部分を Dart 向けのPackageを作りながら、 実現方法を試行錯誤する事にした。 dart...