p5.js 2.0 内容紹介（１）

# はじめに
　リリースノート

https://github.com/processing/p5.js/releases/tag/v2.0.0

これの内容について。

## 前書き
　テストと開発のために、p5.js 2.0 をコミュニティにリリースしました！ 知っておくべきことを以下にまとめました。

- 参考までに: p5.js 1.x のリファレンスは https://p5js.org/ に残り、p5.js 2.x のドキュメントは https://beta.p5js.org/ にあります
- p5.j​​s エディタでは、少なくとも 2026 年 8 月まではデフォルトが 1.x のままになります。タイムラインに関する詳細情報と議論については、こちらのスレッドをご覧ください（[this Discourse thread](https://discourse.processing.org/t/dev-updates-p5-js-2-0-you-are-here/46130)、[this GitHub thread](https://github.com/processing/p5.js/issues/7488)）
- スケッチとアドオンライブラリを更新するには、[こちら](https://github.com/processing/p5.js-compatibility)を確認してください
- コントリビューションについて：npm の最新版はデフォルトで 2.x になりますが、git ブランチは 1.x では main、2.x では dev-2.0 と分かれています。すべての自動化の更新（更新されたドキュメントのウェブサイトへのデプロイを含む）が完了したら、ブランチを切り替えます。アイデアや実装に貢献したいですか？[2.x プロジェクトボード](https://github.com/orgs/processing/projects/21/views/8)で、まだ議論が必要な部分と、すでに作業が完了している部分の概要をご確認ください

## 探索を開始する 🌱

- テキスト関連: [textToContours()](https://beta.p5js.org/reference/p5.font/texttocontours/)、WEBGL の [textToModel()](https://beta.p5js.org/reference/p5.font/texttomodel/)、および可変フォントの [textWeight()](https://beta.p5js.org/reference/p5/textweight/)!
- [colorMode()](https://beta.p5js.org/reference/p5/colormode/) による新しいカラー モード!
- [p5.strands](https://beta.p5js.org/tutorials/intro-to-p5-strands/) を使用して JavaScript でシェーダーを作成します
- [worldToScreen](https://beta.p5js.org/reference/p5/worldtoscreen/) を使用して 3D 画面座標を 2D 画面座標に変換します
- [アドオンライブラリ作成ガイド](https://dev.to/limzykenneth/designing-an-addon-library-system-for-p5js-20-3d4p)

## 変更の詳細🌳
　また、Dave Pagurek による [p5.js 2.0 とオープンソース哲学](https://www.davepagurek.com/blog/p5-2.0-philosophy/)についての考察もご覧ください。

### テキスト関連

- タイポグラフィ システムをリファクタリングして、より小さくし、可変フォントをサポートし、[より正確なテキスト測定](https://beta.p5js.org/reference/p5/textwidth/)を実現 (Daniel Howe [@dhowe](https://github.com/dhowe))
- CSS 経由でのフォント読み込みのサポート ([@dhowe](https://github.com/dhowe) に感謝)
- テキストを描画および操作するより多くの方法 ([@davepagurek](https://github.com/davepagurek) に感謝)
- textToPoints と 3D テキスト押し出しサポートのパフォーマンスが約 350% 向上しました ([@davepagurek](https://github.com/davepagurek) に感謝)

### p5.Color でより多くのカラー スペースをサポート ([@limzykenneth](https://github.com/limzykenneth) と [@dianamgalindo](https://github.com/dianamgalindo) に感謝)

　p5.j​​s 2.0 は、既存の RGB、HSB、HSL カラーモードに加えて、より多くの[colorMode()](https://beta.p5js.org/reference/p5/colormode/)をサポートするようになりました。以下に、新たにサポートされるカラーモードの一覧と簡単な説明を示します。

- RGBHDR - Display P3カラースペース内で定義されたハイダイナミックレンジRGBカラー。この色をキャンバス上に正確に描画するには、以下で説明するHDRキャンバスを使用する必要があります
- HWB - 色相、白度、黒度。これはHSLやHSBと似ており、色相角度を定義しますが、彩度と明度ではなく、白度と黒度のパーセンテージを定義します。Chromeで使用されるGUIカラーピッカーのカラーモデルです

![fqw3f3g3ggg322.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437349/4c3965f6-20d1-4aee-bab6-96f3ce3b983e.png)

- LAB - CIE Labとも呼ばれ、明度、アルファ、ベータに基づいて色を定義します。この色空間は、専門的な色測定の分野でよく使用されます
- LCH - 明度、彩度、色相の定義を使用した、CIE Lab カラーのより使いやすい表現
- OKLAB - OkLabはCIE Lab色空間にわずかな調整を加えたもので、主にCIE Labに存在する不均一性の問題を修正することを目的としています。この違いは、以下の例でより明確に確認できます
- OKLCH - 明度、彩度、色相の定義を使用した、OkLab カラーのより使いやすい表現


[このスケッチ](https://editor.p5js.org/limzykenneth/sketches/l4FtFScH5)で HSL、LCH、OKLCH を比較します：

![et3wf3g3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437349/05cdb3f8-de31-4f22-8774-1b9dde0dbbd7.png)

　左から右へ、それぞれHSL、LCH、OKLCHのカラーホイールです。各ホイール間の色の分布が均一であることに注目してください。OkLCHが最も均一な分布を示しています。LCHホイールには、OkLCHによって固定される大きな青色の部分があることを確認できます。

　p5.j​​s 2.0 でこれらの新しいカラー スペースを使用するために、それぞれの定数が追加され、RGB、HSL、HSB と同じように、[colorMode()](https://beta.p5js.org/reference/p5/colormode/) 関数をこれらの定数と共に使用できるようになりました。

```js
function setup(){
  createCanvas(200, 200);
}

function draw(){
  colorMode(OKLCH);
  background(220); // Should show a teal colored canvas
}
```

### display-p3 モードでの広色域カラーのサポート ([@limzykenneth](https://github.com/limzykenneth) に感謝)
　HDRカラーに対応した2Dキャンバスを作成できるようになりました。より鮮やかなスケッチやHDR画像を作成できます。HDRキャンバスを使用するには、以下のようにP2DHDR定数を使用して作成する必要があります。

```js
function setup(){
  createCanvas(400, 400, P2DHDR);
}
```

　P2DHDRキャンバスを作成すると、デフォルトのカラーモードがRGBではなく新しいRGBHDRカラーモードに切り替わります。実際には、これまでと同じRGBカラー定義を引き続き使用できます。
```js
function setup(){
  createCanvas(400, 400, P2DHDR);
}

function draw(){
  background(255, 0, 0);
  fill(100, 255, 0);
  circle(100, 100, 50);
}
```
　[このサンプルスケッチ](https://editor.p5js.org/limzykenneth/sketches/LB2vJFdj4)は、HDRと非HDRカラーを直接比較したものです。赤、緑、青の3つの帯と、その中にわずかに暗い赤、緑、青の円が表示されます。ただし、違いを確認するには、ブラウザと画面の両方がHDRをサポートしている必要があります。現在、デスクトップ版FirefoxはHDRキャンバスをサポートしていません。違いがわからない場合は、SafariやChromeなどの別のブラウザをお試しください。

　HDR画像を読み込み、[HDRキャンバス](https://editor.p5js.org/limzykenneth/sketches/52J0mtOID)にフルHDRで表示できるようになりました。リンクされたスケッチの画像が暗い場合は、ブラウザまたは画面がHDRに対応していないため、別のブラウザ/デバイスをお試しください。

### WebGLの新しいシンプルなラインモード (thanks to contributions from [@perminder-17](https://github.com/perminder-17))

　たくさんの図形を描画し、ストロークのキャップや結合が不要な場合は、WebGLのパフォーマンスを向上させるためにシンプルな線モードを使用できます。このモードを有効にするには、スケッチで [strokeMode(SIMPLE)](https://beta.p5js.org/reference/p5/strokemode/) を呼び出します。

### 塗りつぶし、ストローク、画像用のカスタムシェーダー (thanks to [@Garima3110](https://github.com/Garima3110) and [@perminder-17](https://github.com/perminder-17))

　塗り、ストローク、画像用の独自のシェーダーを作成し、すべて一度で適用できるようになりました。[shader()](https://beta.p5js.org/reference/p5/shader/) で塗りシェーダーを、[strokeShader()](https://beta.p5js.org/reference/p5/strokeshader/) でストロークシェーダーを、[imageShader()](https://beta.p5js.org/reference/p5/imageshader/) で画像シェーダーを設定できます。カスタムシェーダーを作成するには、[baseMaterialShader().modify(...)](https://beta.p5js.org/reference/p5/basematerialshader/) と [baseStrokeShader().modify(...)](https://beta.p5js.org/reference/p5/basestrokeshader/) をお試しください。
```js
let myFillShader = baseMaterialShader.modify({
  'vec4 getFinalColor': `(vec4 color) {
    return vec4(1., 1., 0., 1.);
  }`
});
let myStrokeShader = baseStrokeShader.modify({
  'vec4 getFinalColor': `(vec4 color) {
    return vec4(1., 0., 1., 1.);
  }`
});
let myImageShader = baseMaterialShader.modify({
  'vec4 getFinalColor': `(vec4 color) {
    return vec4(0., 1., 1., 1.);
  }`
});

shader(myFillShader);
strokeShader(myStrokeShader);
imageShader(myImageShader);

sphere(); // Draws with the custom stroke and image shaders
image(myImg, 0, 0); // Draws with the custom image shader
```

### ベジェ曲線描画関数を更新しました ([@GregStanton](https://github.com/GregStanton) に感謝)

　まず、1つの begin/endShape() ブロックで複数の種類の曲線を組み合わせることができるようになりました。

　長い3次および2次ベジェ頂点の呼び出しが、個々の制御点へと分割されるようになりました。3次曲線と2次曲線の両方が[bezierVertex](https://beta.p5js.org/reference/p5/beziervertex/)で処理されるようになり、[bezierOrder()](https://beta.p5js.org/reference/p5/bezierorder/) を設定することで、3次曲線（3次）から2次曲線（2次）へと変更できるようになりました。WebGLモードでは、制御点ごとにテクスチャ座標を指定したり、制御点間の塗りつぶし、ストローク、法線などを変更したりすることもできます。

```js:p5.js 1.x
beginShape();
vertex(10, 10);
vertex(30, 10);

bezierVertex(35, 10, 40, 15, 40, 20);

vertex(40, 30);

quadraticVertex(40, 40, 30, 40);

vertex(10, 40);

endShape(CLOSE);
```

```js:p5.js 2.x
beginShape();
vertex(10, 10);
vertex(30, 10);

// Default cubic
bezierVertex(35, 10);
bezierVertex(40, 15);
bezierVertex(40, 20);

vertex(40, 30);

bezierOrder(2);
bezierVertex(40, 40);
bezierVertex(30, 40);

vertex(10, 40);

endShape(p5.CLOSE);
```

curvVertex を [splineVertex](https://beta.p5js.org/reference/p5/splinevertex/) に名前変更し、オプションを追加しました。デフォルトではすべての splineVertex を通過するため、splineVertex を通過するために最初と最後の点を重複して指定する必要がなくなりました。

```js:p5.js 1.x
beginShape();
curveVertex(10, 10);
curveVertex(10, 10);
curveVertex(15, 40);
curveVertex(40, 35);
curveVertex(25, 15);
curveVertex(15, 25);
curveVertex(15, 25);
endShape();
```

```js:p5.js 2.x
beginShape();

splineVertex(10, 10);
splineVertex(15, 40);
splineVertex(40, 35);
splineVertex(25, 15);
splineVertex(15, 25);

endShape();
```

同様に、[endShape(CLOSE)](https://beta.p5js.org/reference/p5/endshape/) (または輪郭線内の場合は [endContour(CLOSE))](https://beta.p5js.org/reference/p5/endcontour/) を使用すると、スプラインがスムーズにループバックするため、ポイントを重複させる必要がなくなります。

```js:p5.js 1.x
beginShape();
curveVertex(15, 25);
curveVertex(10, 10);
curveVertex(15, 40);
curveVertex(40, 35);
curveVertex(25, 15);
curveVertex(15, 25);
curveVertex(10, 10);
curveVertex(15, 40);
endShape();
```

```js:p5.js 2.x
beginShape();

splineVertex(10, 10);
splineVertex(15, 40);
splineVertex(40, 35);
splineVertex(25, 15);
splineVertex(15, 25);


endShape(CLOSE);
```

### 非同期読み込み ([@limzykenneth](https://github.com/limzykenneth) に感謝)

　p5 2.0 には、プリロード機能ではなく、非同期セットアップがあります。

```js:p5.js 1.x
let img;

function preload() {
  img = loadImage('cat.jpg');
}

function setup() {
  createCanvas(200, 200);
}
```

```js:p5.js 2.x
let img;

async function setup() {
  createCanvas(200, 200);
  img = await loadImage('cat.jpg');
}
```

🚧 これは 1.x から 2.0 への重大な変更なので、[ここ](https://github.com/processing/p5.js/issues/7488)で互換性に関する議論に参加できます。

### CSS 経由でのフォント読み込みのサポート ([@dhowe](https://github.com/dhowe) に感謝)

　2D モードでは、Google Fonts リンクなどの CSS フォント ファイルへのパスを介してフォントを読み込んでみてください。

```js
loadFont("https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,200..800&display=swap")
loadFont(`@font-face { font-family: "Bricolage Grotesque", serif; font-optical-sizing: auto; font-weight: <weight> font-style: normal; font-variation-settings: "wdth" 100; }`);
loadFont({
    fontFamily: '"Bricolage Grotesque", serif',
    fontOpticalSizing: 'auto',
    fontWeight: '<weight>',
    fontStyle: 'normal',
    fontVariationSettings: '"wdth" 100',
});
loadFont("https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuLyfMZhrib2Bg-4.ttf");
loadFont("path/to/localFont.ttf");
loadFont("system-font-name");
```

### 可変フォントウェイトのサポート ([@dhowe](https://github.com/dhowe) の貢献に感謝)

　2D モードで可変フォントを読み込んだ場合は、その太さを変更してみてください（[textWeight()](https://beta.p5js.org/reference/p5/textweight/)）。

```js
var font;

async function setup() {
  createCanvas(100, 100);
  font = await loadFont(
    'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'
  );
}

function draw() {
  background(255);
  textFont(font);
  textAlign(LEFT, TOP);
  textSize(35);
  textWeight(sin(millis() * 0.002) * 200 + 400);
  text('p5*js', 0, 10);
}
```

### テキストを描画および操作するより多くの方法 ([@davepagurek](https://github.com/davepagurek) に感謝)

　[textToPoints()](https://beta.p5js.org/reference/p5.font/texttopoints/) がテキスト上にポイントを与えるのと同じように、新しい [textToContours()](https://beta.p5js.org/reference/p5.font/texttocontours/) 関数を使用すると、テキスト上のポイントを編集し、塗りつぶして描画することができます。

```js
createCanvas(100, 100);
const font = await loadFont('myFont.ttf');
background(200);
strokeWeight(2);
textSize(50);
const contours = font.textToContours('p5*js', 0, 50, { sampleFactor: 0.5 });
beginShape();
for (const pts of contours) {
  beginContour();
  for (const pt of pts) {
    vertex(pt.x + 20*sin(pt.y*0.01), pt.y + 20*sin(pt.x*0.01));
  }
  endContour(CLOSE);
}
endShape();
```

WebGL では、[textToModel](https://beta.p5js.org/reference/p5.font/texttomodel/) を使用してテキストから 3D モデルを押し出すことができます。

```js
createCanvas(100, 100, WEBGL);
const font = await loadFont('myFont.ttf');
background(200);
textSize(50);
const geom = font.textToModel('p5*js', 0, 50, { sampleFactor: 2, extrude: 20 });
orbitControl();
model(geom);
```

### 新しいポインタイベント処理システム ([@diyaayay](https://github.com/diyaayay) に感謝)
　マウスとタッチに別々のメソッドを用意する代わりに、ブラウザのポインタAPIを使用して両方を同時に処理できるようになりました。マウス関数を通常通り定義し、グローバルなtouches配列にアクセスして、マルチタッチサポートで有効なポインタを確認してください。

### カスタム シェーダー属性 ([@lukeplowden](https://github.com/lukeplowden) に感謝)

　シェーダーを使用しており、シェイプ全体で同じユニフォームに加えて頂点ごとのカスタム プロパティが必要な場合は、頂点の前に [vertexProperty(name, value)](https://beta.p5js.org/reference/p5/vertexproperty/) を呼び出すことができます。

```js
const vertSrc = `#version 300 es
 precision mediump float;
 uniform mat4 uModelViewMatrix;
 uniform mat4 uProjectionMatrix;

 in vec3 aPosition;
 in vec2 aOffset;

 void main(){
   vec4 positionVec4 = vec4(aPosition.xyz, 1.0);
   positionVec4.xy += aOffset;
   gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
 }
`;

const fragSrc = `#version 300 es
 precision mediump float;
 out vec4 outColor;
 void main(){
   outColor = vec4(0.0, 1.0, 1.0, 1.0);
 }
`;

function setup(){
  createCanvas(100, 100, WEBGL);

  // Create and use the custom shader.
  const myShader = createShader(vertSrc, fragSrc);
  shader(myShader);

  describe('A wobbly, cyan circle on a gray background.');
}

function draw(){
  // Set the styles
  background(125);
  noStroke();

  // Draw the circle.
  beginShape();
  for (let i = 0; i < 30; i++){
    const x = 40 * cos(i/30 * TWO_PI);
    const y = 40 * sin(i/30 * TWO_PI);

    // Apply some noise to the coordinates.
    const xOff = 10 * noise(x + millis()/1000) - 5;
    const yOff = 10 * noise(y + millis()/1000) - 5;

    // Apply these noise values to the following vertex.
    vertexProperty('aOffset', [xOff, yOff]);
    vertex(x, y);
  }
  endShape(CLOSE);
}
```

# おわりに
　次回は個々のコミットについてできるだけ見て行く予定です。ここまでお読みいただいてありがとうございました。