Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

canvasのimageData

 const imagedata:ImageData = context.createImageData(sw,sh)

sw,sh 単位はCSSピクセル ImageDataを作成して返却 返却されたピクセルはすべて透明な黒

sw,shの代わりにimagedataを渡しても良い。 その場合、渡したimagedataの寸法の 新たなImageDataが作成される。すべて透明な黒

 const imagedata:ImageData = context.getImageData(sx,sy,sw,sh)

canvasの指定矩形のimagaDataを返す。

引数が有限でもないか0であればNOT_SUPPORTED_ERR , INDEX_SIZE_ERR を投げる。

imagedata.width
imagedata.height

データの実際の寸法で単位はピクセル

imagedata.data

RGBAの順番で1次元配列で0 ~ 255の範囲

context.putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ])

imageDataを描画、dirtyを与えると特定の矩形のピクセルだけ描画

ImageData

interface ImageData {
    /**
     * Returns the one-dimensional array containing the data in RGBA order, as integers in the
     * range 0 to 255.
     */
    readonly data: Uint8ClampedArray;
    /**
     * Returns the actual dimensions of the data in the ImageData object, in
     * pixels.
     */
    readonly height: number;
    readonly width: number;
}

canvasのコンテキスト

    getContext(contextId: "2d", contextAttributes?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D | null;

CanvasRenderingContext2DSettingsの設定

interface CanvasRenderingContext2DSettings {
    alpha?: boolean;
}

alphaはcanvasにアルファ値が含まれているかどうか、falseに指定するとブラウザは背景が不透明であることがわかるので描画が高速化される。

状態モナドを作ってみる

typescriptで状態モナドを作ってみます。

状態モナド

 S \to (R,S)
という状態を受け取って結果と変化した状態を返す関数です。

これを

export type State<R,S> = (s:S) => {result:R,state:S}

と定義しておきます。

初期値を作る関数を

export const unit = <R,S>(result:R) => (state:S) => { return {result:result, state:state}}; 

と定義します。これで

    const m0 = unit<number,number>(100);

のように初期入力値を作ることができます。

次に数を2倍する関数を作りましょう。そして関数が呼ばれる回数を状態としてカウントすることを考えます。
具体的には

    const f = (r:number) => (s:number) => { return {result:r*2, state:s+1}}

のような関数を用意します。つまり、状態を受け取ったら値を2倍しつつ状態を更新して返すという関数です。
これは

    const f: (number) =>State<number, number>

という型を持っていることに注意しましょう。

作っておいた状態モナドm0にこの関数を適用するための関数としてbindを用意します。

export const bind = <R,S,Q>(m:State<R,S>, f:(r:R)=>State<Q,S>) => (s:S) => {
    const next = m(s);
    return f(next.result)(next.state);
}

これは新しく状態モナドを作って、その状態モナドでは、元の状態モナドを先に使って結果を求め、それにfを適用するようにしてあります。

bindを使って、m0にfを3回くらい適用させてみましょう。

    const m0 = unit<number,number>(100);
    const m1 = bind(m0,f);
    const m2 = bind(m1,f);
    const m3 = bind(m2,f);

m1,m2を用いたのはわかりやすさのためで、bindを連続して作用させても構いません。

できた結果の状態モナドm3を使うには初期状態を設定する必要があります。

    const ans = m3(0)

ans.result == 800
ans.state == 3
となり、きちんとカウントしていることがわかると思います。

状態モナドの説明はこれで終わりです。
色々な使い方がありそうだということがわかると思います。

以上をまとめたコードがこちらになります。

export type State<R,S> = (s:S) => {result:R,state:S}

export const unit = <R,S>(result:R) => (state:S) => { return {result:result, state:state}}; 
export const bind = <R,S,Q>(m:State<R,S>, f:(r:R)=>State<Q,S>) => (s:S) => {
    const next = m(s);
    return f(next.result)(next.state);
}

export function stateTest() {
    /// double number , state: count of operation
    const f = (r:number) => (s:number) => { return {result:r*2, state:s+1}}

    const m0 = unit<number,number>(100);
    const m1 = bind(m0,f);
    const m2 = bind(m1,f);
    const m3 = bind(m2,f);
    
    const display = <R>(m:State<R,number>) => {
        console.log("result:"+m(0).result + " state:"+m(0).state);
    }

    display(m0);
    display(m1);
    display(m2);
    display(m3);

    /*
        result:100 state:0
        result:200 state:1
        result:400 state:2
        result:800 state:3
    */

    
}

stateTest();

ありがとうございました。

ローカルHTMLのメモ

WKWebViewで実装すると
フォルダ参照ならhtml内のlinkは./でプロジェクト直下になっているようだ。

WKWebViewは今の所、コード上で貼り付けるしかない。

WKNavigationDelegateでnavigationResponseでdocument.locationの移動を検知できる。
decisionHandler(.allow)で許可する。

challenge: URLAuthenticationChallengeで
信頼するかどうか

        print("[Warning]challenge AuthenticationChallange")
        let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!);
        completionHandler(.useCredential, cred)

Build Phaseでプロジェクト直下のファイルをResourceにコピーできる。
ResourceにコピーできればMainBundleから取得できる。