« 2013年12月 | メイン | 2014年02月 »

2014年01月 アーカイブ

2014年01月08日

[TypeScript] TypeScript に関する参考資料

TypeScript

TypeScript に関する参考資料を集めてみた。

Web

書籍

2014年01月10日

Microsoft Virtual Academy のご紹介

study.jpg

Microsoft Virtual Academy のご紹介

Microsoft Virtual Academy は、マイクロソフトの無償のオンライン トレーニングです。

特徴

入門者向けの内容が多いのが特徴です。

スライドと動画を観ながら講義を受けられます。

(英語のコンテンツもありますが、字幕が出るものが多くあります)

マイクロソフト アカウントでサインアップして参加することで、学習の進み具合も記録され、継続的な学習ができます。

C# / XAML のコンテンツ

C# と XAML によるアプリケーション開発について学びたい人向けのコンテンツの一覧は次の場所にあります。

例えば、これから Windows ストア アプリの C# での開発方法を学習したい人は、次の順に進めていくこ良いでしょう。

  1. 最新 .NET 技術によるアプリケーション開発入門
     これから .NET を始める方向け。Visual Studio 2013 に合わせた新しい内容。
  2. いまさら聞けない Windows アプリ開発入門 XAML/C# 編
    初めて XAML/C# で Windows 用のアプリを開発する人向け。
  3. C# を使用した Windows ストア アプリ開発概要ジャンプ スタート
    より詳しく XAML/C# でのWindows ストア アプリ開発について解説。
  4. C# を使用した高度な Windows ストア アプリ開発ジャンプ スタート
    中級~上級学習者向け。

2014年01月17日

[TypeScript] Lightningtalks Timer by HTML5

lightningtalkstimer.png

以前作った HTML5 用のライトニングトーク用のタイマーを、TypeScript で書きなおしてみた。

TypeScript を使うことで、よりすっきりと書ける。また、Visual Studio でのインテリセンスや静的な型チェックが行える為、とても楽だ。

lightningtalktimer.ts

TypeScript コンパイラーによって lightningtalktimer.js に変換される。

// for lightningtalktimer.html
// generated from lightningtalktimer.ts
// Ver.1.01 2014-01-17
// Copyright © 2014 Sho's Software by Fujiwo http://www.shos.info

module LightningTalkTimer {
    export class Application {
        private static timer = null;

        private static get canvas(): HTMLCanvasElement {
            return <HTMLCanvasElement>document.querySelector("canvas");
        }

        private static get context(): CanvasRenderingContext2D {
            return <CanvasRenderingContext2D>Application.canvas.getContext("2d");
        }

        static run() {
            Application.sizing();
            Application.timer = new Timer(this.context, this.canvas.width, this.canvas.height);
        }

        static onClick() {
            Application.timer.start();
        }

        private static sizing() {
            var canvas    = Application.canvas;
            canvas.height = window.innerHeight;
            canvas.width  = window.innerWidth ;
        }
    }

    class Utility {
        static getQuerystring(key: string, default_: string = null): string {
            if (default_ == null)
                default_ = "";
            key             = key.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
            var regex       = new RegExp("[\\?&]" + key + "=([^&#]*)");
            var queryString = regex.exec(window.location.href);
            return queryString == null ? default_ : queryString[1];
        }

        static secondsToString(totalSeconds: number): string {
            var minutes     = Math.floor(totalSeconds / 60);
            var seconds     = totalSeconds % 60;
            var secondsText = (seconds >= 10) ? seconds.toString() : "0" + seconds;
            return minutes.toString() + ':' + secondsText;
        }

        static getCurrentMilliSeconds(): number {
            return Date.parse(new Date().toString());
        }
    }

    class Parameter {
        maxSeconds       = 60 * 5;
        dangerousSeconds = 60 * 1;
        fontHeightRate   = 70;

        constructor() {
            this.setMaxSeconds      ();
            this.setDangerousSeconds();
            this.setFontHeight      ();
        }

