7
10

More than 1 year has passed since last update.

素のJavaScriptだけでLive2Dを使う ~Node.js無し

Last updated at Posted at 2022-09-21

Node.js(React,Vue,TypeScript)を使いません。
HTMLファイルをLiveServerやxamppのローカルサーバーで起動し、Live2Dを扱えるものです。
もちろんNode.js類とも組み合わせることができます。

ローカルサーバー(何らかのサーバー)で起動して下さい。
サーバー使わないとCDN関係クロスオリジンポリシーで弾かれます。

Replit サンプルページ

デモ
https://live2dexample--supica8219.repl.co/
コード
https://replit.com/@supica8219/Live2Dexample#index.html

github

上記Replitのリンクでコードと動作が見られます。

以下のようなLive2DデータHiyoriを使いました。
下記URLから桃山ひよりプロ版をダウンロードします。runtimeフォルダの名前をrumtime->Hiyoriにしています。
https://www.live2d.com/download/sample-data/

Screenshot 2022-09-22 004836.png

index.html 

index.html
<!DOCTYPE html>
<html>
<head>
  <title>Live2Dサンプル</title>
    <!-- Live2D -->
  <script src="./live2dcubismcore.js"></script>
  <script src="//cdn.jsdelivr.net/gh/dylanNew/live2d/webgl/Live2D/lib/live2d.min.js"></script>
  <!-- PixiJS -->
  <script src="//cdnjs.cloudflare.com/ajax/libs/pixi.js/5.1.3/pixi.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/pixi-live2d-display/dist/index.min.js"></script>
  <!-- Kalidokit -->
  <script src="//cdn.jsdelivr.net/npm/kalidokit@1.1/dist/kalidokit.umd.js"></script>
</head>
<body>
<button onclick="Motion(1);">モーション1</button>
<button onclick="Motion(2);">モーション2</button>
<button onclick="Motion(3);">モーション3</button>
<button onclick="Motion(4);">モーション4</button>
<button onclick="Motion(5);">モーション5</button>
<button onclick="Motion(6);">モーション6</button>
<canvas id="my-live2d"></canvas>
<script src="live2d.js"></script>
<script src="index.js"></script> 
</body>
</html>

・live2dcubismcore.jsの読み込み+各種(live2d,PixiJS,kalidokit)CDNの読み込み
・表示するcanvasの定義

live2d.js ~ライブ2D周りの設定

live2d.js
//index.jsで使うのでスコープを外す
var app;

// PixiJS
var {
  Application, live2d: { Live2DModel }
} = PIXI;

// Kalidokit
var {
  Face, Vector: { lerp }, Utils: { clamp }
} = Kalidokit;


// 1, Live2Dモデルへのパスを指定する
var modelUrl = "./Hiyori/Hiyori.model3.json";
var currentModel;
	
// メインの処理開始
(async function main() {
  // 2, PixiJSを準備する
  app = new PIXI.Application({
    view: document.getElementById("my-live2d"),
    autoStart: true,
    backgroundAlpha: 0,
    backgroundColor: 0x0000ff,
    resizeTo: window
  });

  // 3, Live2Dモデルをロードする
  currentModel = await Live2DModel.from(modelUrl, { autoInteract: false });
  currentModel.scale.set(0.5);//モデルの大きさ★
  currentModel.interactive = true;
  currentModel.anchor.set(0.5, 0.5);//モデルのアンカー★
  currentModel.position.set(window.innerWidth/2, window.innerHeight);//モデルの位置★

  // 4, Live2Dモデルをドラッグ可能にする
  currentModel.on("pointerdown", e => {
    currentModel.offsetX = e.data.global.x - currentModel.position.x;
    currentModel.offsetY = e.data.global.y - currentModel.position.y;
    currentModel.dragging = true;
  });
  currentModel.on("pointerup", e => {
    currentModel.dragging = false;
    var updateFn = currentModel.internalModel.motionManager.update;
    var coreModel = currentModel.internalModel.coreModel;
  });
  currentModel.on("pointermove", e => {
    if (currentModel.dragging) {
      currentModel.position.set(
        e.data.global.x - currentModel.offsetX,
        e.data.global.y - currentModel.offsetY
      );
    }
  });

  // 5, Live2Dモデルを拡大/縮小可能に(マウスホイール) #my-live2dはcanvasのidにして下さい
  document.querySelector("#my-live2d").addEventListener("wheel", e => {
    e.preventDefault();
    currentModel.scale.set(
      clamp(currentModel.scale.x + event.deltaY * -0.001, -0.5, 10)
    );
  });
  //背景を設定./background.jpgを画像のパスに書きかえて下さい
  let background = PIXI.Sprite.fromImage('./background.jpg');
  background.anchor.set(0.5);
  background.x = app.screen.width / 2;
  background.y = app.screen.height / 2;
  background.height = app.screen.height;
  background.width = app.screen.width;
  app.stage.addChild(background);
  
  // 6, Live2Dモデルを配置する
  app.stage.addChild(currentModel);

})();

