木曜日, 6月 19, 2025
- Advertisment -
ホームニューステックニュースTypeScriptとCanvas APIでテトリス風パズルゲームを作ってみよう(初心者向けステップ解説) #JavaScript - Qiita

TypeScriptとCanvas APIでテトリス風パズルゲームを作ってみよう(初心者向けステップ解説) #JavaScript – Qiita



TypeScriptとCanvas APIでテトリス風パズルゲームを作ってみよう(初心者向けステップ解説) #JavaScript - Qiita

概要

今回は、ブラウザ上で動作するテトリス風落ち物パズルゲームを、TypeScriptとHTMLのCanvas APIを用いてゼロから実装する工程を、細かなステップに分けて解説していきます。ソースコードを参考に、どのようにゲームが作られていくのか、その過程を一緒に見ていきましょう。

本記事は、「ゲーム開発に興味があるけれど、何から始めれば良いか分からない」「TypeScriptやCanvas APIに触れてみたい」といった初心者の方を対象としています。基本的な描画から始まり、ブロックの操作、落下、当たり判定、ライン消去、スコア加算といったゲームの主要な要素を順を追って実装していきます。

完成版のソースコードはこちらにおいておきます。

実装イメージ

実装は簡易的に、18×9のマスを作り、ブロックが積み上がるゲームエリアとします。
1ブロックのサイズは30pxとして、ゲームエリアのCanvasのサイズは、縦方向は540px(18行x30px)、横方向は270px(9列x30px)とします。
game_area.jpeg

ブロックの種類は下記の8種類を使います。便宜上、それぞれのブロックの形にアルファベットを振っています。
block.jpg

実装

事前準備:HTMLとCSSでゲーム画面の土台を作る

ゲームのコードを書き始める前に、ゲームを表示するためのHTMLファイルと、見た目を整えるためのCSSファイルを用意します。

index.htmlファイルでは、ゲームの描画領域となる要素を2つ(メイン画面用とNextブロック表示用)、そしてスコアを表示するための要素を配置します。scriptタグで、これから作成するmain.tsファイルを読み込むように設定しておきます。



 lang="en">
  
     charset="UTF-8" />
     name="viewport" content="width=device-width, initial-scale=1.0" />
    </span>Block Puzzle Game<span class="nt"/>
    <span class="nt"><link/> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"src/style.css"</span> <span class="nt">/></span>
  <span class="nt"/>
  <span class="nt"/>
    <span class="nt"><div> <span class="na">class=</span><span class="s">"game-container"</span><span class="nt">></span>
      <span class="nt"><canvas> <span class="na">id=</span><span class="s">"gameCanvas"</span> <span class="na">width=</span><span class="s">"270"</span> <span class="na">height=</span><span class="s">"540"</span><span class="nt">></span></canvas></span>
      <span class="nt"><div> <span class="na">class=</span><span class="s">"side-panel"</span><span class="nt">></span>
        <span class="nt"><p> <span class="na">id=</span><span class="s">"scoreBoard"</span><span class="nt">></span>Score: 00000<span class="nt"/></p></span>
        <span class="nt"><canvas> <span class="na">id=</span><span class="s">"nextBlockCanvas"</span> <span class="na">width=</span><span class="s">"150"</span> <span class="na">height=</span><span class="s">"150"</span><span class="nt">></span></canvas></span>
      <span class="nt"/></div></span>
    <span class="nt"/></div></span>
    <span class="nt"><script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore"><![CDATA[<span class="na">type=]]></script></span><span class="s">"module"</span> <span class="na">src=</span><span class="s">"/src/main.ts"</span><span class="nt">></span>
  <span class="nt"/>
<span class="nt"/>
</span></span></span></span></span></code></pre>
</div>
</div>
<p data-sourcepos="52:1-52:249"><code>style.css</code>ファイルでは、これらのHTML要素に対して、画面中央に配置したり、Canvas要素に枠線をつけたり、スコア表示のフォントを設定したりといった基本的なスタイリングを行います。</p>
<div class="code-frame" data-lang="css" data-sourcepos="54:1-100:3">
<div class="highlight">
<pre><code><span class="c">/* style.css */</span>
<span class="nt">body</span> <span class="p">{</span>
  <span class="nl">display</span><span class="p">:</span> <span class="n">flex</span><span class="p">;</span> <span class="c">/* 子要素(.game-container)をフレックスアイテムに */</span>
  <span class="nl">justify-content</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span> <span class="c">/* 子要素を水平方向の中央に配置 */</span>
  <span class="c">/* ... その他のスタイル */</span>
<span class="p">}</span>
<span class="c">/* ゲームエリアのスタイル */</span>
<span class="nc">.game-container</span> <span class="p">{</span>
  <span class="nl">display</span><span class="p">:</span> <span class="n">flex</span><span class="p">;</span> <span class="c">/* 子要素(canvasとside-panel)をフレックスアイテムに */</span>
  <span class="nl">justify-content</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span> <span class="c">/* 子要素を水平方向の中央に配置 */</span>
  <span class="nl">align-items</span><span class="p">:</span> <span class="n">flex-start</span><span class="p">;</span> <span class="c">/* 子要素を上揃えに */</span>
  <span class="py">gap</span><span class="p">:</span> <span class="m">20px</span><span class="p">;</span> <span class="c">/* 子要素間の隙間 */</span>
<span class="p">}</span>
<span class="c">/* ブロックを移動できるエリアのスタイル */</span>
<span class="nf">#gameCanvas</span> <span class="p">{</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#000</span><span class="p">;</span> <span class="c">/* 枠線 */</span>
  <span class="nl">background-color</span><span class="p">:</span> <span class="m">#eee</span><span class="p">;</span> <span class="c">/* 背景色 */</span>
<span class="p">}</span>
<span class="c">/* サイドパネル(ネクストブロックやスコアボード)のスタイル */</span>
<span class="nc">.side-panel</span> <span class="p">{</span>
  <span class="nl">display</span><span class="p">:</span> <span class="n">flex</span><span class="p">;</span> <span class="c">/* 子要素をフレックスアイテムに */</span>
  <span class="nl">flex-direction</span><span class="p">:</span> <span class="n">column</span><span class="p">;</span> <span class="c">/* 子要素を縦方向に並べる */</span>
  <span class="nl">align-items</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span> <span class="c">/* 子要素を水平方向(主軸と垂直な方向)の中央に揃える */</span>
<span class="p">}</span>
<span class="c">/* 次に落ちてくるブロックを表示するキャンバスのスタイル */</span>
<span class="nf">#nextBlockCanvas</span> <span class="p">{</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#000</span><span class="p">;</span> <span class="c">/* 1ピクセルの実線で黒い枠線 */</span>
  <span class="nl">background-color</span><span class="p">:</span> <span class="m">#ddd</span><span class="p">;</span> <span class="c">/* 薄い灰色の背景色 */</span>
  <span class="nl">margin-bottom</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span> <span class="c">/* 下に10ピクセルの余白 */</span>
<span class="p">}</span>
<span class="c">/* スコア表示要素のスタイル */</span>
<span class="nf">#scoreBoard</span> <span class="p">{</span>
  <span class="nl">margin-bottom</span><span class="p">:</span> <span class="m">24px</span><span class="p">;</span> <span class="c">/* 下に24ピクセルの余白 */</span>
  <span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span> <span class="c">/* テキストを中央揃え */</span>
  <span class="nl">font-size</span><span class="p">:</span> <span class="m">24px</span><span class="p">;</span> <span class="c">/* フォントサイズを24ピクセルに */</span>
  <span class="nl">font-weight</span><span class="p">:</span> <span class="nb">bold</span><span class="p">;</span> <span class="c">/* フォントを太字に */</span>
  <span class="nl">font-family</span><span class="p">:</span> <span class="s1">"Courier New"</span><span class="p">,</span> <span class="nb">monospace</span><span class="p">;</span> <span class="c">/* フォントファミリーを指定(等幅フォント) */</span>
  <span class="nl">background-color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span> <span class="c">/* 白い背景色 */</span>
  <span class="nl">padding</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span> <span class="c">/* 内側に10ピクセルの余白 */</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">#000</span> <span class="m">1px</span> <span class="nb">solid</span><span class="p">;</span> <span class="c">/* 1ピクセルの実線で黒い枠線 */</span>
  <span class="nl">min-width</span><span class="p">:</span> <span class="m">180px</span><span class="p">;</span> <span class="c">/* 最小幅を180ピクセルに */</span>
  <span class="nl">max-width</span><span class="p">:</span> <span class="m">180px</span><span class="p">;</span> <span class="c">/* 最大幅を180ピクセルに(結果的に幅が180pxに固定される) */</span>
  <span class="nl">white-space</span><span class="p">:</span> <span class="nb">nowrap</span><span class="p">;</span> <span class="c">/* テキストを改行しない */</span>
  <span class="nl">overflow</span><span class="p">:</span> <span class="nb">hidden</span><span class="p">;</span> <span class="c">/* 要素からはみ出したコンテンツを非表示 */</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="102:1-102:148">これで、ゲーム画面を表示するための土台が完成しました。次に、いよいよTypeScriptのコードを書き始めます。</p>
