takataka430’s blog

.NET系を中心に勉強したことのまとめを書きます

Blazor WebAssemblyでBootstrapのModalを使う

はじめに

Blazorは空のプロジェクトを作っても最初からBootstrapが導入されています。ですが、以下のページのModalをコンポーネントにはりつけてもうまく動きませんでした。

getbootstrap.com

どうやったら動くのか気になったので、今回調査してみました。

環境

Microsoft Visual Studio Community 2022 Version 17.1.1
Blazor WebAssembly (.NET 6)
Bootstrap 5.1

原因は?

Bootstrap用のJavaScriptファイルがないことが原因のようでした。以下のページを見るとCSSファイルとJavaScriptファイルの2種類が必要かと思いますが、BlazorのテンプレートにはCSSファイルしかありません。

getbootstrap.com

導入手順

以下のページのCDN via jsDelivrから必要なリンクを2つ(CSSJavaScript)取得します。2種類ありますが、今回は上のものを利用しました。

getbootstrap.com

次にBlazorのプロジェクトでこれを利用できるようにします。
wwwroot/index.htmlファイルを開き、先ほどコピーしたリンクをはりつけます。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>BlazorWasmStudy</title>
    <base href="/" />
    <!-- ここはコメントアウト -->
    <!--<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />-->
    
    <!-- 貼り付け1か所目 -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

    <link href="css/app.css" rel="stylesheet" />
    <link href="BlazorWasmStudy.styles.css" rel="stylesheet" />
</head>

<body>
    <div id="app">Loading...</div>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webassembly.js"></script>
    
    <!-- 貼り付け2か所目 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

</body>

</html>

これで準備完了です。
あとはrazorコンポーネントにModalのコードを張り付ければOKです。

getbootstrap.com

例えば、Live demoのコードを使うと以下のように動きます。

WEBブラウザでお絵描きする方法を調べてみた

お絵描きする機能をWEBアプリケーションに実装したいと思い、JavaScriptならできるのでは?と思って調べてみました。
今回はその実装方法について書こうと思います。

実装のポイント

いくつか紹介します。

canvas要素の取得

//canvas要素の取得
const myCanvas = document.getElementById('canvas');

//canvas要素に平面の線を引くためのコンテクストを取得
const ctx = myCanvas.getContext('2d');

HTMLでcanvas要素を配置し、JavaScriptcanvas要素とそのコンテクストを取得します。
コンテクストはcanvasに線を引くために必要です。

マウスが動いた時の座標を取得

//マウスを動かしたときに実行するイベントを定義
myCanvas.onmousemove = OnMouseMove;        
function OnMouseMove(e){
    Draw(e.offsetX, e.offsetY); //線を引く処理を実行する
}

1行目でマウスが動いた時に実行する関数を設定しています。
このイベントからcanvas要素内のマウスポインタの座標を取得できるので(e.offsetX, e.offsetY)、この値を用いて何らかの線を引く処理を実行します。

マウスのボタンを押している間だけ線を引く

上記2つだけだとマウスのポインタがcanvas要素上を移動している間はずっと線を引いてしまうので、以下のように状態を表す数値を設定します。

//線を引くために状態を持つ変数
//0:マウスをクリックしていない
//1:マウスをクリックしている
//2:マウスをクリックしてなおかつ動かしている
let lineStatus = 0;

//マウスのボタンを押したときのイベント
myCanvas.onmousedown = function(){
    lineStatus = 1;
}

//マウスのボタンを放したときのイベント
myCanvas.onmouseup = function(){
    lineStatus = 0;
}

これらを利用してマウスのボタンを押している間だけ線を引くようにしました。

全体のコード

以下のようにしました。

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Test</title>
    <meta charset="utf-8">
