Skip to content

Instantly share code, notes, and snippets.

@ks-tmatsuoka
Last active November 10, 2024 10:41
Show Gist options
  • Save ks-tmatsuoka/7fcdf489df2ba411f29d0189da9a4379 to your computer and use it in GitHub Desktop.
Save ks-tmatsuoka/7fcdf489df2ba411f29d0189da9a4379 to your computer and use it in GitHub Desktop.
kobesoft.co.jpのトップページクリエイティブjs
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js Example</title>
<style>
body { margin: 0; }
#container {
width: 100%;
height: 500px;
background: linear-gradient(to bottom, #ff7e5f, #feb47b);
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
let scene, camera, renderer, points, lines;
let targetPosition = new THREE.Vector3();
let direction = new THREE.Vector3();
let speed = 0.02;
let lastUpdateTime = 0;
function init() {
// シーンの作成
scene = new THREE.Scene();
// カメラの作成
camera = new THREE.PerspectiveCamera(75, window.innerWidth / 500, 0.1, 1000);
camera.position.z = 5;
// レンダラーの作成(背景透過)
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, 500);
renderer.autoClear = false; // 加算合成のために自動クリアを無効にする
document.getElementById('container').appendChild(renderer.domElement);
// 頂点の作成
const vertices = [];
for (let i = 0; i < 300; i++) {
vertices.push(new THREE.Vector3(
(Math.random() - 0.5) * 10,
(Math.random() - 0.5) * 10,
(Math.random() - 0.5) * 10
));
}
// グロー効果のシェーダーマテリアルを作成
const vertexShader = `
varying vec3 vColor;
void main() {
vColor = color;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_PointSize = 0.1 * (300.0 / -mvPosition.z); // 点のサイズを調整
gl_Position = projectionMatrix * mvPosition;
}
`;
const fragmentShader = `
uniform vec3 color;
varying vec3 vColor;
void main() {
float distance = length(gl_PointCoord - vec2(0.5, 0.5));
float strength = 1.0 - distance * 2.0;
gl_FragColor = vec4(color * vColor, strength);
}
`;
const shaderMaterial = new THREE.ShaderMaterial({
uniforms: {
color: { value: new THREE.Color(0xffffff) }
},
vertexShader: vertexShader,
fragmentShader: fragmentShader,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent: true,
vertexColors: true
});
const pointsGeometry = new THREE.BufferGeometry().setFromPoints(vertices);
points = new THREE.Points(pointsGeometry, shaderMaterial);
scene.add(points);
// 距離が近い点同士を線で結ぶ
const maxDistance = 5.0; // 最大距離を5に設定
const edges = [];
const colors = [];
for (let i = 0; i < vertices.length; i++) {
const distances = [];
for (let j = 0; j < vertices.length; j++) {
if (i !== j) {
const distance = vertices[i].distanceTo(vertices[j]);
if (distance < maxDistance) {
distances.push({ index: j, distance: distance });
}
}
}
distances.sort((a, b) => a.distance - b.distance);
for (let k = 0; k < Math.min(5, distances.length); k++) { // 最大5本に制限
const j = distances[k].index;
const distance = distances[k].distance;
edges.push(vertices[i].x, vertices[i].y, vertices[i].z);
edges.push(vertices[j].x, vertices[j].y, vertices[j].z);
const alpha = Math.min(0.1, 1.0 - (distance / maxDistance)); // アルファ値を最大0.1に制限
colors.push(1.0, 1.0, 1.0, alpha);
colors.push(1.0, 1.0, 1.0, alpha);
}
}
const lineGeometry = new THREE.BufferGeometry();
lineGeometry.setAttribute('position', new THREE.Float32BufferAttribute(edges, 3));
lineGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 4));
const lineMaterial = new THREE.LineBasicMaterial({
vertexColors: true,
transparent: true,
blending: THREE.AdditiveBlending
});
lines = new THREE.LineSegments(lineGeometry, lineMaterial);
scene.add(lines);
// 初期目標位置の設定
updateTargetPosition();
// アニメーションの開始
animate();
}
function updateTargetPosition() {
targetPosition.set(
(Math.random() - 0.5) * 10,
(Math.random() - 0.5) * 10,
(Math.random() - 0.5) * 10
);
}
function animate(time) {
requestAnimationFrame(animate);
// 5秒ごとに目標位置を更新
if (time - lastUpdateTime > 5000) {
updateTargetPosition();
lastUpdateTime = time;
}
// カメラが目標位置の近くに来たら目標位置を更新
if (camera.position.distanceTo(targetPosition) < 1) {
updateTargetPosition();
}
// カメラの移動方向を目標位置に向けてゆるやかに更新
direction.lerp(targetPosition.clone().sub(camera.position).normalize(), 0.02);
// カメラを移動
camera.position.add(direction.clone().multiplyScalar(speed));
// カメラが常に中央を見る
camera.lookAt(scene.position);
renderer.clear();
renderer.render(scene, camera);
}
init();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment