modified: app.py
modified: templates/base.html.j2 modified: templates/daily_puzzle.html.j2
This commit is contained in:
parent
e13b5ef5fa
commit
bea0de1ecc
3 changed files with 80 additions and 41 deletions
10
app.py
10
app.py
|
|
@ -708,8 +708,6 @@ def daily_puzzle_view(request):
|
|||
user_id = user.id if user else None
|
||||
display_name = user.username if (user and user.username) else guest_name
|
||||
|
||||
s = request.dbsession
|
||||
|
||||
# Check if user has already solved this puzzle
|
||||
existing_solve = (
|
||||
s.query(Attempt)
|
||||
|
|
@ -788,19 +786,17 @@ def daily_puzzle_view(request):
|
|||
user_rank = idx + 1
|
||||
break
|
||||
|
||||
# Generate URLs for images
|
||||
puzzle_image_url = request.route_url("puzzle_image", puzzle_id=puzzle.id)
|
||||
|
||||
|
||||
return {
|
||||
"request": request,
|
||||
"puzzle": puzzle,
|
||||
"attempt_state_json": attempt.state_json, # Now includes UUIDs
|
||||
"attempt_state": json.loads(attempt.state_json),
|
||||
"attempt_state_json": attempt.state_json,
|
||||
"move_count": attempt.move_count,
|
||||
"rotation_count": attempt.rotation_count,
|
||||
"attempt_is_solved": attempt.is_solved or existing_solve is not None,
|
||||
"puzzle_filename": puzzle_filename,
|
||||
"user_rank": user_rank,
|
||||
"puzzle_image_url": puzzle_image_url,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>{% block title %}My Puzzle Game{% endblock %}</title>
|
||||
<link href="https://unpkg.com/@picocss/pico@1.*/css/pico.min.css" rel="stylesheet">
|
||||
<!-- <link href="https://unpkg.com/@picocss/pico@1.*/css/pico.min.css" rel="stylesheet"> -->
|
||||
<style>
|
||||
/* Custom styles */
|
||||
body { margin: 0; padding: 0; }
|
||||
|
|
|
|||
|
|
@ -2,16 +2,19 @@
|
|||
|
||||
{% block content %}
|
||||
{% if puzzle %}
|
||||
<h1>{{ puzzle.title }}</h1>
|
||||
<p>Date: {{ puzzle.date }}</p>
|
||||
<p>
|
||||
Moves: <span id="moveCount">{{ move_count }}</span><br>
|
||||
Rotations: <span id="rotationCount">{{ rotation_count }}</span><br>
|
||||
</p>
|
||||
<div id="puzzle-page">
|
||||
<div id="puzzle-stats">
|
||||
<h1>{{ puzzle.title }}</h1>
|
||||
<p>Date: {{ puzzle.date }}</p>
|
||||
<p>
|
||||
Moves: <span id="moveCount">{{ move_count }}</span><br>
|
||||
Rotations: <span id="rotationCount">{{ rotation_count }}</span><br>
|
||||
</p>
|
||||
<button id="downloadButton" style="display:none;">Download Image</button>
|
||||
</div>
|
||||
<div id="puzzle-container"></div>
|
||||
</div>
|
||||
|
||||
<div id="puzzle-container"></div>
|
||||
|
||||
<button id="downloadButton" style="display:none;">Download Image</button>
|
||||
|
||||
<!-- Win Modal -->
|
||||
<div id="winModal" class="modal">
|
||||
|
|
@ -30,29 +33,67 @@
|
|||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
/* Puzzle page layout */
|
||||
#puzzle-page {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-gap: 20px;
|
||||
max-width: 960;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
#puzzle-page {
|
||||
grid-template-columns: 1fr 2fr; /* Two columns */
|
||||
align-items: start;
|
||||
}
|
||||
}
|
||||
|
||||
/* Puzzle stats styles */
|
||||
#puzzle-stats {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
#puzzle-stats {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
/* Puzzle container styles */
|
||||
#puzzle-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
padding-bottom: 100%; /* Maintain square aspect ratio */
|
||||
max-width: 640px;
|
||||
min-width: 300px;
|
||||
aspect-ratio: 1 / 1; /* Maintain square aspect ratio */
|
||||
border: 1px solid #ccc;
|
||||
background-color: #eee;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Puzzle piece styles */
|
||||
.puzzle-piece {
|
||||
position: absolute;
|
||||
background-image: url('{{ puzzle_image_url }}');
|
||||
background-size: {{ puzzle.size * 100 }}%;
|
||||
background-image: url('data:image/png;base64,{{ puzzle.image_b64 }}');
|
||||
background-size: {{ puzzle.size * 100 }}% {{ puzzle.size * 100 }}%;
|
||||
background-repeat: no-repeat;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.puzzle-piece.selected {
|
||||
outline: 2px solid red;
|
||||
/* Confetti styles */
|
||||
.confetti {
|
||||
position: fixed;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
top: 0;
|
||||
animation: confetti-fall 3s linear infinite;
|
||||
}
|
||||
|
||||
/* Modal styles */
|
||||
.modal {
|
||||
display: none; /* Hidden by default */
|
||||
position: fixed;
|
||||
|
|
@ -88,24 +129,18 @@
|
|||
color: black;
|
||||
}
|
||||
|
||||
.confetti {
|
||||
position: fixed;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
top: 0;
|
||||
animation: confetti-fall 3s linear infinite;
|
||||
}
|
||||
|
||||
/* Confetti animation */
|
||||
@keyframes confetti-fall {
|
||||
0% {transform: translateY(0);}
|
||||
100% {transform: translateY(100vh);}
|
||||
0% { transform: translateY(0); }
|
||||
100% { transform: translateY(100vh); }
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script>
|
||||
// Ensure the script runs after the DOM is fully loaded
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
let pieces = {{ attempt_state_json | safe }};
|
||||
let pieces = {{ attempt_state | tojson }};
|
||||
const gridSize = {{ puzzle.size }};
|
||||
let isSolved = {{ 'true' if attempt_is_solved else 'false' }};
|
||||
let moveCount = {{ move_count }};
|
||||
|
|
@ -129,6 +164,9 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
function initBoard() {
|
||||
puzzleContainer.innerHTML = '';
|
||||
|
||||
// Calculate the size of each piece in percentage
|
||||
const pieceSizePercent = 100 / gridSize;
|
||||
|
||||
// Build the board
|
||||
pieces.forEach(piece => {
|
||||
const pieceElement = document.createElement("div");
|
||||
|
|
@ -137,11 +175,11 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
pieceElement.dataset.currentIndex = piece.currentIndex;
|
||||
pieceElement.dataset.rotation = piece.rotation;
|
||||
|
||||
// Set size and position
|
||||
const pieceSizePercent = 100 / gridSize;
|
||||
// Set size of the piece
|
||||
pieceElement.style.width = `${pieceSizePercent}%`;
|
||||
pieceElement.style.height = `${pieceSizePercent}%`;
|
||||
|
||||
// Position the piece
|
||||
const currentRow = Math.floor(piece.currentIndex / gridSize);
|
||||
const currentCol = piece.currentIndex % gridSize;
|
||||
pieceElement.style.left = `${currentCol * pieceSizePercent}%`;
|
||||
|
|
@ -150,7 +188,12 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
// Set background position
|
||||
const correctRow = Math.floor(piece.correctIndex / gridSize);
|
||||
const correctCol = piece.correctIndex % gridSize;
|
||||
pieceElement.style.backgroundPosition = `${-correctCol * pieceSizePercent}% ${-correctRow * pieceSizePercent}%`;
|
||||
const backgroundPositionX = (correctCol / (gridSize - 1)) * 100;
|
||||
const backgroundPositionY = (correctRow / (gridSize - 1)) * 100;
|
||||
pieceElement.style.backgroundPosition = `${backgroundPositionX}% ${backgroundPositionY}%`;
|
||||
|
||||
// Set background size
|
||||
pieceElement.style.backgroundSize = `${gridSize * 100}% ${gridSize * 100}%`;
|
||||
|
||||
// Set rotation
|
||||
pieceElement.style.transform = `rotate(${piece.rotation}deg)`;
|
||||
|
|
@ -275,7 +318,7 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
pieces.forEach(piece => {
|
||||
piece.draggable = false;
|
||||
piece.removeEventListener("click", rotatePiece);
|
||||
// Optionally, reset rotation and position
|
||||
// Reset rotation for solved puzzle display
|
||||
piece.style.transform = 'rotate(0deg)';
|
||||
});
|
||||
downloadButton.style.display = "block";
|
||||
|
|
@ -320,8 +363,8 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
// Download button functionality
|
||||
function downloadImage() {
|
||||
const link = document.createElement('a');
|
||||
link.href = "{{ puzzle_image_url }}";
|
||||
link.download = "{{ puzzle_filename }}";
|
||||
link.href = 'data:image/png;base64,{{ puzzle.image_b64 }}';
|
||||
link.download = "{{ puzzle.filename }}";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue