ChatGPT の Canvas の機能アップデートを試してみた（o1利用、React のレンダリング）

公式が以下のポストをしていた「Canvas」の機能アップデートに関する記事です。
それを軽く試してみたのですが、試した流れのメモとして書ｋ。

https://x.com/OpenAI/status/1882876172339757392

## 「o1 ＋ Canvas」「React のレンダリング」を試す
Canvas で o1 が使える話と、React のレンダリングができる話を一気に試します。

### プロンプトを入れる
o1 に切り替えても「キャンバス」の選択肢が「理由」の下に出ています。

![2025-01-25_10-11-57.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/57439e19-e5a1-ada2-6112-c2c60a2524f9.jpeg)

内容が o1 を使ってやるレベル感ではないですが、お試しなので「ReactのシンプルなHelloWorld的なコードを書いて」というシンプルなプロンプトでやってみました。

### コード生成後
そうすると、以下のようにコードが生成されました。

![2025-01-25_10-12-44.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ae251de0-baac-dfb5-086a-1fbd62c07a26.jpeg)

その際、画面右上に「Preview your output」という吹き出しが出ています。

ちなみに、この時点で生成されたコードは以下の通りです。

```react
import React from "react";
import { motion } from "framer-motion";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";

export default function SimpleHelloWorld() {
  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.5 }}
      className="flex items-center justify-center h-screen bg-gray-100"
    >
      <Card className="w-auto p-8 shadow-lg rounded-2xl">
        <CardContent className="flex flex-col items-center space-y-4">
          <h1 className="text-3xl font-bold">Hello, World!</h1>
          <Button variant="default">Click Me</Button>
        </CardContent>
      </Card>
    </motion.div>
  );
}
```

### プレビューを試す
上記の吹き出しで示された先の操作用の部分を押します。

その結果、以下のように描画結果を Canvas上で見ることができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/40207341-b111-b2ea-0e9d-315dc2030546.png)

また以下の部分を押すと、プレビューからコードの表示へもどｓ。

![2025-01-25_11-27-11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d0588e24-3418-0612-a10c-d73273ee4e1b.jpeg)

#### プレビュー画面上での操作を試す
プレビュー上でのボタン操作が行えるかを確かめてみることにしました。

追加のプロンプトで「ボタンを押したら何か表示がされて、押すごとに表示が変わるようにして」というのを入力し、コードを編集してもらうということをやりました。

<iframe width="560" height="315" src="https://www.youtube.com/embed/KUUsh8ZICSQ?si=CUKFXXb6ABzRwHRX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

コードはこんな内容でした。

```react
import React, { useState } from "react";
import { motion } from "framer-motion";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";

export default function SimpleHelloWorld() {
  const messages = [
    "Hello, World!",
    "Welcome to our App!",
    "Hope you're doing well!",
    "Thanks for stopping by!"
  ];

  const [index, setIndex] = useState(0);

  const handleClick = () => {
    setIndex((prevIndex) => (prevIndex + 1) % messages.length);
  };

  return (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      transition={{ duration: 0.5 }}
      className="flex items-center justify-center h-screen bg-gray-100"
    >
      <Card className="w-auto p-8 shadow-lg rounded-2xl">
        <CardContent className="flex flex-col items-center space-y-4">
          <h1 className="text-3xl font-bold">{messages[index]}</h1>
          <Button variant="default" onClick={handleClick}>
            Click Me
          </Button>
        </CardContent>
      </Card>
    </motion.div>
  );
}

```