        private setFontHeight() {
            var fontHeightRateText = Utility.getQuerystring("font");
            if (fontHeightRateText != "") {
                var heightRate = parseInt(fontHeightRateText);
                if (heightRate > 0 && heightRate <= 100)
                    this.fontHeightRate = heightRate;
            }
        }

        private setMaxSeconds() {
            var maxSecondsText = Utility.getQuerystring("max");
            if (maxSecondsText != "") {
                var seconds = parseInt(maxSecondsText);
                if (seconds > 0) {
                    this.maxSeconds = seconds;
                    if (this.dangerousSeconds > this.maxSeconds)
                        this.dangerousSeconds = this.maxSeconds;
                }
            }
        }

        private setDangerousSeconds() {
            var dangerousSecondsText = Utility.getQuerystring("danger");
            if (dangerousSecondsText != "") {
                var seconds = parseInt(dangerousSecondsText);
                if (seconds >= 0 && seconds <= this.maxSeconds)
                    this.dangerousSeconds = seconds;
            }
        }
    }

    class View {
        private static normalDarkColor     = "#100";
        private static normalLightColor    = "#a99";
        private static dangerousDarkColor  = "#e00";
        private static dangerousLightColor = "#f99";
        private static shadowColor         = "gray";

        private context: CanvasRenderingContext2D;

        constructor(context: CanvasRenderingContext2D) {
            this.context = context;
        }

        draw(text: string, isNormal: boolean, width: number, height: number, fontHeightRate: number) {
            this.context.clearRect(0, 0, width, height);
            View.drawText(this.context, text, View.getDarkColor(isNormal), View.getLightColor(isNormal), width, height, fontHeightRate);
        }

        private static drawText(context: CanvasRenderingContext2D, text: string, colorDark: string, colorLight: string, width: number, height: number, fontHeightRate: number) {
            var fontHeight = height * fontHeightRate / 100;
            var y          = fontHeight * (16 + 1) / 16;
            context.font   = fontHeight + "px 'メイリオ',Meiryo,'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro',Calibri,sans-serif";
            View.setGradient(context, fontHeight, colorDark, colorLight);
            View.setShadow  (context, fontHeight                       );
            context.fillText(text, fontHeight / 12, y);
        }

        private static getDarkColor(isNormal: boolean): string {
            return isNormal ? View.normalDarkColor : View.dangerousDarkColor;
        }

        private static getLightColor(isNormal: boolean): string {
            return isNormal ? View.normalLightColor : View.dangerousLightColor;
        }

        private static setGradient(context: CanvasRenderingContext2D, fontHeight: number, darkColor: string, lightColor: string) {
            var gradient      = context.createLinearGradient(0, 0, 0, fontHeight);
            gradient.addColorStop(0.5, darkColor);
            gradient.addColorStop(0.6, lightColor);
            gradient.addColorStop(0.7, darkColor);
            context.fillStyle = gradient;
        }

        private static setShadow(context: CanvasRenderingContext2D, fontHeight: number) {
            context.shadowColor   = View.shadowColor;
            context.shadowOffsetX = fontHeight / 36;
            context.shadowOffsetY = fontHeight / 36;
            context.shadowBlur    = fontHeight / 48;
        }
    }

    class Timer {
        private width    : number;
        private height   : number;
        private parameter: Parameter;
        private view     : View;
        private timerID =  0;

        constructor(context: CanvasRenderingContext2D, width: number, height: number) {
            this.width     = width  ;
            this.height    = height ;
            this.parameter = new Parameter();
            this.view      = new View(context);
            this.draw(this.parameter.maxSeconds, this.isNormal(this.parameter.maxSeconds));
        }

        private start() {
            this.reset();
            var start    = Utility.getCurrentMilliSeconds();
            this.timerID = window.setInterval(() => this.update(start), 1000);
        }

