抽選の結果、『石』さんがプレゼン者に選ばれました
はじめに
前回の記事「ClaudeのGPT-4o超え」って意外と本当かもと驚いた!!!で生成したルーレット・アプリは、Reactを使用したアプリでした。
せっかく生成したもらっておいて失礼ですが笑、Reactを使うまでもないシンプルなアプリなので、シンプルに、HTML+CSS+JavaScriptだけを使ったアプリに書き換えてください、とお願いしてみました。
文句ひとつ言わず、数秒でやってくれました。
もし、私がこんな依頼を受けたなら、もう、文句ブーブーです
ていうか、何時間かかるんだろう
レッツ・トライ!
早速始めます。
プロンプト1
Claudeに生成してもらったReactをHTML+CSS+JavaScriptのみに変換するためのプロンプトを入力します。
ソースコードをHTML+CSS+JavaScriptのみで書き換えてください
何やらエラーが発生しました。
無料枠の回数制限は確実に残っている(理由:本日使用1回目ですので)と思いましたが、よく見ると、length limitとありますので、コンテキストサイズがオーバーしたようです。
ソースコード自体はそれほど大きくないのですが、これまでのやり取りが全てコンテキストに含まれているようで、その結果、length limitに引っかかったようです。
ならばと思い、次に試したのは、こんなプロンプトです。
プロンプト2
そうならばと思い、次に試したのは、こんなプロンプトです。
以下のソースコードをHTML+CSS+JavaScriptのみで書き換えてください
import React, { useState, useEffect, useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
const PresenterRoulette = () => {
const [presenters, setPresenters] = useState([]);
const [newPresenter, setNewPresenter] = useState('');
(以下省略)
指示プロンプトの下に、生成されたソースコードを全てペーストしてみました。
結果は、こちらの通り、15秒前後でコンバートしてくれました。すごすぎる。。。
プロンプト3
実は、ちょっと気になったことがありました。
プレゼン者を入力した後に、いつもの癖で、enterキーを押してしまうのですが、このアプリでは、enterキーでは追加してくれず、必ず[追加]ボタンを押す必要があります。
細かいことですが、enterキーでもプレゼン者リストに追加されるようにお願いしてみます。
プレゼン者の追加は、追加ボタンのほかに、キーボードのenterキーも有効にしてください
それでは実際に試してみます。
enterキーでプレゼン者リストに追加されました。
生成されたHTML
生成されたHTML+CSS+JavaScriptを共有いたします。
ライブラリを必要としませんので、すぐに試せますね。
Simple is best.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>プレゼン者ルーレットアプリ</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 400px;
margin: 0 auto;
padding: 20px;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
}
.input-container {
display: flex;
margin-bottom: 20px;
}
input {
flex-grow: 1;
margin-right: 10px;
padding: 5px;
}
button {
padding: 5px 10px;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
}
button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
ul {
list-style-type: disc;
padding-left: 20px;
}
canvas {
display: block;
margin: 0 auto;
}
#result {
text-align: center;
padding: 15px;
background-color: #e6f3ff;
border-radius: 5px;
margin-top: 20px;
}
#selectedPresenter {
font-size: 24px;
color: #0066cc;
font-weight: bold;
}
</style>
</head>
<body>
<h1>プレゼン者ルーレットアプリ</h1>
<div class="input-container">
<input type="text" id="newPresenter" placeholder="プレゼン者の名前を入力">
<button onclick="addPresenter()">追加</button>
</div>
<div>
<h2>プレゼン者リスト:</h2>
<ul id="presenterList"></ul>
</div>
<canvas id="roulette" width="300" height="300"></canvas>
<button id="spinButton" onclick="spinRoulette()">ルーレットを回す</button>
<div id="result" style="display: none;">
<h2>選ばれたプレゼン者:</h2>
<p id="selectedPresenter"></p>
</div>
<script>
const presenters = [];
let isSpinning = false;
const canvas = document.getElementById('roulette');
const ctx = canvas.getContext('2d');
const spinButton = document.getElementById('spinButton');
const newPresenterInput = document.getElementById('newPresenter');
// Enterキーのイベントリスナーを追加
newPresenterInput.addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
addPresenter();
}
});
function addPresenter() {
const newPresenter = newPresenterInput.value.trim();
if (newPresenter !== '') {
presenters.push(newPresenter);
newPresenterInput.value = '';
updatePresenterList();
drawRoulette(0);
}
}
function updatePresenterList() {
const list = document.getElementById('presenterList');
list.innerHTML = '';
presenters.forEach(presenter => {
const li = document.createElement('li');
li.textContent = presenter;
list.appendChild(li);
});
}
function spinRoulette() {
if (presenters.length > 0 && !isSpinning) {
isSpinning = true;
spinButton.disabled = true;
spinButton.textContent = 'ルーレット回転中...';
const minSpins = 5;
const maxSpins = 10;
const spins = minSpins + Math.random() * (maxSpins - minSpins);
const minDuration = 4000;
const maxDuration = 8000;
const duration = minDuration + Math.random() * (maxDuration - minDuration);
let currentRotation = 0;
const startTime = Date.now();
const sliceAngle = 360 / presenters.length;
const additionalRotation = Math.random() * 360;
function animate() {
const elapsedTime = Date.now() - startTime;
const progress = Math.min(elapsedTime / duration, 1);
const easeOut = 1 - Math.pow(1 - progress, 3);
currentRotation = easeOut * spins * 360 + additionalRotation;
drawRoulette(currentRotation);
if (progress < 1) {
requestAnimationFrame(animate);
} else {
isSpinning = false;
spinButton.disabled = false;
spinButton.textContent = 'ルーレットを回す';
selectPresenter(currentRotation);
}
}
animate();
}
}
function selectPresenter(finalRotation) {
const normalizedRotation = finalRotation % 360;
const sliceAngle = 360 / presenters.length;
const selectedIndex = (presenters.length - Math.floor(normalizedRotation / sliceAngle) - 1) % presenters.length;
const selectedPresenter = presenters[selectedIndex];
document.getElementById('result').style.display = 'block';
document.getElementById('selectedPresenter').textContent = selectedPresenter;
}
function drawRoulette(rotation) {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const radius = Math.min(centerX, centerY) - 10;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate((rotation * Math.PI) / 180);
const sliceAngle = (2 * Math.PI) / presenters.length;
const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8'];
presenters.forEach((presenter, index) => {
const startAngle = index * sliceAngle;
const endAngle = startAngle + sliceAngle;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.arc(0, 0, radius, startAngle, endAngle);
ctx.closePath();
ctx.fillStyle = colors[index % colors.length];
ctx.fill();
ctx.save();
ctx.rotate(startAngle + sliceAngle / 2);
ctx.textAlign = 'right';
ctx.fillStyle = '#000';
ctx.font = 'bold 28px Arial';
ctx.fillText(presenter, radius - 30, 0);
ctx.restore();
});
ctx.restore();
// Draw arrow
ctx.beginPath();
ctx.moveTo(centerX + radius, centerY);
ctx.lineTo(centerX + radius + 20, centerY - 10);
ctx.lineTo(centerX + radius + 20, centerY + 10);
ctx.closePath();
ctx.fillStyle = '#333';
ctx.fill();
}
// 初期描画
drawRoulette(0);
</script>
</body>
</html>
終わりに
もう、ただただ、便利です。
参考