</head>
<body>
    <canvas id="canvas" width="500" height="300" style="border: solid 1px #000;box-sizing: border-box;"></canvas>
    <input type="button" value="clear" id="clear">
    <script>
        //線を引くために状態を持つ変数
        //0:マウスをクリックしていない
        //1:マウスをクリックしている
        //2:マウスをクリックしてなおかつ動かしている
        let lineStatus = 0;

        //canvas要素の取得
        const myCanvas = document.getElementById('canvas');

        //canvas要素に平面の線を引くためのコンテクストを取得
        const ctx = myCanvas.getContext('2d');
        
        //マウスのボタンを押したときのイベント
        myCanvas.onmousedown = function(){
            lineStatus = 1;
        }

        //マウスのボタンを放したときのイベント
        myCanvas.onmouseup = function(){
            lineStatus = 0;
        }

        //マウスを動かしたときに実行するイベントを定義
        myCanvas.onmousemove = OnMouseMove;        
        function OnMouseMove(e){
            Draw(e.offsetX, e.offsetY);
        }

        //線を引く
        function Draw(pos_x, pos_y){
            if(lineStatus == "1"){
                ctx.lineWidth = 5;        //線の太さ
                ctx.lineCap = "round"     //線の末端のスタイル
                ctx.beginPath();          //パスの開始
                ctx.moveTo(pos_x, pos_y); //始点
                lineStatus = 2;

            }else if(lineStatus == "2"){
                ctx.lineTo(pos_x, pos_y); //線を引く座標
                ctx.stroke();             //線を引く
            }
        }

        //以下は描いた線を消すためのもの
        const canvasWidth = myCanvas.width;
        const canvasHeight = myCanvas.height;
        const clear = document.getElementById('clear');
        clear.onclick = function(){
            ctx.clearRect(0,0,canvasWidth, canvasHeight)
        }

    </script>
</body>
</html>

これをWEBブラウザで表示すると以下のようにお絵描きをすることができます。

f:id:takataka430:20220318204931g:plain:w500

参考

developer.mozilla.org

developer.mozilla.org

Blazorで接続文字列を読み込む

はじめに

以前ASP.NET Core Web APIで接続文字列を設定する方法を書きました。

takataka430.hatenablog.com

最近Blazorを使うことがあり、同じ方法でできるだろうと思ったのですが、少しやり方が違いました。

環境

Microsoft Visual Studio Community 2022 Version 17.0.5
Blazor Server(.NET 6)

手順

ASP.NET Coreと同じようにrazorページのコンストラクタでIConfiguration型の変数を受け取るのかと思ったのですが、Blazorでは違うようです。
以下のようにページ先頭に書きます。

@inject IConfiguration Configuration

こうするとIConfiguration型のConfiguration をコード内で利用することができます。

次に接続文字列を設定します。今回はsecrets.jsonに以下のように記載してみます。

{
  "ConnectionStrings": {
    "test": "これは接続文字列です"
  }
}

設定したtestの値を取得するには以下のように記述します。

[何らかの変数] = Configuration.GetConnectionString("test");

今回はページ全体のコードを以下のようにしてみました。

@page "/"
@inject IConfiguration Configuration


<label>@SelectedColor</label>

@code {
    string SelectedColor = ""; //ラベルに表示する文字列

    protected override void OnInitialized()
    {
        base.OnInitialized();
        SelectedColor = Configuration.GetConnectionString("test");
    }
}

これを実行すると画面には「これは接続文字列です」と表示され、接続文字列の値を取得できていることがわかります。

参考

ASP.NET Core Blazor configuration | Microsoft Docs

MRTKのダイアログを使う

はじめに

MRTKで「Yes」「No」のような2択から選べるダイアログを表示して、結果によって処理を変えるということをやりたかったので調査しました。

環境

Unity 2020.3.27f1
MRTK 2.7.2

実装方法

ダイアログの使い方は以下のページに記載があります。

docs.microsoft.com

今回は以下のようにスクリプトを作ります。

using Microsoft.MixedReality.Toolkit.UI;
using UnityEngine;

public class DialogStudy : MonoBehaviour
{
    [SerializeField]GameObject dialogPrefab;

