クリックで画像が出現する処理をどう書けばよいですか?
Q&A
クリックで画像がランダムに出現する処理はどのように書けばよいですか?
https://suisei-inc.com/
上記サイトのように、イラストがカーソルを遅れて追いかけながら、かつ画面をクリックするごとに、そこからランダムに画像が出現する、そして、5枚ほど登場した時点で、自然にフェードアウトする繰り返し処理を書きたいです。
1
Q&A
クリックで画像がランダムに出現する処理はどのように書けばよいですか?
https://suisei-inc.com/
上記サイトのように、イラストがカーソルを遅れて追いかけながら、かつ画面をクリックするごとに、そこからランダムに画像が出現する、そして、5枚ほど登場した時点で、自然にフェードアウトする繰り返し処理を書きたいです。
※この記事は機械翻訳により日本語に翻訳されています。
どのプログラミング言語を使用するか指定されていなかったので、JSとHTMLをベースにした例をここに示します。この種の質問に対しては、ChatGPTや他の有名な大規模言語モデル(LLM)が簡単にコードを提供できることに注意してください。これは私がo1-previewモデルから得た例です。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>カーソル追従イラストとランダム画像</title>
<style>
body {
margin: 0;
overflow: hidden;
position: relative;
height: 100vh;
background-color: #f0f0f0;
}
.illustration {
position: absolute;
pointer-events: none;
will-change: transform;
}
.random-image {
position: absolute;
transition: opacity 0.5s linear;
opacity: 1;
}
</style>
</head>
<body>
<script>
// カーソルの位置を保持する変数
var mouseX = window.innerWidth / 2;
var mouseY = window.innerHeight / 2;
var illustrationX = mouseX;
var illustrationY = mouseY;
// 画像を管理する配列
var imagesArray = [];
// クリック回数をカウントする変数
var clickCounter = 0;
var maxClicks = 6; // 6回目のクリック後に画像がフェードアウト
// ランダム画像のURL配列
var randomImages = [
'https://via.placeholder.com/100x100/ff0000/ffffff?text=1',
'https://via.placeholder.com/100x100/00ff00/ffffff?text=2',
'https://via.placeholder.com/100x100/0000ff/ffffff?text=3',
'https://via.placeholder.com/100x100/ffff00/ffffff?text=4',
'https://via.placeholder.com/100x100/00ffff/ffffff?text=5'
];
// イラスト要素を作成
var illustration = document.createElement('img');
illustration.src = 'https://via.placeholder.com/50x50/000000/ffffff?text=Cursor';
illustration.classList.add('illustration');
document.body.appendChild(illustration);
// イラスト画像の読み込み後
illustration.onload = function () {
illustrationX = mouseX;
illustrationY = mouseY;
updateIllustration(); // アニメーションを開始
};
// マウス位置の更新
document.addEventListener('mousemove', onMouseMove);
function onMouseMove(event) {
mouseX = event.clientX;
mouseY = event.clientY;
}
// 遅延付きでイラストの位置を更新
function updateIllustration() {
var dx = mouseX - illustrationX;
var dy = mouseY - illustrationY;
var delayFactor = 0.1; // 遅延の調整
illustrationX += dx * delayFactor;
illustrationY += dy * delayFactor;
illustration.style.transform = 'translate(' + (illustrationX - illustration.width / 2) + 'px, ' + (illustrationY - illustration.height / 2) + 'px)';
requestAnimationFrame(updateIllustration);
}
// クリック時にランダム画像を生成
document.addEventListener('click', onClick);
function onClick(event) {
clickCounter++; // クリックカウンターを増加
var randomImage = document.createElement('img');
var randomIndex = Math.floor(Math.random() * randomImages.length);
randomImage.src = randomImages[randomIndex];
randomImage.classList.add('random-image');
randomImage.style.opacity = 1;
document.body.appendChild(randomImage);
// 画像の読み込み後に位置を設定
randomImage.onload = function () {
randomImage.style.left = (mouseX - randomImage.width / 2) + 'px';
randomImage.style.top = (mouseY - randomImage.height / 2) + 'px';
};
// 画像を配列に追加
imagesArray.push(randomImage);
// 6回目のクリック後に全ての画像をフェードアウト
if (clickCounter === maxClicks) {
imagesArray.forEach(function(image) {
image.style.opacity = 0;
// フェードアウト後にDOMから削除
image.addEventListener('transitionend', function () {
if (image.parentNode) {
image.parentNode.removeChild(image);
}
});
});
// 配列をクリア
imagesArray = [];
// クリックカウンターをリセット
clickCounter = 0;
}
}
</script>
</body>
</html>
updateIllustration
関数でイラストの位置を更新しています。onClick
関数が呼ばれ、ランダムな画像を生成します。randomImages
配列や illustration.src
を変更して、お好みの画像に差し替えることができます。maxClicks
の値を変更することで、フェードアウトが起こるクリック回数を調整できます。transition
プロパティを変更して、フェードアウトの速度を調整できます。面白いWebデザインですね!!
既に回答をされている方がいらっしゃいますが...
稚拙ながら回答させていただきます。
下記などで試してみてはいかがでしょうか?
画像のフェードインやフェードアウトはCSSアニメーションで実現しています。
<header id="header"></header>
<main>
<div class="mouseStoker"></div>
<section id="hero"></section>
<section id="paragraph"></section>
</main>
body {
margin: 0;
padding: 0;
}
#header {
width: 100vw;
height: 70px;
background-color: black;
position: fixed;
z-index: 10;
}
#hero {
width: 100vw;
height: 100vh;
background-color: white;
padding-top: 70px;
position: relative;
/*↓Hero要素から画像がはみ出ないようにする*/
overflow: hidden;
}
#paragraph {
width: 100vw;
height: 100vh;
background-color: gray;
}
/* マウスストーカー */
.mouseStoker{
width: 40px;
height: 40px;
position: fixed;
display: none;
border-radius: 50%;
background-color: red;
top: 0;
left: 0;
z-index: 5;
}
.active {
display: block;
}
/* クリックイベントで表示する画像 */
.image {
width: 300px;
height: auto;
position: absolute;
animation: fadein 1s forwards;
}
@keyframes fadein{
0%{
opacity: 0;
}
100%{
opacity: 1;
}
}
.hidden{
animation: fadeout 1s forwards;
}
@keyframes fadeout{
0%{
opacity: 1;
}
100%{
opacity: 0;
}
}
const hero = document.getElementById("hero");
const mouseStoker = document.querySelector(".mouseStoker");
//マウスの位置座標
let mouseX = 0;
let mouseY = 0;
//画像のパス(ファイル名を格納)
const paths = ["img1.jpg", "img2.jpg", "img3.jpg"];
//重複せずにランダムな値を取り出すための配列
let selectNumbers = [];
/*==========
マウスストーカー
==========*/
//マウスの位置座標の取得とマウスストカーの移動
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
updateMouseStoker(mouseX, mouseY);
});
function updateMouseStoker(x, y) {
mouseStoker.style.transform = `translate(${x}px, ${y}px)`;
}
//マウスストーカーの制御
hero.addEventListener('mouseover', () => handlerMouseStoker(true));
hero.addEventListener('mouseout', () => handlerMouseStoker(false));
function handlerMouseStoker(isActive) {
mouseStoker.classList.toggle('active', isActive);
}
/*==========
Heroエリアをクリックして画像の表示
==========*/
hero.addEventListener("click", () => {
//ランダムに画像の表示
if (selectNumbers.length < paths.length) {
const num = getRandomNumber(selectNumbers, paths);
const newImage = createImage(num);
newImage.onload = () => positionImage(newImage);
hero.appendChild(newImage);
} else {
//任意の回数以上クリックされたら表示した画像をすべて削除
//今回は表示用に用意した画像の枚数(paths)を任意の回数設定
resetImages();
}
});
//重複なくランダムに数を抽出する関数
function getRandomNumber(selectNumbers, array) {
let num;
let isVaild = false;
while (!isVaild) {
num = Math.floor(Math.random() * paths.length);
if (!selectNumbers.includes(num)) {
isVaild = true
}
}
selectNumbers.push(num);
return num;
}
//抽出したランダムな数に応じて画像要素を生成する関数
const createImage = (num) => {
const newImage = document.createElement("img");
newImage.setAttribute("src", `./assets/image/${paths[num]}`);
newImage.setAttribute("class", "image");
return newImage;
};
//表示する画像の位置を中心に合わせる関数
function positionImage(newImage) {
const [centerX, centerY] = getCenterImage(newImage);
newImage.style.left = `${mouseX - centerX}px`;
newImage.style.top = `${mouseY - centerY}px`;
}
//表示する画像の中心を取得
const getCenterImage = (newImage) => {
const rect = newImage.getBoundingClientRect();
const centerX =rect.width / 2;
const centerY = rect.height / 2
return [centerX, centerY];
};
//画像を削除する関数
function resetImages() {
selectNumbers = [];
const images = document.querySelectorAll(".image");
images.forEach((e) => {
e.classList.add('hidden');
e.addEventListener('animationend', () => e.remove());
});
}