        private update(start: number) {
            var now = Utility.getCurrentMilliSeconds();
            var remainingSeconds = this.parameter.maxSeconds - (now - start) / 1000;
            if (remainingSeconds < 0)
                remainingSeconds = 0;
            this.draw(remainingSeconds, this.isNormal(remainingSeconds));
            if (remainingSeconds == 0)
                window.clearInterval(this.timerID);
        }

        private reset() {
            window.clearInterval(this.timerID);
            this.draw(this.parameter.maxSeconds, this.isNormal(this.parameter.maxSeconds));
        }

        private draw(seconds: number, isNormal: boolean) {
            this.view.draw(Utility.secondsToString(seconds), isNormal, this.width, this.height, this.parameter.fontHeightRate);
        }

        private isNormal(remainingSeconds: number): boolean {
            return remainingSeconds > this.parameter.dangerousSeconds;
        }
    }
}

window.onload = () => {
    LightningTalkTimer.Application.run();
};

lightningtalktimer.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,minimum-scale=1, maximum-scale=1, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>Sho's Lightning Talks Timer by HTML5</title>
    <style>
        html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, dialog, figure, footer, header, hgroup, menu, nav, section, menu, time, mark, audio, video {
            margin: 0;
            padding: 0;
            border: 0;
            outline: 0;
            font-size: 100%;
            vertical-align: baseline;
            background: transparent;
        }

        article, aside, dialog, figure, footer, header, hgroup, nav, section {
            display: block;
        }

        body {
            width: 100%;
            overflow: hidden;
        }
    </style>
    <script src="lightningtalktimer.js"></script>
</head>
<body>
    <canvas width="500" height="500" onclick="LightningTalkTimer.Application.onClick()"></canvas>
</body>
</html>

<!--
Usage:
    Click: reset and start counting down.

    lightningtalktimer.html		               : max = 300 seconds, dangerous =  60 seconds, font height 70%

    lightningtalktimer.html?max=100&danger=50  : max = 100 seconds, dangerous =  50 seconds
    lightningtalktimer.html?max=100&danger=100 : max = 100 seconds, dangerous = 100 seconds
    lightningtalktimer.html?max=100	           : max = 100 seconds, dangerous =  60 seconds
    lightningtalktimer.html?max=10	           : max =	10 seconds, dangerous =  10 seconds
    lightningtalktimer.html?danger=0	       : max = 300 seconds, dangerous =   0 seconds

    lightningtalktimer.html?font=50	           : font height 50%

    - This HTML can work with lightningtalktimer.js online or offline.

Ver.1.01 2014-01-17
Copyright © 2014 Sho's Software by Fujiwo http://www.shos.info
-->

実際に動くもの

使い方

  • クリックするたびカウントダウン (デフォルト 5分)
  • 残り時間が少なくなると赤くなる (デフォルト 1分)
  • クエリー文字列:
    • max で、時間 (秒) の設定 (lightningtalktimer.html?max=100 で 100秒)
    • danger で、赤くなる時間 (秒) の設定 (lightningtalktimer.html?danger=10 で 10秒、lightningtalktimer.html?danger=0 だと最後だけ赤くなる)
    • font で、文字サイズ (%) の設定 (lightningtalktimer.html?font=90 で文字の高さが最大値の90%)
  • Internet Explorer、Firefox、Safari、Google Chrome、Opera の現時点での最新版で動作
  • iPhone、Android フォン等スマートフォンで動作

関連記事

2014年01月26日

[Event] Hokuriku.NET Vol.13 in 富山

Hokuriku.NET Vol.13 in 富山』に参加してきた。

Hokuriku.NET Vol.13 in 富山
開催日 2014/01/25
会場 富山県民会館
詳細 http://atnd.org/events/46157

イベントの写真

イベントの様子
懇親会はブリしゃぶ

当日のスライド (一部)

参加された方が書かれた記事

About 2014年01月

2014年01月にブログ「プログラミング C# - 翔ソフトウェア (Sho's)」に投稿されたすべてのエントリーです。過去のものから新しいものへ順番に並んでいます。

前のアーカイブは2013年12月です。

次のアーカイブは2014年02月です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 3.35