    void Start()
    {
        //ダイアログの表示
        Dialog dialog = Dialog.Open(dialogPrefab, DialogButtonType.Yes | DialogButtonType.No, "Title", "Message", true);
        
        if(dialog != null)
        {
            dialog.OnClosed += (DialogResult result) => 
            { 
                //ダイアログのボタンを選択後、やりたい処理を書く
                //今回はログに選択したボタンを表示
                Debug.Log(result.Result.ToString()); 
            };
        }
    }
}

あとはこのスクリプトをオブジェクトにアタッチして、ダイアログのPrefabを設定すれば完了です。 f:id:takataka430:20220216095122p:plain

以下のようにエディタ上で実行するとダイアログが表示されます。 f:id:takataka430:20220216095151p:plain

nugetパッケージをコマンドからダウンロードする

はじめに

nugetパッケージを(プロジェクトにインストールではなく)ローカルフォルダにダウンロードしたいと思い、方法を調べました。ホームページからダウンロードボタンを押す方法もありますが、今回はコマンドで実行する方法について書きます。

環境

nuget.exe v6.0.0

手順

以下のページからnuget.exeをダウンロードします。 www.nuget.org

あとはnuget.exeがある場所でコマンドプロンプトを起動してコマンドを実行するだけです。

以下のコマンドを実行するとコマンドプロンプトで開いている場所にパッケージがダウンロードされます。
nuget install <packageID>
オプションとして以下のものがあります。
-OutputDirectory <ディレクトリ名>
→指定のディレクトリにダウンロードされます。ディレクトがなくても自動で作成されます。
-Version <version>
→パッケージのバージョンを指定できます。

例えば、Newtonsoft.Jsonのバージョン13.0.1をtestディレクトリにダウンロードするためには以下のコマンドになります。
nuget install Newtonsoft.Json -Version 13.0.1 -OutputDirectory test

参考

nuget.exe CLI を使用して NuGet パッケージを管理する | Microsoft Docs

【MRTK】Hand Coachを使う

MRTKのHand Coachを使ってみました。

docs.microsoft.com

上記にドキュメントがあるのですが、どのように使えばいいのかわからなかったので使い方をメモしておきます。

環境

MRTK 2.7.2
Unity 2020.3.0f1

手順

まずProjectウィンドウから手のPrefabを追加します。場所は以下の通りです。 Packages/com.microsoft.mixedreality.toolkit.foundation/SDK/Features/UX/Prefabs/HandCoach
今回はStaticHandCoachRoot_Lを利用します。 f:id:takataka430:20211123123653p:plain

次にアニメーションを設定します。
StaticHandCoachRoot_Lを展開してInteractionHint_Lをクリックします。Inspectorを見るとHand Interaction Hint (Script)があります。このスクリプトAnimation Stateにアニメーションファイルの文字列を記入するとアニメーションが実行されます。

f:id:takataka430:20211123123757p:plain

アニメーションファイルはMRTKに準備されており、以下の場所にあります。 Packages/com.microsoft.mixedreality.toolkit.foundation/SDK/Features/UX/Animations/HandCoach

f:id:takataka430:20211123123822p:plain

今回はLeftHand内にあるAirTap_Lを利用します。
以下のように文字列で指定します。これで準備は完了です。

f:id:takataka430:20211123123846p:plain

Unityのエディタで実行すると以下のようになります。 f:id:takataka430:20211123124717g:plain

Unityでスクリプトから3Dオブジェクトを作成する

忘れやすいのでメモです。
Unityでヒエラルキーメニューから右クリックで3Dオブジェクトを作ることができますが、今回はスクリプトから作る方法を調べました。

環境

Unity 2020.3.01f Personal

作り方

以下のようにスクリプトに記述すると3Dオブジェクトを作成することができます。

var obj = GameObject.CreatePrimitive(PrimitiveType.Cube);

上記は立方体が生成されますが、PrimitiveTypeを変更すると他の3Dオブジェクトも生成可能です。

docs.unity3d.com

また、以下のように書くと位置や大きさのの指定もできます。

obj.transform.position = new Vector3(0f,0f,0f); //位置
obj.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); //大きさ