・live2dフォルダを読み込む
(フォルダ構成でmodel3.jsonあるものにして下さい)
・モデルの位置、大きさ、背景の設定
・index.jsで変数appを使うためにグローバル変数にします。

index.js

短いですがindex.jsは3行だけです。

index.js
function Motion(number){
  app.stage.children[1].internalModel.motionManager.startMotion('TapBody',number,2);
}

HTMLのボタンで上記関数Motionを実行します。そして
live2d.jsの最初のappから階層をたどりstartMotionを起動=>該当アニメーションが再生します。
引数numberにてTapBody内から起動するアニメーション種類を指定しています。

最後にindex.htmlをローカルサーバー上で動かしてください。
(LiveServer xampp等)
Screenshot 2022-09-22 011604.png

参考サイトhttps://zenn.dev/sdkfz181tiger/articles/df3a8bd1c3ef25
以上です。質問等ありましたら↓からコメントください。

以下追記

背景を消したい

pixi.jsのデフォルト背景と画像として差し込んだ背景と、
二つ背景があるのでそれぞれ消します!
live2d.jsを2箇所,index.jsを1箇所変更します。

デフォルト背景から、
上記live2d.jsにpixi.jsのセットアップ部分があります。

live2d.js
  // 2, PixiJSを準備する
  app = new PIXI.Application({
    view: document.getElementById("my-live2d"),
    autoStart: true,
    backgroundAlpha: 0,
    backgroundColor: 0x0000ff,
    resizeTo: window
  });

その項目に[transparent: true,]をつけ足してください。

live2d.js
  // 2, PixiJSを準備する
  app = new PIXI.Application({
    view: document.getElementById("my-live2d"),
    transparent: true, //この行を付け足す
    backgroundColor: 0x0000ff,
    autoStart: true,
    backgroundAlpha: 0,
    backgroundColor: 0x0000ff,
    resizeTo: window
  });

次に画像として差し込んだ背景を消します。
live2d.jsのファイル内で以下のように
画像を追加している部分があります。

live2d.js
  //背景を設定./background.jpgを画像のパスに書きかえて下さい
  let background = PIXI.Sprite.fromImage('./background.jpg');
  background.anchor.set(0.5);
  background.x = app.screen.width / 2;
  background.y = app.screen.height / 2;
  background.height = app.screen.height;
  background.width = app.screen.width;
  app.stage.addChild(background);// 画像追加しているとこ

この一番下のapp.stage.addChildをコメントアウトして
画像スプライトを追加しないようにします。
以下にlive2d.jsの全文を載せておきます。

live2d.js
 //背景を表示しないバージョン live2d.js全文
//appをindex.jsで使いたいのでスコープを外しています。
var app;

// PixiJS
var {
  Application, live2d: { Live2DModel }
} = PIXI;

// Kalidokit
var {
  Face, Vector: { lerp }, Utils: { clamp }
} = Kalidokit;


// 1, Live2Dモデルへのパスを指定する
var modelUrl = "./Hiyori/Hiyori.model3.json";
var currentModel;
	
