Input | |
---|---|
0 | witness #0#1utf8 ��R;�i�`�T8W&�K���Y�*��d������ cordtext/html;charset=utf-8 M<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bitcoin Cemetery</title>
<style>
body, html {
margin: 0;
padding: 0;
height: 100%;
font-family: Arial, sans-serif;
background-color: #2c3e50;
}
#cemetery-container {
position: relative;
height: 100vh;
overflow: hidden;
}
/* 远M景和近景视图样式 */
#far-view, #near-view {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: opacity 0.5s ease;
}
#far-view {
background-size: cover;
background-position: center;
transition: background-image 0.5s ease;
}
#names-list {
position: absolute;
bottom: 20px;
right: 20px;
width: M200px;
height: 300px;
overflow-y: auto;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
border-radius: 5px;
}
#enter-near-view {
position: absolute;
bottom: 20px;
left: 20px;
padding: 10px 20px;
background: #34495e;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#near-view {M
display: none;
width: 100%;
height: 100%;
}
#tombstones-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 0; /* 移除间距 */
height: 100%;
width: 100%;
padding: 0; /* 移除内边距 */
box-sizing: border-box;
}
.tombstone {
position: relative;
width: 100%;
heightM: 100%;
overflow: hidden;
}
.grass-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
z-index: 1;
}
.tombstone-image {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 80%;
max-height: 80%;
M object-fit: contain;
z-index: 2;
}
.tombstone-name {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
text-align: center;
font-weight: bold;
color: #ffffff;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
font-size: 0.75em;
z-index: 3;
}
.flower {
position: absolute;
z-index: 4;
transition: transform 0.3s eaMse;
width: 50px;
height: auto;
}
.flower:hover {
transform: scale(1.2) rotate(10deg) !important;
}
/* 工具栏样式 */
#toolbar {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(44, 62, 80, 0.8);
padding: 10px;
border-radius: 30px;
display: flex;
align-items: center;
z-index:M 1000;
justify-content: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
#toolbar button, #toolbar select {
background-color: #3498db;
color: white;
border: none;
padding: 8px 15px;
margin: 0 5px;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s, transform 0.1s;
}
#toolbar button:hover, #toolbar select:hover {
M background-color: #2980b9;
}
#toolbar button:active, #toolbar select:active {
transform: scale(0.95);
}
#search-input {
padding: 8px 15px;
border: none;
border-radius: 20px;
margin-right: 5px;
font-size: 14px;
}
#search-button, #enter-cemetery {
background-color: #34495e;
color: #ecf0f1;
border: none;
padding: 5px 10px;
border-Mradius: 15px;
cursor: pointer;
font-size: 12px;
transition: background-color 0.3s;
}
#search-button:hover, #enter-cemetery:hover {
background-color: #2c3e50;
}
/* 模态框样式 */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0M,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 500px;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
M }
/* 响应式设计 */
@media (max-width: 1200px) {
#tombstones-grid {
grid-template-columns: repeat(4, 1fr);
}
}
@media (max-width: 992px) {
#tombstones-grid {
grid-template-columns: repeat(3, 1fr);
}
#near-view {
padding: 0;
}
}
@media (max-width: 768px) {
#names-list {
width: 150px;
height: 200px;
M }
#tombstones-grid {
grid-template-columns: repeat(2, 1fr);
}
#near-view {
padding: 0;
}
}
@media (max-width: 480px) {
#tombstones-grid {
grid-template-columns: repeat(2, 1fr);
}
#near-view {
padding: 0;
}
}
#far-view-controls {
position: absolute;
bottom: 20px;
left: 50%;
M transform: translateX(-50%);
display: flex;
gap: 10px;
}
.far-view-button {
padding: 10px 20px;
background: #34495e;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#search-results {
position: absolute;
top: -200px; /* 将搜索结果显示在搜索框上方 */
left: 0;
background: white;
border: 1px solid #ccMc;
max-height: 200px;
width: 100%;
overflow-y: auto;
display: none;
z-index: 1001; /* 确保搜索结果显示在最上层 */
}
#search-results div {
padding: 5px;
cursor: pointer;
}
#search-results div:hover {
background-color: #f0f0f0;
}
#page-select {
padding: 5px;
border: none;
border-radius: 15px;
margin-right: 5px;
M font-size: 12px;
}
#butterfly {
position: absolute;
width: 100px; /* 调整为实际单个蝴蝶图像的宽度 */
height: 100px; /* 调整为实际图像高度 */
background-image: url('/content/90109feb784da31eb5f92f2c009ec1914c69257a1754fcf54ee588e0aedd8efci0');
background-size: 300px 100px; /* 宽度是单个蝴蝶的3倍,高度不变 */
animation: fly 20s infinite alternate, flap 0.6s steps(3) infinite;
}
M @keyframes fly {
0% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(200px, -100px) rotate(10deg); }
50% { transform: translate(400px, 0) rotate(-10deg); }
75% { transform: translate(200px, 100px) rotate(10deg); }
100% { transform: translate(0, 0) rotate(0deg); }
}
@keyframes flap {
100% { background-position: -300px 0; }
}
#butterflies-container {
position: absolute;
M top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1000;
}
.butterfly {
position: absolute;
width: 50px;
height: 50px;
background-size: 150px 50px;
animation: flap 0.6s steps(3) infinite;
transition: transform 0.5s ease-in-out;
}
@keyframes flap {
100% { background-position: -150px 0; }
}
M /* 添加选择墓园页面的样式 */
#cemetery-selection {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 2000;
}
#cemetery-list {
background-color: white;
padding: 20px;
border-radius: 10px;
M max-width: 80%;
max-height: 80%;
overflow-y: auto;
}
.cemetery-item {
margin: 10px 0;
padding: 10px;
background-color: #f0f0f0;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.cemetery-item:hover {
background-color: #e0e0e0;
}
#loading {
position: fixed;
top: 0;
left: 0;
M width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 2001;
color: white;
font-size: 24px;
}
.spinner {
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
M margin-right: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#cemetery-owners {
position: absolute;
top: 20px;
left: 20px;
background-color: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 5px;
max-width: 300px;
}
#search-modal {
display: none;
position: fixed;
M z-index: 2000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.7);
}
.search-modal-content {
background-color: #f4f4f4;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 600px;
border-radius: 10px;
}
#search-input {
width: 100%;
padding: 10px;
Mmargin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}
#search-results {
max-height: 300px;
overflow-y: auto;
}
#search-results div {
padding: 10px;
border-bottom: 1px solid #ddd;
cursor: pointer;
}
#search-results div:hover {
background-color: #e9e9e9;
}
</style>
</head>
<body>
<!-- 添加选择墓园的页面 -->
<div id="cemetery-selectMion">
<div id="cemetery-list"></div>
</div>
<div id="cemetery-container">
<div id="far-view">
<div id="names-list"></div>
</div>
<div id="near-view">
<div id="tombstones-grid"></div>
</div>
<div id="butterflies-container"></div>
</div>
<div id="toolbar">
<button id="search-button">🔍 Search</button>
<select id="page-select"></select>
<button id="toggle-view">Go Closer</button>
<button id="back-Mto-selection">Change Cemetery</button>
</div>
<div id="tombstoneModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h2 id="modalName"></h2>
<p id="modalEpitaph"></p>
<p id="modalNumber"></p>
</div>
</div>
<div id="loading">
<div class="spinner"></div>
<span>Loading...</span>
</div>
<div id="cemetery-owners" style="display: none;"></div>
<div id="search-modal">
<divM class="search-modal-content">
<input type="text" id="search-input" placeholder="Search tombstones...">
<div id="search-results"></div>
</div>
</div>
<script src="/content/512d2fb34e7b1a321021b6b4fb3eda88f92630bc408edb6a26895e741124bf01i0"></script>
<script>
// 将 fetchInscriptionContent 函数定义移到这里
window.fetchInscriptionContent = async function(inscriptionId) {
try {
const response = await fetch(`/content/${inscMriptionId}`);
return await response.text();
} catch (error) {
console.error(`Error fetching content for inscription ${inscriptionId}:`, error);
return '{}';
}
};
const api = new OrdinalsAPI();
let resourceInscription = null;
let allTombstones = [];
let currentPage = 1;
const tombstonesPerPage = 12;
const cemeteryGrandparentId = '21aefb0f5e2c4d77a7d2b3bdc7aecf0a0e9ce1e54f50dd77b6afae805aa2M89c3i0';
const resourceParentId = '5f25c31199f77fab9d219ac95a731433ab9c8602fe9fc7333a1d41b117d6579bi0';
const butterflyBaseId = '629659878d2a0a8e9907d91ecfc9544ef47d3ff9b3dd6ed7acfbea80c94096eei';
const totalButterflies = 30;
const maxActiveButterflies = 2;
let activeButterflies = [];
let butterflyTimeout;
let isNearView = false;
const minButterflyCooldown = 10000; // 最小蝴蝶冷却时间(10秒)
const maxButterflyCooldown = 20000; // �M��大蝴蝶冷却时间(20秒)
let lastButterflyTime = 0;
const flowerIds = [
'4990c1707b951262b9f8ca823c29220778d7ce31c4d3cffe38139cde66a522f4i0',
'70d070304ea3edcebd9e67fc4d029117c58f5f275c56585582d4a4482ae3da25i0',
'17f7644935c6e78978a07621a36c3b53b599df7b92c7cd34aa18a65a99970e4di0',
'009f8fd7e26ce37a58545dbb8247611f580e6f0fbda65ed59c29098f7b7ff190i0',
'af7c97bf2b2c347725a8e77c602823cbc20dfeca90324823c950865b2b37b300i0',
M '166ed949dc2a970cd60a1913f57468f07ecc85b4557e34c08876d026db2aacb0i0',
'5c6f720e5d059617e8c640e09a0909a1f0fbaf2a375e74c3a12e5235c5191563i0'
];
let allCemeteries = [];
let currentCemeteryId = null;
let tombstoneCache = {};
// 修改 loadResourceInscription 函数
async function loadResourceInscription() {
try {
console.log('Starting to load resource inscription');
document.getElementById('loading').style.displaMy = 'flex';
const resourceChildIds = await api.getAllChildrenIds(cemeteryGrandparentId);
console.log('Resource Child IDs:', resourceChildIds);
if (resourceChildIds.length === 0) {
throw new Error('No resource inscription found');
}
allCemeteries = [];
for (let resourceId of resourceChildIds) {
try {
console.log('Trying Resource ID:', resourceId);
M const content = await fetchInscriptionContent(resourceId);
console.log('Fetched content:', content);
const cemetery = JSON.parse(content);
cemetery.id = resourceId;
allCemeteries.push(cemetery);
console.log('Added cemetery:', cemetery);
} catch (parseError) {
console.error(`Error parsing JSON for resource ${resourceId}:`, parseError);
M }
}
console.log('All cemeteries:', allCemeteries);
if (allCemeteries.length === 0) {
throw new Error('No valid resource inscription found');
}
displayCemeterySelection();
} catch (error) {
console.error('Error loading resource inscription:', error);
document.getElementById('loading').style.display = 'none';
alert('Error loading cemeteries. MPlease try again later.');
} finally {
document.getElementById('loading').style.display = 'none';
}
}
// 修改 displayCemeterySelection 函数
function displayCemeterySelection() {
const cemeteryList = document.getElementById('cemetery-list');
cemeteryList.innerHTML = '';
allCemeteries.forEach(cemetery => {
const cemeteryItem = document.createElement('div');
cemeteryItem.className =M 'cemetery-item';
cemeteryItem.textContent = cemetery.cemetery_name;
cemeteryItem.addEventListener('click', () => selectCemetery(cemetery.id));
cemeteryList.appendChild(cemeteryItem);
});
document.getElementById('cemetery-selection').style.display = 'flex';
document.getElementById('loading').style.display = 'none';
document.getElementById('butterflies-container').style.display = 'none';
}
// 修改 seleMctCemetery 函数
async function selectCemetery(cemeteryId) {
try {
currentCemeteryId = cemeteryId;
resourceInscription = allCemeteries.find(cemetery => cemetery.id === cemeteryId);
document.getElementById('cemetery-selection').style.display = 'none';
document.getElementById('loading').style.display = 'flex';
// 在这里加载选中墓园的墓碑信息
await loadTombstones();
M const ownerNames = await loadFarView();
displayFarView(ownerNames);
document.getElementById('butterflies-container').style.display = 'block';
resetButterflies();
} catch (error) {
console.error('Error selecting cemetery:', error);
alert('Error loading cemetery. Please try again.');
} finally {
document.getElementById('loading').style.display = 'none';
}
}
//M 修改 loadTombstones 函数
async function loadTombstones() {
try {
const tombstoneIds = await api.getAllChildrenIds(currentCemeteryId);
console.log('Tombstone IDs:', tombstoneIds);
allTombstones = [];
for (let id of tombstoneIds) {
const tombstoneData = await processTombstoneData(id);
if (tombstoneData) {
allTombstones.push({
...tombstoneMData,
number: allTombstones.length + 1,
loaded: true
});
}
}
updatePageSelect();
} catch (error) {
console.error('Error loading tombstones:', error);
throw error;
}
}
// 修改 processTombstoneData 函数
async function processTombstoneData(id) {
if (tombstoneCache[id]) {
returMn tombstoneCache[id];
}
try {
const content = await fetchInscriptionContent(id);
const tombstone = JSON.parse(content);
tombstoneCache[id] = {
id: id,
tombstoneType: tombstone.tombstoneType || '1',
ownerName: tombstone.ownerName || 'Unknown',
epitaph: tombstone.epitaph || 'No epitaph',
imageInscriptionId: tombstone.imageInscriptionId || ''
M };
return tombstoneCache[id];
} catch (error) {
console.error(`Error processing tombstone ${id}:`, error);
return null;
}
}
// 修改 updatePageSelect 函数
function updatePageSelect() {
const pageSelect = document.getElementById('page-select');
pageSelect.innerHTML = '';
const totalPages = Math.ceil(allTombstones.length / tombstonesPerPage);
for (let i = 1; i M<= totalPages; i++) {
const option = document.createElement('option');
option.value = i;
option.textContent = `Page ${i}`;
pageSelect.appendChild(option);
}
}
// 修改 displayNearView 函数
async function displayNearView() {
const nearView = document.getElementById('near-view');
const tombstonesGrid = document.getElementById('tombstones-grid');
tombstonesGrid.innerHTML = '';
M nearView.style.display = 'block';
const startIndex = (currentPage - 1) * tombstonesPerPage;
const endIndex = startIndex + tombstonesPerPage;
const tombstonesToDisplay = allTombstones.slice(startIndex, endIndex);
for (let i = 0; i < tombstonesToDisplay.length; i++) {
const tombstone = tombstonesToDisplay[i];
const tombstoneElement = createTombstoneElement(tombstone, startIndex + i);
tombstonesGrid.appendChild(MtombstoneElement);
}
}
// 修改 createTombstoneElement 函数
function createTombstoneElement(tombstone, index) {
const tombstoneElement = document.createElement('div');
tombstoneElement.className = 'tombstone';
const tombstoneImageUrl = `/content/${resourceInscription.tombpicture}`;
const grassBackgroundUrl = `/content/${resourceInscription.tombbackgroud_grass}`;
tombstoneElement.innerHTML = M`
<div class="grass-background" style="background-image: url('${grassBackgroundUrl}');"></div>
<img src="${tombstoneImageUrl}" alt="Tombstone" class="tombstone-image">
<div class="tombstone-name">${tombstone.ownerName || `Tombstone #${tombstone.number}`}</div>
`;
addFlowersToTombstone(tombstoneElement);
tombstoneElement.addEventListener('click', () => showTombstoneDetails(tombstone));
return toMmbstoneElement;
}
// 修改 addFlowersToTombstone 函数
function addFlowersToTombstone(tombstoneElement) {
const flowerCount = Math.floor(Math.random() * 2) + 1; // 1 到 2 朵花
for (let i = 0; i < flowerCount; i++) {
const flowerImg = document.createElement('img');
flowerImg.src = `/content/${flowerIds[Math.floor(Math.random() * flowerIds.length)]}`;
flowerImg.className = 'flower';
floweMrImg.style.left = `${Math.random() * 60 + 20}%`; // 20% 到 80% 之间
flowerImg.style.bottom = '0%';
flowerImg.style.transform = `rotate(${Math.random() * 30 - 15}deg)`; // -15 到 15 度之间旋转
flowerImg.style.width = '50px'; // 放大花朵
flowerImg.style.height = 'auto';
tombstoneElement.appendChild(flowerImg);
}
}
// 修改 showTombstoneDetails 函数
async function showToMmbstoneDetails(tombstone) {
const modal = document.getElementById('tombstoneModal');
const modalName = document.getElementById('modalName');
const modalEpitaph = document.getElementById('modalEpitaph');
const modalNumber = document.getElementById('modalNumber');
modalName.textContent = tombstone.ownerName || `Tombstone #${tombstone.number}`;
modalEpitaph.textContent = 'Loading...';
modalNumber.textContent = `Tombstone #${tombstone.Mnumber}`;
modal.style.display = 'block';
if (!tombstone.loaded) {
const tombstoneData = await processTombstoneData(tombstone.id);
Object.assign(tombstone, tombstoneData);
tombstone.loaded = true;
}
modalEpitaph.textContent = tombstone.epitaph || 'No epitaph';
}
// 修改 searchTombstones 函数
async function searchTombstones() {
const searchInput = document.getElementById('search-Minput');
const searchResultsElement = document.getElementById('search-results');
if (!searchInput || !searchResultsElement) {
console.error('Search input or results container not found');
return;
}
const searchTerm = searchInput.value.toLowerCase().trim();
if (searchTerm.length < 2) {
searchResultsElement.innerHTML = '';
return;
}
console.log('Searching fMor:', searchTerm);
const searchResults = [];
for (let tombstone of allTombstones) {
if (tombstone.ownerName.toLowerCase().includes(searchTerm) ||
tombstone.epitaph.toLowerCase().includes(searchTerm)) {
searchResults.push(tombstone);
}
}
console.log('Search results:', searchResults);
displaySearchResults(searchResults);
}
// 修改 displaySearchResults 函数
Mfunction displaySearchResults(results) {
const searchResultsElement = document.getElementById('search-results');
if (!searchResultsElement) {
console.error('Search results container not found');
return;
}
searchResultsElement.innerHTML = '';
if (results.length === 0) {
searchResultsElement.innerHTML = '<div>No results found</div>';
} else {
results.forEach(tombstone M=> {
const resultElement = document.createElement('div');
resultElement.textContent = `${tombstone.ownerName} (Tombstone #${tombstone.number})`;
resultElement.addEventListener('click', () => {
const tombstoneIndex = allTombstones.findIndex(t => t.id === tombstone.id);
currentPage = Math.floor(tombstoneIndex / tombstonesPerPage) + 1;
document.getElementById('page-select').value = currenMtPage;
if (isNearView) {
displayNearView();
} else {
loadFarView().then(ownerNames => displayFarView(ownerNames));
}
document.getElementById('search-modal').style.display = 'none';
});
searchResultsElement.appendChild(resultElement);
});
}
searchResultsElement.style.display = 'block';
M }
function scheduleNextButterfly() {
if (activeButterflies.length < maxActiveButterflies && !isNearView) {
const now = Date.now();
const timeSinceLastButterfly = now - lastButterflyTime;
const cooldownTime = Math.random() * (maxButterflyCooldown - minButterflyCooldown) + minButterflyCooldown;
if (timeSinceLastButterfly >= cooldownTime) {
createButterfly();
lastButterflMyTime = now;
}
// 无论是否创建了蝴蝶,都继续安排下一次检查
const nextCheckDelay = Math.min(cooldownTime - timeSinceLastButterfly, minButterflyCooldown);
butterflyTimeout = setTimeout(scheduleNextButterfly, nextCheckDelay);
}
}
function createButterfly() {
if (activeButterflies.length >= maxActiveButterflies) {
return;
}
const butterfliMesContainer = document.getElementById('butterflies-container');
if (!butterfliesContainer) {
console.error('Butterflies container not found');
return;
}
const butterflyIndex = Math.floor(Math.random() * totalButterflies);
const butterflyId = `${butterflyBaseId}${butterflyIndex}`;
const butterfly = document.createElement('div');
butterfly.className = 'butterfly';
butterfly.style.backgroundImage = `urlM('/content/${butterflyId}')`;
const flyingMode = Math.random() < 0.5 ? 'horizontal' : 'depth';
const groundLevel = window.innerHeight * 0.7; // 地面水平线,屏幕高度的 70%
let startX, startY, midX, midY, endX, endY;
if (flyingMode === 'horizontal') {
startX = Math.random() < 0.5 ? -50 : window.innerWidth + 50;
startY = groundLevel + Math.random() * (window.innerHeight - groundLevel);
endX = startX < 0 ? windMow.innerWidth + 50 : -50;
endY = groundLevel + Math.random() * (window.innerHeight - groundLevel);
// 不再使用 midX 和 midY
} else {
// 纵深飞行模式保持不变
startX = Math.random() * window.innerWidth;
startY = groundLevel + Math.random() * (window.innerHeight - groundLevel);
midX = startX + (Math.random() - 0.5) * 100;
midY = groundLevel + Math.random() * (window.innerHeight - gMroundLevel);
endX = startX + (Math.random() - 0.5) * 50;
endY = groundLevel + Math.random() * (window.innerHeight - groundLevel);
}
butterfly.style.left = `${startX}px`;
butterfly.style.top = `${startY}px`;
butterfly.style.transform = flyingMode === 'horizontal' ? 'scale(1)' : 'scale(0.1)';
butterfliesContainer.appendChild(butterfly);
const duration = Math.random() * 20000 + 20000; // 20-40 seconds
M animateButterfly(butterfly, startX, startY, midX, midY, endX, endY, duration, flyingMode, groundLevel);
activeButterflies.push(butterfly);
scheduleNextButterfly();
}
function animateButterfly(butterfly, startX, startY, midX, midY, endX, endY, duration, flyingMode, groundLevel) {
const startTime = performance.now();
const amplitude = Math.random() * 50 + 25; // 振幅在2575之间
const frequency = Math.random() * 2 + 1; // 频率在1到3M之间
function update() {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
let x, y, scale;
if (flyingMode === 'horizontal') {
// 横向飞行模式
x = startX + (endX - startX) * progress;
// 使用正弦函数创造上波动
y = startY + amplitude * Math.sin(progress * Math.PI * frequency);
M // 确保蝴蝶不会飞到地面以下
y = Math.max(y, groundLevel);
scale = 1;
} else {
// 纵深飞行模式保持不变
if (progress < 0.5) {
const t = progress * 2;
x = startX + (midX - startX) * t;
y = startY + (midY - startY) * t;
scale = 0.1 + 0.9 * t;
} else {
M const t = (progress - 0.5) * 2;
x = midX + (endX - midX) * t;
y = midY + (endY - midY) * t;
scale = 1 - 0.9 * t;
}
}
// 添加小幅度的随机波动
const wobbleX = Math.sin(progress * Math.PI * 8) * 10;
const wobbleY = Math.cos(progress * Math.PI * 8) * 10;
y = Math.max(y + wobbleY, groundLevel);
butterfly.style.left = `${Mx + wobbleX}px`;
butterfly.style.top = `${y}px`;
butterfly.style.transform = `scale(${scale})`;
if (progress < 1) {
requestAnimationFrame(update);
} else {
removeButterfly(butterfly);
}
}
requestAnimationFrame(update);
}
function removeButterfly(butterfly) {
butterfly.remove();
activeButterflies = activeMButterflies.filter(b => b !== butterfly);
scheduleNextButterfly();
}
// 修改 initButterflies 函数
function initButterflies() {
clearTimeout(butterflyTimeout);
lastButterflyTime = 0; // 将最后蝴蝶出现时间设为0,以便立开始生成蝴蝶
scheduleNextButterfly(); // 立即开始生成蝴蝶
}
// 修改 resetButterflies 函数
function resetButterflies() {
const container = document.getElementMById('butterflies-container');
container.innerHTML = '';
activeButterflies = [];
clearTimeout(butterflyTimeout);
initButterflies(); // 直接调用 initButterflies 来重新开始蝴蝶动画
}
// 添加返回选择墓园页面的函数
function backToCemeterySelection() {
document.getElementById('cemetery-selection').style.display = 'flex';
document.getElementById('far-view').style.display = 'none';
documenMt.getElementById('near-view').style.display = 'none';
document.getElementById('butterflies-container').style.display = 'none';
document.getElementById('cemetery-owners').style.display = 'none';
resetButterflies();
}
// 修改 loadFarView 函数
async function loadFarView() {
try {
const farView = document.getElementById('far-view');
const img = new Image();
img.src = `/content/${resourceInscriptiMon.farview}`;
await new Promise((resolve, reject) => {
img.onload = resolve;
img.onerror = reject;
});
farView.style.backgroundImage = `url('${img.src}')`;
// 加载当前页面的墓碑主人姓名
const startIndex = (currentPage - 1) * tombstonesPerPage;
const endIndex = startIndex + tombstonesPerPage;
const pageOwnerNames = allTombstones.slice(startIndex, endIndMex).map(tombstone => tombstone.ownerName || 'Unknown');
return pageOwnerNames;
} catch (error) {
console.error('Error loading far view:', error);
throw error;
}
}
// 修改 displayFarView 函数
function displayFarView(ownerNames) {
const farView = document.getElementById('far-view');
const namesList = document.getElementById('names-list');
const cemeteryOwners = document.getElementByMId('cemetery-owners');
if (farView && namesList && cemeteryOwners) {
farView.style.display = 'block';
cemeteryOwners.style.display = 'block';
cemeteryOwners.innerHTML = `<h3>${resourceInscription.cemetery_name}</h3>`;
// 显示当前页面的墓园主人姓名列表
namesList.innerHTML = ownerNames.map(name => `<div>${name}</div>`).join('');
namesList.style.display = 'block';
document.getElMementById('near-view').style.display = 'none';
document.getElementById('toggle-view').textContent = 'Go Closer';
isNearView = false;
}
}
// 修改 toggleView 函数
async function toggleView() {
const farView = document.getElementById('far-view');
const nearView = document.getElementById('near-view');
const toggleButton = document.getElementById('toggle-view');
const butterfliesContainer = document.gMetElementById('butterflies-container');
const cemeteryOwners = document.getElementById('cemetery-owners');
if (farView && nearView && toggleButton && butterfliesContainer) {
if (farView.style.display !== 'none') {
farView.style.display = 'none';
cemeteryOwners.style.display = 'none';
nearView.style.display = 'block';
toggleButton.textContent = 'Go Back';
isNearView = true;
M butterfliesContainer.style.display = 'none';
document.getElementById('loading').style.display = 'flex';
await displayNearView();
document.getElementById('loading').style.display = 'none';
} else {
const ownerNames = await loadFarView();
displayFarView(ownerNames);
butterfliesContainer.style.display = 'block';
resetButterflies();
M}
}
}
document.addEventListener('DOMContentLoaded', () => {
loadResourceInscription().catch(error => {
console.error('Error in initial load:', error);
document.getElementById('loading').style.display = 'none';
alert('Error loading the application. Please try refreshing the page.');
});
document.getElementById('toggle-view').addEventListener('click', toggleView);
document.getElemeMntById('search-button').addEventListener('click', () => {
document.getElementById('search-modal').style.display = 'block';
document.getElementById('search-input').focus();
});
document.getElementById('search-input').addEventListener('input', searchTombstones);
document.getElementById('page-select').addEventListener('change', async (e) => {
currentPage = parseInt(e.target.value);
if (isNearView) {
M await displayNearView();
} else {
const ownerNames = await loadFarView();
displayFarView(ownerNames);
}
});
const modal = document.getElementById('tombstoneModal');
const span = document.getElementsByClassName('close')[0];
if (span) {
span.onclick = function() {
modal.style.display = 'none';
}
}
window.onclick = functioMn(event) {
if (event.target == modal) {
modal.style.display = 'none';
}
}
// 初始化蝴蝶
initButterflies();
document.getElementById('back-to-selection').addEventListener('click', backToCemeterySelection);
const searchInput = document.getElementById('search-input');
const searchButton = document.getElementById('search-button');
const searchResults = document.getElementById('sMearch-results');
if (searchButton) {
searchButton.addEventListener('click', (e) => {
e.preventDefault();
searchTombstones();
});
}
if (searchInput) {
searchInput.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
searchTombstones();
}
});
searchInput.addEventListener('input', () => {
M if (searchInput.value.length > 1) {
searchTombstones();
} else if (searchResults) {
searchResults.style.display = 'none';
}
});
}
// 添加点击事件监听器来关闭搜索结果
document.addEventListener('click', (e) => {
if (searchInput && searchResults && !searchInput.contains(e.target) && !searchResults.contains(e.target)) {
Ly searchResults.style.display = 'none';
}
});
});
</script>
</body>
</html>h ��R;�i�`�T8W&�K���Y�*��d������ cordtext/html;charset=utf-8 M<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bitcoin Cemetery</title>
<style>
body, html {
margin: 0;
padding: 0;
height: 100%;
font-family: Arial, sans-serif;
background-color: #2c3e50;
}
#cemetery-container {
position: relative;
height: 100vh;
overflow: hidden;
}
/* 远M景和近景视图样式 */
#far-view, #near-view {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: opacity 0.5s ease;
}
#far-view {
background-size: cover;
background-position: center;
transition: background-image 0.5s ease;
}
#names-list {
position: absolute;
bottom: 20px;
right: 20px;
width: M200px;
height: 300px;
overflow-y: auto;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
border-radius: 5px;
}
#enter-near-view {
position: absolute;
bottom: 20px;
left: 20px;
padding: 10px 20px;
background: #34495e;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#near-view {M
display: none;
width: 100%;
height: 100%;
}
#tombstones-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 0; /* 移除间距 */
height: 100%;
width: 100%;
padding: 0; /* 移除内边距 */
box-sizing: border-box;
}
.tombstone {
position: relative;
width: 100%;
heightM: 100%;
overflow: hidden;
}
.grass-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
z-index: 1;
}
.tombstone-image {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 80%;
max-height: 80%;
M object-fit: contain;
z-index: 2;
}
.tombstone-name {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
text-align: center;
font-weight: bold;
color: #ffffff;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
font-size: 0.75em;
z-index: 3;
}
.flower {
position: absolute;
z-index: 4;
transition: transform 0.3s eaMse;
width: 50px;
height: auto;
}
.flower:hover {
transform: scale(1.2) rotate(10deg) !important;
}
/* 工具栏样式 */
#toolbar {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(44, 62, 80, 0.8);
padding: 10px;
border-radius: 30px;
display: flex;
align-items: center;
z-index:M 1000;
justify-content: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
#toolbar button, #toolbar select {
background-color: #3498db;
color: white;
border: none;
padding: 8px 15px;
margin: 0 5px;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s, transform 0.1s;
}
#toolbar button:hover, #toolbar select:hover {
M background-color: #2980b9;
}
#toolbar button:active, #toolbar select:active {
transform: scale(0.95);
}
#search-input {
padding: 8px 15px;
border: none;
border-radius: 20px;
margin-right: 5px;
font-size: 14px;
}
#search-button, #enter-cemetery {
background-color: #34495e;
color: #ecf0f1;
border: none;
padding: 5px 10px;
border-Mradius: 15px;
cursor: pointer;
font-size: 12px;
transition: background-color 0.3s;
}
#search-button:hover, #enter-cemetery:hover {
background-color: #2c3e50;
}
/* 模态框样式 */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0M,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 500px;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
M }
/* 响应式设计 */
@media (max-width: 1200px) {
#tombstones-grid {
grid-template-columns: repeat(4, 1fr);
}
}
@media (max-width: 992px) {
#tombstones-grid {
grid-template-columns: repeat(3, 1fr);
}
#near-view {
padding: 0;
}
}
@media (max-width: 768px) {
#names-list {
width: 150px;
height: 200px;
M }
#tombstones-grid {
grid-template-columns: repeat(2, 1fr);
}
#near-view {
padding: 0;
}
}
@media (max-width: 480px) {
#tombstones-grid {
grid-template-columns: repeat(2, 1fr);
}
#near-view {
padding: 0;
}
}
#far-view-controls {
position: absolute;
bottom: 20px;
left: 50%;
M transform: translateX(-50%);
display: flex;
gap: 10px;
}
.far-view-button {
padding: 10px 20px;
background: #34495e;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#search-results {
position: absolute;
top: -200px; /* 将搜索结果显示在搜索框上方 */
left: 0;
background: white;
border: 1px solid #ccMc;
max-height: 200px;
width: 100%;
overflow-y: auto;
display: none;
z-index: 1001; /* 确保搜索结果显示在最上层 */
}
#search-results div {
padding: 5px;
cursor: pointer;
}
#search-results div:hover {
background-color: #f0f0f0;
}
#page-select {
padding: 5px;
border: none;
border-radius: 15px;
margin-right: 5px;
M font-size: 12px;
}
#butterfly {
position: absolute;
width: 100px; /* 调整为实际单个蝴蝶图像的宽度 */
height: 100px; /* 调整为实际图像高度 */
background-image: url('/content/90109feb784da31eb5f92f2c009ec1914c69257a1754fcf54ee588e0aedd8efci0');
background-size: 300px 100px; /* 宽度是单个蝴蝶的3倍,高度不变 */
animation: fly 20s infinite alternate, flap 0.6s steps(3) infinite;
}
M @keyframes fly {
0% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(200px, -100px) rotate(10deg); }
50% { transform: translate(400px, 0) rotate(-10deg); }
75% { transform: translate(200px, 100px) rotate(10deg); }
100% { transform: translate(0, 0) rotate(0deg); }
}
@keyframes flap {
100% { background-position: -300px 0; }
}
#butterflies-container {
position: absolute;
M top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1000;
}
.butterfly {
position: absolute;
width: 50px;
height: 50px;
background-size: 150px 50px;
animation: flap 0.6s steps(3) infinite;
transition: transform 0.5s ease-in-out;
}
@keyframes flap {
100% { background-position: -150px 0; }
}
M /* 添加选择墓园页面的样式 */
#cemetery-selection {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 2000;
}
#cemetery-list {
background-color: white;
padding: 20px;
border-radius: 10px;
M max-width: 80%;
max-height: 80%;
overflow-y: auto;
}
.cemetery-item {
margin: 10px 0;
padding: 10px;
background-color: #f0f0f0;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.cemetery-item:hover {
background-color: #e0e0e0;
}
#loading {
position: fixed;
top: 0;
left: 0;
M width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 2001;
color: white;
font-size: 24px;
}
.spinner {
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
M margin-right: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#cemetery-owners {
position: absolute;
top: 20px;
left: 20px;
background-color: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 5px;
max-width: 300px;
}
#search-modal {
display: none;
position: fixed;
M z-index: 2000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.7);
}
.search-modal-content {
background-color: #f4f4f4;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 600px;
border-radius: 10px;
}
#search-input {
width: 100%;
padding: 10px;
Mmargin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}
#search-results {
max-height: 300px;
overflow-y: auto;
}
#search-results div {
padding: 10px;
border-bottom: 1px solid #ddd;
cursor: pointer;
}
#search-results div:hover {
background-color: #e9e9e9;
}
</style>
</head>
<body>
<!-- 添加选择墓园的页面 -->
<div id="cemetery-selectMion">
<div id="cemetery-list"></div>
</div>
<div id="cemetery-container">
<div id="far-view">
<div id="names-list"></div>
</div>
<div id="near-view">
<div id="tombstones-grid"></div>
</div>
<div id="butterflies-container"></div>
</div>
<div id="toolbar">
<button id="search-button">🔍 Search</button>
<select id="page-select"></select>
<button id="toggle-view">Go Closer</button>
<button id="back-Mto-selection">Change Cemetery</button>
</div>
<div id="tombstoneModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h2 id="modalName"></h2>
<p id="modalEpitaph"></p>
<p id="modalNumber"></p>
</div>
</div>
<div id="loading">
<div class="spinner"></div>
<span>Loading...</span>
</div>
<div id="cemetery-owners" style="display: none;"></div>
<div id="search-modal">
<divM class="search-modal-content">
<input type="text" id="search-input" placeholder="Search tombstones...">
<div id="search-results"></div>
</div>
</div>
<script src="/content/512d2fb34e7b1a321021b6b4fb3eda88f92630bc408edb6a26895e741124bf01i0"></script>
<script>
// 将 fetchInscriptionContent 函数定义移到这里
window.fetchInscriptionContent = async function(inscriptionId) {
try {
const response = await fetch(`/content/${inscMriptionId}`);
return await response.text();
} catch (error) {
console.error(`Error fetching content for inscription ${inscriptionId}:`, error);
return '{}';
}
};
const api = new OrdinalsAPI();
let resourceInscription = null;
let allTombstones = [];
let currentPage = 1;
const tombstonesPerPage = 12;
const cemeteryGrandparentId = '21aefb0f5e2c4d77a7d2b3bdc7aecf0a0e9ce1e54f50dd77b6afae805aa2M89c3i0';
const resourceParentId = '5f25c31199f77fab9d219ac95a731433ab9c8602fe9fc7333a1d41b117d6579bi0';
const butterflyBaseId = '629659878d2a0a8e9907d91ecfc9544ef47d3ff9b3dd6ed7acfbea80c94096eei';
const totalButterflies = 30;
const maxActiveButterflies = 2;
let activeButterflies = [];
let butterflyTimeout;
let isNearView = false;
const minButterflyCooldown = 10000; // 最小蝴蝶冷却时间(10秒)
const maxButterflyCooldown = 20000; // �M��大蝴蝶冷却时间(20秒)
let lastButterflyTime = 0;
const flowerIds = [
'4990c1707b951262b9f8ca823c29220778d7ce31c4d3cffe38139cde66a522f4i0',
'70d070304ea3edcebd9e67fc4d029117c58f5f275c56585582d4a4482ae3da25i0',
'17f7644935c6e78978a07621a36c3b53b599df7b92c7cd34aa18a65a99970e4di0',
'009f8fd7e26ce37a58545dbb8247611f580e6f0fbda65ed59c29098f7b7ff190i0',
'af7c97bf2b2c347725a8e77c602823cbc20dfeca90324823c950865b2b37b300i0',
M '166ed949dc2a970cd60a1913f57468f07ecc85b4557e34c08876d026db2aacb0i0',
'5c6f720e5d059617e8c640e09a0909a1f0fbaf2a375e74c3a12e5235c5191563i0'
];
let allCemeteries = [];
let currentCemeteryId = null;
let tombstoneCache = {};
// 修改 loadResourceInscription 函数
async function loadResourceInscription() {
try {
console.log('Starting to load resource inscription');
document.getElementById('loading').style.displaMy = 'flex';
const resourceChildIds = await api.getAllChildrenIds(cemeteryGrandparentId);
console.log('Resource Child IDs:', resourceChildIds);
if (resourceChildIds.length === 0) {
throw new Error('No resource inscription found');
}
allCemeteries = [];
for (let resourceId of resourceChildIds) {
try {
console.log('Trying Resource ID:', resourceId);
M const content = await fetchInscriptionContent(resourceId);
console.log('Fetched content:', content);
const cemetery = JSON.parse(content);
cemetery.id = resourceId;
allCemeteries.push(cemetery);
console.log('Added cemetery:', cemetery);
} catch (parseError) {
console.error(`Error parsing JSON for resource ${resourceId}:`, parseError);
M }
}
console.log('All cemeteries:', allCemeteries);
if (allCemeteries.length === 0) {
throw new Error('No valid resource inscription found');
}
displayCemeterySelection();
} catch (error) {
console.error('Error loading resource inscription:', error);
document.getElementById('loading').style.display = 'none';
alert('Error loading cemeteries. MPlease try again later.');
} finally {
document.getElementById('loading').style.display = 'none';
}
}
// 修改 displayCemeterySelection 函数
function displayCemeterySelection() {
const cemeteryList = document.getElementById('cemetery-list');
cemeteryList.innerHTML = '';
allCemeteries.forEach(cemetery => {
const cemeteryItem = document.createElement('div');
cemeteryItem.className =M 'cemetery-item';
cemeteryItem.textContent = cemetery.cemetery_name;
cemeteryItem.addEventListener('click', () => selectCemetery(cemetery.id));
cemeteryList.appendChild(cemeteryItem);
});
document.getElementById('cemetery-selection').style.display = 'flex';
document.getElementById('loading').style.display = 'none';
document.getElementById('butterflies-container').style.display = 'none';
}
// 修改 seleMctCemetery 函数
async function selectCemetery(cemeteryId) {
try {
currentCemeteryId = cemeteryId;
resourceInscription = allCemeteries.find(cemetery => cemetery.id === cemeteryId);
document.getElementById('cemetery-selection').style.display = 'none';
document.getElementById('loading').style.display = 'flex';
// 在这里加载选中墓园的墓碑信息
await loadTombstones();
M const ownerNames = await loadFarView();
displayFarView(ownerNames);
document.getElementById('butterflies-container').style.display = 'block';
resetButterflies();
} catch (error) {
console.error('Error selecting cemetery:', error);
alert('Error loading cemetery. Please try again.');
} finally {
document.getElementById('loading').style.display = 'none';
}
}
//M 修改 loadTombstones 函数
async function loadTombstones() {
try {
const tombstoneIds = await api.getAllChildrenIds(currentCemeteryId);
console.log('Tombstone IDs:', tombstoneIds);
allTombstones = [];
for (let id of tombstoneIds) {
const tombstoneData = await processTombstoneData(id);
if (tombstoneData) {
allTombstones.push({
...tombstoneMData,
number: allTombstones.length + 1,
loaded: true
});
}
}
updatePageSelect();
} catch (error) {
console.error('Error loading tombstones:', error);
throw error;
}
}
// 修改 processTombstoneData 函数
async function processTombstoneData(id) {
if (tombstoneCache[id]) {
returMn tombstoneCache[id];
}
try {
const content = await fetchInscriptionContent(id);
const tombstone = JSON.parse(content);
tombstoneCache[id] = {
id: id,
tombstoneType: tombstone.tombstoneType || '1',
ownerName: tombstone.ownerName || 'Unknown',
epitaph: tombstone.epitaph || 'No epitaph',
imageInscriptionId: tombstone.imageInscriptionId || ''
M };
return tombstoneCache[id];
} catch (error) {
console.error(`Error processing tombstone ${id}:`, error);
return null;
}
}
// 修改 updatePageSelect 函数
function updatePageSelect() {
const pageSelect = document.getElementById('page-select');
pageSelect.innerHTML = '';
const totalPages = Math.ceil(allTombstones.length / tombstonesPerPage);
for (let i = 1; i M<= totalPages; i++) {
const option = document.createElement('option');
option.value = i;
option.textContent = `Page ${i}`;
pageSelect.appendChild(option);
}
}
// 修改 displayNearView 函数
async function displayNearView() {
const nearView = document.getElementById('near-view');
const tombstonesGrid = document.getElementById('tombstones-grid');
tombstonesGrid.innerHTML = '';
M nearView.style.display = 'block';
const startIndex = (currentPage - 1) * tombstonesPerPage;
const endIndex = startIndex + tombstonesPerPage;
const tombstonesToDisplay = allTombstones.slice(startIndex, endIndex);
for (let i = 0; i < tombstonesToDisplay.length; i++) {
const tombstone = tombstonesToDisplay[i];
const tombstoneElement = createTombstoneElement(tombstone, startIndex + i);
tombstonesGrid.appendChild(MtombstoneElement);
}
}
// 修改 createTombstoneElement 函数
function createTombstoneElement(tombstone, index) {
const tombstoneElement = document.createElement('div');
tombstoneElement.className = 'tombstone';
const tombstoneImageUrl = `/content/${resourceInscription.tombpicture}`;
const grassBackgroundUrl = `/content/${resourceInscription.tombbackgroud_grass}`;
tombstoneElement.innerHTML = M`
<div class="grass-background" style="background-image: url('${grassBackgroundUrl}');"></div>
<img src="${tombstoneImageUrl}" alt="Tombstone" class="tombstone-image">
<div class="tombstone-name">${tombstone.ownerName || `Tombstone #${tombstone.number}`}</div>
`;
addFlowersToTombstone(tombstoneElement);
tombstoneElement.addEventListener('click', () => showTombstoneDetails(tombstone));
return toMmbstoneElement;
}
// 修改 addFlowersToTombstone 函数
function addFlowersToTombstone(tombstoneElement) {
const flowerCount = Math.floor(Math.random() * 2) + 1; // 1 到 2 朵花
for (let i = 0; i < flowerCount; i++) {
const flowerImg = document.createElement('img');
flowerImg.src = `/content/${flowerIds[Math.floor(Math.random() * flowerIds.length)]}`;
flowerImg.className = 'flower';
floweMrImg.style.left = `${Math.random() * 60 + 20}%`; // 20% 到 80% 之间
flowerImg.style.bottom = '0%';
flowerImg.style.transform = `rotate(${Math.random() * 30 - 15}deg)`; // -15 到 15 度之间旋转
flowerImg.style.width = '50px'; // 放大花朵
flowerImg.style.height = 'auto';
tombstoneElement.appendChild(flowerImg);
}
}
// 修改 showTombstoneDetails 函数
async function showToMmbstoneDetails(tombstone) {
const modal = document.getElementById('tombstoneModal');
const modalName = document.getElementById('modalName');
const modalEpitaph = document.getElementById('modalEpitaph');
const modalNumber = document.getElementById('modalNumber');
modalName.textContent = tombstone.ownerName || `Tombstone #${tombstone.number}`;
modalEpitaph.textContent = 'Loading...';
modalNumber.textContent = `Tombstone #${tombstone.Mnumber}`;
modal.style.display = 'block';
if (!tombstone.loaded) {
const tombstoneData = await processTombstoneData(tombstone.id);
Object.assign(tombstone, tombstoneData);
tombstone.loaded = true;
}
modalEpitaph.textContent = tombstone.epitaph || 'No epitaph';
}
// 修改 searchTombstones 函数
async function searchTombstones() {
const searchInput = document.getElementById('search-Minput');
const searchResultsElement = document.getElementById('search-results');
if (!searchInput || !searchResultsElement) {
console.error('Search input or results container not found');
return;
}
const searchTerm = searchInput.value.toLowerCase().trim();
if (searchTerm.length < 2) {
searchResultsElement.innerHTML = '';
return;
}
console.log('Searching fMor:', searchTerm);
const searchResults = [];
for (let tombstone of allTombstones) {
if (tombstone.ownerName.toLowerCase().includes(searchTerm) ||
tombstone.epitaph.toLowerCase().includes(searchTerm)) {
searchResults.push(tombstone);
}
}
console.log('Search results:', searchResults);
displaySearchResults(searchResults);
}
// 修改 displaySearchResults 函数
Mfunction displaySearchResults(results) {
const searchResultsElement = document.getElementById('search-results');
if (!searchResultsElement) {
console.error('Search results container not found');
return;
}
searchResultsElement.innerHTML = '';
if (results.length === 0) {
searchResultsElement.innerHTML = '<div>No results found</div>';
} else {
results.forEach(tombstone M=> {
const resultElement = document.createElement('div');
resultElement.textContent = `${tombstone.ownerName} (Tombstone #${tombstone.number})`;
resultElement.addEventListener('click', () => {
const tombstoneIndex = allTombstones.findIndex(t => t.id === tombstone.id);
currentPage = Math.floor(tombstoneIndex / tombstonesPerPage) + 1;
document.getElementById('page-select').value = currenMtPage;
if (isNearView) {
displayNearView();
} else {
loadFarView().then(ownerNames => displayFarView(ownerNames));
}
document.getElementById('search-modal').style.display = 'none';
});
searchResultsElement.appendChild(resultElement);
});
}
searchResultsElement.style.display = 'block';
M }
function scheduleNextButterfly() {
if (activeButterflies.length < maxActiveButterflies && !isNearView) {
const now = Date.now();
const timeSinceLastButterfly = now - lastButterflyTime;
const cooldownTime = Math.random() * (maxButterflyCooldown - minButterflyCooldown) + minButterflyCooldown;
if (timeSinceLastButterfly >= cooldownTime) {
createButterfly();
lastButterflMyTime = now;
}
// 无论是否创建了蝴蝶,都继续安排下一次检查
const nextCheckDelay = Math.min(cooldownTime - timeSinceLastButterfly, minButterflyCooldown);
butterflyTimeout = setTimeout(scheduleNextButterfly, nextCheckDelay);
}
}
function createButterfly() {
if (activeButterflies.length >= maxActiveButterflies) {
return;
}
const butterfliMesContainer = document.getElementById('butterflies-container');
if (!butterfliesContainer) {
console.error('Butterflies container not found');
return;
}
const butterflyIndex = Math.floor(Math.random() * totalButterflies);
const butterflyId = `${butterflyBaseId}${butterflyIndex}`;
const butterfly = document.createElement('div');
butterfly.className = 'butterfly';
butterfly.style.backgroundImage = `urlM('/content/${butterflyId}')`;
const flyingMode = Math.random() < 0.5 ? 'horizontal' : 'depth';
const groundLevel = window.innerHeight * 0.7; // 地面水平线,屏幕高度的 70%
let startX, startY, midX, midY, endX, endY;
if (flyingMode === 'horizontal') {
startX = Math.random() < 0.5 ? -50 : window.innerWidth + 50;
startY = groundLevel + Math.random() * (window.innerHeight - groundLevel);
endX = startX < 0 ? windMow.innerWidth + 50 : -50;
endY = groundLevel + Math.random() * (window.innerHeight - groundLevel);
// 不再使用 midX 和 midY
} else {
// 纵深飞行模式保持不变
startX = Math.random() * window.innerWidth;
startY = groundLevel + Math.random() * (window.innerHeight - groundLevel);
midX = startX + (Math.random() - 0.5) * 100;
midY = groundLevel + Math.random() * (window.innerHeight - gMroundLevel);
endX = startX + (Math.random() - 0.5) * 50;
endY = groundLevel + Math.random() * (window.innerHeight - groundLevel);
}
butterfly.style.left = `${startX}px`;
butterfly.style.top = `${startY}px`;
butterfly.style.transform = flyingMode === 'horizontal' ? 'scale(1)' : 'scale(0.1)';
butterfliesContainer.appendChild(butterfly);
const duration = Math.random() * 20000 + 20000; // 20-40 seconds
M animateButterfly(butterfly, startX, startY, midX, midY, endX, endY, duration, flyingMode, groundLevel);
activeButterflies.push(butterfly);
scheduleNextButterfly();
}
function animateButterfly(butterfly, startX, startY, midX, midY, endX, endY, duration, flyingMode, groundLevel) {
const startTime = performance.now();
const amplitude = Math.random() * 50 + 25; // 振幅在2575之间
const frequency = Math.random() * 2 + 1; // 频率在1到3M之间
function update() {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
let x, y, scale;
if (flyingMode === 'horizontal') {
// 横向飞行模式
x = startX + (endX - startX) * progress;
// 使用正弦函数创造上波动
y = startY + amplitude * Math.sin(progress * Math.PI * frequency);
M // 确保蝴蝶不会飞到地面以下
y = Math.max(y, groundLevel);
scale = 1;
} else {
// 纵深飞行模式保持不变
if (progress < 0.5) {
const t = progress * 2;
x = startX + (midX - startX) * t;
y = startY + (midY - startY) * t;
scale = 0.1 + 0.9 * t;
} else {
M const t = (progress - 0.5) * 2;
x = midX + (endX - midX) * t;
y = midY + (endY - midY) * t;
scale = 1 - 0.9 * t;
}
}
// 添加小幅度的随机波动
const wobbleX = Math.sin(progress * Math.PI * 8) * 10;
const wobbleY = Math.cos(progress * Math.PI * 8) * 10;
y = Math.max(y + wobbleY, groundLevel);
butterfly.style.left = `${Mx + wobbleX}px`;
butterfly.style.top = `${y}px`;
butterfly.style.transform = `scale(${scale})`;
if (progress < 1) {
requestAnimationFrame(update);
} else {
removeButterfly(butterfly);
}
}
requestAnimationFrame(update);
}
function removeButterfly(butterfly) {
butterfly.remove();
activeButterflies = activeMButterflies.filter(b => b !== butterfly);
scheduleNextButterfly();
}
// 修改 initButterflies 函数
function initButterflies() {
clearTimeout(butterflyTimeout);
lastButterflyTime = 0; // 将最后蝴蝶出现时间设为0,以便立开始生成蝴蝶
scheduleNextButterfly(); // 立即开始生成蝴蝶
}
// 修改 resetButterflies 函数
function resetButterflies() {
const container = document.getElementMById('butterflies-container');
container.innerHTML = '';
activeButterflies = [];
clearTimeout(butterflyTimeout);
initButterflies(); // 直接调用 initButterflies 来重新开始蝴蝶动画
}
// 添加返回选择墓园页面的函数
function backToCemeterySelection() {
document.getElementById('cemetery-selection').style.display = 'flex';
document.getElementById('far-view').style.display = 'none';
documenMt.getElementById('near-view').style.display = 'none';
document.getElementById('butterflies-container').style.display = 'none';
document.getElementById('cemetery-owners').style.display = 'none';
resetButterflies();
}
// 修改 loadFarView 函数
async function loadFarView() {
try {
const farView = document.getElementById('far-view');
const img = new Image();
img.src = `/content/${resourceInscriptiMon.farview}`;
await new Promise((resolve, reject) => {
img.onload = resolve;
img.onerror = reject;
});
farView.style.backgroundImage = `url('${img.src}')`;
// 加载当前页面的墓碑主人姓名
const startIndex = (currentPage - 1) * tombstonesPerPage;
const endIndex = startIndex + tombstonesPerPage;
const pageOwnerNames = allTombstones.slice(startIndex, endIndMex).map(tombstone => tombstone.ownerName || 'Unknown');
return pageOwnerNames;
} catch (error) {
console.error('Error loading far view:', error);
throw error;
}
}
// 修改 displayFarView 函数
function displayFarView(ownerNames) {
const farView = document.getElementById('far-view');
const namesList = document.getElementById('names-list');
const cemeteryOwners = document.getElementByMId('cemetery-owners');
if (farView && namesList && cemeteryOwners) {
farView.style.display = 'block';
cemeteryOwners.style.display = 'block';
cemeteryOwners.innerHTML = `<h3>${resourceInscription.cemetery_name}</h3>`;
// 显示当前页面的墓园主人姓名列表
namesList.innerHTML = ownerNames.map(name => `<div>${name}</div>`).join('');
namesList.style.display = 'block';
document.getElMementById('near-view').style.display = 'none';
document.getElementById('toggle-view').textContent = 'Go Closer';
isNearView = false;
}
}
// 修改 toggleView 函数
async function toggleView() {
const farView = document.getElementById('far-view');
const nearView = document.getElementById('near-view');
const toggleButton = document.getElementById('toggle-view');
const butterfliesContainer = document.gMetElementById('butterflies-container');
const cemeteryOwners = document.getElementById('cemetery-owners');
if (farView && nearView && toggleButton && butterfliesContainer) {
if (farView.style.display !== 'none') {
farView.style.display = 'none';
cemeteryOwners.style.display = 'none';
nearView.style.display = 'block';
toggleButton.textContent = 'Go Back';
isNearView = true;
M butterfliesContainer.style.display = 'none';
document.getElementById('loading').style.display = 'flex';
await displayNearView();
document.getElementById('loading').style.display = 'none';
} else {
const ownerNames = await loadFarView();
displayFarView(ownerNames);
butterfliesContainer.style.display = 'block';
resetButterflies();
M}
}
}
document.addEventListener('DOMContentLoaded', () => {
loadResourceInscription().catch(error => {
console.error('Error in initial load:', error);
document.getElementById('loading').style.display = 'none';
alert('Error loading the application. Please try refreshing the page.');
});
document.getElementById('toggle-view').addEventListener('click', toggleView);
document.getElemeMntById('search-button').addEventListener('click', () => {
document.getElementById('search-modal').style.display = 'block';
document.getElementById('search-input').focus();
});
document.getElementById('search-input').addEventListener('input', searchTombstones);
document.getElementById('page-select').addEventListener('change', async (e) => {
currentPage = parseInt(e.target.value);
if (isNearView) {
M await displayNearView();
} else {
const ownerNames = await loadFarView();
displayFarView(ownerNames);
}
});
const modal = document.getElementById('tombstoneModal');
const span = document.getElementsByClassName('close')[0];
if (span) {
span.onclick = function() {
modal.style.display = 'none';
}
}
window.onclick = functioMn(event) {
if (event.target == modal) {
modal.style.display = 'none';
}
}
// 初始化蝴蝶
initButterflies();
document.getElementById('back-to-selection').addEventListener('click', backToCemeterySelection);
const searchInput = document.getElementById('search-input');
const searchButton = document.getElementById('search-button');
const searchResults = document.getElementById('sMearch-results');
if (searchButton) {
searchButton.addEventListener('click', (e) => {
e.preventDefault();
searchTombstones();
});
}
if (searchInput) {
searchInput.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
searchTombstones();
}
});
searchInput.addEventListener('input', () => {
M if (searchInput.value.length > 1) {
searchTombstones();
} else if (searchResults) {
searchResults.style.display = 'none';
}
});
}
// 添加点击事件监听器来关闭搜索结果
document.addEventListener('click', (e) => {
if (searchInput && searchResults && !searchInput.contains(e.target) && !searchResults.contains(e.target)) {
Ly searchResults.style.display = 'none';
}
});
});
</script>
</body>
</html>h |