<h3 data-sourcepos="104:1-104:45">
<span id="step-1-ゲームキャンバスの描画" class="fragment"/><a href="#step-1-%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%90%E3%82%B9%E3%81%AE%E6%8F%8F%E7%94%BB"><i class="fa fa-link"/></a>Step 1: ゲームキャンバスの描画</h3>
<p data-sourcepos="106:1-106:105">まずは、ゲームのメイン画面となる<code>gameCanvas</code>に描画するための準備をします。</p>
<p data-sourcepos="108:1-108:247"><code>main.ts</code>ファイルの冒頭で、HTMLで用意した<code><canvas/></code>要素を取得し、その要素から2D描画のためのコンテキストを取得します。このコンテキストを使って、様々な図形を描画していきます。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="110:1-114:3">
<div class="highlight">
<pre><code><span class="c1">// main.ts</span>
<span class="kd">const</span> <span class="nx">canvas</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">gameCanvas</span><span class="dl">"</span><span class="p">)</span> <span class="kd">as </span><span class="nx">HTMLCanvasElement</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">context</span> <span class="o">=</span> <span class="nx">canvas</span><span class="p">.</span><span class="nf">getContext</span><span class="p">(</span><span class="dl">"</span><span class="s2">2d</span><span class="dl">"</span><span class="p">)</span><span class="o">!</span><span class="p">;</span> <span class="c1">// 2D描画コンテキストを取得</span>
</code></pre>
</div>
</div>
<p data-sourcepos="116:1-116:133">また、ゲームボードのサイズやブロック1マスあたりのサイズなどを定数として定義しておきます。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="118:1-122:3">
<div class="highlight">
<pre><code><span class="kd">const</span> <span class="nx">grid</span> <span class="o">=</span> <span class="mi">30</span><span class="p">;</span> <span class="c1">// 1マスあたりのピクセルサイズ</span>
<span class="kd">const</span> <span class="nx">rows</span> <span class="o">=</span> <span class="mi">18</span><span class="p">;</span> <span class="c1">// ボードの縦マス数</span>
<span class="kd">const</span> <span class="nx">cols</span> <span class="o">=</span> <span class="mi">9</span><span class="p">;</span>  <span class="c1">// ボードの横マス数</span>
</code></pre>
</div>
</div>
<p data-sourcepos="124:1-124:252">このゲームでは、ゲームボード自体やブロックは小さな正方形の集まりで表現します。そこで、指定された座標とサイズ、色で正方形を一つ描画する基本的な関数<code>drawSquare</code>を作成します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="126:1-141:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">drawSquare</span><span class="p">(</span>
  <span class="nx">x</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span>
  <span class="nx">y</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span>
  <span class="nx">color</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>
  <span class="nx">ctx</span><span class="p">:</span> <span class="nx">CanvasRenderingContext2D</span><span class="p">,</span>
  <span class="nx">size</span><span class="p">:</span> <span class="kr">number</span>
<span class="p">)</span> <span class="p">{</span>
  <span class="nx">ctx</span><span class="p">.</span><span class="nx">fillStyle</span> <span class="o">=</span> <span class="nx">color</span><span class="p">;</span> <span class="c1">// 塗りつぶしの色を指定</span>
  <span class="c1">// 指定したマス目の位置 (x * size, y * size) から、サイズ (size, size) の四角形を塗りつぶす</span>
  <span class="nx">ctx</span><span class="p">.</span><span class="nf">fillRect</span><span class="p">(</span><span class="nx">x</span> <span class="o">*</span> <span class="nx">size</span><span class="p">,</span> <span class="nx">y</span> <span class="o">*</span> <span class="nx">size</span><span class="p">,</span> <span class="nx">size</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
  <span class="nx">ctx</span><span class="p">.</span><span class="nx">strokeStyle</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">white</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// 線の色を指定</span>
  <span class="c1">// 指定したマス目の位置から、サイズ (size, size) の四角形の境界線を描画する</span>
  <span class="nx">ctx</span><span class="p">.</span><span class="nf">strokeRect</span><span class="p">(</span><span class="nx">x</span> <span class="o">*</span> <span class="nx">size</span><span class="p">,</span> <span class="nx">y</span> <span class="o">*</span> <span class="nx">size</span><span class="p">,</span> <span class="nx">size</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="143:1-143:138"><code>drawSquare</code>関数は、これからブロックやボードを描画する際に何度も利用する基本的な部品となります。</p>
<h3 data-sourcepos="145:1-145:42">
<span id="step-2-ブロックの定義と描画" class="fragment"/><a href="#step-2-%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%81%AE%E5%AE%9A%E7%BE%A9%E3%81%A8%E6%8F%8F%E7%94%BB"><i class="fa fa-link"/></a>Step 2: ブロックの定義と描画</h3>
<p data-sourcepos="147:1-147:117">落ちてくるブロックの形状や色を定義し、それを<code>gameCanvas</code>に描画できるようにします。</p>
<p data-sourcepos="149:1-149:57">まず、ブロックの色と形状を定義します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="151:1-187:3">
<div class="highlight">
<pre><code><span class="kd">const</span> <span class="nx">colors</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">red</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">blue</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">purple</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">teal</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">green</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">orange</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">brown</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">gold</span><span class="dl">"</span><span class="p">];</span> <span class="c1">// ブロックの色</span>

<span class="kd">const</span> <span class="nx">shapes</span> <span class="o">=</span> <span class="p">[</span>
  <span class="p">[</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
  <span class="p">],</span> <span class="c1">// I型</span>
  <span class="p">[</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
  <span class="p">],</span> <span class="c1">// J型</span>
  <span class="p">[</span>
    <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
  <span class="p">],</span> <span class="c1">// L型</span>
  <span class="p">[</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
  <span class="p">],</span> <span class="c1">// O型</span>
  <span class="p">[</span>
    <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
  <span class="p">],</span> <span class="c1">// S型</span>
  <span class="p">[</span>
    <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
  <span class="p">],</span> <span class="c1">// T型</span>
  <span class="p">[</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
  <span class="p">],</span> <span class="c1">// Z型</span>
  <span class="p">[</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
    <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
  <span class="p">],</span> <span class="c1">// U型</span>
<span class="p">];</span>
</code></pre>
</div>
</div>
<p data-sourcepos="189:1-189:171"><code>shapes</code>配列は、それぞれのブロックの形状を2次元配列で表現しています。<code>1</code>がある場所がブロックの存在するセルを表します。</p>
<p data-sourcepos="191:1-191:165">次に、ゲーム中に操作する「落ちてくるブロック」の状態を管理するための型(インターフェース)と変数を用意します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="193:1-203:3">
<div class="highlight">
<pre><code><span class="kr">interface</span> <span class="nx">Piece</span> <span class="p">{</span>
  <span class="nl">shape</span><span class="p">:</span> <span class="kr">number</span><span class="p">[][];</span> <span class="c1">// 形状 (shapesの要素)</span>
  <span class="nl">color</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span> <span class="c1">// 色 (colorsの要素)</span>
  <span class="nl">x</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span> <span class="c1">// ゲームボード上のX座標 (列)</span>
  <span class="nl">y</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span> <span class="c1">// ゲームボード上のY座標 (行)</span>
<span class="p">}</span>

<span class="kd">let</span> <span class="nx">currentPiece</span><span class="p">:</span> <span class="nx">Piece</span><span class="p">;</span> <span class="c1">// 現在操作中のブロック</span>
<span class="c1">// let nextPiece: Piece; // 次のブロック (Step 7で追加)</span>
</code></pre>
</div>
</div>
<p data-sourcepos="205:1-205:188"><code>currentPiece</code>は、現在プレイヤーが操作しているブロックの形状、色、そしてゲームボード上の現在位置(左上のセルの座標)を保持します。</p>
<p data-sourcepos="207:1-207:132">これらの定義を元に、特定の<code>Piece</code>オブジェクトを<code>gameCanvas</code>に描画する関数<code>drawPiece</code>を作成します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="209:1-222:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">drawPiece</span><span class="p">(</span><span class="nx">piece</span><span class="p">:</span> <span class="nx">Piece</span><span class="p">,</span> <span class="nx">ctx</span><span class="p">:</span> <span class="nx">CanvasRenderingContext2D</span><span class="p">,</span> <span class="nx">size</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// pieceオブジェクトのshape配列をループ処理</span>
  <span class="nx">piece</span><span class="p">.</span><span class="nx">shape</span><span class="p">.</span><span class="nf">forEach</span><span class="p">((</span><span class="nx">row</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
    <span class="nx">row</span><span class="p">.</span><span class="nf">forEach</span><span class="p">((</span><span class="nx">value</span><span class="p">,</span> <span class="nx">x</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// valueが1 (ブロックが存在するセル) なら描画</span>
        <span class="c1">// pieceの現在位置(piece.x, piece.y)に、shape内の相対位置(x, y)を加算して</span>
        <span class="c1">// ゲームボード上の絶対位置を計算し、drawSquareで描画</span>
        <span class="nf">drawSquare</span><span class="p">(</span><span class="nx">piece</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">x</span><span class="p">,</span> <span class="nx">piece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">piece</span><span class="p">.</span><span class="nx">color</span><span class="p">,</span> <span class="nx">ctx</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">});</span>
  <span class="p">});</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="224:1-224:393">この関数は、<code>Piece</code>オブジェクトの形状(<code>shape</code>)を調べ、<code>1</code>になっているセルに対応する位置に、<code>piece.color</code>を使って<code>drawSquare</code>でブロックを描画します。描画位置は、<code>piece.x</code>と<code>piece.y</code>(ブロック全体の基準位置)に、形状内の相対位置(<code>x</code>と<code>y</code>)を加えたゲームボード上の絶対位置になります。</p>
<p data-sourcepos="226:1-226:230">最後に、ゲームボード自体の描画関数<code>drawBoard</code>も作成します。これは、Step 6以降で固定されたブロックを描画するために使用しますが、この時点ではまだボードは空です。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="228:1-242:3">
<div class="highlight">
<pre><code><span class="kd">let</span> <span class="nx">board</span><span class="p">:</span> <span class="kr">number</span><span class="p">[][]</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="k">from</span><span class="p">({</span> <span class="na">length</span><span class="p">:</span> <span class="nx">rows</span> <span class="p">},</span> <span class="p">()</span> <span class="o">=></span> <span class="nc">Array</span><span class="p">(</span><span class="nx">cols</span><span class="p">).</span><span class="nf">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span> <span class="c1">// ゲームボードの状態を表す2次元配列 (最初は全て空きマス0)</span>

<span class="kd">function</span> <span class="nf">drawBoard</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">context</span><span class="p">.</span><span class="nf">clearRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span> <span class="c1">// Canvas全体をクリア</span>
  <span class="k">for </span><span class="p">(</span><span class="kd">let</span> <span class="nx">row</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">row</span> <span class="o"> <span class="nx">rows</span><span class="p">;</span> <span class="nx">row</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// ボードの各行をループ</span>
    <span class="k">for </span><span class="p">(</span><span class="kd">let</span> <span class="nx">col</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">col</span> <span class="o"> <span class="nx">cols</span><span class="p">;</span> <span class="nx">col</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// ボードの各列をループ</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">board</span><span class="p">[</span><span class="nx">row</span><span class="p">][</span><span class="nx">col</span><span class="p">])</span> <span class="p">{</span> <span class="c1">// そのセルにブロックが存在する場合 (値が0以外)</span>
        <span class="c1">// boardの値 (色のインデックス+1) を使って色を取得し、drawSquareで描画</span>
        <span class="nf">drawSquare</span><span class="p">(</span><span class="nx">col</span><span class="p">,</span> <span class="nx">row</span><span class="p">,</span> <span class="nx">colors</span><span class="p">[</span><span class="nx">board</span><span class="p">[</span><span class="nx">row</span><span class="p">][</span><span class="nx">col</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">],</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">grid</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</span></span></code></pre>
</div>
</div>
<p data-sourcepos="244:1-244:297"><code>drawBoard</code>関数は、<code>board</code>配列を走査し、0以外の値が入っているセル(固定されたブロックがある場所)に色付きのブロックを描画します。値が1以上なのは、<code>colors</code>配列のインデックスに+1したものを格納しているためです。</p>
<h3 data-sourcepos="246:1-246:42">
<span id="step-3-キーボード操作で移動" class="fragment"/><a href="#step-3-%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E6%93%8D%E4%BD%9C%E3%81%A7%E7%A7%BB%E5%8B%95"><i class="fa fa-link"/></a>Step 3: キーボード操作で移動</h3>
<p data-sourcepos="248:1-248:222">プレイヤーが矢印キーを使ってブロックを左右に移動させたり、回転させたりできるように、キーボードイベントを捕捉して対応する処理を呼び出すようにします。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="250:1-274:3">
<div class="highlight">
<pre><code><span class="nb">document</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">keydown</span><span class="dl">"</span><span class="p">,</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">key</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">ArrowLeft</span><span class="dl">"</span><span class="p">)</span> <span class="nf">movePiece</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// 左矢印キーでmovePiece(-1)を呼び出し</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">key</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">ArrowRight</span><span class="dl">"</span><span class="p">)</span> <span class="nf">movePiece</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// 右矢印キーでmovePiece(1)を呼び出し</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">key</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">ArrowUp</span><span class="dl">"</span><span class="p">)</span> <span class="nf">rotatePiece</span><span class="p">();</span> <span class="c1">// 上矢印キーでrotatePiece()を呼び出し</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">key</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">ArrowDown</span><span class="dl">"</span><span class="p">)</span> <span class="nf">hardDrop</span><span class="p">();</span> <span class="c1">// 下矢印キーでhardDrop()を呼び出し (Step 4/5で実装)</span>
<span class="p">});</span>

<span class="kd">function</span> <span class="nf">movePiece</span><span class="p">(</span><span class="nx">dx</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">x</span> <span class="o">+=</span> <span class="nx">dx</span><span class="p">;</span> <span class="c1">// ブロックのX座標をdxだけ増減</span>
  <span class="c1">// ※ 注意: この時点ではまだ壁や他のブロックとの衝突判定は考慮していません。</span>
  <span class="c1">//   次のステップ以降で衝突判定を実装し、移動可能かチェックします。</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">rotatePiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// 形状を表す2次元配列を90度回転させるロジック</span>
  <span class="kd">const</span> <span class="nx">rotatedShape</span> <span class="o">=</span> <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nf">map</span><span class="p">((</span><span class="nx">_</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">=></span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">.</span><span class="nf">map</span><span class="p">((</span><span class="nx">row</span><span class="p">)</span> <span class="o">=></span> <span class="nx">row</span><span class="p">[</span><span class="nx">index</span><span class="p">]).</span><span class="nf">reverse</span><span class="p">()</span>
  <span class="p">);</span>
  <span class="kd">const</span> <span class="nx">backup</span> <span class="o">=</span> <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">;</span> <span class="c1">// 回転前の形状をバックアップ</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span> <span class="o">=</span> <span class="nx">rotatedShape</span><span class="p">;</span> <span class="c1">// 回転後の形状をセット</span>
  <span class="c1">// ※ 注意: この時点ではまだ回転後の衝突判定は考慮していません。</span>
  <span class="c1">//   次のステップ以降で衝突判定を実装し、回転可能かチェックします。</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="276:1-276:290"><code>movePiece(dx)</code>関数は、<code>currentPiece</code>のX座標を引数<code>dx</code>の値(左移動なら-1、右移動なら1)だけ変更します。<code>rotatePiece()</code>関数は、現在のブロックの形状を90度回転させた新しい形状を計算し、<code>currentPiece.shape</code>にセットします。</p>
<p data-sourcepos="278:1-278:264">この時点では、まだ壁や他のブロックとの衝突判定は行っていません。そのため、ブロックが壁を突き抜けたり、他のブロックに重なったりしてしまいますが、これは次のステップで解決します。</p>
<h3 data-sourcepos="280:1-280:75">
<span id="step-4-時間が立つとブロックが落ちていく処理の実装" class="fragment"/><a href="#step-4-%E6%99%82%E9%96%93%E3%81%8C%E7%AB%8B%E3%81%A4%E3%81%A8%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%81%8C%E8%90%BD%E3%81%A1%E3%81%A6%E3%81%84%E3%81%8F%E5%87%A6%E7%90%86%E3%81%AE%E5%AE%9F%E8%A3%85"><i class="fa fa-link"/></a>Step 4: 時間が立つとブロックが落ちていく処理の実装</h3>
<p data-sourcepos="282:1-282:126">落ち物ゲームの主要な要素の一つである、時間経過によるブロックの自動落下を実装します。</p>
<p data-sourcepos="284:1-284:158">ゲームの描画や状態更新を一定間隔で行うために、ブラウザの<code>requestAnimationFrame</code>を使ったゲームループを構築します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="286:1-317:3">
<div class="highlight">
<pre><code><span class="kd">let</span> <span class="nx">dropStart</span> <span class="o">=</span> <span class="nx">performance</span><span class="p">.</span><span class="nf">now</span><span class="p">();</span> <span class="c1">// 前回の落下処理または描画更新が行われた時刻</span>
<span class="kd">let</span> <span class="nx">dropInterval</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span> <span class="c1">// ブロックが1マス落下するまでの時間(ミリ秒)</span>

<span class="kd">function</span> <span class="nf">update</span><span class="p">(</span><span class="nx">timestamp</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// timestampはrequestAnimationFrameが提供する現在の時刻</span>

  <span class="c1">// 前回の処理からの経過時間を計算</span>
  <span class="kd">const</span> <span class="nx">deltaTime</span> <span class="o">=</span> <span class="nx">timestamp</span> <span class="o">-</span> <span class="nx">dropStart</span><span class="p">;</span>

  <span class="c1">// 経過時間が落下間隔を超えていたらブロックを落とす</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">deltaTime</span> <span class="o">></span> <span class="nx">dropInterval</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">dropPiece</span><span class="p">();</span> <span class="c1">// ブロックを1マス落下させる関数を呼び出し</span>
    <span class="nx">dropStart</span> <span class="o">=</span> <span class="nx">timestamp</span><span class="p">;</span> <span class="c1">// dropStartを現在の時刻に更新</span>
  <span class="p">}</span>

  <span class="c1">// ゲーム画面を最新の状態に描画</span>
  <span class="nf">drawBoard</span><span class="p">();</span> <span class="c1">// 固定されたブロックを描画</span>
  <span class="nf">drawPiece</span><span class="p">(</span><span class="nx">currentPiece</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">grid</span><span class="p">);</span> <span class="c1">// 現在落下中のブロックを描画</span>

  <span class="c1">// 次のフレームでのupdate関数の実行をブラウザに依頼</span>
  <span class="nf">requestAnimationFrame</span><span class="p">(</span><span class="nx">update</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// ゲーム開始時に最初に一度だけ呼び出す処理</span>
<span class="kd">function</span> <span class="nf">initializeGame</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// ... 初期化処理(ブロック生成など、Step 7で追加) ...</span>
    <span class="nf">requestAnimationFrame</span><span class="p">(</span><span class="nx">update</span><span class="p">);</span> <span class="c1">// ゲームループを開始</span>
<span class="p">}</span>

<span class="c1">// initializeGame(); // ゲーム開始 (initializeGameはStep 7で定義)</span>
</code></pre>
</div>
</div>
<p data-sourcepos="319:1-319:399"><code>update(timestamp)</code>関数が、ブラウザの描画更新タイミングに合わせて繰り返し呼び出されます。この関数の中で、<code>performance.now()</code>を使って前回の処理からの経過時間を計測し、<code>dropInterval</code>で設定した時間(例: 500ms)ごとに<code>dropPiece()</code>関数を呼び出すことで、ブロックが自動で落下する仕組みを作ります。</p>
<p data-sourcepos="321:1-321:130"><code>dropPiece()</code>関数は、シンプルに<code>currentPiece.y</code>を1つ増やすことでブロックを1マス下に移動させます。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="323:1-329:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">dropPiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// ブロックを1マス下に移動</span>
  <span class="c1">// ※ 注意: この時点では落下後の衝突判定はまだ考慮していません。</span>
  <span class="c1">//   次のステップで衝突判定を実装し、落下可能かチェックします。</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="331:1-331:309"><code>update</code>関数の最後で<code>requestAnimationFrame(update)</code>を呼び出すことで、再帰的に<code>update</code>関数が呼び出され、ゲームループが継続します。また、ゲーム開始時に一度だけ<code>requestAnimationFrame(update)</code>を呼び出すことで、ゲームループを開始します。</p>
<h3 data-sourcepos="333:1-333:54">
<span id="step-5-壁とブロックの衝突判定の実装" class="fragment"/><a href="#step-5-%E5%A3%81%E3%81%A8%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%81%AE%E8%A1%9D%E7%AA%81%E5%88%A4%E5%AE%9A%E3%81%AE%E5%AE%9F%E8%A3%85"><i class="fa fa-link"/></a>Step 5: 壁とブロックの衝突判定の実装</h3>
<p data-sourcepos="335:1-335:312">このゲームでは、ブロックがゲームボードの境界(壁や底)を突き抜けたり、既に固定されている他のブロックと重なったりすることはできないようにします。これらの「衝突」を検出する処理を実装し、操作や落下を制限します。</p>
<p data-sourcepos="337:1-337:227">Step 4で作成した<code>dropPiece</code>関数や、Step 3で作成した<code>movePiece</code>, <code>rotatePiece</code>関数の中に、衝突判定のロジックを追加します。衝突判定を行うための<code>collision()</code>関数を実装します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="339:1-362:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">collision</span><span class="p">():</span> <span class="nx">boolean</span> <span class="p">{</span>
  <span class="c1">// currentPieceの形状を構成する各セルについてループ</span>
  <span class="k">return</span> <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">.</span><span class="nf">some</span><span class="p">((</span><span class="nx">row</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="c1">// 形状の各行</span>
    <span class="nx">row</span><span class="p">.</span><span class="nf">some</span><span class="p">(</span>
      <span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">x</span><span class="p">)</span> <span class="o">=></span>
        <span class="nx">value</span> <span class="o">&&</span> <span class="c1">// そのセルがブロックの一部であるか (valueが1か)</span>
        <span class="p">(</span>
          <span class="c1">// ゲームボードの境界外に出ていないかチェック</span>
          <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">x</span> <span class="o"> <span class="mi">0</span> <span class="o">||</span> <span class="c1">// 左端の境界判定</span>
          <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">x</span> <span class="o">>=</span> <span class="nx">cols</span> <span class="o">||</span> <span class="c1">// 右端の境界判定</span>
          <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">y</span> <span class="o">>=</span> <span class="nx">rows</span> <span class="o">||</span> <span class="c1">// 下端 (底) の境界判定</span>
          <span class="c1">// 既にボードに固定されているブロックと重なっていないかチェック</span>
          <span class="c1">// ※ ただし、currentPiece.y + y が負になる可能性 (ボードより上) も考慮が必要ですが、</span>
          <span class="c1">//    ここではシンプル化のため、ボード内の座標を前提としています。</span>
          <span class="c1">//    厳密には board[currentPiece.y + y] が undefined にならないかのチェックも必要ですが、</span>
          <span class="c1">//    形状のy座標は通常0以上から始まるため、y >= 0 と currentPiece.y >= 0 であれば問題ありません。</span>
          <span class="c1">//    ゲーム開始時のy=0で即衝突判定するケースなどを考慮します。</span>
          <span class="p">(</span><span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">y</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">&&</span> <span class="nx">board</span><span class="p">[</span><span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">y</span><span class="p">][</span><span class="nx">currentPiece</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">x</span><span class="p">])</span>
        <span class="p">)</span>
    <span class="p">)</span>
  <span class="p">);</span>
<span class="p">}</span>
</span></code></pre>
</div>
</div>
<p data-sourcepos="364:1-364:261"><code>collision()</code>関数は、<code>currentPiece</code>の形状を構成する各セルについて、そのセルがゲームボード上のどの位置に来るかを計算し、以下のいずれかに当てはまる場合に<code>true</code>(衝突している)を返します。</p>
<ul data-sourcepos="366:1-370:0">
<li data-sourcepos="366:1-366:82">ゲームボードの左端より左に出ている (<code>currentPiece.x + x )</code></li>
<li data-sourcepos="367:1-367:86">ゲームボードの右端より右に出ている (<code>currentPiece.x + x >= cols</code>)</li>
<li data-sourcepos="368:1-368:83">ゲームボードの底より下に出ている (<code>currentPiece.y + y >= rows</code>)</li>
<li data-sourcepos="369:1-370:0">計算された位置に、既に<code>board</code>配列上でブロックが固定されている (<code>board[currentPiece.y + y][currentPiece.x + x]</code> が0以外)</li>
</ul>
<p data-sourcepos="371:1-371:91">この<code>collision()</code>関数を、移動、回転、落下の各関数に組み込みます。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="373:1-412:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">movePiece</span><span class="p">(</span><span class="nx">dx</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">x</span> <span class="o">+=</span> <span class="nx">dx</span><span class="p">;</span> <span class="c1">// とりあえず移動させてみる</span>
  <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span> <span class="c1">// 衝突したら</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">x</span> <span class="o">-=</span> <span class="nx">dx</span><span class="p">;</span> <span class="c1">// 移動をキャンセル (元に戻す)</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">rotatePiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">rotatedShape</span> <span class="o">=</span> <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nf">map</span><span class="p">((</span><span class="nx">_</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">=></span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">.</span><span class="nf">map</span><span class="p">((</span><span class="nx">row</span><span class="p">)</span> <span class="o">=></span> <span class="nx">row</span><span class="p">[</span><span class="nx">index</span><span class="p">]).</span><span class="nf">reverse</span><span class="p">()</span>
  <span class="p">);</span>
  <span class="kd">const</span> <span class="nx">backup</span> <span class="o">=</span> <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">;</span> <span class="c1">// 回転前の形状をバックアップ</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span> <span class="o">=</span> <span class="nx">rotatedShape</span><span class="p">;</span> <span class="c1">// 回転後の形状を仮セット</span>
  <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span> <span class="c1">// 回転後の形状で衝突したら</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span> <span class="o">=</span> <span class="nx">backup</span><span class="p">;</span> <span class="c1">// 回転をキャンセル (元の形状に戻す)</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">dropPiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// とりあえず下に移動</span>
  <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span> <span class="c1">// 下に移動して衝突したら</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 移動をキャンセル (元のY座標に戻す)</span>
    <span class="c1">// ※ 注意: この後、ブロックを固定する処理に進みます (Step 6)</span>
  <span class="p">}</span>
  <span class="c1">// ※ 注意: この時点ではまだ時間経過による自動落下で落下できなかった場合の固定処理は未実装です。</span>
  <span class="c1">//   次のステップで固定処理を実装します。</span>
<span class="p">}</span>

<span class="c1">// 下矢印キーで呼び出される hardDrop() も、collision() を使って最下部を判定します (Step 5/6 で完成)</span>
<span class="kd">function</span> <span class="nf">hardDrop</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">while </span><span class="p">(</span><span class="o">!</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span> <span class="c1">// 衝突しない間、下に移動し続ける</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 衝突した位置から1マス戻る (最下部確定)</span>
  <span class="c1">// ※ 注意: この後、ブロックを固定する処理に進みます (Step 6)</span>
  <span class="c1">// lockStart = performance.now(); // ハードドロップ後の猶予 (Step 10で追加)</span>
  <span class="c1">// dropPiece(); // 通常の落下処理に任せる (Step 10で修正)</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="414:1-414:138">これで、ブロックが壁や他のブロックにめり込むことなく、正しく操作・落下するようになりました。</p>
<h3 data-sourcepos="416:1-416:60">
<span id="step-6-ブロックを積み上げて固定する実装" class="fragment"/><a href="#step-6-%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%82%92%E7%A9%8D%E3%81%BF%E4%B8%8A%E3%81%92%E3%81%A6%E5%9B%BA%E5%AE%9A%E3%81%99%E3%82%8B%E5%AE%9F%E8%A3%85"><i class="fa fa-link"/></a>Step 6: ブロックを積み上げて固定する実装</h3>
<p data-sourcepos="418:1-418:192">ブロックがそれ以上下に移動できなくなった際に、そのブロックをゲームボードの一部として固定し、次のブロックが出現するようにします。</p>
<p data-sourcepos="420:1-420:263"><code>dropPiece()</code>関数内で、落下後に<code>collision()</code>が<code>true</code>になった場合(つまり、下に移動しようとしたが衝突した、落下できない状態になった場合)に、ブロックをボードに固定する処理を呼び出します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="422:1-476:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">dropPiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span> <span class="c1">// 下に移動して衝突した (落下できない)</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 元のY座標に戻す</span>

    <span class="c1">// ブロックをゲームボードに固定する処理を呼び出し</span>
    <span class="nf">placePiece</span><span class="p">();</span>

    <span class="c1">// 次のブロックを生成し、現在のブロックと入れ替える (Step 7で完成)</span>
    <span class="c1">// currentPiece = nextPiece;</span>
    <span class="c1">// nextPiece = randomPiece();</span>
    <span class="c1">// drawNextPiece();</span>
    <span class="c1">// lockStart = null; // 固定猶予をリセット (Step 10で追加)</span>

    <span class="c1">// ライン消去とスコア加算のチェック (Step 8/9で追加)</span>
    <span class="c1">// clearLines();</span>

    <span class="c1">// 新しいブロックが出現した時点で即衝突したらゲームオーバー (Step 7/??で追加)</span>
    <span class="c1">// if (collision()) {</span>
    <span class="c1">//   gameOver();</span>
    <span class="c1">// }</span>

  <span class="p">}</span>
  <span class="c1">// else { // 落下できた場合は猶予をリセット (Step 10で追加)</span>
  <span class="c1">//   lockStart = null;</span>
  <span class="c1">// }</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">placePiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// currentPieceの形状を構成する各セルについてループ</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">.</span><span class="nf">forEach</span><span class="p">((</span><span class="nx">row</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
    <span class="nx">row</span><span class="p">.</span><span class="nf">forEach</span><span class="p">((</span><span class="nx">value</span><span class="p">,</span> <span class="nx">x</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// そのセルがブロックの一部であれば (valueが1)</span>
        <span class="c1">// ゲームボード上の該当セルに、ブロックの色に対応する値を書き込む</span>
        <span class="c1">// colors配列のインデックス (0-7) に+1した値 (1-8) を格納することで、0 (空き) と区別し色も保持</span>
        <span class="nx">board</span><span class="p">[</span><span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">y</span><span class="p">][</span><span class="nx">currentPiece</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">x</span><span class="p">]</span> <span class="o">=</span>
          <span class="nx">colors</span><span class="p">.</span><span class="nf">indexOf</span><span class="p">(</span><span class="nx">currentPiece</span><span class="p">.</span><span class="nx">color</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
      <span class="p">}</span>
    <span class="p">});</span>
  <span class="p">});</span>
<span class="p">}</span>

<span class="c1">// hardDrop() も、最下部に到達したらplacePiece() を呼び出すようにする</span>
<span class="kd">function</span> <span class="nf">hardDrop</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">while </span><span class="p">(</span><span class="o">!</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span>

  <span class="nf">placePiece</span><span class="p">();</span> <span class="c1">// 最下部に固定</span>

  <span class="c1">// ... (ライン消去、次のブロック生成などの後処理) ...</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="478:1-478:430"><code>placePiece()</code>関数は、<code>currentPiece</code>が現在位置に固定されたものとして、その形状を<code>board</code>配列に書き込みます。<code>board</code>配列の該当セルに、ブロックの色を識別するための値(<code>colors</code>配列のインデックス + 1)をセットします。これにより、そのブロックはゲームボードの一部となり、<code>drawBoard()</code>関数で描画されるようになります。</p>
<p data-sourcepos="480:1-480:119">また、<code>hardDrop()</code>関数も、最下部に到達した後に<code>placePiece()</code>を呼び出すように修正します。</p>
<h3 data-sourcepos="482:1-482:70">
<span id="step-7-nextブロックのキャンバスとロジックの実装" class="fragment"/><a href="#step-7-next%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%81%AE%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%90%E3%82%B9%E3%81%A8%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%E3%81%AE%E5%AE%9F%E8%A3%85"><i class="fa fa-link"/></a>Step 7: Nextブロックのキャンバスとロジックの実装</h3>
<p data-sourcepos="484:1-484:190">次に落ちてくるブロックをプレイヤーに示すためのNextブロック表示エリアを実装し、ゲームの進行に合わせて表示を更新するようにします。</p>
<p data-sourcepos="486:1-486:105">事前準備でHTMLに用意した<code>nextBlockCanvas</code>要素の描画コンテキストを取得します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="488:1-497:3">
<div class="highlight">
<pre><code><span class="kd">const</span> <span class="nx">nextBlockCanvas</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">nextBlockCanvas</span><span class="dl">"</span>
<span class="p">)</span> <span class="kd">as </span><span class="nx">HTMLCanvasElement</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">nextContext</span> <span class="o">=</span> <span class="nx">nextBlockCanvas</span><span class="p">.</span><span class="nf">getContext</span><span class="p">(</span><span class="dl">"</span><span class="s2">2d</span><span class="dl">"</span><span class="p">)</span><span class="o">!</span><span class="p">;</span> <span class="c1">// Nextブロック用コンテキスト</span>
<span class="kd">const</span> <span class="nx">nextBlockGrid</span> <span class="o">=</span> <span class="mi">30</span><span class="p">;</span> <span class="c1">// Nextブロックエリアの1マスサイズ (今回はゲームボードと同じ)</span>
<span class="kd">const</span> <span class="nx">nextBlockSize</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span> <span class="c1">// Nextブロックエリアを何マス分として扱うか (ブロックは最大4マスなので5マスあれば収まる)</span>

<span class="kd">let</span> <span class="nx">nextPiece</span><span class="p">:</span> <span class="nx">Piece</span><span class="p">;</span> <span class="c1">// 次のブロックを保持する変数</span>
</code></pre>
</div>
</div>
<p data-sourcepos="499:1-499:84">ブロックをランダムに生成する<code>randomPiece()</code>関数を作成します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="501:1-511:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">randomPiece</span><span class="p">():</span> <span class="nx">Piece</span> <span class="p">{</span>
  <span class="c1">// shapes配列からランダムに形状を選ぶ</span>
  <span class="kd">const</span> <span class="nx">index</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nf">random</span><span class="p">()</span> <span class="o">*</span> <span class="nx">shapes</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">shape</span> <span class="o">=</span> <span class="nx">shapes</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
  <span class="c1">// ゲームボードの上部中央に出現するように初期X座標を計算</span>
  <span class="kd">const</span> <span class="nx">startX</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">floor</span><span class="p">((</span><span class="nx">cols</span> <span class="o">-</span> <span class="nx">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">);</span>
  <span class="c1">// ランダムな形状、対応する色、計算した初期位置でPieceオブジェクトを作成して返す</span>
  <span class="k">return</span> <span class="p">{</span> <span class="nx">shape</span><span class="p">,</span> <span class="na">color</span><span class="p">:</span> <span class="nx">colors</span><span class="p">[</span><span class="nx">index</span><span class="p">],</span> <span class="na">x</span><span class="p">:</span> <span class="nx">startX</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="mi">0</span> <span class="p">};</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="513:1-513:204">Nextブロックエリアに<code>nextPiece</code>を描画する関数<code>drawNextPiece()</code>を作成します。Nextブロックエリアの中央に表示されるように位置を調整する計算を含めます。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="515:1-526:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">drawNextPiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// NextブロックCanvasをクリア</span>
  <span class="nx">nextContext</span><span class="p">.</span><span class="nf">clearRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">nextBlockCanvas</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="nx">nextBlockCanvas</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span>
  <span class="c1">// Nextブロックエリアの中央に描画するためのオフセットを計算</span>
  <span class="kd">const</span> <span class="nx">offsetX</span> <span class="o">=</span> <span class="p">(</span><span class="nx">nextBlockSize</span> <span class="o">-</span> <span class="nx">nextPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span>
  <span class="kd">const</span> <span class="nx">offsetY</span> <span class="o">=</span> <span class="p">(</span><span class="nx">nextBlockSize</span> <span class="o">-</span> <span class="nx">nextPiece</span><span class="p">.</span><span class="nx">shape</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span>
  <span class="c1">// オフセットを適用した新しいPieceオブジェクトを作成し、drawPieceで描画</span>
  <span class="kd">const</span> <span class="nx">nextPieceCentered</span><span class="p">:</span> <span class="nx">Piece</span> <span class="o">=</span> <span class="p">{</span> <span class="p">...</span><span class="nx">nextPiece</span><span class="p">,</span> <span class="na">x</span><span class="p">:</span> <span class="nx">offsetX</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="nx">offsetY</span> <span class="p">};</span>
  <span class="nf">drawPiece</span><span class="p">(</span><span class="nx">nextPieceCentered</span><span class="p">,</span> <span class="nx">nextContext</span><span class="p">,</span> <span class="nx">nextBlockGrid</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="528:1-528:279">ゲーム開始時や、ブロックが固定されて次のブロックが出現する際に、これらの関数を呼び出すようにします。ゲーム開始時の初期化関数<code>initializeGame()</code>を定義し、ゲームループの開始前に一度呼び出します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="530:1-546:3">
<div class="highlight">
<pre><code><span class="c1">// initializeGame 関数を定義</span>
<span class="kd">function</span> <span class="nf">initializeGame</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// ゲームボードを初期化(全て空きマスに)</span>
  <span class="nx">board</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="k">from</span><span class="p">({</span> <span class="na">length</span><span class="p">:</span> <span class="nx">rows</span> <span class="p">},</span> <span class="p">()</span> <span class="o">=></span> <span class="nc">Array</span><span class="p">(</span><span class="nx">cols</span><span class="p">).</span><span class="nf">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
  <span class="c1">// 最初のブロックと次のブロックを生成</span>
  <span class="nx">currentPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
  <span class="nx">nextPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
  <span class="c1">// Nextブロックを描画</span>
  <span class="nf">drawNextPiece</span><span class="p">();</span>
  <span class="c1">// ゲームループを開始</span>
  <span class="nf">requestAnimationFrame</span><span class="p">(</span><span class="nx">update</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// ゲーム開始!</span>
<span class="nf">initializeGame</span><span class="p">();</span>
</code></pre>
</div>
</div>
<p data-sourcepos="548:1-548:257">そして、Step 6で実装した<code>dropPiece()</code>関数内で、ブロックを固定(<code>placePiece()</code>)した後に、<code>currentPiece</code>と<code>nextPiece</code>を入れ替え、新しい<code>nextPiece</code>を生成し、<code>drawNextPiece()</code>を呼び出す処理を追加します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="550:1-601:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">dropPiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span>

    <span class="nf">placePiece</span><span class="p">();</span> <span class="c1">// ブロック固定</span>

    <span class="c1">// 次のブロックを現在のブロックにする</span>
    <span class="nx">currentPiece</span> <span class="o">=</span> <span class="nx">nextPiece</span><span class="p">;</span>
    <span class="c1">// 新しい次のブロックを生成</span>
    <span class="nx">nextPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
    <span class="c1">// Nextブロック表示を更新</span>
    <span class="nf">drawNextPiece</span><span class="p">();</span>
    <span class="c1">// lockStart = null; // 固定猶予をリセット (Step 10で追加)</span>

    <span class="c1">// ライン消去とスコア加算のチェック (Step 8/9で追加)</span>
    <span class="c1">// clearLines();</span>

    <span class="c1">// 新しいブロックが出現した時点で、即座に他のブロックと衝突している場合、ゲームオーバー</span>
    <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
      <span class="nf">gameOver</span><span class="p">();</span> <span class="c1">// ゲームオーバー処理 (別途定義)</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="c1">// else { // 落下できた場合は猶予をリセット (Step 10で追加)</span>
  <span class="c1">//   lockStart = null;</span>
  <span class="c1">// }</span>
<span class="p">}</span>

<span class="c1">// ゲームオーバー処理の定義 (リセットなど)</span>
<span class="kd">function</span> <span class="nf">gameOver</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">alert</span><span class="p">(</span><span class="dl">"</span><span class="s2">Game Over!</span><span class="dl">"</span><span class="p">);</span> <span class="c1">// 例としてアラート表示</span>
  <span class="nf">resetGame</span><span class="p">();</span> <span class="c1">// ゲーム状態をリセットする関数 (別途定義)</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">resetGame</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">score</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// スコアをリセット (Step 8で追加)</span>
  <span class="c1">// updateScore(0); // スコア表示を更新 (Step 9で追加)</span>
  <span class="nx">board</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="k">from</span><span class="p">({</span> <span class="na">length</span><span class="p">:</span> <span class="nx">rows</span> <span class="p">},</span> <span class="p">()</span> <span class="o">=></span> <span class="nc">Array</span><span class="p">(</span><span class="nx">cols</span><span class="p">).</span><span class="nf">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span> <span class="c1">// ボードをリセット</span>
  <span class="nf">initializePieces</span><span class="p">();</span> <span class="c1">// ブロックを再生成 (initializePiecesはinitializeGameから名前変更または一部抽出)</span>
<span class="p">}</span>

<span class="c1">//initializeGame から一部抽出・改変した initializePieces 関数(リセット時などに使用)</span>
<span class="kd">function</span> <span class="nf">initializePieces</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">currentPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
  <span class="nx">nextPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
  <span class="nf">drawNextPiece</span><span class="p">();</span>
<span class="p">}</span>

<span class="c1">// ゲーム開始は initializeGame() を使用</span>
<span class="c1">// initializeGame(); // main.tsの末尾で呼び出す</span>
</code></pre>
</div>
</div>
<p data-sourcepos="603:1-603:313">これで、ブロックが固定されるたびにNextブロックが表示され、次のブロックがゲームボードの上部に出現するようになりました。また、新しいブロックが出現した時点で既に衝突していた場合のゲームオーバー判定も加わりました。</p>
<h3 data-sourcepos="605:1-605:55">
<span id="step-8-1行そろうとブロックを消す実装" class="fragment"/><a href="#step-8-1%E8%A1%8C%E3%81%9D%E3%82%8D%E3%81%86%E3%81%A8%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%82%92%E6%B6%88%E3%81%99%E5%AE%9F%E8%A3%85"><i class="fa fa-link"/></a>Step 8: 1行そろうとブロックを消す実装</h3>
<p data-sourcepos="607:1-607:216">このゲームのゲーム性として、横一列にブロックが揃うとラインが消去され、上のブロックが下に落ちてくるようにします。このライン消去処理を実装します。</p>
<p data-sourcepos="609:1-609:121">Step 6でブロックを固定(<code>placePiece()</code>)した後に、<code>clearLines()</code>関数を呼び出すようにします。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="611:1-671:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">clearLines</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">linesCleared</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// 今回の操作で消去したライン数をカウント</span>

  <span class="c1">// ゲームボードの下から順番に各行をチェック</span>
  <span class="k">for </span><span class="p">(</span><span class="kd">let</span> <span class="nx">y</span> <span class="o">=</span> <span class="nx">rows</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">y</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// その行の全てのセルにブロックがあるか? (値が0以外か)</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">board</span><span class="p">[</span><span class="nx">y</span><span class="p">].</span><span class="nf">every</span><span class="p">((</span><span class="nx">value</span><span class="p">)</span> <span class="o">=></span> <span class="nx">value</span> <span class="o">!==</span> <span class="mi">0</span><span class="p">))</span> <span class="p">{</span>
      <span class="c1">// 全て埋まっていた場合、その行をボード配列から削除</span>
      <span class="nx">board</span><span class="p">.</span><span class="nf">splice</span><span class="p">(</span><span class="nx">y</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
      <span class="c1">// ボードの一番上に新しい空の行 (全て0) を追加</span>
      <span class="nx">board</span><span class="p">.</span><span class="nf">unshift</span><span class="p">(</span><span class="nc">Array</span><span class="p">(</span><span class="nx">cols</span><span class="p">).</span><span class="nf">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
      <span class="c1">// 行を削除したので、同じy座標をもう一度チェックする必要があるため、yをインクリメント</span>
      <span class="nx">y</span><span class="o">++</span><span class="p">;</span>
      <span class="c1">// 消去したライン数をカウント</span>
      <span class="nx">linesCleared</span><span class="o">++</span><span class="p">;</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="c1">// ※ スコア加算処理は次のステップで追加</span>
  <span class="c1">// if (linesCleared > 0) { ... updateScore(...) ... }</span>
<span class="p">}</span>

<span class="c1">// dropPiece関数内で placePiece() の後に clearLines() を呼び出すように修正</span>
<span class="kd">function</span> <span class="nf">dropPiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="nf">placePiece</span><span class="p">();</span>
    <span class="c1">// ここでライン消去を呼び出す</span>
    <span class="nf">clearLines</span><span class="p">();</span> <span class="c1">// 
    <span class="nx">currentPiece</span> <span class="o">=</span> <span class="nx">nextPiece</span><span class="p">;</span>
    <span class="nx">nextPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
    <span class="nf">drawNextPiece</span><span class="p">();</span>
    <span class="c1">// lockStart = null; // Step 10</span>
    <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
      <span class="nf">gameOver</span><span class="p">();</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="c1">// else { lockStart = null; } // Step 10</span>
<span class="p">}</span>

<span class="c1">// hardDrop関数内でも placePiece() の後に clearLines() を呼び出すように修正</span>
<span class="kd">function</span> <span class="nf">hardDrop</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">while </span><span class="p">(</span><span class="o">!</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="nf">placePiece</span><span class="p">();</span>
  <span class="c1">// ここでライン消去を呼び出す</span>
  <span class="nf">clearLines</span><span class="p">();</span> <span class="c1">// 
  <span class="c1">// lockStart = performance.now(); // Step 10</span>
  <span class="c1">// dropPiece(); // Step 10 で修正</span>
  <span class="nx">currentPiece</span> <span class="o">=</span> <span class="nx">nextPiece</span><span class="p">;</span> <span class="c1">// hardDrop後も次のブロックが登場</span>
  <span class="nx">nextPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
  <span class="nf">drawNextPiece</span><span class="p">();</span>
  <span class="c1">// lockStart = null; // Step 10</span>
  <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
      <span class="nf">gameOver</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span>
</span></span></code></pre>
</div>
</div>
<p data-sourcepos="673:1-673:598"><code>clearLines()</code>関数は、ボードの最も下の行から順番に上に向かって、各行が全てブロックで埋まっているか(<code>every</code>メソッドを使って判定)を確認します。もし全て埋まっていれば、その行を<code>board</code>配列から削除し、配列の先頭(一番上)に新しい空の行を追加します。これにより、上の行が一段下に移動したように見えます。削除した行の位置をもう一度チェックする必要があるため、ループ変数の<code>y</code>をインクリメントしているのがポイントです。</p>
<p data-sourcepos="675:1-675:75">これで、ラインが揃うと消去されるようになりました。</p>
<h3 data-sourcepos="677:1-677:61">
<span id="step-9-1行そろうとスコアが加算される実装" class="fragment"/><a href="#step-9-1%E8%A1%8C%E3%81%9D%E3%82%8D%E3%81%86%E3%81%A8%E3%82%B9%E3%82%B3%E3%82%A2%E3%81%8C%E5%8A%A0%E7%AE%97%E3%81%95%E3%82%8C%E3%82%8B%E5%AE%9F%E8%A3%85"><i class="fa fa-link"/></a>Step 9: 1行そろうとスコアが加算される実装</h3>
<p data-sourcepos="679:1-679:138">ラインを消去した際に、消去したライン数に応じてプレイヤーのスコアを加算し、画面に表示します。</p>
<p data-sourcepos="681:1-681:124">事前準備でHTMLに用意した<code>scoreBoard</code>要素を取得します。スコアを保持する変数も用意します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="683:1-712:3">
<div class="highlight">
<pre><code><span class="kd">const</span> <span class="nx">scoreBoard</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">scoreBoard</span><span class="dl">"</span><span class="p">)</span> <span class="kd">as </span><span class="nx">HTMLElement</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">score</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// 現在のスコア</span>

<span class="c1">// スコア表示を更新する関数</span>
<span class="kd">function</span> <span class="nf">updateScore</span><span class="p">(</span><span class="nx">points</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">score</span> <span class="o">+=</span> <span class="nx">points</span><span class="p">;</span> <span class="c1">// スコアを加算</span>
  <span class="c1">// スコアボードのテキストを更新</span>
  <span class="nx">scoreBoard</span><span class="p">.</span><span class="nx">innerText</span> <span class="o">=</span> <span class="s2">`Score: </span><span class="p">${</span><span class="nx">score</span><span class="p">.</span><span class="nf">toString</span><span class="p">().</span><span class="nf">padStart</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="dl">'</span><span class="s1">0</span><span class="dl">'</span><span class="p">)}</span><span class="s2">`</span><span class="p">;</span> <span class="c1">// 5桁表示の例</span>
<span class="p">}</span>

<span class="c1">// ゲーム開始時やリセット時にスコアを0にリセットし、表示を更新</span>
<span class="kd">function</span> <span class="nf">resetGame</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">score</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="nf">updateScore</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="c1">// 初期スコア表示を更新</span>
  <span class="nx">board</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="k">from</span><span class="p">({</span> <span class="na">length</span><span class="p">:</span> <span class="nx">rows</span> <span class="p">},</span> <span class="p">()</span> <span class="o">=></span> <span class="nc">Array</span><span class="p">(</span><span class="nx">cols</span><span class="p">).</span><span class="nf">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
  <span class="nf">initializePieces</span><span class="p">();</span>
<span class="p">}</span>

<span class="c1">// initializeGame 関数内でも初期スコア表示を呼び出す</span>
<span class="kd">function</span> <span class="nf">initializeGame</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">board</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="k">from</span><span class="p">({</span> <span class="na">length</span><span class="p">:</span> <span class="nx">rows</span> <span class="p">},</span> <span class="p">()</span> <span class="o">=></span> <span class="nc">Array</span><span class="p">(</span><span class="nx">cols</span><span class="p">).</span><span class="nf">fill</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
  <span class="nx">score</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// スコア初期化</span>
  <span class="nf">updateScore</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="c1">// スコア表示を初期化</span>
  <span class="nx">currentPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
  <span class="nx">nextPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span>
  <span class="nf">drawNextPiece</span><span class="p">();</span>
  <span class="nf">requestAnimationFrame</span><span class="p">(</span><span class="nx">update</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="714:1-714:175">そして、Step 8で作成した<code>clearLines()</code>関数内に、消去したライン数(<code>linesCleared</code>)に応じてスコアを加算するロジックを追加します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="716:1-729:3">
<div class="highlight">
<pre><code><span class="kd">function</span> <span class="nf">clearLines</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">linesCleared</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="c1">// ... (ライン消去処理) ...</span>

  <span class="c1">// 消去したライン数が1以上の場合</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">linesCleared</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// 消去したライン数に応じたポイントを計算 (例: 1ライン100点, 2ライン300点, 3ライン500点, 4ライン800点)</span>
    <span class="kd">const</span> <span class="nx">points</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">500</span><span class="p">,</span> <span class="mi">800</span><span class="p">][</span><span class="nx">linesCleared</span><span class="p">];</span>
    <span class="c1">// スコア更新関数を呼び出し</span>
    <span class="nf">updateScore</span><span class="p">(</span><span class="nx">points</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="731:1-731:405"><code>updateScore(points)</code>関数は、引数で受け取ったポイントをグローバル変数<code>score</code>に加算し、<code>scoreBoard</code>要素のテキストを更新することで、現在のスコアを画面に表示します。<code>clearLines</code>関数内で、消去したライン数に応じて<code>[0, 100, 300, 500, 800]</code>のような配列を使って得点を計算し、<code>updateScore</code>を呼び出しています。</p>
<p data-sourcepos="733:1-733:84">これで、ラインを揃えることで得点が入るようになりました。</p>
<h3 data-sourcepos="735:1-735:97">
<span id="step-10-ブロックが落ちてもロックされるまでに少し時間を設ける実装" class="fragment"/><a href="#step-10-%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%81%8C%E8%90%BD%E3%81%A1%E3%81%A6%E3%82%82%E3%83%AD%E3%83%83%E3%82%AF%E3%81%95%E3%82%8C%E3%82%8B%E3%81%BE%E3%81%A7%E3%81%AB%E5%B0%91%E3%81%97%E6%99%82%E9%96%93%E3%82%92%E8%A8%AD%E3%81%91%E3%82%8B%E5%AE%9F%E8%A3%85"><i class="fa fa-link"/></a>Step 10: ブロックが落ちてもロックされるまでに少し時間を設ける実装</h3>
<p data-sourcepos="737:1-737:331">落ち物パズルゲームでは、ブロックが接地(他のブロックやボードの底に触れること)しても、すぐに固定されるわけではなく、少しの間操作の猶予がつけるとゲームの面白さが上がります。この「固定猶予(Lock Delay)」の仕組みを実装します。</p>
<p data-sourcepos="739:1-739:271">これは、Step 6でブロックを固定する処理を呼び出していた<code>dropPiece()</code>関数を修正することで実現します。固定猶予の時間を設定する定数と、猶予時間の計測を開始した時刻を記録する変数を導入します。</p>
<div class="code-frame" data-lang="typescript" data-sourcepos="741:1-799:3">
<div class="highlight">
<pre><code><span class="kd">const</span> <span class="nx">lockDelay</span> <span class="o">=</span> <span class="mi">300</span><span class="p">;</span> <span class="c1">// 固定猶予時間 (ミリ秒) - 例: 0.3秒</span>
<span class="kd">let</span> <span class="nx">lockStart</span><span class="p">:</span> <span class="kr">number</span> <span class="o">|</span> <span class="kc">null</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span> <span class="c1">// 固定猶予の計測開始時刻。猶予中でないときはnull</span>

<span class="kd">function</span> <span class="nf">dropPiece</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// まず下に移動させてみる</span>
  <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span> <span class="c1">// 下に移動して衝突した (落下できない)</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 元のY座標に戻す</span>

    <span class="c1">// 落下できない状態になったのが初めてなら、猶予時間の計測を開始</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">lockStart</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">lockStart</span> <span class="o">=</span> <span class="nx">performance</span><span class="p">.</span><span class="nf">now</span><span class="p">();</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="c1">// 既に落下できない状態が継続していて、かつ猶予時間(lockDelay)が経過したかチェック</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">performance</span><span class="p">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">-</span> <span class="nx">lockStart</span> <span class="o">>=</span> <span class="nx">lockDelay</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// 猶予時間経過!ブロックを固定する</span>
        <span class="nf">placePiece</span><span class="p">();</span>
        <span class="nf">clearLines</span><span class="p">();</span> <span class="c1">// ライン消去</span>
        <span class="nx">currentPiece</span> <span class="o">=</span> <span class="nx">nextPiece</span><span class="p">;</span> <span class="c1">// 次のブロックへ</span>
        <span class="nx">nextPiece</span> <span class="o">=</span> <span class="nf">randomPiece</span><span class="p">();</span> <span class="c1">// 新しいNextブロック生成</span>
        <span class="nf">drawNextPiece</span><span class="p">();</span> <span class="c1">// Nextブロック描画更新</span>
        <span class="nx">lockStart</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span> <span class="c1">// 固定猶予をリセット</span>

        <span class="c1">// 新しいブロックが出現した時点で即衝突ならゲームオーバー</span>
        <span class="k">if </span><span class="p">(</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
          <span class="nf">gameOver</span><span class="p">();</span>
        <span class="p">}</span>
      <span class="p">}</span>
      <span class="c1">// 猶予時間内であれば、ここではまだ固定しない</span>
    <span class="p">}</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="c1">// 下に移動できた場合(接地していない)、固定猶予は発生しないのでリセット</span>
    <span class="nx">lockStart</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// hardDrop() 関数も、落下後にlockStartを設定するように修正します。</span>
<span class="c1">// ハードドロップ後も、接地したブロックに少し操作猶予を与えるためです。</span>
<span class="kd">function</span> <span class="nf">hardDrop</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">while </span><span class="p">(</span><span class="o">!</span><span class="nf">collision</span><span class="p">())</span> <span class="p">{</span>
    <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="nx">currentPiece</span><span class="p">.</span><span class="nx">y</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 最下部位置に決定</span>

  <span class="nx">lockStart</span> <span class="o">=</span> <span class="nx">performance</span><span class="p">.</span><span class="nf">now</span><span class="p">();</span> <span class="c1">// ハードドロップ後、固定猶予の計測を開始</span>

  <span class="c1">// ハードドロップ後の固定処理は、dropPieceの猶予時間判定に任せる</span>
  <span class="c1">// ※ 元コードでは hardDrop内でも placePiece等を呼んでいますが、</span>
  <span class="c1">//    ロック猶予をdropPieceに集約するなら、ここでplacePieceは呼びません。</span>
  <span class="c1">//    ただし、元のコードはハードドロップ即固定+猶予という少し異なる挙動なので、</span>
  <span class="c1">//    元のコードの意図通りにする場合は以下のようになります。</span>
  <span class="c1">// placePiece(); // 最下部に固定 (猶予時間内でも操作はできるが即固定されている状態)</span>
  <span class="c1">// clearLines();</span>
  <span class="c1">// currentPiece = nextPiece;</span>
  <span class="c1">// nextPiece = randomPiece();</span>
  <span class="c1">// drawNextPiece();</span>
  <span class="c1">// if (collision()) { gameOver(); }</span>
<span class="p">}</span>
</code></pre>
</div>
</div>
<p data-sourcepos="801:1-801:599"><code>lockDelay</code>と<code>lockStart</code>変数を使って、ブロックが接地した(落下できなくなった)タイミングで<code>lockStart</code>に現在の時刻を記録します。その状態が<code>lockDelay</code>ミリ秒以上続いた場合にのみ、ブロックの固定処理(<code>placePiece()</code>など)を実行します。猶予時間内にプレイヤーがブロックを左右に移動させたり回転させたりして、再び下に落下できるようになった場合は、<code>collision()</code>が<code>false</code>になるため<code>lockStart</code>が<code>null</code>にリセットされ、猶予期間は終了となります。</p>
<p data-sourcepos="803:1-803:161"><code>hardDrop()</code>後も<code>lockStart</code>を設定することで、ハードドロップ後もわずかな時間だけ操作の猶予が生まれるようになります。</p>
<h2 data-sourcepos="805:1-805:12">
<span id="まとめ" class="fragment"/><a href="#%E3%81%BE%E3%81%A8%E3%82%81"><i class="fa fa-link"/></a>まとめ</h2>
<p data-sourcepos="807:1-807:257">今回の記事では、TypeScriptとHTMLのCanvas APIを使って、ブラウザ上で動作するテトリスのような落ち物パズルゲームゲームをゼロから構築する過程を、10のステップに分けて丁寧に解説しました。</p>
<ol data-sourcepos="809:1-819:0">
<li data-sourcepos="809:1-809:35">Canvasを使った描画方法</li>
<li data-sourcepos="810:1-810:44">ブロックのデータ構造と描画</li>
<li data-sourcepos="811:1-811:41">キーボード入力による操作</li>
<li data-sourcepos="812:1-812:59">ゲームループと時間経過による自動落下</li>
<li data-sourcepos="813:1-813:47">壁や固定ブロックとの衝突判定</li>
<li data-sourcepos="814:1-814:26">ブロックの固定</li>
<li data-sourcepos="815:1-815:41">次のブロックの描画と出現</li>
<li data-sourcepos="816:1-816:20">ライン消去</li>
<li data-sourcepos="817:1-817:20">スコア加算</li>
<li data-sourcepos="818:1-819:0">操作猶予を生むロックディレイ</li>
</ol>
<p data-sourcepos="820:1-820:434">これらのステップを通じて、ゲーム開発における基本的な考え方や実装テクニックを学んでいただけたかと思います。特に、ゲームの状態をデータとして持ち、ゲームループの中でその状態を更新し、Canvasに再描画するというサイクルが、多くの2Dゲームの基本構造であることを理解していただけたのではないでしょうか。</p>
<p data-sourcepos="822:1-822:390">今回作成したゲームはシンプルなものですが、ここからさらにホールド機能、異なる回転法則(SRS)、ゴーストピース表示、レベルによる落下速度の変化、サウンドエフェクト、スコアランキング機能など、様々な要素を追加してゲームをより面白く、完成度高くしていくことが可能です。</p>
<p data-sourcepos="824:1-824:228">ぜひ、この記事で得た知識を元に、ご自身のアイデアを加えてオリジナルのゲーム開発に挑戦してみてください。皆様の今後の学習や制作のきっかけとなれば幸いです。</p>
</div>
<p><script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore">!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '305156090176370');
fbq('trackSingle', '305156090176370', 'PageView');</script><br />
<br /><script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" type="text/javascript">
var adstir_vars = {
  ver: "4.0",
  app_id: "MEDIA-8126b05a",
  ad_spot: 4,
  center: false
};
</script>
<script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" type="text/javascript" src="https://js.ad-stir.com/js/adstir.js"></script>
<br />
<br /><a rel="noopener nofollow" target="_blank" href="https://qiita.com/hiranuma/items/e8e43390b540a8eb692a?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items">Source link </a></p>
<p>Views: 2</p><div class="sharedaddy sd-sharing-enabled"><div class="robots-nocontent sd-block sd-social sd-social-icon sd-sharing"><h3 class="sd-title">共有:</h3><div class="sd-content"><ul><li class="share-facebook"><a rel="nofollow noopener noreferrer"
				data-shared="sharing-facebook-91221"
				class="share-facebook sd-button share-icon no-text"
				href="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/?share=facebook"
				target="_blank"
				aria-labelledby="sharing-facebook-91221"
				>
				<span id="sharing-facebook-91221" hidden>Facebook で共有するにはクリックしてください (新しいウィンドウで開きます)</span>
				<span>Facebook</span>
			</a></li><li class="share-x"><a rel="nofollow noopener noreferrer"
				data-shared="sharing-x-91221"
				class="share-x sd-button share-icon no-text"
				href="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/?share=x"
				target="_blank"
				aria-labelledby="sharing-x-91221"
				>
				<span id="sharing-x-91221" hidden>クリックして X で共有 (新しいウィンドウで開きます)</span>
				<span>X</span>
			</a></li><li class="share-linkedin"><a rel="nofollow noopener noreferrer"
				data-shared="sharing-linkedin-91221"
				class="share-linkedin sd-button share-icon no-text"
				href="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/?share=linkedin"
				target="_blank"
				aria-labelledby="sharing-linkedin-91221"
				>
				<span id="sharing-linkedin-91221" hidden>クリックして LinkedIn で共有 (新しいウィンドウで開きます)</span>
				<span>LinkedIn</span>
			</a></li><li class="share-tumblr"><a rel="nofollow noopener noreferrer"
				data-shared="sharing-tumblr-91221"
				class="share-tumblr sd-button share-icon no-text"
				href="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/?share=tumblr"
				target="_blank"
				aria-labelledby="sharing-tumblr-91221"
				>
				<span id="sharing-tumblr-91221" hidden>クリックして Tumblr で共有 (新しいウィンドウで開きます)</span>
				<span>Tumblr</span>
			</a></li><li class="share-pinterest"><a rel="nofollow noopener noreferrer"
				data-shared="sharing-pinterest-91221"
				class="share-pinterest sd-button share-icon no-text"
				href="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/?share=pinterest"
				target="_blank"
				aria-labelledby="sharing-pinterest-91221"
				>
				<span id="sharing-pinterest-91221" hidden>クリックして Pinterest で共有 (新しいウィンドウで開きます)</span>
				<span>Pinterest</span>
			</a></li><li class="share-threads"><a rel="nofollow noopener noreferrer"
				data-shared="sharing-threads-91221"
				class="share-threads sd-button share-icon no-text"
				href="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/?share=threads"
				target="_blank"
				aria-labelledby="sharing-threads-91221"
				>
				<span id="sharing-threads-91221" hidden>クリックして Threads で共有 (新しいウィンドウで開きます)</span>
				<span>Threads</span>
			</a></li><li class="share-bluesky"><a rel="nofollow noopener noreferrer"
				data-shared="sharing-bluesky-91221"
				class="share-bluesky sd-button share-icon no-text"
				href="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/?share=bluesky"
				target="_blank"
				aria-labelledby="sharing-bluesky-91221"
				>
				<span id="sharing-bluesky-91221" hidden>クリックして Bluesky で共有 (新しいウィンドウで開きます)</span>
				<span>Bluesky</span>
			</a></li><li class="share-end"></li></ul></div></div></div><div class='sharedaddy sd-block sd-like jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded' id='like-post-wrapper-241714808-91221-685401aabdb0b' data-src='https://widgets.wp.com/likes/?ver=14.6#blog_id=241714808&post_id=91221&origin=inmobilexion.com&obj_id=241714808-91221-685401aabdb0b' data-name='like-post-frame-241714808-91221-685401aabdb0b' data-title='いいねまたはリブログ'><h3 class="sd-title">いいね:</h3><div class='likes-widget-placeholder post-likes-widget-placeholder' style='height: 55px;'><span class='button'><span>いいね</span></span> <span class="loading">読み込み中…</span></div><span class='sd-text-color'></span><a class='sd-link-color'></a></div>
<div id='jp-relatedposts' class='jp-relatedposts' >
	<h3 class="jp-relatedposts-headline"><em>関連</em></h3>
</div></div></div><div class="td_block_wrap tdb_single_tags tdi_51 td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_51" >
<style>.tdb_single_tags{margin-bottom:2px;font-family:var(--td_default_google_font_1,'Open Sans','Open Sans Regular',sans-serif);font-weight:600}.tdb_single_tags span,.tdb_single_tags a{font-size:11px}.tdb_single_tags span{text-transform:uppercase}.tdb_single_tags a:hover{background-color:var(--td_theme_color,#4db2ec);border-color:var(--td_theme_color,#4db2ec);color:#fff}.tdb_single_tags ul{display:inline-block;margin:0;list-style-type:none;font-size:0}.tdb_single_tags li{display:inline-block;margin-left:0}.tdi_51 span{margin-right:4px;padding:2px 8px 3px;color:#fff;background-color:#222}.tdi_51 a{margin-right:4px;padding:1px 7px 2px;border:1px solid #ededed;color:#111}@media (min-width:1019px) and (max-width:1140px){.tdi_51 a{border:1px solid #ededed}}@media (min-width:768px) and (max-width:1018px){.tdi_51 a{border:1px solid #ededed}}@media (max-width:767px){.tdi_51 a{border:1px solid #ededed}}</style><div class="tdb-block-inner td-fix-index"><ul class="tdb-tags"><li><span>Tags</span></li><li><a href="https://inmobilexion.com/tag/api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86%e5%88%9d%e5%bf%83/">APIでテトリス風パズルゲームを作ってみよう初心者向けステップ解説</a></li><li><a href="https://inmobilexion.com/tag/javascript/">JavaScript</a></li><li><a href="https://inmobilexion.com/tag/qiita/">Qiita</a></li><li><a href="https://inmobilexion.com/tag/typescript%e3%81%a8canvas/">TypeScriptとCanvas</a></li></ul></div></div><div class="wpb_wrapper td_block_separator td_block_wrap vc_separator tdi_53  td_separator_solid td_separator_center"><span style="border-color:#EBEBEB;border-width:1px;width:100%;"></span>
<style scoped>.tdi_53{margin-top:28px!important;margin-bottom:20px!important}</style></div><div class="td_block_wrap tdb_single_post_share tdi_54  td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_54" >
<style>.tdi_54 .td-post-sharing-visible{align-items:flex-start}</style><div id="tdi_54" class="td-post-sharing tdb-block td-ps-bg td-ps-notext td-post-sharing-style1 "><div class="td-post-sharing-visible"><div class="td-social-sharing-button td-social-sharing-button-js td-social-handler td-social-share-text">
                                        <div class="td-social-but-icon"><i class="td-icon-share"></i></div>
                                        <div class="td-social-but-text">シェア</div>
                                    </div><a class="td-social-sharing-button td-social-sharing-button-js td-social-network td-social-facebook" href="https://www.facebook.com/sharer.php?u=https%3A%2F%2Finmobilexion.com%2Ftypescript%25e3%2581%25a8canvas-api%25e3%2581%25a7%25e3%2583%2586%25e3%2583%2588%25e3%2583%25aa%25e3%2582%25b9%25e9%25a2%25a8%25e3%2583%2591%25e3%2582%25ba%25e3%2583%25ab%25e3%2582%25b2%25e3%2583%25bc%25e3%2583%25a0%25e3%2582%2592%25e4%25bd%259c%25e3%2581%25a3%25e3%2581%25a6%25e3%2581%25bf%25e3%2582%2588%25e3%2581%2586%2F" title="Facebook" ><div class="td-social-but-icon"><i class="td-icon-facebook"></i></div><div class="td-social-but-text">Facebook</div></a><a class="td-social-sharing-button td-social-sharing-button-js td-social-network td-social-twitter" href="https://twitter.com/intent/tweet?text=TypeScript%E3%81%A8Canvas+API%E3%81%A7%E3%83%86%E3%83%88%E3%83%AA%E3%82%B9%E9%A2%A8%E3%83%91%E3%82%BA%E3%83%AB%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86%EF%BC%88%E5%88%9D%E5%BF%83%E8%80%85%E5%90%91%E3%81%91%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%E8%A7%A3%E8%AA%AC%EF%BC%89+%23JavaScript+%E2%80%93+Qiita&url=https%3A%2F%2Finmobilexion.com%2Ftypescript%25e3%2581%25a8canvas-api%25e3%2581%25a7%25e3%2583%2586%25e3%2583%2588%25e3%2583%25aa%25e3%2582%25b9%25e9%25a2%25a8%25e3%2583%2591%25e3%2582%25ba%25e3%2583%25ab%25e3%2582%25b2%25e3%2583%25bc%25e3%2583%25a0%25e3%2582%2592%25e4%25bd%259c%25e3%2581%25a3%25e3%2581%25a6%25e3%2581%25bf%25e3%2582%2588%25e3%2581%2586%2F&via=inmobi_info" title="Twitter" ><div class="td-social-but-icon"><i class="td-icon-twitter"></i></div><div class="td-social-but-text">Twitter</div></a><a class="td-social-sharing-button td-social-sharing-button-js td-social-network td-social-pinterest" href="https://pinterest.com/pin/create/button/?url=https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/&media=https://inmobilexion.com/wp-content/uploads/2025/05/1746327051_https3A2F2Fqiita-user-contents.imgix_.net2Fhttps253A252F252Fcdn.qiita_.com252Fassets252Fpubli.jpeg&description=TypeScript%E3%81%A8Canvas+API%E3%81%A7%E3%83%86%E3%83%88%E3%83%AA%E3%82%B9%E9%A2%A8%E3%83%91%E3%82%BA%E3%83%AB%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86%EF%BC%88%E5%88%9D%E5%BF%83%E8%80%85%E5%90%91%E3%81%91%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%E8%A7%A3%E8%AA%AC%EF%BC%89+%23JavaScript+%E2%80%93+Qiita" title="Pinterest" ><div class="td-social-but-icon"><i class="td-icon-pinterest"></i></div><div class="td-social-but-text">Pinterest</div></a><a class="td-social-sharing-button td-social-sharing-button-js td-social-network td-social-whatsapp" href="https://api.whatsapp.com/send?text=TypeScript%E3%81%A8Canvas+API%E3%81%A7%E3%83%86%E3%83%88%E3%83%AA%E3%82%B9%E9%A2%A8%E3%83%91%E3%82%BA%E3%83%AB%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86%EF%BC%88%E5%88%9D%E5%BF%83%E8%80%85%E5%90%91%E3%81%91%E3%82%B9%E3%83%86%E3%83%83%E3%83%97%E8%A7%A3%E8%AA%AC%EF%BC%89+%23JavaScript+%E2%80%93+Qiita %0A%0A https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/" title="WhatsApp" ><div class="td-social-but-icon"><i class="td-icon-whatsapp"></i></div><div class="td-social-but-text">WhatsApp</div></a><a class="td-social-sharing-button td-social-sharing-button-js td-social-network td-social-copy_url" href="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/" title="Copy URL" ><div class="td-social-but-icon"><div class="td-social-copy_url-check td-icon-check"></div><i class="td-icon-copy_url"></i></div><div class="td-social-but-text">Copy URL</div></a></div><div class="td-social-sharing-hidden"><ul class="td-pulldown-filter-list"></ul><a class="td-social-sharing-button td-social-handler td-social-expand-tabs" href="#" data-block-uid="tdi_54" title="More">
                                    <div class="td-social-but-icon"><i class="td-icon-plus td-social-expand-tabs-icon"></i></div>
                                </a></div></div></div><div class="wpb_wrapper td_block_separator td_block_wrap vc_separator tdi_56  td_separator_solid td_separator_center"><span style="border-color:#EBEBEB;border-width:1px;width:100%;"></span>
<style scoped>.tdi_56{margin-bottom:30px!important}@media (max-width:767px){.tdi_56{margin-top:-7px!important}}</style></div><div class="td_block_wrap tdb_single_next_prev tdi_57 td-animation-stack td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_57" >
<style>.tdi_57{margin-bottom:43px!important}</style>
<style>.tdb_single_next_prev{*zoom:1}.tdb_single_next_prev:before,.tdb_single_next_prev:after{display:table;content:'';line-height:0}.tdb_single_next_prev:after{clear:both}.tdb-next-post{font-family:var(--td_default_google_font_2,'Roboto',sans-serif);width:48%;float:left;transform:translateZ(0);-webkit-transform:translateZ(0);min-height:1px;line-height:1}.tdb-next-post span{display:block;font-size:12px;color:#747474;margin-bottom:7px}.tdb-next-post a{font-size:15px;color:#222;line-height:21px;-webkit-transition:color 0.2s ease;transition:color 0.2s ease}.tdb-next-post a:hover{color:var(--td_theme_color,#4db2ec)}.tdb-post-next{margin-left:2%;text-align:right}.tdb-post-prev{margin-right:2%}.tdb-post-next .td-image-container{display:inline-block}.tdi_57 .td-module-container{display:flex;flex-direction:column}.tdi_57 .tdb-post-next .td-module-container{align-items:flex-end}.tdi_57 .td-image-container{display:block;order:0}.ie10 .tdi_57 .next-prev-title,.ie11 .tdi_57 .next-prev-title{flex:auto}.tdi_57 .td-module-title a{box-shadow:inset 0 0 0 0 #000}@media (min-width:768px){.tdi_57 .td-module-title a{transition:all 0.2s ease;-webkit-transition:all 0.2s ease}}@media (min-width:1019px) and (max-width:1140px){.tdi_57 .td-module-title a{box-shadow:inset 0 0 0 0 #000}@media (min-width:768px){.tdi_57 .td-module-title a{transition:all 0.2s ease;-webkit-transition:all 0.2s ease}}}@media (min-width:768px) and (max-width:1018px){.tdi_57 .td-module-title a{box-shadow:inset 0 0 0 0 #000}@media (min-width:768px){.tdi_57 .td-module-title a{transition:all 0.2s ease;-webkit-transition:all 0.2s ease}}}@media (max-width:767px){.tdi_57 .td-module-title a{box-shadow:inset 0 0 0 0 #000}@media (min-width:768px){.tdi_57 .td-module-title a{transition:all 0.2s ease;-webkit-transition:all 0.2s ease}}}</style><div class="tdb-block-inner td-fix-index"><div class="tdb-next-post tdb-next-post-bg tdb-post-prev"><span>前の記事</span><div class="td-module-container"><div class="next-prev-title"><a href="https://inmobilexion.com/%e3%82%b3%e3%83%bc%e3%83%92%e3%83%bc%e3%81%ab%e3%81%b2%e3%81%a8%e3%81%a4%e3%81%be%e3%81%bf%e3%81%ae%e5%a1%a9%e3%82%92%e5%85%a5%e3%82%8c%e3%82%8b%e3%81%a8%e8%8b%a6%e5%91%b3%e3%81%8c%e6%b6%88%e3%81%88/">コーヒーにひとつまみの塩を入れると苦味が消える? – ナゾロジー</a></div></div></div><div class="tdb-next-post tdb-next-post-bg tdb-post-next"><span>次の記事</span><div class="td-module-container"><div class="next-prev-title"><a href="https://inmobilexion.com/%e3%83%8b%e3%83%a5%e3%83%bc%e3%83%87%e3%82%a4%e3%82%ba%e3%80%8c%e3%81%8a%e5%80%a4%e6%ae%b5%e3%81%9d%e3%81%ae%e3%81%be%e3%81%be%ef%bc%81%e5%a2%97%e9%87%8f%e3%83%95%e3%82%a7%e3%82%b9%e3%80%8d%e3%81%9f/">ニューデイズ「お値段そのまま!増量フェス」たまごコッペは具40%増</a></div></div></div></div></div><div class="td_block_wrap td_flex_block_1 tdi_58 td_with_ajax_pagination td-pb-border-top td_block_template_1 td_flex_block"  data-td-block-uid="tdi_58" >
<style>.tdi_58 .td-image-wrap{padding-bottom:70%}.tdi_58 .entry-thumb{background-position:center 50%}.tdi_58 .td-module-container{flex-direction:column;border-color:#eaeaea!important}.tdi_58 .td-image-container{display:block;order:0}.ie10 .tdi_58 .td-module-meta-info,.ie11 .tdi_58 .td-module-meta-info{flex:auto}body .tdi_58 .td-favorite{font-size:36px;box-shadow:1px 1px 4px 0px rgba(0,0,0,0.2)}.tdi_58 .td-module-meta-info{border-color:#eaeaea}.tdi_58 .td_module_wrap{width:33.33333333%;float:left;padding-left:10px;padding-right:10px;padding-bottom:10px;margin-bottom:10px}.rtl .tdi_58 .td_module_wrap{float:right}.tdi_58 .td_block_inner{margin-left:-10px;margin-right:-10px}.tdi_58 .td-module-container:before{bottom:-10px;border-color:#eaeaea}.tdi_58 .td-post-vid-time{display:block}.tdi_58 .td-post-category:not(.td-post-extra-category){display:inline-block}.tdi_58 .td-author-photo .avatar{width:20px;height:20px;margin-right:6px;border-radius:50%}.tdi_58 .td-excerpt{display:none;column-count:1;column-gap:48px}.tdi_58 .td-audio-player{opacity:1;visibility:visible;height:auto;font-size:13px}.tdi_58 .td-read-more{display:none}.tdi_58 .td-author-date{display:inline}.tdi_58 .td-post-author-name{display:none}.tdi_58 .td-post-date,.tdi_58 .td-post-author-name span{display:none}.tdi_58 .entry-review-stars{display:inline-block}.tdi_58 .td-icon-star,.tdi_58 .td-icon-star-empty,.tdi_58 .td-icon-star-half{font-size:15px}.tdi_58 .td-module-comments{display:none}.tdi_58 .td_module_wrap:nth-child(3n+1){clear:both}.tdi_58 .td_module_wrap:nth-last-child(-n+3){margin-bottom:0;padding-bottom:0}.tdi_58 .td_module_wrap:nth-last-child(-n+3) .td-module-container:before{display:none}.tdi_58 .td-module-title a{box-shadow:inset 0 0 0 0 #000}.tdi_58 .td-module-exclusive .td-module-title a:before{display:inline-block}.tdi_58 .entry-title{font-size:13px!important;line-height:1.4!important;font-weight:500!important}html:not([class*='ie']) .tdi_58 .td-module-container:hover .entry-thumb:before{opacity:0}@media (min-width:768px){.tdi_58 .td-module-title a{transition:all 0.2s ease;-webkit-transition:all 0.2s ease}}@media (min-width:1019px) and (max-width:1140px){.tdi_58 .td_module_wrap{padding-bottom:10px;margin-bottom:10px;clear:none!important;padding-bottom:10px!important;margin-bottom:10px!important}.tdi_58 .td-module-container:before{bottom:-10px}.tdi_58 .td_module_wrap:nth-child(3n+1){clear:both!important}.tdi_58 .td_module_wrap:nth-last-child(-n+3){margin-bottom:0!important;padding-bottom:0!important}.tdi_58 .td_module_wrap .td-module-container:before{display:block!important}.tdi_58 .td_module_wrap:nth-last-child(-n+3) .td-module-container:before{display:none!important}.tdi_58 .td-module-title a{box-shadow:inset 0 0 0 0 #000}@media (min-width:768px){.tdi_58 .td-module-title a{transition:all 0.2s ease;-webkit-transition:all 0.2s ease}}}@media (min-width:768px) and (max-width:1018px){.tdi_58 .td_module_wrap{padding-left:7.5px;padding-right:7.5px;padding-bottom:7.5px;margin-bottom:7.5px;clear:none!important;padding-bottom:7.5px!important;margin-bottom:7.5px!important}.tdi_58 .td_block_inner{margin-left:-7.5px;margin-right:-7.5px}.tdi_58 .td-module-container:before{bottom:-7.5px}.tdi_58 .td-video-play-ico{width:24px;height:24px;font-size:24px}.tdi_58 .td_module_wrap:nth-child(3n+1){clear:both!important}.tdi_58 .td_module_wrap:nth-last-child(-n+3){margin-bottom:0!important;padding-bottom:0!important}.tdi_58 .td_module_wrap .td-module-container:before{display:block!important}.tdi_58 .td_module_wrap:nth-last-child(-n+3) .td-module-container:before{display:none!important}.tdi_58 .td-module-title a{box-shadow:inset 0 0 0 0 #000}.tdi_58 .entry-title{font-size:12px!important}@media (min-width:768px){.tdi_58 .td-module-title a{transition:all 0.2s ease;-webkit-transition:all 0.2s ease}}}@media (max-width:767px){.tdi_58 .td-image-container{flex:0 0 30%;width:30%;display:block;order:0}.ie10 .tdi_58 .td-image-container,.ie11 .tdi_58 .td-image-container{flex:0 0 auto}.tdi_58 .td-module-container{flex-direction:row}.ie10 .tdi_58 .td-module-meta-info,.ie11 .tdi_58 .td-module-meta-info{flex:1}.tdi_58 .td-module-meta-info{margin:0 0 0 16px;padding:0px}.tdi_58 .td_module_wrap{width:100%;float:left;padding-left:7.5px;padding-right:7.5px;padding-bottom:13px;margin-bottom:13px;padding-bottom:13px!important;margin-bottom:13px!important}.rtl .tdi_58 .td_module_wrap{float:right}.tdi_58 .td_block_inner{margin-left:-7.5px;margin-right:-7.5px}.tdi_58 .td-module-container:before{bottom:-13px}.tdi_58 .td-video-play-ico{width:24px;height:24px;font-size:24px}.tdi_58 .td-post-date,.tdi_58 .td-post-author-name span{display:inline-block}.tdi_58 .td_module_wrap:nth-last-child(1){margin-bottom:0!important;padding-bottom:0!important}.tdi_58 .td_module_wrap .td-module-container:before{display:block!important}.tdi_58 .td_module_wrap:nth-last-child(1) .td-module-container:before{display:none!important}.tdi_58 .td-module-title a{box-shadow:inset 0 0 0 0 #000}.tdi_58 .entry-title{margin:0 0 6px 0;font-size:14px!important}@media (min-width:768px){.tdi_58 .td-module-title a{transition:all 0.2s ease;-webkit-transition:all 0.2s ease}}}</style><script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore">var block_tdi_58 = new tdBlock();
block_tdi_58.id = "tdi_58";
block_tdi_58.atts = '{"title_tag":"div","modules_on_row":"eyJhbGwiOiIzMy4zMzMzMzMzMyUiLCJwaG9uZSI6IjEwMCUifQ==","limit":"3","modules_category":"image","show_btn":"none","show_excerpt":"none","ajax_pagination":"next_prev","sort":"","category_id":"_related_cat","f_title_font_size":"eyJwaG9uZSI6IjE0IiwiYWxsIjoiMTMiLCJwb3J0cmFpdCI6IjEyIn0=","f_title_font_line_height":"eyJwaG9uZSI6IjEuNCIsImFsbCI6IjEuNCJ9","modules_gap":"eyJhbGwiOiIyMCIsInBvcnRyYWl0IjoiMTUiLCJwaG9uZSI6IjE1In0=","show_com":"none","show_date":"eyJhbGwiOiJub25lIiwicGhvbmUiOiJpbmxpbmUtYmxvY2sifQ==","show_author":"none","image_height":"70","f_title_font_weight":"500","all_modules_space":"eyJhbGwiOiIyMCIsImxhbmRzY2FwZSI6IjIwIiwicG9ydHJhaXQiOiIxNSIsInBob25lIjoiMjYifQ==","custom_title":"RELATED ARTICLES","image_floated":"eyJwaG9uZSI6ImZsb2F0X2xlZnQifQ==","image_width":"eyJwaG9uZSI6IjMwIn0=","meta_info_align":"","meta_margin":"eyJwaG9uZSI6IjAgMCAwIDE2cHgifQ==","meta_padding":"eyJwaG9uZSI6IjAifQ==","video_icon":"eyJwb3J0cmFpdCI6IjI0IiwicGhvbmUiOiIyNCJ9","image_size":"td_485x360","art_title":"eyJwaG9uZSI6IjAgMCA2cHggMCJ9","block_type":"td_flex_block_1","separator":"","custom_url":"","block_template_id":"","mc1_tl":"","mc1_title_tag":"","mc1_el":"","post_ids":"-91221","taxonomies":"","category_ids":"","in_all_terms":"","tag_slug":"","autors_id":"","installed_post_types":"","include_cf_posts":"","exclude_cf_posts":"","popular_by_date":"","linked_posts":"","favourite_only":"","locked_only":"","offset":"","open_in_new_window":"","show_modified_date":"","time_ago":"","time_ago_add_txt":"ago","time_ago_txt_pos":"","review_source":"","el_class":"","td_query_cache":"","td_query_cache_expiration":"","td_ajax_filter_type":"","td_ajax_filter_ids":"","td_filter_default_txt":"All","td_ajax_preloading":"","container_width":"","m_padding":"","modules_border_size":"","modules_border_style":"","modules_border_color":"#eaeaea","modules_border_radius":"","modules_divider":"","modules_divider_color":"#eaeaea","h_effect":"","image_alignment":"50","image_radius":"","hide_image":"","show_favourites":"","fav_size":"2","fav_space":"","fav_ico_color":"","fav_ico_color_h":"","fav_bg":"","fav_bg_h":"","fav_shadow_shadow_header":"","fav_shadow_shadow_title":"Shadow","fav_shadow_shadow_size":"","fav_shadow_shadow_offset_horizontal":"","fav_shadow_shadow_offset_vertical":"","fav_shadow_shadow_spread":"","fav_shadow_shadow_color":"","video_popup":"yes","video_rec":"","spot_header":"","video_rec_title":"","video_rec_color":"","video_rec_disable":"","autoplay_vid":"yes","show_vid_t":"block","vid_t_margin":"","vid_t_padding":"","video_title_color":"","video_title_color_h":"","video_bg":"","video_overlay":"","vid_t_color":"","vid_t_bg_color":"","f_vid_title_font_header":"","f_vid_title_font_title":"Video pop-up article title","f_vid_title_font_settings":"","f_vid_title_font_family":"","f_vid_title_font_size":"","f_vid_title_font_line_height":"","f_vid_title_font_style":"","f_vid_title_font_weight":"","f_vid_title_font_transform":"","f_vid_title_font_spacing":"","f_vid_title_":"","f_vid_time_font_title":"Video duration text","f_vid_time_font_settings":"","f_vid_time_font_family":"","f_vid_time_font_size":"","f_vid_time_font_line_height":"","f_vid_time_font_style":"","f_vid_time_font_weight":"","f_vid_time_font_transform":"","f_vid_time_font_spacing":"","f_vid_time_":"","excl_show":"inline-block","excl_txt":"","excl_margin":"","excl_padd":"","all_excl_border":"","all_excl_border_style":"solid","excl_radius":"","excl_color":"","excl_color_h":"","excl_bg":"","excl_bg_h":"","all_excl_border_color":"","excl_border_color_h":"","f_excl_font_header":"","f_excl_font_title":"Label text","f_excl_font_settings":"","f_excl_font_family":"","f_excl_font_size":"","f_excl_font_line_height":"","f_excl_font_style":"","f_excl_font_weight":"","f_excl_font_transform":"","f_excl_font_spacing":"","f_excl_":"","meta_info_horiz":"layout-default","meta_width":"","meta_space":"","art_btn":"","meta_info_border_size":"","meta_info_border_style":"","meta_info_border_color":"#eaeaea","meta_info_border_radius":"","modules_category_margin":"","modules_category_padding":"","modules_cat_border":"","modules_category_radius":"0","show_cat":"inline-block","modules_extra_cat":"","author_photo":"","author_photo_size":"","author_photo_space":"","author_photo_radius":"","show_review":"inline-block","review_space":"","review_size":"2.5","review_distance":"","art_excerpt":"","excerpt_col":"1","excerpt_gap":"","excerpt_middle":"","excerpt_inline":"","show_audio":"block","hide_audio":"","art_audio":"","art_audio_size":"1.5","btn_title":"","btn_margin":"","btn_padding":"","btn_border_width":"","btn_radius":"","pag_space":"","pag_padding":"","pag_border_width":"","pag_border_radius":"","prev_tdicon":"","next_tdicon":"","pag_icons_size":"","f_header_font_header":"","f_header_font_title":"Block header","f_header_font_settings":"","f_header_font_family":"","f_header_font_size":"","f_header_font_line_height":"","f_header_font_style":"","f_header_font_weight":"","f_header_font_transform":"","f_header_font_spacing":"","f_header_":"","f_ajax_font_title":"Ajax categories","f_ajax_font_settings":"","f_ajax_font_family":"","f_ajax_font_size":"","f_ajax_font_line_height":"","f_ajax_font_style":"","f_ajax_font_weight":"","f_ajax_font_transform":"","f_ajax_font_spacing":"","f_ajax_":"","f_more_font_title":"Load more button","f_more_font_settings":"","f_more_font_family":"","f_more_font_size":"","f_more_font_line_height":"","f_more_font_style":"","f_more_font_weight":"","f_more_font_transform":"","f_more_font_spacing":"","f_more_":"","f_title_font_header":"","f_title_font_title":"Article title","f_title_font_settings":"","f_title_font_family":"","f_title_font_style":"","f_title_font_transform":"","f_title_font_spacing":"","f_title_":"","f_cat_font_title":"Article category tag","f_cat_font_settings":"","f_cat_font_family":"","f_cat_font_size":"","f_cat_font_line_height":"","f_cat_font_style":"","f_cat_font_weight":"","f_cat_font_transform":"","f_cat_font_spacing":"","f_cat_":"","f_meta_font_title":"Article meta info","f_meta_font_settings":"","f_meta_font_family":"","f_meta_font_size":"","f_meta_font_line_height":"","f_meta_font_style":"","f_meta_font_weight":"","f_meta_font_transform":"","f_meta_font_spacing":"","f_meta_":"","f_ex_font_title":"Article excerpt","f_ex_font_settings":"","f_ex_font_family":"","f_ex_font_size":"","f_ex_font_line_height":"","f_ex_font_style":"","f_ex_font_weight":"","f_ex_font_transform":"","f_ex_font_spacing":"","f_ex_":"","f_btn_font_title":"Article read more button","f_btn_font_settings":"","f_btn_font_family":"","f_btn_font_size":"","f_btn_font_line_height":"","f_btn_font_style":"","f_btn_font_weight":"","f_btn_font_transform":"","f_btn_font_spacing":"","f_btn_":"","mix_color":"","mix_type":"","fe_brightness":"1","fe_contrast":"1","fe_saturate":"1","mix_color_h":"","mix_type_h":"","fe_brightness_h":"1","fe_contrast_h":"1","fe_saturate_h":"1","m_bg":"","color_overlay":"","shadow_shadow_header":"","shadow_shadow_title":"Module Shadow","shadow_shadow_size":"","shadow_shadow_offset_horizontal":"","shadow_shadow_offset_vertical":"","shadow_shadow_spread":"","shadow_shadow_color":"","title_txt":"","title_txt_hover":"","all_underline_height":"","all_underline_color":"","cat_style":"","cat_bg":"","cat_bg_hover":"","cat_txt":"","cat_txt_hover":"","cat_border":"","cat_border_hover":"","meta_bg":"","author_txt":"","author_txt_hover":"","date_txt":"","ex_txt":"","com_bg":"","com_txt":"","rev_txt":"","audio_btn_color":"","audio_time_color":"","audio_bar_color":"","audio_bar_curr_color":"","shadow_m_shadow_header":"","shadow_m_shadow_title":"Meta info shadow","shadow_m_shadow_size":"","shadow_m_shadow_offset_horizontal":"","shadow_m_shadow_offset_vertical":"","shadow_m_shadow_spread":"","shadow_m_shadow_color":"","btn_bg":"","btn_bg_hover":"","btn_txt":"","btn_txt_hover":"","btn_border":"","btn_border_hover":"","pag_text":"","pag_h_text":"","pag_bg":"","pag_h_bg":"","pag_border":"","pag_h_border":"","ajax_pagination_next_prev_swipe":"","ajax_pagination_infinite_stop":"","css":"","tdc_css":"","td_column_number":1,"header_color":"","color_preset":"","border_top":"","class":"tdi_58","tdc_css_class":"tdi_58","tdc_css_class_style":"tdi_58_rand_style","live_filter":"cur_post_same_categories","live_filter_cur_post_id":91221,"live_filter_cur_post_parent_id":0}';
block_tdi_58.td_column_number = "1";
block_tdi_58.block_type = "td_flex_block_1";
block_tdi_58.post_count = "3";
block_tdi_58.found_posts = "6497";
block_tdi_58.header_color = "";
block_tdi_58.ajax_pagination_infinite_stop = "";
block_tdi_58.max_num_pages = "2166";
tdBlocksArray.push(block_tdi_58);
</script><div class="td-block-title-wrap"><div class="block-title td-block-title"><span class="td-pulldown-size">RELATED ARTICLES</span></div></div><div id=tdi_58 class="td_block_inner td-mc1-wrap">
        <div class="td_module_flex td_module_flex_1 td_module_wrap td-animation-stack td-cpt-post">
            <div class="td-module-container td-category-pos-image">
                                    <div class="td-image-container">
                        <a href="https://inmobilexion.com/%e3%83%8b%e3%83%a5%e3%83%bc%e3%82%b9/%e3%83%86%e3%83%83%e3%82%af%e3%83%8b%e3%83%a5%e3%83%bc%e3%82%b9/" class="td-post-category" >テックニュース</a>                        <div class="td-module-thumb"><a href="https://inmobilexion.com/%e3%80%8cgoogle%e3%81%aeai%e3%80%8egemini%e3%80%8f%e3%80%81%e5%8b%95%e7%94%bb%e3%82%a2%e3%83%83%e3%83%97%e3%83%ad%e3%83%bc%e3%83%89%e5%af%be%e5%bf%9c%ef%bc%81%e3%80%8d/"  rel="nofollow bookmark" class="td-image-wrap " title="「GoogleのAI『Gemini』、動画アップロード対応!」" ><span class="entry-thumb td-thumb-css" data-type="css_image" data-img-url="https://inmobilexion.com/wp-content/uploads/2025/06/「GoogleのAI-485x360.png"  ></span></a></div>                                                                    </div>
                
                <div class="td-module-meta-info">
                                        
                    <h3 class="entry-title td-module-title"><a href="https://inmobilexion.com/%e3%80%8cgoogle%e3%81%aeai%e3%80%8egemini%e3%80%8f%e3%80%81%e5%8b%95%e7%94%bb%e3%82%a2%e3%83%83%e3%83%97%e3%83%ad%e3%83%bc%e3%83%89%e5%af%be%e5%bf%9c%ef%bc%81%e3%80%8d/"  rel="bookmark" title="「GoogleのAI『Gemini』、動画アップロード対応!」">「GoogleのAI『Gemini』、動画アップロード対応!」</a></h3>
                    
                                            <div class="td-editor-date">
                                                        
                                                            <span class="td-author-date">
                                                                                                            <span class="td-post-date"><time class="entry-date updated td-module-date" datetime="2025-06-19T21:13:25+09:00" >2025年6月19日</time></span>                                                                                                        </span>
                                                    </div>
                    
                    
                    
                                    </div>
            </div>
        </div>

        
        <div class="td_module_flex td_module_flex_1 td_module_wrap td-animation-stack td-cpt-post">
            <div class="td-module-container td-category-pos-image">
                                    <div class="td-image-container">
                        <a href="https://inmobilexion.com/%e3%83%8b%e3%83%a5%e3%83%bc%e3%82%b9/%e3%83%86%e3%83%83%e3%82%af%e3%83%8b%e3%83%a5%e3%83%bc%e3%82%b9/" class="td-post-category" >テックニュース</a>                        <div class="td-module-thumb"><a href="https://inmobilexion.com/%e3%82%a2%e3%83%8a%e3%83%ad%e3%82%b0%e3%83%ac%e3%82%b3%e3%83%bc%e3%83%89%e3%83%90%e3%83%83%e3%82%b020%ef%bc%85off%ef%bc%81%e3%80%8cphileweb-shop%e3%80%8d%e6%96%b0%e7%99%bb%e5%a0%b4/"  rel="nofollow bookmark" class="td-image-wrap " title="アナログレコードバッグ20%OFF!「PHILEWEB.shop」新登場" ><span class="entry-thumb td-thumb-css" data-type="css_image" data-img-url="https://inmobilexion.com/wp-content/uploads/2025/06/02e141ebea22d6ddfc1fe614e2af6748-485x360.jpg"  ></span></a></div>                                                                    </div>
                
                <div class="td-module-meta-info">
                                        
                    <h3 class="entry-title td-module-title"><a href="https://inmobilexion.com/%e3%82%a2%e3%83%8a%e3%83%ad%e3%82%b0%e3%83%ac%e3%82%b3%e3%83%bc%e3%83%89%e3%83%90%e3%83%83%e3%82%b020%ef%bc%85off%ef%bc%81%e3%80%8cphileweb-shop%e3%80%8d%e6%96%b0%e7%99%bb%e5%a0%b4/"  rel="bookmark" title="アナログレコードバッグ20%OFF!「PHILEWEB.shop」新登場">アナログレコードバッグ20%OFF!「PHILEWEB.shop」新登場</a></h3>
                    
                                            <div class="td-editor-date">
                                                        
                                                            <span class="td-author-date">
                                                                                                            <span class="td-post-date"><time class="entry-date updated td-module-date" datetime="2025-06-19T21:08:12+09:00" >2025年6月19日</time></span>                                                                                                        </span>
                                                    </div>
                    
                    
                    
                                    </div>
            </div>
        </div>

        
        <div class="td_module_flex td_module_flex_1 td_module_wrap td-animation-stack td-cpt-post">
            <div class="td-module-container td-category-pos-image">
                                    <div class="td-image-container">
                        <a href="https://inmobilexion.com/%e3%83%8b%e3%83%a5%e3%83%bc%e3%82%b9/%e3%83%86%e3%83%83%e3%82%af%e3%83%8b%e3%83%a5%e3%83%bc%e3%82%b9/" class="td-post-category" >テックニュース</a>                        <div class="td-module-thumb"><a href="https://inmobilexion.com/notebooklm%e2%9c%96%ef%b8%8fchatgpt%e3%81%a7%e3%83%81%e3%83%bc%e3%83%a0%e3%81%ae%e6%94%b9%e5%96%84%e6%b4%bb%e5%8b%95%e3%82%92%e8%a8%98%e4%ba%8b%e3%81%ab%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f-ai-qiita/"  rel="nofollow bookmark" class="td-image-wrap " title="NotebookLM✖️ChatGPTでチームの改善活動を記事にしてみた #AI – Qiita" ><span class="entry-thumb td-thumb-css" data-type="css_image" data-img-url="https://inmobilexion.com/wp-content/uploads/2025/06/1750334800_https3A2F2Fqiita-user-contents.imgix_.net2Fhttps253A252F252Fcdn.qiita_.com252Fassets252Fpubli-485x360.jpeg"  ></span></a></div>                                                                    </div>
                
                <div class="td-module-meta-info">
                                        
                    <h3 class="entry-title td-module-title"><a href="https://inmobilexion.com/notebooklm%e2%9c%96%ef%b8%8fchatgpt%e3%81%a7%e3%83%81%e3%83%bc%e3%83%a0%e3%81%ae%e6%94%b9%e5%96%84%e6%b4%bb%e5%8b%95%e3%82%92%e8%a8%98%e4%ba%8b%e3%81%ab%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f-ai-qiita/"  rel="bookmark" title="NotebookLM✖️ChatGPTでチームの改善活動を記事にしてみた #AI – Qiita">NotebookLM✖️ChatGPTでチームの改善活動を記事にしてみた #AI – Qiita</a></h3>
                    
                                            <div class="td-editor-date">
                                                        
                                                            <span class="td-author-date">
                                                                                                            <span class="td-post-date"><time class="entry-date updated td-module-date" datetime="2025-06-19T21:06:38+09:00" >2025年6月19日</time></span>                                                                                                        </span>
                                                    </div>
                    
                    
                    
                                    </div>
            </div>
        </div>

        </div><div class="td-next-prev-wrap"><a href="#" class="td-ajax-prev-page ajax-page-disabled" aria-label="prev-page" id="prev-page-tdi_58" data-td_block_id="tdi_58"><i class="td-next-prev-icon td-icon-font td-icon-menu-left"></i></a><a href="#"  class="td-ajax-next-page" aria-label="next-page" id="next-page-tdi_58" data-td_block_id="tdi_58"><i class="td-next-prev-icon td-icon-font td-icon-menu-right"></i></a></div></div>

<script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore">

var tdb_login_sing_in_shortcode="on";

</script>

<div class="td_block_wrap tdb_single_comments tdi_59 tdb-comm-layout1 td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_59" >
<style>.tdb_single_comments input[type=text]{min-height:34px;height:auto}.tdb_single_comments .comments,.tdb_single_comments .comment-respond:last-child,.tdb_single_comments .form-submit{margin-bottom:0}.is-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tdb-comm-layout3 form,.tdb-comm-layout5 form{display:flex;flex-wrap:wrap}.tdb-comm-layout3 .td-form-comment,.tdb-comm-layout5 .td-form-comment,.tdb-comm-layout3 .form-submit,.tdb-comm-layout5 .form-submit{flex:0 0 100%;order:1}.tdb-comm-layout3 .td-form-author,.tdb-comm-layout3 .td-form-email,.tdb-comm-layout3 .td-form-url{flex:0 0 32%}.tdb-comm-layout5 .td-form-author,.tdb-comm-layout5 .td-form-email{flex:0 0 49%}.tdb-comm-layout5 .td-form-url{flex:0 0 100%}.tdb-comm-leave_reply_top .comments{display:flex;flex-direction:column}.tdb-comm-leave_reply_top .td-comments-title{order:0;margin-bottom:14px}.tdb-comm-leave_reply_top .comment-respond .form-submit{order:1;margin-bottom:21px}.tdb-comm-leave_reply_top .comment-list{order:2}.tdb-comm-leave_reply_top .comment-pagination{order:3}.tdi_59 .comment-link{display:inline-block}.tdi_59 .comment{border-bottom-style:dashed}.tdi_59 .comment .children{border-top-style:dashed}@media (min-width:767px){.tdb-comm-layout2 form,.tdb-comm-layout4 form{margin:0 -10px}.tdb-comm-layout2 .logged-in-as,.tdb-comm-layout4 .logged-in-as,.tdb-comm-layout2 .comment-form-input-wrap,.tdb-comm-layout4 .comment-form-input-wrap,.tdb-comm-layout2 .form-submit,.tdb-comm-layout4 .form-submit,.tdb-comm-layout2 .comment-respond p,.tdb-comm-layout4 .comment-respond p{padding:0 10px}.tdb-comm-layout2 .td-form-author,.tdb-comm-layout2 .td-form-email{float:left;width:33.3333%}.tdb-comm-layout2 .td-form-url{width:33.3333%}.tdb-comm-layout2 .td-form-url{float:left}.tdb-comm-layout4 .td-form-author,.tdb-comm-layout4 .td-form-email{float:left;width:50%}.tdb-comm-layout3 .td-form-author,.tdb-comm-layout5 .td-form-author,.tdb-comm-layout3 .td-form-email{margin-right:2%}}@media (max-width:767px){.tdb-comm-layout3 .td-form-author,.tdb-comm-layout3 .td-form-email,.tdb-comm-layout3 .td-form-url,.tdb-comm-layout5 .td-form-author,.tdb-comm-layout5 .td-form-email{flex:0 0 100%}}</style><div class="tdb-block-inner td-fix-index"><div class="comments" id="comments">	<div id="respond" class="comment-respond">
		<h3 id="reply-title" class="comment-reply-title">返事を書く <small><a rel="nofollow" id="cancel-comment-reply-link" href="/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/#respond" style="display:none;">返事をキャンセル</a></small></h3><form action="https://inmobilexion.com/wp-comments-post.php" method="post" id="commentform" class="comment-form" novalidate><div class="clearfix"></div>
                        <div class="comment-form-input-wrap td-form-comment">
                            <textarea 
                                placeholder="コメント:" 
                                id="comment" 
                                name="comment" 
                                cols="45" 
                                rows="8" 
                                aria-required="true"
                            ></textarea>
                            <label for="comment" class="is-visually-hidden">コメント:</label>
                            <div class="td-warning-comment">あなたのコメントを入力してください。</div>
                        </div><div class="comment-form-input-wrap td-form-author">
                                <input 
                                    class="" 
                                    id="author" 
                                    name="author" 
                                    placeholder="名前:*" 
                                    type="text" 
                                    value="" 
                                    size="30"  aria-required='true' 
                                />
                                <label for="author" class="is-visually-hidden">名前:*</label>
                                <div class="td-warning-author">ここにあなたの名前を入力してください</div>
                            </div>
<div class="comment-form-input-wrap td-form-email">
                                <input 
                                    class="" 
                                    id="email" 
                                    name="email" 
                                    placeholder="Eメール:*" 
                                    type="text" 
                                    value="" 
                                    size="30"  aria-required='true' 
                                />
                                <label for="email" class="is-visually-hidden">Eメール:*</label>
                                <div class="td-warning-email-error">間違ったメールアドレスを入力しました。</div>
                                <div class="td-warning-email">ここにあなたのEメールアドレスを入力してください</div>
                            </div>
<div class="comment-form-input-wrap td-form-url">
                            <input 
                                class="" 
                                id="url" 
                                name="url" 
                                placeholder="ウェブサイト:" 
                                type="text" 
                                value="" 
                                size="30" 
                            />
                            <label for="url" class="is-visually-hidden">ウェブサイト:</label>
                         </div>
<p class="comment-form-cookies-consent">
                            <input 
                                id="wp-comment-cookies-consent" 
                                name="wp-comment-cookies-consent" 
                                type="checkbox" 
                                value="yes"
                                 
                            />
                            <label for="wp-comment-cookies-consent">次回の私のコメントのためにこのブラウザに私の名前、電子メール、そしてウェブサイトを保存してください。</label>
                          </p>
<p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="コメントを書く" /> <input type='hidden' name='comment_post_ID' value='91221' id='comment_post_ID' />
<input type='hidden' name='comment_parent' id='comment_parent' value='0' />
</p><p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="df2635920e" /></p><p style="display: none !important;" class="akismet-fields-container" data-prefix="ak_"><label>Δ<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_1" name="ak_js" value="97"/><script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore">document.getElementById( "ak_js_1" ).setAttribute( "value", ( new Date() ).getTime() );</script></p></form>	</div><!-- #respond -->
	</div></div></div></div></div><div class="vc_column tdi_61  wpb_column vc_column_container tdc-column td-pb-span3 td-is-sticky">
<style scoped>.tdi_61{vertical-align:baseline}.tdi_61>.wpb_wrapper,.tdi_61>.wpb_wrapper>.tdc-elements{display:block}.tdi_61>.wpb_wrapper>.tdc-elements{width:100%}.tdi_61>.wpb_wrapper>.vc_row_inner{width:auto}.tdi_61>.wpb_wrapper{width:auto;height:auto}</style><div class="wpb_wrapper" data-sticky-enabled-on="W3RydWUsdHJ1ZSx0cnVlLHRydWVd" data-sticky-offset="20" data-sticky-is-width-auto="W2ZhbHNlLGZhbHNlLGZhbHNlLGZhbHNlXQ=="><div class="td-a-rec td-a-rec-id-sidebar  tdi_62 td_block_template_1">
<style>.tdi_62{margin-bottom:48px!important}</style>
<style>.tdi_62.td-a-rec{text-align:center}.tdi_62.td-a-rec:not(.td-a-rec-no-translate){transform:translateZ(0)}.tdi_62 .td-element-style{z-index:-1}.tdi_62 .td_spot_img_all img,.tdi_62 .td_spot_img_tl img,.tdi_62 .td_spot_img_tp img,.tdi_62 .td_spot_img_mob img{border-style:none}</style><span class="td-adspot-title">- Advertisment -</span><div class="td-visible-desktop">
    <!-- ここに AdSense 以外のコードを入力 - この広告はデスクトップにのみ表示されます -->
<script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" type="text/javascript">
var adstir_vars = {
  ver: "4.0",
  app_id: "MEDIA-793b1aa3",
  ad_spot: 3,
  center: false
};
</script>
<script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" type="text/javascript" src="https://js.ad-stir.com/js/adstir.js"></script>
</div>
<div class="td-visible-tablet-landscape">
    <!-- ここに AdSense 以外のコードを入力 - この広告は横向きのタブレットでのみ表示されます -->
<!-- admax -->
<script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" src="https://adm.shinobi.jp/s/5b327d388315bf8fa1b917ba429500a5"></script>
<!-- admax -->
</div>
<div class="td-visible-tablet-portrait">
    <!-- ここに AdSense 以外のコードを入力してください - この広告は縦向きのタブレットでのみ表示されます -->
<!-- admax -->
<script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" src="https://adm.shinobi.jp/s/5b327d388315bf8fa1b917ba429500a5"></script>
<!-- admax -->
</div>
<div class="td-visible-phone">
    <!-- ここに AdSense 以外のコードを入力してください - この広告は携帯電話にのみ表示されます -->
<!-- admax -->
<script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" src="https://adm.shinobi.jp/s/5b327d388315bf8fa1b917ba429500a5"></script>
<!-- admax -->
</div></div></div></div></div></div></div></div>                    <span class="td-page-meta" itemprop="author" itemscope itemtype="https://schema.org/Person"><meta itemprop="name" content="インモビ運営局"><meta itemprop="url" content="https://inmobilexion.com/author/kanri/"></span><meta itemprop="datePublished" content="2025-05-04T11:50:50+09:00"><meta itemprop="dateModified" content="2025-05-04T11:50:50+09:00"><meta itemscope itemprop="mainEntityOfPage" itemType="https://schema.org/WebPage" itemid="https://inmobilexion.com/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86/"/><span class="td-page-meta" itemprop="publisher" itemscope itemtype="https://schema.org/Organization"><span class="td-page-meta" itemprop="logo" itemscope itemtype="https://schema.org/ImageObject"><meta itemprop="url" content="http://inmobilexion.com/wp-content/uploads/2025/04/3-2.png"></span><meta itemprop="name" content="インモビ"></span><meta itemprop="headline" content="TypeScriptとCanvas APIでテトリス風パズルゲームを作ってみよう(初心者向けステップ解説) #JavaScript - Qiita"><span class="td-page-meta" itemprop="image" itemscope itemtype="https://schema.org/ImageObject"><meta itemprop="url" content="https://inmobilexion.com/wp-content/uploads/2025/05/1746327051_https3A2F2Fqiita-user-contents.imgix_.net2Fhttps253A252F252Fcdn.qiita_.com252Fassets252Fpubli.jpeg"><meta itemprop="width" content="1200"><meta itemprop="height" content="630"></span>                </article>
            </div>
        </div>
        
    </div> <!-- #tdb-autoload-article -->


    <div class="td-footer-template-wrap" style="position: relative; ">
                <div class="td-footer-wrap ">
            <div id="tdi_63" class="tdc-zone"><div class="tdc_zone tdi_64  wpb_row td-pb-row"  >
<style scoped>.tdi_64{min-height:0}</style><div id="tdi_65" class="tdc-row stretch_row"><div class="vc_row tdi_66  wpb_row td-pb-row tdc-element-style" >
<style scoped>.tdi_66,.tdi_66 .tdc-columns{min-height:0}.tdi_66,.tdi_66 .tdc-columns{display:block}.tdi_66 .tdc-columns{width:100%}.tdi_66:before,.tdi_66:after{display:table}.tdi_66{padding-top:54px!important;padding-bottom:20px!important;position:relative}.tdi_66 .td_block_wrap{text-align:left}@media (max-width:767px){.tdi_66{padding-top:40px!important}}@media (min-width:768px) and (max-width:1018px){.tdi_66{padding-top:44px!important}}</style>
<div class="tdi_65_rand_style td-element-style" ><div class="td-element-style-before"><style>.tdi_65_rand_style>.td-element-style-before{content:''!important;width:100%!important;height:100%!important;position:absolute!important;top:0!important;left:0!important;display:block!important;z-index:0!important;background-image:url("http://inmobilexion.com/wp-content/uploads/2025/04/footer_bg.jpg")!important;opacity:0.1!important;background-size:cover!important;background-position:center top!important}</style></div><style>.tdi_65_rand_style{background-color:#111111!important}</style></div><div class="vc_column tdi_68  wpb_column vc_column_container tdc-column td-pb-span12">
<style scoped>.tdi_68{vertical-align:baseline}.tdi_68>.wpb_wrapper,.tdi_68>.wpb_wrapper>.tdc-elements{display:block}.tdi_68>.wpb_wrapper>.tdc-elements{width:100%}.tdi_68>.wpb_wrapper>.vc_row_inner{width:auto}.tdi_68>.wpb_wrapper{width:auto;height:auto}</style><div class="wpb_wrapper" ><div class="vc_row_inner tdi_70  vc_row vc_inner wpb_row td-pb-row" >
<style scoped>.tdi_70{position:relative!important;top:0;transform:none;-webkit-transform:none}.tdi_70,.tdi_70 .tdc-inner-columns{display:block}.tdi_70 .tdc-inner-columns{width:100%}.tdi_70{padding-bottom:30px!important}.tdi_70 .td_block_wrap{text-align:left}@media (min-width:768px) and (max-width:1018px){.tdi_70{padding-bottom:20px!important}}</style><div class="vc_column_inner tdi_72  wpb_column vc_column_container tdc-inner-column td-pb-span4">
<style scoped>.tdi_72{vertical-align:baseline}.tdi_72 .vc_column-inner>.wpb_wrapper,.tdi_72 .vc_column-inner>.wpb_wrapper .tdc-elements{display:block}.tdi_72 .vc_column-inner>.wpb_wrapper .tdc-elements{width:100%}.tdi_72{width:25%!important}@media (max-width:767px){.tdi_72{margin-bottom:50px!important;width:100%!important}}</style><div class="vc_column-inner"><div class="wpb_wrapper" ><div class="td_block_wrap tdb_header_logo tdi_73 td-pb-border-top td_block_template_1 tdb-header-align"  data-td-block-uid="tdi_73" >
<style>.tdi_73{margin-top:37px!important}@media (min-width:768px) and (max-width:1018px){.tdi_73{margin-top:44px!important}}@media (max-width:767px){.tdi_73{margin-top:0px!important}}</style>
<style>.tdb_header_logo{margin-bottom:0;clear:none}.tdb_header_logo .tdb-logo-a,.tdb_header_logo h1{display:flex;pointer-events:auto;align-items:flex-start}.tdb_header_logo h1{margin:0;line-height:0}.tdb_header_logo .tdb-logo-img-wrap img{display:block}.tdb_header_logo .tdb-logo-svg-wrap+.tdb-logo-img-wrap{display:none}.tdb_header_logo .tdb-logo-svg-wrap svg{width:50px;display:block;transition:fill .3s ease}.tdb_header_logo .tdb-logo-text-wrap{display:flex}.tdb_header_logo .tdb-logo-text-title,.tdb_header_logo .tdb-logo-text-tagline{-webkit-transition:all 0.2s ease;transition:all 0.2s ease}.tdb_header_logo .tdb-logo-text-title{background-size:cover;background-position:center center;font-size:75px;font-family:serif;line-height:1.1;color:#222;white-space:nowrap}.tdb_header_logo .tdb-logo-text-tagline{margin-top:2px;font-size:12px;font-family:serif;letter-spacing:1.8px;line-height:1;color:#767676}.tdb_header_logo .tdb-logo-icon{position:relative;font-size:46px;color:#000}.tdb_header_logo .tdb-logo-icon-svg{line-height:0}.tdb_header_logo .tdb-logo-icon-svg svg{width:46px;height:auto}.tdb_header_logo .tdb-logo-icon-svg svg,.tdb_header_logo .tdb-logo-icon-svg svg *{fill:#000}.tdi_73 .tdb-logo-a,.tdi_73 h1{flex-direction:row;align-items:flex-start;justify-content:center}.tdi_73 .tdb-logo-svg-wrap{display:block}.tdi_73 .tdb-logo-svg-wrap+.tdb-logo-img-wrap{display:none}.tdi_73 .tdb-logo-img-wrap{display:block}.tdi_73 .tdb-logo-text-tagline{margin-top:2px;margin-left:0;display:block}.tdi_73 .tdb-logo-text-title{display:block}.tdi_73 .tdb-logo-text-wrap{flex-direction:column;align-items:flex-start}.tdi_73 .tdb-logo-icon{top:0px;display:block}@media (max-width:767px){.tdb_header_logo .tdb-logo-text-title{font-size:36px}}@media (max-width:767px){.tdb_header_logo .tdb-logo-text-tagline{font-size:11px}}</style><div class="tdb-block-inner td-fix-index"><a class="tdb-logo-a" href="https://inmobilexion.com/"><span class="tdb-logo-img-wrap"><img class="tdb-logo-img td-retina-data" data-retina="http://inmobilexion.com/wp-content/uploads/2025/04/3-3.png" src="http://inmobilexion.com/wp-content/uploads/2025/04/3-2.png" alt="Logo"  title=""  /></span><span class="tdb-logo-text-wrap"><span class="tdb-logo-text-title">インモビ</span><span class="tdb-logo-text-tagline">インモビ</span></span></a></div></div> <!-- ./block --></div></div></div><div class="vc_column_inner tdi_75  wpb_column vc_column_container tdc-inner-column td-pb-span4">
<style scoped>.tdi_75{vertical-align:baseline}.tdi_75 .vc_column-inner>.wpb_wrapper,.tdi_75 .vc_column-inner>.wpb_wrapper .tdc-elements{display:block}.tdi_75 .vc_column-inner>.wpb_wrapper .tdc-elements{width:100%}.tdi_75{width:41.66666667%!important}@media (max-width:767px){.tdi_75{margin-bottom:50px!important;width:100%!important;justify-content:center!important;text-align:center!important}}</style><div class="vc_column-inner"><div class="wpb_wrapper" ><div class="tdm_block td_block_wrap tdm_block_column_title tdi_76 tdm-content-horiz-left td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_76" >
<style>@media (max-width:767px){.tdi_76{justify-content:center!important;text-align:center!important}}</style>
<style>.tdm_block_column_title{margin-bottom:0;display:inline-block;width:100%}</style><div class="td-block-row"><div class="td-block-span12 tdm-col">
<style>body .tdi_77 .tdm-title{color:#ffffff}.tdi_77 .tdm-title{font-size:18px!important;line-height:1!important;font-weight:700!important}</style><div class="tds-title tds-title1 td-fix-index tdi_77 "><h3 class="tdm-title tdm-title-md">ABOUT US</h3></div></div></div></div><div class="tdm_block td_block_wrap tdm_block_inline_text tdi_78 td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_78" >
<style>@media (max-width:767px){.tdi_78{justify-content:center!important;text-align:center!important}}</style>
<style>.tdm_block.tdm_block_inline_text{margin-bottom:0;vertical-align:top}.tdm_block.tdm_block_inline_text .tdm-descr{margin-bottom:0;-webkit-transform:translateZ(0);transform:translateZ(0)}.tdc-row-content-vert-center .tdm-inline-text-yes{vertical-align:middle}.tdc-row-content-vert-bottom .tdm-inline-text-yes{vertical-align:bottom}.tdi_78{text-align:left!important}.tdi_78 .tdm-descr{color:#eaeaea;font-size:14px!important;line-height:1.6!important}@media (min-width:768px) and (max-width:1018px){.tdi_78 .tdm-descr{font-size:13px!important}}</style><p class="tdm-descr">inmobilexion(インモビ)は、動画・ニュース・サイト紹介を中心に、信頼性の高い情報をわかりやすくお届けする情報プラットフォームです。  
「in-mobile」×造語の"〜xion"から生まれたインモビは、厳選・接続・導線など多様な意味を内包しながら、次世代の情報体験を提案します。</p></div><div class="tdm_block td_block_wrap tdm_block_inline_text tdi_79 td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_79" >
<style>.tdi_79{margin-top:21px!important}@media (max-width:767px){.tdi_79{justify-content:center!important;text-align:center!important}}</style>
<style>.tdi_79{text-align:left!important}.tdi_79 .tdm-descr{color:#eaeaea;font-size:14px!important;line-height:1.6!important}.tdi_79 .tdm-descr a{color:#1aa4ce}@media (min-width:768px) and (max-width:1018px){.tdi_79 .tdm-descr{font-size:13px!important}}</style><p class="tdm-descr">Contact us: <a href="mailto:info@inmobilexion.com">info@inmobilexion.com</a></p></div></div></div></div><div class="vc_column_inner tdi_81  wpb_column vc_column_container tdc-inner-column td-pb-span4">
<style scoped>.tdi_81{vertical-align:baseline}.tdi_81 .vc_column-inner>.wpb_wrapper,.tdi_81 .vc_column-inner>.wpb_wrapper .tdc-elements{display:block}.tdi_81 .vc_column-inner>.wpb_wrapper .tdc-elements{width:100%}@media (max-width:767px){.tdi_81{justify-content:center!important;text-align:center!important}}</style><div class="vc_column-inner"><div class="wpb_wrapper" ><div class="tdm_block td_block_wrap tdm_block_column_title tdi_82 tdm-content-horiz-left td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_82" >
<style>@media (max-width:767px){.tdi_82{justify-content:center!important;text-align:center!important}}</style><div class="td-block-row"><div class="td-block-span12 tdm-col">
<style>body .tdi_83 .tdm-title{color:#ffffff}.tdi_83 .tdm-title{font-size:18px!important;line-height:1!important;font-weight:700!important}</style><div class="tds-title tds-title1 td-fix-index tdi_83 "><h3 class="tdm-title tdm-title-md">FOLLOW US</h3></div></div></div></div><div class="tdm_block td_block_wrap tdm_block_socials tdi_84 tdm-content-horiz-left td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_84" >
<style>@media (max-width:767px){.tdi_84{justify-content:center!important;text-align:center!important}}</style>
<style>.tdi_85 .tdm-social-item i{font-size:14px;vertical-align:middle;line-height:39.2px}.tdi_85 .tdm-social-item i.td-icon-linkedin,.tdi_85 .tdm-social-item i.td-icon-pinterest,.tdi_85 .tdm-social-item i.td-icon-blogger,.tdi_85 .tdm-social-item i.td-icon-vimeo{font-size:11.2px}.tdi_85 .tdm-social-item{width:39.2px;height:39.2px;margin:5px 10px 5px 0;background:rgba(255,255,255,0.03)}.tdi_85 .tdm-social-item-wrap:last-child .tdm-social-item{margin-right:0!important}.tdi_85 .tdm-social-item i,.tds-team-member2 .tdi_85.tds-social4 .tdm-social-item i{color:#ffffff}.tdi_85 .tdm-social-item-wrap:hover i,body .tds-team-member2 .tdi_85.tds-social4 .tdm-social-item-wrap:hover i{color:#4db2ec}body .tdi_85 .tdm-social-item{border:1px solid rgba(255,255,255,0.03)}.tdi_85 .tdm-social-text{display:none;margin-left:2px;margin-right:18px}@media (min-width:1019px) and (max-width:1140px){body .tdi_85 .tdm-social-item{border:1px solid rgba(255,255,255,0.03)}}@media (min-width:768px) and (max-width:1018px){.tdi_85 .tdm-social-item{width:35px;height:35px}.tdi_85 .tdm-social-item i{line-height:35px}body .tdi_85 .tdm-social-item{border:1px solid rgba(255,255,255,0.03)}}@media (max-width:767px){body .tdi_85 .tdm-social-item{border:1px solid rgba(255,255,255,0.03)}}</style><div class="tdm-social-wrapper tds-social4 tdi_85"><div class="tdm-social-item-wrap"><a href="#"  title="Blogger" class="tdm-social-item"><i class="td-icon-font td-icon-blogger"></i><span style="display: none">Blogger</span></a></div><div class="tdm-social-item-wrap"><a href="#"  title="Facebook" class="tdm-social-item"><i class="td-icon-font td-icon-facebook"></i><span style="display: none">Facebook</span></a></div><div class="tdm-social-item-wrap"><a href="#"  title="Flickr" class="tdm-social-item"><i class="td-icon-font td-icon-flickr"></i><span style="display: none">Flickr</span></a></div><div class="tdm-social-item-wrap"><a href="#"  title="Instagram" class="tdm-social-item"><i class="td-icon-font td-icon-instagram"></i><span style="display: none">Instagram</span></a></div><div class="tdm-social-item-wrap"><a href="#"  title="VKontakte" class="tdm-social-item"><i class="td-icon-font td-icon-vk"></i><span style="display: none">VKontakte</span></a></div></div></div></div></div></div></div></div></div></div></div><div id="tdi_86" class="tdc-row stretch_row"><div class="vc_row tdi_87  wpb_row td-pb-row tdc-element-style" >
<style scoped>.tdi_87,.tdi_87 .tdc-columns{min-height:0}.tdi_87,.tdi_87 .tdc-columns{display:block}.tdi_87 .tdc-columns{width:100%}.tdi_87:before,.tdi_87:after{display:table}.tdi_87{position:relative}.tdi_87 .td_block_wrap{text-align:left}@media (max-width:767px){.tdi_87{padding-top:6px!important;padding-bottom:6px!important}}</style>
<div class="tdi_86_rand_style td-element-style" ><style>.tdi_86_rand_style{background-color:#0d0d0d!important}</style></div><div class="vc_column tdi_89  wpb_column vc_column_container tdc-column td-pb-span6">
<style scoped>.tdi_89{vertical-align:baseline}.tdi_89>.wpb_wrapper,.tdi_89>.wpb_wrapper>.tdc-elements{display:block}.tdi_89>.wpb_wrapper>.tdc-elements{width:100%}.tdi_89>.wpb_wrapper>.vc_row_inner{width:auto}.tdi_89>.wpb_wrapper{width:auto;height:auto}</style><div class="wpb_wrapper" ><div class="tdm_block td_block_wrap tdm_block_inline_text tdi_90 td-pb-border-top td_block_template_1"  data-td-block-uid="tdi_90" >
<style>.tdi_90{margin-top:2px!important;margin-bottom:0px!important;padding-top:8px!important;padding-bottom:8px!important}@media (max-width:767px){.tdi_90{margin-top:0px!important;justify-content:center!important;text-align:center!important}}</style>
<style>.tdi_90{text-align:left!important}.tdi_90 .tdm-descr{color:#cccccc;font-size:12px!important;line-height:21px!important}</style><p class="tdm-descr">© インモビ by inmobilexion.com</p></div></div></div><div class="vc_column tdi_92  wpb_column vc_column_container tdc-column td-pb-span6">
<style scoped>.tdi_92{vertical-align:baseline}.tdi_92>.wpb_wrapper,.tdi_92>.wpb_wrapper>.tdc-elements{display:block}.tdi_92>.wpb_wrapper>.tdc-elements{width:100%}.tdi_92>.wpb_wrapper>.vc_row_inner{width:auto}.tdi_92>.wpb_wrapper{width:auto;height:auto}.tdi_92{justify-content:flex-end!important;text-align:right!important}@media (max-width:767px){.tdi_92{justify-content:center!important;text-align:center!important}}</style><div class="wpb_wrapper" ><div class="td_block_wrap td_block_list_menu tdi_93 td-blm-display-horizontal td-pb-border-top td_block_template_1 widget"  data-td-block-uid="tdi_93" >
<style>.tdi_93{margin-bottom:0px!important;padding-top:8px!important;padding-bottom:8px!important}@media(min-width:1141px){.tdi_93{display:inline-table!important}}@media (max-width:767px){.tdi_93{margin-left:16px!important;justify-content:center!important;text-align:center!important;display:inline-table!important}}@media (min-width:768px) and (max-width:1018px){.tdi_93{display:inline-table!important}}@media (min-width:1019px) and (max-width:1140px){.tdi_93{display:inline-table!important}}</style>
<style>.td_block_list_menu ul{flex-wrap:wrap;margin-left:12px}.td_block_list_menu ul li{margin-left:0}.td_block_list_menu ul li a{display:flex;margin-left:0}.td_block_list_menu .td-blm-menu-item-txt{display:flex;align-items:center;flex-grow:1}.td_block_list_menu .sub-menu{padding-left:22px}.td_block_list_menu .sub-menu li{font-size:13px}.td_block_list_menu li.current-menu-item>a,.td_block_list_menu li.current-menu-ancestor>a,.td_block_list_menu li.current-category-ancestor>a,.td_block_list_menu li.current-page-ancestor>a{color:var(--td_theme_color,#4db2ec)}.td_block_list_menu .td-blm-sub-icon{display:flex;align-items:center;justify-content:center;margin-left:.6em;padding:0 .6em;transition:transform .2s ease-in-out}.td_block_list_menu .td-blm-sub-icon svg{display:block;width:1em;height:auto}.td_block_list_menu .td-blm-sub-icon svg,.td_block_list_menu .td-blm-sub-icon svg *{fill:currentColor}.td_block_list_menu.td-blm-display-accordion .menu-item-has-children ul{display:none}.td_block_list_menu.td-blm-display-accordion .menu-item-has-children-open>a>.td-blm-sub-icon{transform:rotate(180deg)}.td_block_list_menu.td-blm-display-horizontal ul{display:flex}body .tdi_93 ul{text-align:left;justify-content:flex-start;margin:0px}body .tdi_93 ul li a{justify-content:flex-start}body .tdi_93 .td-blm-menu-item-txt{flex-grow:1}body .tdi_93 ul li{margin-right:16px}body .tdi_93 ul li:last-child{margin-right:0}body .tdi_93 a,body .tdi_93 .td-blm-sub-icon{color:#cccccc}body .tdi_93 li.current-menu-item>a,body .tdi_93 li.current-menu-ancestor>a,body .tdi_93 li.current-category-ancestor>a,body .tdi_93 li.current-page-ancestor>a,body .tdi_93 a:hover,body .tdi_93 li.current-menu-item>a>.td-blm-sub-icon,body .tdi_93 li.current-menu-ancestor>a>.td-blm-sub-icon,body .tdi_93 li.current-category-ancestor>a>.td-blm-sub-icon,body .tdi_93 li.current-page-ancestor>a>.td-blm-sub-icon,body .tdi_93 a:hover>.td-blm-sub-icon{color:#1aa4ce}body .tdi_93 li{font-size:12px!important;line-height:21px!important}</style><div class="td-block-title-wrap"></div><div id=tdi_93 class="td_block_inner td-fix-index"><div class="menu-information-container"><ul id="menu-information-2" class="menu"><li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-21093"><a href="https://inmobilexion.com/video/"><span class="td-blm-menu-item-txt">インモビ動画</span></a></li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor menu-item-47033"><a href="https://inmobilexion.com/%e3%83%8b%e3%83%a5%e3%83%bc%e3%82%b9/"><span class="td-blm-menu-item-txt">ニュース</span></a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-97946"><a href="https://inmobilexion.com/about-inmobilexion/"><span class="td-blm-menu-item-txt">About</span></a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-13204"><a href="https://inmobilexion.com/%e5%90%84%e7%a8%ae%e3%81%8a%e5%95%8f%e3%81%84%e5%90%88%e3%82%8f%e3%81%9b/"><span class="td-blm-menu-item-txt">お問い合わせ</span></a></li>
</ul></div></div></div></div></div></div></div></div></div>        </div>

    </div>
    

<style>.tdc-footer-template .td-main-content-wrap{padding-bottom:0}</style>

</div><!--close td-outer-wrap-->







    <!--

        Theme: Newspaper by tagDiv.com 2025
        Version: 12.7.1 (rara)
        Deploy mode: deploy
        
        uid: 685401aacd375
    -->

    
<!-- Custom css from theme panel -->
<style type="text/css" media="screen">.entry-content img,.post-content img,.td-post-content img{max-width:100%;height:auto;display:block;margin-left:auto;margin-right:auto}.comment-bubbles{display:flex;flex-direction:column;gap:16px;margin-top:10px}.comment-bubble{background:#f9f9f9;padding:12px 16px;border-radius:8px;box-shadow:1px 1px 4px rgba(0,0,0,0.05);position:relative;font-size:15px;line-height:1.6;border-left:4px solid #ff66aa}.comment-meta{font-weight:bold;margin-bottom:6px;color:#d03380;font-size:14px}.comment-text{white-space:pre-wrap}</style>

		
			
	
	
						<link rel='stylesheet' id='all-css-048f26774c9d147f5868e89fc20361b2' href='https://inmobilexion.com/wp-content/boost-cache/static/7efb99245a.min.css' type='text/css' media='all' />


































	<iframe src='https://widgets.wp.com/likes/master.html?ver=20250619#ver=20250619&lang=ja' scrolling='no' id='likes-master' name='likes-master' style='display:none;'></iframe>
	<div id='likes-other-gravatars' role="dialog" aria-hidden="true" tabindex="-1"><div class="likes-text"><span>%d</span></div><ul class="wpl-avatars sd-like-gravatars"></ul></div>
	




















<!-- JS generated by theme -->






<script>window._wca = window._wca || [];</script><script type="text/javascript">
/* <![CDATA[ */
window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/15.1.0\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/15.1.0\/svg\/","svgExt":".svg","source":{"concatemoji":"https:\/\/inmobilexion.com\/wp-includes\/js\/wp-emoji-release.min.js?ver=6.8.1"}};
/*! This file is auto-generated */
!function(i,n){var o,s,e;function c(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function p(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data),r=(e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0),new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data));return t.every(function(e,t){return e===r[t]})}function u(e,t,n){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\uddfa\ud83c\uddf3","\ud83c\uddfa\u200b\ud83c\uddf3")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!n(e,"\ud83d\udc26\u200d\ud83d\udd25","\ud83d\udc26\u200b\ud83d\udd25")}return!1}function f(e,t,n){var r="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):i.createElement("canvas"),a=r.getContext("2d",{willReadFrequently:!0}),o=(a.textBaseline="top",a.font="600 32px Arial",{});return e.forEach(function(e){o[e]=t(a,e,n)}),o}function t(e){var t=i.createElement("script");t.src=e,t.defer=!0,i.head.appendChild(t)}"undefined"!=typeof Promise&&(o="wpEmojiSettingsSupports",s=["flag","emoji"],n.supports={everything:!0,everythingExceptFlag:!0},e=new Promise(function(e){i.addEventListener("DOMContentLoaded",e,{once:!0})}),new Promise(function(t){var n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(s),u.toString(),p.toString()].join(",")+"));",r=new Blob([e],{type:"text/javascript"}),a=new Worker(URL.createObjectURL(r),{name:"wpTestEmojiSupports"});return void(a.onmessage=function(e){c(n=e.data),a.terminate(),t(n)})}catch(e){}c(n=f(s,u,p))}t(n)}).then(function(e){for(var t in e)n.supports[t]=e[t],n.supports.everything=n.supports.everything&&n.supports[t],"flag"!==t&&(n.supports.everythingExceptFlag=n.supports.everythingExceptFlag&&n.supports[t]);n.supports.everythingExceptFlag=n.supports.everythingExceptFlag&&!n.supports.flag,n.DOMReady=!1,n.readyCallback=function(){n.DOMReady=!0}}).then(function(){return e}).then(function(){var e;n.supports.everything||(n.readyCallback(),(e=n.source||{}).concatemoji?t(e.concatemoji):e.wpemoji&&e.twemoji&&(t(e.twemoji),t(e.wpemoji)))}))}((window,document),window._wpemojiSettings);
/* ]]> */
</script><script type="text/javascript" id="WCPAY_ASSETS-js-extra">
/* <![CDATA[ */
var wcpayAssets = {"url":"https:\/\/inmobilexion.com\/wp-content\/plugins\/woocommerce-payments\/dist\/"};
/* ]]> */
</script><script type="text/javascript" id="jetpack_related-posts-js-extra">
/* <![CDATA[ */
var related_posts_js_options = {"post_heading":"h4"};
/* ]]> */
</script><script type="text/javascript" id="wc-add-to-cart-js-extra">
/* <![CDATA[ */
var wc_add_to_cart_params = {"ajax_url":"\/wp-admin\/admin-ajax.php","wc_ajax_url":"\/?wc-ajax=%%endpoint%%","i18n_view_cart":"\u304a\u8cb7\u3044\u7269\u30ab\u30b4\u3092\u8868\u793a","cart_url":"https:\/\/inmobilexion.com\/cart-2\/","is_cart":"","cart_redirect_after_add":"no"};
/* ]]> */
</script><script type="text/javascript" id="woocommerce-js-extra">
/* <![CDATA[ */
var woocommerce_params = {"ajax_url":"\/wp-admin\/admin-ajax.php","wc_ajax_url":"\/?wc-ajax=%%endpoint%%","i18n_password_show":"\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u8868\u793a","i18n_password_hide":"\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u96a0\u3059"};
/* ]]> */
</script><script type='text/javascript' src='https://inmobilexion.com/wp-content/boost-cache/static/14c369cdbc.min.js'></script><script type="text/javascript" src="https://stats.wp.com/s-202525.js" id="woocommerce-analytics-js" defer="defer" data-wp-strategy="defer"></script><script type='text/javascript' src='https://inmobilexion.com/wp-content/boost-cache/static/8a4c43386a.min.js'></script><script type="text/javascript">
	window._se_plugin_version = '8.3';
</script><script>
        window.tdb_global_vars = {"wpRestUrl":"https:\/\/inmobilexion.com\/wp-json\/","permalinkStructure":"\/%postname%\/"};
        window.tdb_p_autoload_vars = {"isAjax":false,"isAdminBarShowing":false,"autoloadStatus":"off","origPostEditUrl":null};
    </script><script type="text/javascript" id="td-generated-header-js">
    
    

	    var tdBlocksArray = []; //here we store all the items for the current page

	    // td_block class - each ajax block uses a object of this class for requests
	    function tdBlock() {
		    this.id = '';
		    this.block_type = 1; //block type id (1-234 etc)
		    this.atts = '';
		    this.td_column_number = '';
		    this.td_current_page = 1; //
		    this.post_count = 0; //from wp
		    this.found_posts = 0; //from wp
		    this.max_num_pages = 0; //from wp
		    this.td_filter_value = ''; //current live filter value
		    this.is_ajax_running = false;
		    this.td_user_action = ''; // load more or infinite loader (used by the animation)
		    this.header_color = '';
		    this.ajax_pagination_infinite_stop = ''; //show load more at page x
	    }

        // td_js_generator - mini detector
        ( function () {
            var htmlTag = document.getElementsByTagName("html")[0];

	        if ( navigator.userAgent.indexOf("MSIE 10.0") > -1 ) {
                htmlTag.className += ' ie10';
            }

            if ( !!navigator.userAgent.match(/Trident.*rv\:11\./) ) {
                htmlTag.className += ' ie11';
            }

	        if ( navigator.userAgent.indexOf("Edge") > -1 ) {
                htmlTag.className += ' ieEdge';
            }

            if ( /(iPad|iPhone|iPod)/g.test(navigator.userAgent) ) {
                htmlTag.className += ' td-md-is-ios';
            }

            var user_agent = navigator.userAgent.toLowerCase();
            if ( user_agent.indexOf("android") > -1 ) {
                htmlTag.className += ' td-md-is-android';
            }

            if ( -1 !== navigator.userAgent.indexOf('Mac OS X')  ) {
                htmlTag.className += ' td-md-is-os-x';
            }

            if ( /chrom(e|ium)/.test(navigator.userAgent.toLowerCase()) ) {
               htmlTag.className += ' td-md-is-chrome';
            }

            if ( -1 !== navigator.userAgent.indexOf('Firefox') ) {
                htmlTag.className += ' td-md-is-firefox';
            }

            if ( -1 !== navigator.userAgent.indexOf('Safari') && -1 === navigator.userAgent.indexOf('Chrome') ) {
                htmlTag.className += ' td-md-is-safari';
            }

            if( -1 !== navigator.userAgent.indexOf('IEMobile') ){
                htmlTag.className += ' td-md-is-iemobile';
            }

        })();

        var tdLocalCache = {};

        ( function () {
            "use strict";

            tdLocalCache = {
                data: {},
                remove: function (resource_id) {
                    delete tdLocalCache.data[resource_id];
                },
                exist: function (resource_id) {
                    return tdLocalCache.data.hasOwnProperty(resource_id) && tdLocalCache.data[resource_id] !== null;
                },
                get: function (resource_id) {
                    return tdLocalCache.data[resource_id];
                },
                set: function (resource_id, cachedData) {
                    tdLocalCache.remove(resource_id);
                    tdLocalCache.data[resource_id] = cachedData;
                }
            };
        })();

    
    
var td_viewport_interval_list=[{"limitBottom":767,"sidebarWidth":228},{"limitBottom":1018,"sidebarWidth":300},{"limitBottom":1140,"sidebarWidth":324}];
var td_animation_stack_effect="type0";
var tds_animation_stack=true;
var td_animation_stack_specific_selectors=".entry-thumb, img, .td-lazy-img";
var td_animation_stack_general_selectors=".td-animation-stack img, .td-animation-stack .entry-thumb, .post img, .td-animation-stack .td-lazy-img";
var tds_general_modal_image="yes";
var tds_show_more_info="\u3055\u3089\u306b\u60c5\u5831\u3092\u8868\u793a";
var tds_show_less_info="\u8868\u793a\u3059\u308b\u60c5\u5831\u3092\u6e1b\u3089\u3057\u307e\u3059";
var tdc_is_installed="yes";
var tdc_domain_active=false;
var td_ajax_url="https:\/\/inmobilexion.com\/wp-admin\/admin-ajax.php?td_theme_name=Newspaper&v=12.7.1";
var td_get_template_directory_uri="https:\/\/inmobilexion.com\/wp-content\/plugins\/td-composer\/legacy\/common";
var tds_snap_menu="";
var tds_logo_on_sticky="";
var tds_header_style="";
var td_please_wait="\u304a\u5f85\u3061\u304f\u3060\u3055\u3044";
var td_email_user_pass_incorrect="\u30e6\u30fc\u30b6\u30fc\u304b\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u9593\u9055\u3063\u3066\u307e\u3059\uff01";
var td_email_user_incorrect="E\u30e1\u30fc\u30eb\u304b\u30e6\u30fc\u30b6\u540d\u304c\u9593\u9055\u3063\u3066\u307e\u3059\uff01";
var td_email_incorrect="E\u30e1\u30fc\u30eb\u304c\u9593\u9055\u3063\u3066\u307e\u3059\uff01";
var td_user_incorrect="\u30e6\u30fc\u30b6\u30fc\u540d\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\uff01";
var td_email_user_empty="\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u307e\u305f\u306f\u30e6\u30fc\u30b6\u30fc\u540d\u304c\u7a7a\u3067\u3059\uff01";
var td_pass_empty="\u7a7a\u3092\u6e21\u3059\uff01";
var td_pass_pattern_incorrect="\u30d1\u30b9\u30d1\u30bf\u30fc\u30f3\u304c\u7121\u52b9\u3067\u3059\uff01";
var td_retype_pass_incorrect="\u518d\u5165\u529b\u3057\u305f\u30d1\u30b9\u304c\u9593\u9055\u3063\u3066\u3044\u307e\u3059!";
var tds_more_articles_on_post_enable="";
var tds_more_articles_on_post_time_to_wait="";
var tds_more_articles_on_post_pages_distance_from_top=0;
var tds_captcha="";
var tds_theme_color_site_wide="#4db2ec";
var tds_smart_sidebar="enabled";
var tdThemeName="Newspaper";
var tdThemeNameWl="Newspaper";
var td_magnific_popup_translation_tPrev="\u524d\uff08\u5de6\u30a2\u30ed\u30fc\u3000\u30ad\u30fc\uff09";
var td_magnific_popup_translation_tNext="\u6b21\uff08\u53f3\u30a2\u30ed\u30fc\u3000\u30ad\u30fc\uff09";
var td_magnific_popup_translation_tCounter="\uff05curr%\u306e\uff05total\uff05";
var td_magnific_popup_translation_ajax_tError="\uff05url%\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u30ed\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002";
var td_magnific_popup_translation_image_tError="#\uff05curr%\u304b\u3089\u306e\u753b\u50cf\u306f\u30ed\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002";
var tdBlockNonce="6f7c9374c6";
var tdMobileMenu="enabled";
var tdMobileSearch="enabled";
var tdDateNamesI18n={"month_names":["1\u6708","2\u6708","3\u6708","4\u6708","5\u6708","6\u6708","7\u6708","8\u6708","9\u6708","10\u6708","11\u6708","12\u6708"],"month_names_short":["1\u6708","2\u6708","3\u6708","4\u6708","5\u6708","6\u6708","7\u6708","8\u6708","9\u6708","10\u6708","11\u6708","12\u6708"],"day_names":["\u65e5\u66dc\u65e5","\u6708\u66dc\u65e5","\u706b\u66dc\u65e5","\u6c34\u66dc\u65e5","\u6728\u66dc\u65e5","\u91d1\u66dc\u65e5","\u571f\u66dc\u65e5"],"day_names_short":["\u65e5","\u6708","\u706b","\u6c34","\u6728","\u91d1","\u571f"]};
var td_reset_pass_empty="\u7d9a\u884c\u3059\u308b\u524d\u306b\u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002";
var td_reset_pass_confirm_empty="\u7d9a\u884c\u3059\u308b\u524d\u306b\u3001\u65b0\u3057\u3044\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002";
var td_reset_pass_not_matching="\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u4e00\u81f4\u3057\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002";
var tdb_modal_confirm="\u4fdd\u5b58";
var tdb_modal_cancel="\u30ad\u30e3\u30f3\u30bb\u30eb";
var tdb_modal_confirm_alt="\u306f\u3044";
var tdb_modal_cancel_alt="\u3044\u3044\u3048";
var td_deploy_mode="deploy";
var td_ad_background_click_link="";
var td_ad_background_click_target="";
</script><script async src="https://www.googletagmanager.com/gtag/js?id=G-GT6DD21E39"></script><script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-GT6DD21E39');
</script><script type="speculationrules">
{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"\/*"},{"not":{"href_matches":["\/wp-*.php","\/wp-admin\/*","\/wp-content\/uploads\/*","\/wp-content\/*","\/wp-content\/plugins\/*","\/wp-content\/themes\/Newspaper\/*","\/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}
</script><script type="text/javascript" id="bbp-swap-no-js-body-class">
	document.body.className = document.body.className.replace( 'bbp-no-js', 'bbp-js' );
</script><script>
			function copy_to_clipBoard(btn) {
				var copyText = btn.previousSibling;
				copyText.select();
				document.execCommand("copy");
			}
		</script><script type='text/javascript'>
		(function () {
			var c = document.body.className;
			c = c.replace(/woocommerce-no-js/, 'woocommerce-js');
			document.body.className = c;
		})();
	</script><script type="text/javascript">
		window.WPCOM_sharing_counts = {"https:\/\/inmobilexion.com\/typescript%e3%81%a8canvas-api%e3%81%a7%e3%83%86%e3%83%88%e3%83%aa%e3%82%b9%e9%a2%a8%e3%83%91%e3%82%ba%e3%83%ab%e3%82%b2%e3%83%bc%e3%83%a0%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%88%e3%81%86\/":91221};
	</script><script type="text/javascript" id="aal-ajax-unit-loading-js-extra">
/* <![CDATA[ */
var aalAjaxUnitLoading = {"ajaxURL":"https:\/\/inmobilexion.com\/wp-json\/wp\/v2\/aal_ajax_unit_loading","spinnerURL":"https:\/\/inmobilexion.com\/wp-admin\/images\/loading.gif","nonce":"348cfd7186","delay":"0","messages":{"ajax_error":"\u30d7\u30ed\u30c0\u30af\u30c8\u30ea\u30f3\u30af\u306e\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002"},"term_id":"0","author_name":"","page_type":"singular","post_id":"91221","REQUEST":{"s":""}};
/* ]]> */
</script><script type='text/javascript' src='https://inmobilexion.com/wp-content/plugins/amazon-auto-links/include/core/component/unit/asset/js/ajax-unit-loading.min.js?m=1744550687'></script><script type="text/javascript" src="https://inmobilexion.com/wp-includes/js/underscore.min.js?ver=1.13.7" id="underscore-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-includes/js/backbone.min.js?ver=1.6.0" id="backbone-js"></script><script type="text/javascript" id="wp-util-js-extra">
/* <![CDATA[ */
var _wpUtilSettings = {"ajax":{"url":"\/wp-admin\/admin-ajax.php"}};
/* ]]> */
</script><script type="text/javascript" id="media-models-js-extra">
/* <![CDATA[ */
var _wpMediaModelsL10n = {"settings":{"ajaxurl":"\/wp-admin\/admin-ajax.php","post":{"id":0}}};
/* ]]> */
</script><script type="text/javascript" id="wp-plupload-js-extra">
/* <![CDATA[ */
var pluploadL10n = {"queue_limit_exceeded":"\u30ad\u30e5\u30fc\u306b\u5165\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u304c\u591a\u3059\u304e\u307e\u3059\u3002","file_exceeds_size_limit":"%s \u306f\u3001\u3053\u306e\u30b5\u30a4\u30c8\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u30b5\u30a4\u30ba\u4e0a\u9650\u3092\u8d85\u3048\u3066\u3044\u307e\u3059\u3002","zero_byte_file":"\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u7a7a\u3067\u3059\u3002\u5225\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002","invalid_filetype":"\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u30a6\u30a7\u30d6\u30b5\u30fc\u30d0\u30fc\u3067\u306f\u51e6\u7406\u3067\u304d\u307e\u305b\u3093\u3002","not_an_image":"\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u753b\u50cf\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u5225\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002","image_memory_exceeded":"\u30e1\u30e2\u30ea\u306e\u8a31\u5bb9\u91cf\u3092\u8d85\u3048\u307e\u3057\u305f\u3002\u5225\u306e\u5c0f\u3055\u3044\u30b5\u30a4\u30ba\u306e\u30d5\u30a1\u30a4\u30eb\u3067\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002","image_dimensions_exceeded":"\u30d5\u30a1\u30a4\u30eb\u30b5\u30a4\u30ba\u306e\u4e0a\u9650\u3092\u8d85\u3048\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u3002\u5225\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002","default_error":"\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u5f8c\u307b\u3069\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002","missing_upload_url":"\u8a2d\u5b9a\u306b\u30a8\u30e9\u30fc\u304c\u3042\u308a\u307e\u3057\u305f\u3002\u30b5\u30fc\u30d0\u30fc\u7ba1\u7406\u8005\u306b\u304a\u554f\u3044\u5408\u308f\u305b\u304f\u3060\u3055\u3044\u3002","upload_limit_exceeded":"\u30d5\u30a1\u30a4\u30eb\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306f1\u3064\u307e\u3067\u3067\u3059\u3002","http_error":"\u30b5\u30fc\u30d0\u30fc\u304b\u3089\u4e88\u671f\u3057\u306a\u3044\u30ec\u30b9\u30dd\u30f3\u30b9\u304c\u3042\u308a\u307e\u3057\u305f\u3002\u30d5\u30a1\u30a4\u30eb\u306f\u6b63\u3057\u304f\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3055\u308c\u3066\u3044\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002\u30e1\u30c7\u30a3\u30a2\u30e9\u30a4\u30d6\u30e9\u30ea\u3082\u3057\u304f\u306f\u30da\u30fc\u30b8\u3092\u30ea\u30ed\u30fc\u30c9\u3057\u3066\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002","http_error_image":"\u30b5\u30fc\u30d0\u30fc\u304c\u753b\u50cf\u3092\u51e6\u7406\u3067\u304d\u307e\u305b\u3093\u3002\u3053\u306e\u30a8\u30e9\u30fc\u306f\u3001\u30b5\u30fc\u30d0\u30fc\u304c\u5fd9\u3057\u3044\u304b\u3001\u30bf\u30b9\u30af\u3092\u5b8c\u4e86\u3059\u308b\u305f\u3081\u306b\u5341\u5206\u306a\u30ea\u30bd\u30fc\u30b9\u304c\u306a\u3044\u5834\u5408\u306b\u767a\u751f\u3057\u307e\u3059\u3002\u5c0f\u3055\u306a\u753b\u50cf\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308c\u3070\u89e3\u6c7a\u3059\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002\u63a8\u5968\u3059\u308b\u6700\u5927\u30b5\u30a4\u30ba\u306f2560\u30d4\u30af\u30bb\u30eb\u3067\u3059\u3002","upload_failed":"\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002","big_upload_failed":"%1$s\u30d6\u30e9\u30a6\u30b6\u30fc\u30a2\u30c3\u30d7\u30ed\u30fc\u30c0\u30fc%2$s\u3067\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002","big_upload_queued":"%s \u306f\u3001\u30d6\u30e9\u30a6\u30b6\u30fc\u4e0a\u304b\u3089\u30de\u30eb\u30c1\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c0\u30fc\u3092\u4f7f\u3046\u969b\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u30b5\u30a4\u30ba\u4e0a\u9650\u3092\u8d85\u3048\u3066\u3044\u307e\u3059\u3002","io_error":"IO \u30a8\u30e9\u30fc\u3002","security_error":"\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30a8\u30e9\u30fc\u3002","file_cancelled":"\u30d5\u30a1\u30a4\u30eb\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3057\u305f\u3002","upload_stopped":"\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3092\u4e2d\u6b62\u3057\u307e\u3057\u305f\u3002","dismiss":"\u975e\u8868\u793a","crunching":"\u51e6\u7406\u4e2d\u2026","deleted":"\u30b4\u30df\u7bb1\u3078\u79fb\u52d5\u3057\u307e\u3057\u305f\u3002","error_uploading":"\u201c%s\u201d \u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002","unsupported_image":"\u3053\u306e\u753b\u50cf\u306f\u30d6\u30e9\u30a6\u30b6\u30fc\u306b\u306f\u8868\u793a\u3055\u308c\u307e\u305b\u3093\u3002\u6700\u826f\u306e\u7d50\u679c\u3092\u5f97\u308b\u306b\u306f\u3001\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u524d\u306b JPEG \u306b\u5909\u63db\u3057\u3066\u304f\u3060\u3055\u3044\u3002","noneditable_image":"Web \u30b5\u30fc\u30d0\u30fc\u306f\u3053\u306e\u753b\u50cf\u306b\u5bfe\u3057\u3066\u30ec\u30b9\u30dd\u30f3\u30b7\u30d6\u306a\u753b\u50cf\u30b5\u30a4\u30ba\u3092\u751f\u6210\u3067\u304d\u307e\u305b\u3093\u3002\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u524d\u306b JPEG \u307e\u305f\u306f PNG \u306b\u5909\u63db\u3057\u3066\u304f\u3060\u3055\u3044\u3002","file_url_copied":"URL \u3092\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3057\u305f"};
/* ]]> */
</script><script type="text/javascript" id="ai1wpsa-frontend-js-extra">
/* <![CDATA[ */
var ai1wpsa = {"nonce":"dfc8f8a73a","isPro":"","isLoggedIn":"","stickyData":{"stickyClass":".widget_custom_html","stickyZIndex":"9999","stickySidebar":"false","stickySidebarElement":"#ninja_pc_ad","stickySidebarContainer":"","stickySidebarDevice":"all","StickySidebarMarginTop":"90","StickySidebarMarginBottom":"0","stickyMinWidth":"795","stickySidebarHeight":"false","customCss":""}};
/* ]]> */
</script><script type='text/javascript' src='https://inmobilexion.com/wp-content/boost-cache/static/96fc61a57b.min.js'></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdPostImages.js?ver=12.7.1" id="tdPostImages-js"></script><script type='text/javascript' src='https://inmobilexion.com/wp-content/boost-cache/static/63b967f5fe.min.js'></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdModalPostImages.js?ver=12.7.1" id="tdModalPostImages-js"></script><script type='text/javascript' src='https://inmobilexion.com/wp-includes/js/comment-reply.min.js?m=1732251956'></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/lazy-load-for-videos/public/js/lazyload-shared.js?ver=2.18.4" id="lazyload-video-js-js"></script><script type="text/javascript" id="lazyload-youtube-js-js-before">
/* <![CDATA[ */
window.llvConfig=window.llvConfig||{};window.llvConfig.youtube={"colour":"red","buttonstyle":"","controls":true,"loadpolicy":true,"thumbnailquality":"0","preroll":"","postroll":"","overlaytext":"","loadthumbnail":true,"cookies":false,"callback":"<!--YOUTUBE_CALLBACK-->"};
/* ]]> */
</script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/lazy-load-for-videos/public/js/lazyload-youtube.js?ver=2.18.4" id="lazyload-youtube-js-js"></script><script type="text/javascript" id="lazyload-vimeo-js-js-before">
/* <![CDATA[ */
window.llvConfig=window.llvConfig||{};window.llvConfig.vimeo={"buttonstyle":"","playercolour":"","preroll":"","postroll":"","show_title":false,"overlaytext":"","loadthumbnail":true,"thumbnailquality":false,"cookies":false,"callback":"<!--VIMEO_CALLBACK-->"};
/* ]]> */
</script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/lazy-load-for-videos/public/js/lazyload-vimeo.js?ver=2.18.4" id="lazyload-vimeo-js-js"></script><script type="text/javascript" id="wc-order-attribution-js-extra">
/* <![CDATA[ */
var wc_order_attribution = {"params":{"lifetime":1.0000000000000000818030539140313095458623138256371021270751953125e-5,"session":30,"base64":false,"ajaxurl":"https:\/\/inmobilexion.com\/wp-admin\/admin-ajax.php","prefix":"wc_order_attribution_","allowTracking":true},"fields":{"source_type":"current.typ","referrer":"current_add.rf","utm_campaign":"current.cmp","utm_source":"current.src","utm_medium":"current.mdm","utm_content":"current.cnt","utm_id":"current.id","utm_term":"current.trm","utm_source_platform":"current.plt","utm_creative_format":"current.fmt","utm_marketing_tactic":"current.tct","session_entry":"current_add.ep","session_start_time":"current_add.fd","session_pages":"session.pgs","session_count":"udata.vst","user_agent":"udata.uag"}};
/* ]]> */
</script><script type='text/javascript' src='https://inmobilexion.com/wp-content/boost-cache/static/26cfa98fd5.min.js'></script><script type="text/javascript" src="https://inmobilexion.com/wp-includes/js/dist/i18n.min.js?ver=5e580eb46a90c2b997e6" id="wp-i18n-js"></script><script type="text/javascript" id="wp-i18n-js-after">
/* <![CDATA[ */
wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );
/* ]]> */
</script><script type="text/javascript" id="wp-pointer-js-translations">
/* <![CDATA[ */
( function( domain, translations ) {
	var localeData = translations.locale_data[ domain ] || translations.locale_data.messages;
	localeData[""].domain = domain;
	wp.i18n.setLocaleData( localeData, domain );
} )( "default", {"translation-revision-date":"2025-06-13 13:27:36+0000","generator":"GlotPress\/4.0.1","domain":"messages","locale_data":{"messages":{"":{"domain":"messages","plural-forms":"nplurals=1; plural=0;","lang":"ja_JP"},"Dismiss":["\u975e\u8868\u793a"]}},"comment":{"reference":"wp-includes\/js\/wp-pointer.js"}} );
/* ]]> */
</script><script type="text/javascript" src="https://inmobilexion.com/wp-includes/js/wp-pointer.min.js?ver=6.8.1" id="wp-pointer-js"></script><script type="text/javascript" id="tds_js_files_for_front-js-extra">
/* <![CDATA[ */
var tds_js_globals = {"wpRestNonce":"348cfd7186","wpRestUrl":"https:\/\/inmobilexion.com\/wp-json\/","permalinkStructure":"\/%postname%\/"};
/* ]]> */
</script><script type='text/javascript' src='https://inmobilexion.com/wp-content/boost-cache/static/c5999c1699.min.js'></script><script type="text/javascript" id="wp-statistics-tracker-js-extra">
/* <![CDATA[ */
var WP_Statistics_Tracker_Object = {"requestUrl":"https:\/\/inmobilexion.com","ajaxUrl":"https:\/\/inmobilexion.com\/wp-admin\/admin-ajax.php","hitParams":{"wp_statistics_hit":1,"source_type":"post","source_id":91221,"search_query":"","signature":"51e45a883f9e3640ad2ccc294a6c6090","action":"wp_statistics_hit_record"},"onlineParams":{"wp_statistics_hit":1,"source_type":"post","source_id":91221,"search_query":"","signature":"51e45a883f9e3640ad2ccc294a6c6090","action":"wp_statistics_online_check"},"option":{"userOnline":"1","dntEnabled":"","bypassAdBlockers":"1","consentIntegration":{"name":null,"status":[]},"isPreview":false,"trackAnonymously":false,"isWpConsentApiActive":false,"consentLevel":""},"jsCheckTime":"60000","isLegacyEventLoaded":""};
/* ]]> */
</script><script type="text/javascript" src="https://inmobilexion.com/?da3463=92545802c8.js&ver=14.14" id="wp-statistics-tracker-js"></script><script type="text/javascript" id="jetpack-stats-js-before">
/* <![CDATA[ */
_stq = window._stq || [];
_stq.push([ "view", JSON.parse("{\"v\":\"ext\",\"blog\":\"241714808\",\"post\":\"91221\",\"tz\":\"9\",\"srv\":\"inmobilexion.com\",\"j\":\"1:14.6\"}") ]);
_stq.push([ "clickTrackerInit", "241714808", "91221" ]);
/* ]]> */
</script><script type="text/javascript" src="https://stats.wp.com/e-202525.js" id="jetpack-stats-js" defer="defer" data-wp-strategy="defer"></script><script type='text/javascript' src='https://inmobilexion.com/wp-content/boost-cache/static/010d7d54e2.min.js'></script><script type="text/javascript" id="sharing-js-js-extra">
/* <![CDATA[ */
var sharing_js_options = {"lang":"en","counts":"1","is_stats_active":"1"};
/* ]]> */
</script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/jetpack/_inc/build/sharedaddy/sharing.min.js?ver=14.6" id="sharing-js-js"></script><script type="text/javascript" id="sharing-js-js-after">
/* <![CDATA[ */
var windowOpen;
			( function () {
				function matches( el, sel ) {
					return !! (
						el.matches && el.matches( sel ) ||
						el.msMatchesSelector && el.msMatchesSelector( sel )
					);
				}

				document.body.addEventListener( 'click', function ( event ) {
					if ( ! event.target ) {
						return;
					}

					var el;
					if ( matches( event.target, 'a.share-facebook' ) ) {
						el = event.target;
					} else if ( event.target.parentNode && matches( event.target.parentNode, 'a.share-facebook' ) ) {
						el = event.target.parentNode;
					}

					if ( el ) {
						event.preventDefault();

						// If there's another sharing window open, close it.
						if ( typeof windowOpen !== 'undefined' ) {
							windowOpen.close();
						}
						windowOpen = window.open( el.getAttribute( 'href' ), 'wpcomfacebook', 'menubar=1,resizable=1,width=600,height=400' );
						return false;
					}
				} );
			} )();
var windowOpen;
			( function () {
				function matches( el, sel ) {
					return !! (
						el.matches && el.matches( sel ) ||
						el.msMatchesSelector && el.msMatchesSelector( sel )
					);
				}

				document.body.addEventListener( 'click', function ( event ) {
					if ( ! event.target ) {
						return;
					}

					var el;
					if ( matches( event.target, 'a.share-x' ) ) {
						el = event.target;
					} else if ( event.target.parentNode && matches( event.target.parentNode, 'a.share-x' ) ) {
						el = event.target.parentNode;
					}

					if ( el ) {
						event.preventDefault();

						// If there's another sharing window open, close it.
						if ( typeof windowOpen !== 'undefined' ) {
							windowOpen.close();
						}
						windowOpen = window.open( el.getAttribute( 'href' ), 'wpcomx', 'menubar=1,resizable=1,width=600,height=350' );
						return false;
					}
				} );
			} )();
var windowOpen;
			( function () {
				function matches( el, sel ) {
					return !! (
						el.matches && el.matches( sel ) ||
						el.msMatchesSelector && el.msMatchesSelector( sel )
					);
				}

				document.body.addEventListener( 'click', function ( event ) {
					if ( ! event.target ) {
						return;
					}

					var el;
					if ( matches( event.target, 'a.share-linkedin' ) ) {
						el = event.target;
					} else if ( event.target.parentNode && matches( event.target.parentNode, 'a.share-linkedin' ) ) {
						el = event.target.parentNode;
					}

					if ( el ) {
						event.preventDefault();

						// If there's another sharing window open, close it.
						if ( typeof windowOpen !== 'undefined' ) {
							windowOpen.close();
						}
						windowOpen = window.open( el.getAttribute( 'href' ), 'wpcomlinkedin', 'menubar=1,resizable=1,width=580,height=450' );
						return false;
					}
				} );
			} )();
var windowOpen;
			( function () {
				function matches( el, sel ) {
					return !! (
						el.matches && el.matches( sel ) ||
						el.msMatchesSelector && el.msMatchesSelector( sel )
					);
				}

				document.body.addEventListener( 'click', function ( event ) {
					if ( ! event.target ) {
						return;
					}

					var el;
					if ( matches( event.target, 'a.share-tumblr' ) ) {
						el = event.target;
					} else if ( event.target.parentNode && matches( event.target.parentNode, 'a.share-tumblr' ) ) {
						el = event.target.parentNode;
					}

					if ( el ) {
						event.preventDefault();

						// If there's another sharing window open, close it.
						if ( typeof windowOpen !== 'undefined' ) {
							windowOpen.close();
						}
						windowOpen = window.open( el.getAttribute( 'href' ), 'wpcomtumblr', 'menubar=1,resizable=1,width=450,height=450' );
						return false;
					}
				} );
			} )();
var windowOpen;
			( function () {
				function matches( el, sel ) {
					return !! (
						el.matches && el.matches( sel ) ||
						el.msMatchesSelector && el.msMatchesSelector( sel )
					);
				}

				document.body.addEventListener( 'click', function ( event ) {
					if ( ! event.target ) {
						return;
					}

					var el;
					if ( matches( event.target, 'a.share-threads' ) ) {
						el = event.target;
					} else if ( event.target.parentNode && matches( event.target.parentNode, 'a.share-threads' ) ) {
						el = event.target.parentNode;
					}

					if ( el ) {
						event.preventDefault();

						// If there's another sharing window open, close it.
						if ( typeof windowOpen !== 'undefined' ) {
							windowOpen.close();
						}
						windowOpen = window.open( el.getAttribute( 'href' ), 'wpcomthreads', 'menubar=1,resizable=1,width=600,height=400' );
						return false;
					}
				} );
			} )();
var windowOpen;
			( function () {
				function matches( el, sel ) {
					return !! (
						el.matches && el.matches( sel ) ||
						el.msMatchesSelector && el.msMatchesSelector( sel )
					);
				}

				document.body.addEventListener( 'click', function ( event ) {
					if ( ! event.target ) {
						return;
					}

					var el;
					if ( matches( event.target, 'a.share-bluesky' ) ) {
						el = event.target;
					} else if ( event.target.parentNode && matches( event.target.parentNode, 'a.share-bluesky' ) ) {
						el = event.target.parentNode;
					}

					if ( el ) {
						event.preventDefault();

						// If there's another sharing window open, close it.
						if ( typeof windowOpen !== 'undefined' ) {
							windowOpen.close();
						}
						windowOpen = window.open( el.getAttribute( 'href' ), 'wpcombluesky', 'menubar=1,resizable=1,width=600,height=400' );
						return false;
					}
				} );
			} )();
/* ]]> */
</script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdToTop.js?ver=12.7.1" id="tdToTop-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdLoginMobile.js?ver=12.7.1" id="tdLoginMobile-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdTrendingNow.js?ver=12.7.1" id="tdTrendingNow-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-cloud-library/assets/js/tdbSearch.js?ver=d578089f160957352b9b4ca6d880fd8f" id="tdbSearch-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdLogin.js?ver=12.7.1" id="tdLogin-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdMenu.js?ver=12.7.1" id="tdMenu-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdAjaxSearch.js?ver=12.7.1" id="tdAjaxSearch-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdSmartSidebar.js?ver=12.7.1" id="tdSmartSidebar-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdLoadingBox.js?ver=12.7.1" id="tdLoadingBox-js"></script><script type="text/javascript" src="https://inmobilexion.com/wp-content/plugins/td-composer/legacy/Newspaper/js/tdAjaxCount.js?ver=12.7.1" id="tdAjaxCount-js"></script><script type="text/javascript" id="td-generated-footer-js">
    

        
            jQuery().ready(function () {

                var tdbSearchItem = new tdbSearch.item();

                //block unique ID
                tdbSearchItem.blockUid = 'tdi_16';
                tdbSearchItem.blockAtts = '{"inline":"yes","toggle_txt_pos":"after","form_align":"content-horiz-right","results_msg_align":"content-horiz-center","image_floated":"float_left","image_width":"30","image_size":"td_324x400","show_cat":"none","show_btn":"none","show_date":"","show_review":"none","show_com":"none","show_excerpt":"none","show_author":"none","meta_padding":"2px 0 0 15px","art_title":"0 0 5px","all_modules_space":"20","block_type":"tdb_header_search","post_type":"","disable_trigger":"","show_form":"","show_results":"yes","separator":"","disable_live_search":"","exclude_pages":"","exclude_posts":"","search_section_header":"","results_section_1_title":"","results_section_1_taxonomies":"","results_section_1_level":"","results_section_2_title":"","results_section_2_taxonomies":"","results_section_2_level":"","results_section_3_title":"","results_section_3_taxonomies":"","results_section_3_level":"","results_section_search_query_terms":"","results_section_search_query_terms_title":"","results_section_search_query_terms_taxonomies":"","sec_title_space":"","sec_title_color":"","tax_space":"","tax_title_color":"","tax_title_color_h":"","f_sec_title_font_header":"","f_sec_title_font_title":"Section title text","f_sec_title_font_settings":"","f_sec_title_font_family":"","f_sec_title_font_size":"","f_sec_title_font_line_height":"","f_sec_title_font_style":"","f_sec_title_font_weight":"","f_sec_title_font_transform":"","f_sec_title_font_spacing":"","f_sec_title_":"","f_tax_title_font_title":"Taxonomy title text","f_tax_title_font_settings":"","f_tax_title_font_family":"","f_tax_title_font_size":"","f_tax_title_font_line_height":"","f_tax_title_font_style":"","f_tax_title_font_weight":"","f_tax_title_font_transform":"","f_tax_title_font_spacing":"","f_tax_title_":"","tdicon":"","icon_size":"20","icon_padding":"2.4","toggle_txt":"","toggle_txt_align":"0","toggle_txt_space":"","aria_label":"Search","toggle_horiz_align":"content-horiz-left","float_block":"","form_offset":"","form_offset_left":"","form_width":"","form_content_width":"","form_padding":"","form_border":"","form_align_screen":"","input_placeholder":"","placeholder_travel":"0","input_padding":"","input_border":"","input_radius":"","btn_text":"Search","btn_aria_label":"Search","btn_tdicon":"","btn_icon_pos":"","btn_icon_size":"","btn_icon_space":"","btn_icon_align":"0","btn_margin":"","btn_padding":"","btn_border":"","btn_radius":"","results_padding":"","results_border":"","results_msg_padding":"","results_msg_border":"","mc1_tl":"","mc1_title_tag":"","mc1_el":"","results_limit":"","open_in_new_window":"","modules_on_row":"100%","modules_gap":"","m_padding":"","modules_border_size":"","modules_border_style":"","modules_border_color":"#eaeaea","modules_divider":"","modules_divider_color":"#eaeaea","h_effect":"","image_alignment":"50","image_height":"","image_radius":"","hide_image":"","video_icon":"","show_vid_t":"block","vid_t_margin":"","vid_t_padding":"","vid_t_color":"","vid_t_bg_color":"","f_vid_time_font_header":"","f_vid_time_font_title":"Video duration text","f_vid_time_font_settings":"","f_vid_time_font_family":"","f_vid_time_font_size":"","f_vid_time_font_line_height":"","f_vid_time_font_style":"","f_vid_time_font_weight":"","f_vid_time_font_transform":"","f_vid_time_font_spacing":"","f_vid_time_":"","excl_show":"inline-block","excl_txt":"","excl_margin":"","excl_padd":"","all_excl_border":"","all_excl_border_style":"solid","excl_radius":"","excl_color":"","excl_color_h":"","excl_bg":"","excl_bg_h":"","all_excl_border_color":"","excl_border_color_h":"","f_excl_font_header":"","f_excl_font_title":"Label text","f_excl_font_settings":"","f_excl_font_family":"","f_excl_font_size":"","f_excl_font_line_height":"","f_excl_font_style":"","f_excl_font_weight":"","f_excl_font_transform":"","f_excl_font_spacing":"","f_excl_":"","meta_info_align":"","meta_info_horiz":"content-horiz-left","meta_width":"","meta_margin":"","meta_info_border_size":"","meta_info_border_style":"","meta_info_border_color":"#eaeaea","art_btn":"","modules_category":"","modules_category_margin":"","modules_category_padding":"","modules_cat_border":"","modules_category_radius":"0","modules_extra_cat":"","author_photo":"","author_photo_size":"","author_photo_space":"","author_photo_radius":"","show_modified_date":"","time_ago":"","time_ago_add_txt":"ago","time_ago_txt_pos":"","review_space":"","review_size":"2.5","review_distance":"","art_excerpt":"","excerpt_col":"1","excerpt_gap":"","excerpt_middle":"","btn_title":"","btn_border_width":"","form_general_bg":"","icon_color":"","icon_color_h":"","toggle_txt_color":"","toggle_txt_color_h":"","f_toggle_txt_font_header":"","f_toggle_txt_font_title":"Text","f_toggle_txt_font_settings":"","f_toggle_txt_font_family":"","f_toggle_txt_font_size":"","f_toggle_txt_font_line_height":"","f_toggle_txt_font_style":"","f_toggle_txt_font_weight":"","f_toggle_txt_font_transform":"","f_toggle_txt_font_spacing":"","f_toggle_txt_":"","form_bg":"","form_border_color":"","arrow_color":"","form_shadow_shadow_header":"","form_shadow_shadow_title":"Shadow","form_shadow_shadow_size":"","form_shadow_shadow_offset_horizontal":"","form_shadow_shadow_offset_vertical":"","form_shadow_shadow_spread":"","form_shadow_shadow_color":"","input_color":"","placeholder_color":"","placeholder_opacity":"0","input_bg":"","input_border_color":"","input_shadow_shadow_header":"","input_shadow_shadow_title":"Input shadow","input_shadow_shadow_size":"","input_shadow_shadow_offset_horizontal":"","input_shadow_shadow_offset_vertical":"","input_shadow_shadow_spread":"","input_shadow_shadow_color":"","btn_color":"","btn_color_h":"","btn_icon_color":"","btn_icon_color_h":"","btn_bg":"","btn_bg_h":"","btn_border_color":"","btn_border_color_h":"","btn_shadow_shadow_header":"","btn_shadow_shadow_title":"Button shadow","btn_shadow_shadow_size":"","btn_shadow_shadow_offset_horizontal":"","btn_shadow_shadow_offset_vertical":"","btn_shadow_shadow_spread":"","btn_shadow_shadow_color":"","f_input_font_header":"","f_input_font_title":"Input text","f_input_font_settings":"","f_input_font_family":"","f_input_font_size":"","f_input_font_line_height":"","f_input_font_style":"","f_input_font_weight":"","f_input_font_transform":"","f_input_font_spacing":"","f_input_":"","f_placeholder_font_title":"Placeholder text","f_placeholder_font_settings":"","f_placeholder_font_family":"","f_placeholder_font_size":"","f_placeholder_font_line_height":"","f_placeholder_font_style":"","f_placeholder_font_weight":"","f_placeholder_font_transform":"","f_placeholder_font_spacing":"","f_placeholder_":"","f_btn_font_title":"Button text","f_btn_font_settings":"","f_btn_font_family":"","f_btn_font_size":"","f_btn_font_line_height":"","f_btn_font_style":"","f_btn_font_weight":"","f_btn_font_transform":"","f_btn_font_spacing":"","f_btn_":"","results_bg":"","results_border_color":"","results_msg_color":"","results_msg_color_h":"","results_msg_bg":"","results_msg_border_color":"","f_results_msg_font_header":"","f_results_msg_font_title":"Text","f_results_msg_font_settings":"","f_results_msg_font_family":"","f_results_msg_font_size":"","f_results_msg_font_line_height":"","f_results_msg_font_style":"","f_results_msg_font_weight":"","f_results_msg_font_transform":"","f_results_msg_font_spacing":"","f_results_msg_":"","m_bg":"","color_overlay":"","shadow_module_shadow_header":"","shadow_module_shadow_title":"Module Shadow","shadow_module_shadow_size":"","shadow_module_shadow_offset_horizontal":"","shadow_module_shadow_offset_vertical":"","shadow_module_shadow_spread":"","shadow_module_shadow_color":"","title_txt":"","title_txt_hover":"","all_underline_height":"","all_underline_color":"#000","cat_bg":"","cat_bg_hover":"","cat_txt":"","cat_txt_hover":"","cat_border":"","cat_border_hover":"","meta_bg":"","author_txt":"","author_txt_hover":"","date_txt":"","ex_txt":"","com_bg":"","com_txt":"","rev_txt":"","shadow_meta_shadow_header":"","shadow_meta_shadow_title":"Meta info shadow","shadow_meta_shadow_size":"","shadow_meta_shadow_offset_horizontal":"","shadow_meta_shadow_offset_vertical":"","shadow_meta_shadow_spread":"","shadow_meta_shadow_color":"","btn_bg_hover":"","btn_txt":"","btn_txt_hover":"","btn_border_hover":"","f_title_font_header":"","f_title_font_title":"Article title","f_title_font_settings":"","f_title_font_family":"","f_title_font_size":"","f_title_font_line_height":"","f_title_font_style":"","f_title_font_weight":"","f_title_font_transform":"","f_title_font_spacing":"","f_title_":"","f_cat_font_title":"Article category tag","f_cat_font_settings":"","f_cat_font_family":"","f_cat_font_size":"","f_cat_font_line_height":"","f_cat_font_style":"","f_cat_font_weight":"","f_cat_font_transform":"","f_cat_font_spacing":"","f_cat_":"","f_meta_font_title":"Article meta info","f_meta_font_settings":"","f_meta_font_family":"","f_meta_font_size":"","f_meta_font_line_height":"","f_meta_font_style":"","f_meta_font_weight":"","f_meta_font_transform":"","f_meta_font_spacing":"","f_meta_":"","f_ex_font_title":"Article excerpt","f_ex_font_settings":"","f_ex_font_family":"","f_ex_font_size":"","f_ex_font_line_height":"","f_ex_font_style":"","f_ex_font_weight":"","f_ex_font_transform":"","f_ex_font_spacing":"","f_ex_":"","el_class":"","tdc_css":"","block_template_id":"","td_column_number":1,"header_color":"","ajax_pagination_infinite_stop":"","offset":"","limit":"5","td_ajax_preloading":"","td_ajax_filter_type":"","td_filter_default_txt":"","td_ajax_filter_ids":"","color_preset":"","ajax_pagination":"","ajax_pagination_next_prev_swipe":"","border_top":"","css":"","class":"tdi_16","tdc_css_class":"tdi_16","tdc_css_class_style":"tdi_16_rand_style"}';
                tdbSearchItem.jqueryObj = jQuery('.tdi_16');
                tdbSearchItem._openSearchFormClass = 'tdb-drop-down-search-open';
                tdbSearchItem._resultsLimit = '4';

                
	            
                
                tdbSearch.addItem( tdbSearchItem );

            });
        
        

            
                jQuery(window).on( 'load', function () {
                    var block = jQuery('.tdi_46'),
                        blockClass = '.tdi_46',
                        blockInner = block.find('.tdb-block-inner'),
                        blockOffsetLeft;

                    if( block.find('audio').length > 0 ) {
                        jQuery(blockClass + ' audio').mediaelementplayer();
                    }

                    if( block.hasClass('tdb-sfi-stretch') ) {
                        jQuery(window).resize(function () {
                            blockOffsetLeft = block.offset().left;

                            if( block.hasClass('tdb-sfi-stretch-left') ) {
                                blockInner.css('margin-left', -blockOffsetLeft + 'px');
                            } else {
                                blockInner.css('margin-right', -(jQuery(window).width() - (blockOffsetLeft + block.outerWidth())) + 'px');
                            }
                        });
                        jQuery(window).resize();
                    }

                    setTimeout(function () {
                        block.css('opacity', 1);
                    }, 500);
                });
            
            

                    jQuery().ready(function jQuery_ready() {
                        tdAjaxCount.tdGetViewsCountsAjax("post","[91221]");
                    });
                
</script><script>var td_res_context_registered_atts=["style_general_trending_now","style_general_header_date","style_general_header_align","style_general_module_header","style_general_header_search","style_general_header_search_trigger_enabled","style_general_header_user","style_general_socials","style_general_separator","style_general_breadcrumbs","style_general_single_categories","style_general_single_title","style_general_title_single","style_bg_space","style_general_post_meta","style_general_single_author","style_general_single_date","style_general_comments_count","style_general_post_views","style_general_single_post_share","style_general_featured_image","style_general_single_content","style_general_single_tags","style_general_header_logo","style_general_column_title","style_general_inline_text","style_general_list_menu","style_specific_list_menu_vertical","style_specific_list_menu_accordion","style_specific_list_menu_horizontal"];</script></body>
</html>