// メインの処理開始
(async function main() {
  // 2, PixiJSを準備する
  app = new PIXI.Application({
    view: document.getElementById("my-live2d"),
    transparent: true,
    backgroundColor: 0x0000ff,
    autoStart: true,
    backgroundAlpha: 0,
    backgroundColor: 0x0000ff,
    resizeTo: window
  });

  // 3, Live2Dモデルをロードする
  currentModel = await Live2DModel.from(modelUrl, { autoInteract: false });
  currentModel.scale.set(0.5);//モデルの大きさ★
  currentModel.interactive = true;
  currentModel.anchor.set(0.5, 0.5);//モデルのアンカー★
  currentModel.position.set(window.innerWidth/2, window.innerHeight*1.1);//モデルの位置★

  // 4, Live2Dモデルをドラッグ可能にする
  currentModel.on("pointerdown", e => {
    currentModel.offsetX = e.data.global.x - currentModel.position.x;
    currentModel.offsetY = e.data.global.y - currentModel.position.y;
    currentModel.dragging = true;
  });
  currentModel.on("pointerup", e => {
    currentModel.dragging = false;
    var updateFn = currentModel.internalModel.motionManager.update;
    var coreModel = currentModel.internalModel.coreModel;
    //モーション周りのパスcurrentModel.internalModel.motionManager.startMotion('TapBody', 0,2);

  });
  currentModel.on("pointermove", e => {
    if (currentModel.dragging) {
      currentModel.position.set(
        e.data.global.x - currentModel.offsetX,
        e.data.global.y - currentModel.offsetY
      );
    }
  });

  // 5, Live2Dモデルを拡大/縮小可能に(マウスホイール) #my-live2dはcanvasのidにして下さい
  document.querySelector("#my-live2d").addEventListener("wheel", e => {
    e.preventDefault();
    currentModel.scale.set(
      clamp(currentModel.scale.x + event.deltaY * -0.001, -0.5, 10)
    );
  });
  //背景を設定./background.jpgを画像のパスに書きかえて下さい
  let background = PIXI.Sprite.fromImage('./background.jpg');
  background.anchor.set(0.5);
  background.x = app.screen.width / 2;
  background.y = app.screen.height / 2;
  background.height = app.screen.height;
  background.width = app.screen.width;
  //app.stage.addChild(background);
  
  // 6, Live2Dモデルを配置する
  app.stage.addChild(currentModel);
})();

index.js

短いですが同じく背景無しのindex.jsは3行だけです。
backgroundを消したのでapp.stageのchildrenを[1]から[0]にします。

index.js
function Motion(number){
  app.stage.children[0].internalModel.motionManager.startMotion('TapBody',number,2);
}

すると背景無しの
live2dモデルを表示できるようになります。
(背景無しバージョンの動作例、コード)
デモ
https://live2dexample2--supica8219.repl.co/
コード
https://replit.com/@supica8219/Live2Dexample2#live2d.js
github
https://github.com/supica8219/Live2D_example2
Screenshot 2022-12-18 184520.png

別のLive2Dモデルで動かしたい場合

ネックとなるのが2つあります。

まずモデルが何のLive2Dバージョンで作られているかです。
その判別方法は構成ファイルにmodel3.json,cdi3.jsonなど「3」を含むファイルが存在することです。この形のファイルを含んでいるならバージョンは大丈夫です。
例ライスグライフィールドモデル(魔法使い女の子)
https://www.live2d.com/download/sample-data/#dl_rice_pro
その他バージョンのモデルを使う場合CubismEditorで
新しいバージョンに変更し、アニメーションも一から作る必要があります。

次にアニメーションを再生するにはmodel3.jsonの"Motion"設定を見る必要があります。
以下ひよりモデルの例で説明します。

対応するモデル(Hiyori).model3.json
"Motions": {
			"Idle": [
				{
					"File": "motions/motion1.motion3.json",
					"FadeInTime": 0.5,
					"FadeOutTime": 0.5
				}
			],
			"TapBody": [
				{
					"File": "motions/motion1.motion3.json",
					"FadeInTime": 0.5,
					"FadeOutTime": 0.5
				},
				{
					"File": "motions/motion2.motion3.json",
					"FadeInTime": 0.5,
					"FadeOutTime": 0.5
				},
				{
					"File": "motions/motion3.motion3.json",
					"FadeInTime": 0.5,
					"FadeOutTime": 0.5
				}
			]
		}

Motionsの中にIdleとTapBodyという塊があります。その中に
"File" アニメーションを一つ定義するファイルmotion3.jsonへのパス
"FadeInTime","FadeOutTime"が幾つか入っています。
入っていない場合はどうしようもないのでcubismEditorで作るしかないです。
IdleはLive2D待機時のモーション群,TapBodyは指定されたタイミングのアクション群です。
前述のindex.jsではTapBodyのnumber版目のアニメーションを再生していました。

index.js
function Motion(number){
app.stage.children[0].internalModel.motionManager.startMotion('TapBody',number,2);
}
7
10
12

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10