mirror of
https://github.com/bszczuka/steel-training.git
synced 2025-12-21 13:23:02 +01:00
Add shootoff and ipsc el presidente drills
This commit is contained in:
195
app.py
195
app.py
@@ -6,6 +6,14 @@ import io
|
|||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
SHOOTOFF_DISTANCE = 1200
|
||||||
|
SHOOTOFF_GAP = 100
|
||||||
|
IPSC_DISTANCE = 914
|
||||||
|
IPSC_GAP = 92
|
||||||
|
IPSC_TARGET_WIDTH = 46
|
||||||
|
IPSC_TARGET_HEIGHT = 58
|
||||||
|
IPSC_STAGE_WIDTH = 322
|
||||||
|
|
||||||
VALUES = {
|
VALUES = {
|
||||||
"five_to_go": {
|
"five_to_go": {
|
||||||
"t1": {"len_a": 3100, "len_h": 9100, 'width': 250, 'height': 250, 'elevation': 0, 'stop_plate': False,
|
"t1": {"len_a": 3100, "len_h": 9100, 'width': 250, 'height': 250, 'elevation': 0, 'stop_plate': False,
|
||||||
@@ -109,6 +117,135 @@ VALUES = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
return render_template('sc.html', current_url=request.path)
|
||||||
|
|
||||||
|
@app.route('/shootoff')
|
||||||
|
def shootoff():
|
||||||
|
return render_template('shootoff.html', current_url=request.path)
|
||||||
|
|
||||||
|
@app.route('/ipsc')
|
||||||
|
def ipsc():
|
||||||
|
return render_template('ipsc.html', current_url=request.path)
|
||||||
|
|
||||||
|
@app.route('/generate-pdf', methods=['POST'])
|
||||||
|
def generate_pdf():
|
||||||
|
distance = int(request.form.get('distance', 1) or 1)
|
||||||
|
distance_in_mm = distance * 10
|
||||||
|
stage = request.form.get('stage')
|
||||||
|
size = request.form.get('size')
|
||||||
|
distance_type = request.form.get('distance_type')
|
||||||
|
if distance_type == 'wall':
|
||||||
|
distance_in_mm = calculate_distance(distance_in_mm, stage, size)
|
||||||
|
|
||||||
|
targets = [f't{i}' for i in range(1, 6)]
|
||||||
|
target_info = [_target_info(distance_in_mm, stage, size, target) for target in targets]
|
||||||
|
wall_extra_space_for_paper = 297 if size == 'a3' else 210
|
||||||
|
wall_length = target_info[-1]['position'] + wall_extra_space_for_paper
|
||||||
|
preview_size = 267 if size == 'a3' else 190
|
||||||
|
preview_scale = preview_size / target_info[-1]['position']
|
||||||
|
preview_distance = distance_in_mm * preview_scale
|
||||||
|
preview_target_info = [_target_info(preview_distance, stage, size, target) for target in targets]
|
||||||
|
box_position = int(target_info[0]['sim_a_len']) / 10
|
||||||
|
|
||||||
|
rendered_html = render_template(
|
||||||
|
'pdf_template.html',
|
||||||
|
distance=distance_in_mm/10,
|
||||||
|
size=size,
|
||||||
|
stage=stage,
|
||||||
|
target_info=target_info,
|
||||||
|
preview_target_info=preview_target_info,
|
||||||
|
wall_length=wall_length,
|
||||||
|
box_position=box_position,
|
||||||
|
)
|
||||||
|
#return rendered_html
|
||||||
|
|
||||||
|
pdf_file = io.BytesIO()
|
||||||
|
HTML(string=rendered_html).write_pdf(pdf_file)
|
||||||
|
pdf_file.seek(0)
|
||||||
|
filename = 'Paper Challenge - ' + stage.replace('_', ' ') + ' - ' + str(distance) + 'cm-' + size + '.pdf'
|
||||||
|
|
||||||
|
return send_file(pdf_file, download_name=filename, as_attachment=False)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/generate-pdf-shootoff', methods=['POST'])
|
||||||
|
def generate_pdf_shootoff():
|
||||||
|
distance = int(request.form.get('distance', 1) or 1)
|
||||||
|
size = request.form.get('size')
|
||||||
|
distance_type = request.form.get('distance_type')
|
||||||
|
target_count = 6
|
||||||
|
if distance_type == 'wall':
|
||||||
|
desired_wall_length = distance
|
||||||
|
distance = calculate_distance_shootoff(desired_wall_length, size, target_count)
|
||||||
|
target_line = (target_count - 1) * SHOOTOFF_GAP
|
||||||
|
scale = distance / SHOOTOFF_DISTANCE
|
||||||
|
wall_extra_space_for_paper = 29.7 if size == 'a3' else 21.0
|
||||||
|
wall_length = target_line * scale + wall_extra_space_for_paper
|
||||||
|
preview_size = 25.7 if size == 'a3' else 18
|
||||||
|
preview_scale = preview_size /target_line
|
||||||
|
box_position = wall_length / 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rendered_html = render_template(
|
||||||
|
'pdf_template_shootoff.html',
|
||||||
|
distance=distance,
|
||||||
|
size=size,
|
||||||
|
wall_length=wall_length,
|
||||||
|
gap=SHOOTOFF_GAP*scale,
|
||||||
|
target_count=target_count,
|
||||||
|
scale=scale,
|
||||||
|
preview_scale=preview_scale,
|
||||||
|
box_position=box_position
|
||||||
|
)
|
||||||
|
#return rendered_html
|
||||||
|
|
||||||
|
pdf_file = io.BytesIO()
|
||||||
|
HTML(string=rendered_html).write_pdf(pdf_file)
|
||||||
|
pdf_file.seek(0)
|
||||||
|
filename = 'Paper Challenge - Shootoff - ' + str(distance) + 'cm-' + size + '.pdf'
|
||||||
|
|
||||||
|
return send_file(pdf_file, download_name=filename, as_attachment=False)
|
||||||
|
|
||||||
|
@app.route('/generate-pdf-ipsc', methods=['POST'])
|
||||||
|
def generate_pdf_ipsc():
|
||||||
|
distance = int(request.form.get('distance', 1) or 1)
|
||||||
|
size = request.form.get('size')
|
||||||
|
distance_type = request.form.get('distance_type')
|
||||||
|
scale = distance / IPSC_DISTANCE
|
||||||
|
wall_extra_space_for_paper = 29.7 if size == 'a3' else 21.0
|
||||||
|
if distance_type == 'wall':
|
||||||
|
scale = (distance - wall_extra_space_for_paper) / IPSC_STAGE_WIDTH
|
||||||
|
distance = scale * IPSC_DISTANCE
|
||||||
|
target_line = scale * IPSC_STAGE_WIDTH + wall_extra_space_for_paper
|
||||||
|
preview_size = 15 if size == 'a3' else 10
|
||||||
|
preview_scale = preview_size /target_line
|
||||||
|
box_position = target_line / 2
|
||||||
|
|
||||||
|
rendered_html = render_template(
|
||||||
|
'pdf_template_ipsc.html',
|
||||||
|
distance=distance,
|
||||||
|
size=size,
|
||||||
|
wall_length=target_line,
|
||||||
|
target_height=scale * IPSC_TARGET_HEIGHT,
|
||||||
|
target_width=scale * IPSC_TARGET_WIDTH,
|
||||||
|
gap=scale * IPSC_GAP + scale * IPSC_TARGET_WIDTH,
|
||||||
|
preview_margin=(wall_extra_space_for_paper - preview_size) / 2,
|
||||||
|
scale=scale,
|
||||||
|
preview_scale=preview_scale,
|
||||||
|
box_position=box_position
|
||||||
|
)
|
||||||
|
# return rendered_html
|
||||||
|
|
||||||
|
pdf_file = io.BytesIO()
|
||||||
|
HTML(string=rendered_html).write_pdf(pdf_file)
|
||||||
|
pdf_file.seek(0)
|
||||||
|
filename = 'Paper Challenge - IPSC - EL Presidente - ' + str(distance) + 'cm-' + size + '.pdf'
|
||||||
|
|
||||||
|
return send_file(pdf_file, download_name=filename, as_attachment=False)
|
||||||
|
|
||||||
|
|
||||||
def calculate_distance(desired_wall_length, stage, size):
|
def calculate_distance(desired_wall_length, stage, size):
|
||||||
wall_extra_space_for_paper = 297 if size == 'a3' else 210
|
wall_extra_space_for_paper = 297 if size == 'a3' else 210
|
||||||
|
|
||||||
@@ -175,50 +312,30 @@ def _target_info(distance, stage, size, target):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
|
||||||
def index():
|
|
||||||
return render_template('index.html')
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/generate-pdf', methods=['POST'])
|
|
||||||
def generate_pdf():
|
|
||||||
distance = int(request.form.get('distance', 1) or 1)
|
|
||||||
distance_in_mm = distance * 10
|
|
||||||
stage = request.form.get('stage')
|
|
||||||
size = request.form.get('size')
|
|
||||||
distance_type = request.form.get('distance_type')
|
|
||||||
if distance_type == 'wall':
|
|
||||||
distance_in_mm = calculate_distance(distance_in_mm, stage, size)
|
|
||||||
|
|
||||||
targets = [f't{i}' for i in range(1, 6)]
|
def calculate_distance_shootoff(desired_wall_length, size, target_count):
|
||||||
target_info = [_target_info(distance_in_mm, stage, size, target) for target in targets]
|
wall_extra_space_for_paper = 29.7 if size == 'a3' else 21.0
|
||||||
wall_extra_space_for_paper = 297 if size == 'a3' else 210
|
distance = 1
|
||||||
wall_length = target_info[-1]['position'] + wall_extra_space_for_paper
|
step = 100
|
||||||
preview_size = 267 if size == 'a3' else 190
|
|
||||||
preview_scale = preview_size / target_info[-1]['position']
|
|
||||||
preview_distance = distance_in_mm * preview_scale
|
|
||||||
preview_target_info = [_target_info(preview_distance, stage, size, target) for target in targets]
|
|
||||||
box_position = int(target_info[0]['sim_a_len']) / 10
|
|
||||||
|
|
||||||
rendered_html = render_template(
|
while True:
|
||||||
'pdf_template.html',
|
target_line = (target_count - 1) * SHOOTOFF_GAP
|
||||||
distance=distance_in_mm/10,
|
scale = distance / SHOOTOFF_DISTANCE
|
||||||
size=size,
|
wall_length = target_line * scale + wall_extra_space_for_paper
|
||||||
stage=stage,
|
print(distance, wall_length, desired_wall_length)
|
||||||
target_info=target_info,
|
if abs(wall_length - desired_wall_length) <= 0.5:
|
||||||
preview_target_info=preview_target_info,
|
break
|
||||||
wall_length=wall_length,
|
if wall_length > desired_wall_length:
|
||||||
box_position=box_position,
|
distance -= step
|
||||||
)
|
step = step / 10
|
||||||
#return rendered_html
|
continue
|
||||||
|
distance += step;
|
||||||
pdf_file = io.BytesIO()
|
if distance > 700:
|
||||||
HTML(string=rendered_html).write_pdf(pdf_file)
|
break
|
||||||
pdf_file.seek(0)
|
|
||||||
filename = 'Paper Challenge - ' + stage.replace('_', ' ') + ' - ' + str(distance) + 'cm-' + size + '.pdf'
|
|
||||||
|
|
||||||
return send_file(pdf_file, download_name=filename, as_attachment=False)
|
|
||||||
|
|
||||||
|
return distance
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|||||||
BIN
static/images/ipsc.png
Normal file
BIN
static/images/ipsc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
9
static/images/ipsc.svg
Normal file
9
static/images/ipsc.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 42 KiB |
BIN
static/images/ipsc_preview.png
Normal file
BIN
static/images/ipsc_preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
static/images/shootoff.png
Normal file
BIN
static/images/shootoff.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.1 KiB |
49
templates/base.html
Normal file
49
templates/base.html
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Paper Challenge</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,line-clamp,container-queries"></script>
|
||||||
|
<style>
|
||||||
|
/* Style the labels to act like buttons */
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 2px solid gray;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: border-color 0.2s, box-shadow 0.2s;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Highlight the selected label */
|
||||||
|
label:has(input[type="radio"]:checked) {
|
||||||
|
border-color: dodgerblue;
|
||||||
|
box-shadow: 0 0 10px #3b82f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-gray-100 font-sans">
|
||||||
|
<div class="max-w-4xl mx-auto p-6 bg-white shadow-md rounded-lg mt-10">
|
||||||
|
<h1 class="text-2xl font-bold mb-6 text-center text-gray-700">Paper Challenge</h1>
|
||||||
|
<h2 class="my-10 mx-auto text-center font-bold text-xl">Wygeneruj tor {% block title %}{% endblock %}</h2>
|
||||||
|
<div class="flex justify-center gap-6">
|
||||||
|
<a href="{{ url_for('index') }}"
|
||||||
|
class="{{ 'shadow-inner shadow-blue-900' if current_url == url_for('index') else '' }} bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition-colors">
|
||||||
|
Steel Challenge
|
||||||
|
</a>
|
||||||
|
<a href="{{ url_for('shootoff') }}"
|
||||||
|
class="{{ 'shadow-inner shadow-blue-900' if current_url == url_for('shootoff') else '' }} bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition-colors">
|
||||||
|
Shootoff
|
||||||
|
</a>
|
||||||
|
<a href="{{ url_for('ipsc') }}"
|
||||||
|
class="{{ 'shadow-inner shadow-blue-900' if current_url == url_for('ipsc') else '' }} bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition-colors">
|
||||||
|
IPSC - El Presidente
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Paper Challenge</title>
|
|
||||||
<script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,line-clamp,container-queries"></script>
|
|
||||||
<style>
|
|
||||||
/* Style the labels to act like buttons */
|
|
||||||
label {
|
|
||||||
display: block;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 2px solid gray;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: border-color 0.2s, box-shadow 0.2s;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Highlight the selected label */
|
|
||||||
input[type="radio"]:checked + label {
|
|
||||||
border-color: #3b82f6; /* Blue color */
|
|
||||||
box-shadow: 0 0 10px #3b82f6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add hover effect */
|
|
||||||
label:hover {
|
|
||||||
border-color: #3b82f6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Style the images */
|
|
||||||
label img {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Style the text below images */
|
|
||||||
label p {
|
|
||||||
margin-top: 8px;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #374151; /* Gray color */
|
|
||||||
}
|
|
||||||
|
|
||||||
#about {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.about-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#about:checked ~ .about-container {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body class="bg-gray-100 font-sans">
|
|
||||||
<div class="max-w-4xl mx-auto p-6 bg-white shadow-md rounded-lg mt-10">
|
|
||||||
<h1 class="text-2xl font-bold mb-6 text-center text-gray-700">Paper Challenge</h1>
|
|
||||||
<input type="checkbox" class="text-2xl font-bold mb-6 text-center text-gray-700" id="about"/>
|
|
||||||
<label class="mx-auto max-w-2xl" for="about">O projekcie</label>
|
|
||||||
<div class="about-container max-w-2xl mx-auto">
|
|
||||||
<p class="mt-4">Projekt powstał na potrzeby treningu Steel Challenge w domowym zaciszu</p>
|
|
||||||
<p class="mt-2">Ostrzeżenie: Od ponad 11 lat pracuję z PHP, więc mogą być widoczne naleciałości!<br/>Ten projekt
|
|
||||||
to moje pierwsze... no może drugie kroki w Pythonie. </p>
|
|
||||||
<p class="mt-2">Kopiowanie, rozpowszechnianie, modyfikowanie i udostępnianie na potrzeby własne, klubowe lub dla
|
|
||||||
kolegi, stanowczo zalecane</p>
|
|
||||||
</div>
|
|
||||||
<h2 class="my-10 mx-auto text-center font-bold text-xl">Wygeneruj tor</h2>
|
|
||||||
<form class="" action="/generate-pdf" method="post">
|
|
||||||
<div class="mb-6 max-w-2xl mx-auto mt-10">
|
|
||||||
<h2>Wybierz rodzaj kalkulacji ze względu na ograniczoną długość ściany lub ograniczoną odległość stanowiska od ściany</h2>
|
|
||||||
<div id="size" class="flex place-content-center">
|
|
||||||
<label for="floor"
|
|
||||||
class="cursor-pointer border-2 border-transparent rounded-lg overflow-hidden transition-all hover:border-blue-400">
|
|
||||||
<img src="{{ url_for('static', filename='images/floor.png') }}" alt="Odległość od ściany"
|
|
||||||
class="w-40 h-auto">
|
|
||||||
<input type="radio" id="floor" name="distance_type" value="floor" required>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label for="wall"
|
|
||||||
class="cursor-pointer border-2 border-transparent rounded-lg overflow-hidden transition-all hover:border-blue-400">
|
|
||||||
<img src="{{ url_for('static', filename='images/wall.png') }}" alt="Długość ściany"
|
|
||||||
class="w-40 h-auto">
|
|
||||||
<input type="radio" id="wall" name="distance_type" value="wall" required>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="mb-6 max-w-2xl mx-auto">
|
|
||||||
<h2>dystans [cm]</h2>
|
|
||||||
<input type="number" id="distance" name="distance" min="100" max="700" class="w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mb-6 max-w-2xl mx-auto mt-10">
|
|
||||||
<h2>Format druku</h2>
|
|
||||||
<div id="size" class="flex place-content-center">
|
|
||||||
<label for="a4"
|
|
||||||
class="cursor-pointer border-2 border-transparent rounded-lg overflow-hidden transition-all hover:border-blue-400">
|
|
||||||
<img src="{{ url_for('static', filename='images/a4.png') }}" alt="A4 (210mm x 297mm)"
|
|
||||||
class="w-40 h-auto">
|
|
||||||
<input type="radio" id="a4" name="size" value="a4" required>
|
|
||||||
</label>
|
|
||||||
<label for="a3"
|
|
||||||
class="cursor-pointer border-2 border-transparent rounded-lg overflow-hidden transition-all hover:border-blue-400">
|
|
||||||
<img src="{{ url_for('static', filename='images/a3.png') }}" alt="A3 (297mm x 420mm)"
|
|
||||||
class="w-40 h-auto">
|
|
||||||
<input type="radio" id="a3" name="size" value="a3" required>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-6 max-w-2xl mx-auto">
|
|
||||||
<h2>Tor</h2>
|
|
||||||
<div id="stage" class="grid grid-cols-1 gap-4">
|
|
||||||
<div>
|
|
||||||
<label for="five_to_go">
|
|
||||||
<p>Five To Go</p>
|
|
||||||
<img src="{{ url_for('static', filename='images/five_to_go.png') }}" alt="Five To Go">
|
|
||||||
<input type="radio" id="five_to_go" name="stage" value="five_to_go" required>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="showdown_left">
|
|
||||||
<p>Showdown (left box)</p>
|
|
||||||
<img src="{{ url_for('static', filename='images/showdown_left.png') }}"
|
|
||||||
alt="Showdown (left box)">
|
|
||||||
<input type="radio" id="showdown_left" name="stage" value="showdown_left">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="showdown_right">
|
|
||||||
<p>Showdown (right box)</p>
|
|
||||||
<img src="{{ url_for('static', filename='images/showdown_right.png') }}"
|
|
||||||
alt="Showdown (right box)">
|
|
||||||
<input type="radio" id="showdown_right" name="stage" value="showdown_right">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="smoke_and_hope">
|
|
||||||
<p>Smoke & Hope</p>
|
|
||||||
<img src="{{ url_for('static', filename='images/smoke_and_hope.png') }}" alt="Smoke & Hope">
|
|
||||||
<input type="radio" id="smoke_and_hope" name="stage" value="smoke_and_hope">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="accelerator">
|
|
||||||
<p>Accelerator</p>
|
|
||||||
<img src="{{ url_for('static', filename='images/accelerator.png') }}" alt="Accelerator">
|
|
||||||
<input type="radio" id="accelerator" name="stage" value="accelerator">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="pendulum">
|
|
||||||
<p>Pendulum</p>
|
|
||||||
<img src="{{ url_for('static', filename='images/pendulum.png') }}" alt="Pendulum">
|
|
||||||
<input type="radio" id="pendulum" name="stage" value="pendulum">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="speed_option">
|
|
||||||
<p>Speed Option</p>
|
|
||||||
<img src="{{ url_for('static', filename='images/speed_option.png') }}" alt="Speed Option">
|
|
||||||
<input type="radio" id="speed_option" name="stage" value="speed_option">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="roundabout">
|
|
||||||
<p>Roundabout</p>
|
|
||||||
<img src="{{ url_for('static', filename='images/roundabout.png') }}" alt="RoundAbout">
|
|
||||||
<input type="radio" id="roundabout" name="stage" value="roundabout">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<button type="submit"
|
|
||||||
class="bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition-colors">
|
|
||||||
Generuj
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
20
templates/ipsc.html
Normal file
20
templates/ipsc.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}IPSC - El Presidente{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<form class="" action="/generate-pdf-ipsc" method="post">
|
||||||
|
{% include 'setup.html' %}
|
||||||
|
<div class="mb-6 max-w-2xl mx-auto">
|
||||||
|
<h2>IPSC - El Presidente</h2>
|
||||||
|
|
||||||
|
<div class="mb-6 max-w-2xl mx-auto mt-4">
|
||||||
|
<img src="{{ url_for('static', filename='images/ipsc_preview.png') }}" alt="IPSC - El Presidente">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit"
|
||||||
|
class="bg-green-500 text-white py-2 px-4 rounded-md hover:bg-green-600 transition-colors">
|
||||||
|
Generuj
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
1
templates/ipsc_target.html
Normal file
1
templates/ipsc_target.html
Normal file
File diff suppressed because one or more lines are too long
@@ -83,11 +83,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>Wymagana długość ściany: {{ wall_length/10 }}cm</p>
|
<p>Wymagana długość ściany: {{ wall_length/10 }}cm</p>
|
||||||
<p>Odległość od ściany: {{ distance }}cm</p>
|
<p>Odległość od ściany: {{ distance|round(1,'ceil') }}cm</p>
|
||||||
<p>Przygotowanie toru:</p>
|
<p>Przygotowanie toru:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Umieść z lewej strony ściany pierwszy cel ze znacznikiem "punkt ZERO"</li>
|
<li>Umieść z lewej strony ściany pierwszy cel ze znacznikiem "punkt ZERO"</li>
|
||||||
<li>Wyznacz pole startowe {{ box_position }}cm od punktu "zero"</li>
|
<li>Wyznacz pole startowe {{ box_position }}cm od punktu "zero" (wzdłuż ściany) oraz w odległości {{distance}}cm od ściany</li>
|
||||||
<li>Upewnij się, że pole startowe znjaduje się w dogodnym miejscu, pomieszczenia, tak aby nic nie przeszkazdało
|
<li>Upewnij się, że pole startowe znjaduje się w dogodnym miejscu, pomieszczenia, tak aby nic nie przeszkazdało
|
||||||
w swobodnym dobyciu i składaniu do celów na całej szerokości ściany
|
w swobodnym dobyciu i składaniu do celów na całej szerokości ściany
|
||||||
</li>
|
</li>
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
{% if target.target == 't1' %}
|
{% if target.target == 't1' %}
|
||||||
<div class="mounting-info">punkt ZERO ({{ stage.split('_') | map('capitalize') | join(' ') }})</div>
|
<div class="mounting-info">punkt ZERO ({{ stage.split('_') | map('capitalize') | join(' ') }})</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="mounting-info">{{ target.position / 10 }}cm from 0 point ({{ stage.split('_') | map('capitalize') | join(' ') }})</div>
|
<div class="mounting-info">{{ target.position / 10 }}cm od punktu ZERO ({{ stage.split('_') | map('capitalize') | join(' ') }})</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="mounting-point"></div>
|
<div class="mounting-point"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
126
templates/pdf_template_ipsc.html
Normal file
126
templates/pdf_template_ipsc.html
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Paper Challenge - IPSC - El Presidente - {{ distance }} cm
|
||||||
|
- {{ size|capitalize }}</title>
|
||||||
|
<style>
|
||||||
|
@page {
|
||||||
|
size: {{size}};
|
||||||
|
margin: 5mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target {
|
||||||
|
margin: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-break {
|
||||||
|
page-break-after: always;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mounting-point {
|
||||||
|
height: 10mm;
|
||||||
|
width: 0.5mm;
|
||||||
|
background-color: #ccc;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mounting-info {
|
||||||
|
font-size: xx-small;
|
||||||
|
color: #ccc;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
display: block;
|
||||||
|
border-bottom: solid 1px black;
|
||||||
|
border-top: solid 1px black;
|
||||||
|
width: 100%;
|
||||||
|
height: 75mm;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.preview-target {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="page-break">
|
||||||
|
<h1>Paper Challenge</h1>
|
||||||
|
<h2>IPSC - El Presidente</h2>
|
||||||
|
|
||||||
|
<div class="preview">
|
||||||
|
{% for i in range(3) %}
|
||||||
|
<div class="preview-target w-[{{target_width*preview_scale}}cm] h-[{{target_height*preview_scale}}cm]" style="left: {{(preview_margin + i * preview_scale * gap)}}cm;">
|
||||||
|
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420 530" width="{{target_width*preview_scale}}cm" height="{{target_height*preview_scale}}cm">
|
||||||
|
<title>ipsc-svg</title>
|
||||||
|
<defs>
|
||||||
|
{% include 'ipsc_target.html' %}
|
||||||
|
</defs>
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
<use id="Background" href="#img1" x="0" y="0"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Wymagana długość ściany: {{ wall_length|round(1,'ceil') }}cm</p>
|
||||||
|
<p>Odległość od ściany: {{ distance|round(1,'ceil') }}cm</p>
|
||||||
|
<p>Przygotowanie toru:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Umieść z lewej lub prawej strony ściany pierwszy cel ze znacznikiem "punkt ZERO"</li>
|
||||||
|
<li>Wyznacz pole startowe {{ box_position|round(1,'ceil') }}cm od punktu "zero" (wzdłuż ściany) oraz w odległości {{distance}}cm od ściany</li>
|
||||||
|
<li>Upewnij się, że pole startowe znjaduje się w dogodnym miejscu, pomieszczenia, tak aby nic nie
|
||||||
|
przeszkazdało
|
||||||
|
w swobodnym dobyciu i składaniu do celów na całej szerokości ściany
|
||||||
|
</li>
|
||||||
|
<li>W razie potrzeby dostosuj pierwszy cel wraz z punktem ZERO i powtórz dwa powyższe kroki</li>
|
||||||
|
<li>Umieść na ścianie pozostałe cele zgodnie z odległościami podanymi na znacznikach pozycji na dole każdego
|
||||||
|
celu. Upewnij się, że wszystkie cele są umieszczone w jednej linii równoległej do podłoża</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% for i in range(3) %}
|
||||||
|
<div class="page-break">
|
||||||
|
<div class="content">
|
||||||
|
<div class="target mx-auto" style="width: {{target_width}}cm; height: {{target_height}}cm;" >
|
||||||
|
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420 530" width="{{target_width}}cm" height="{{target_height}}cm" >
|
||||||
|
<title>ipsc-svg</title>
|
||||||
|
<defs>
|
||||||
|
{% include 'ipsc_target.html' %}
|
||||||
|
</defs>
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
<use id="Background" href="#img1" x="0" y="0"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if i==0 %}
|
||||||
|
<div class="mounting-info">punkt ZERO (El Presidente)</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="mounting-info">{{ i * gap|round(1,'ceil') }}cm od punktu ZERO (El Presidente)</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="mounting-point"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
172
templates/pdf_template_shootoff.html
Normal file
172
templates/pdf_template_shootoff.html
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Paper Challenge - Shootoff - {{ distance }} cm
|
||||||
|
- {{ size|capitalize }}</title>
|
||||||
|
<style>
|
||||||
|
@page {
|
||||||
|
size: {{size}};
|
||||||
|
margin: 5mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target {
|
||||||
|
background-color: dodgerblue;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post {
|
||||||
|
margin: auto;
|
||||||
|
background-color: dodgerblue;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stop-plate {
|
||||||
|
background-color: red !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-break {
|
||||||
|
page-break-after: always;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mounting-point {
|
||||||
|
height: 10mm;
|
||||||
|
width: 0.5mm;
|
||||||
|
background-color: #ccc;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mounting-info {
|
||||||
|
font-size: xx-small;
|
||||||
|
color: #ccc;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
border-bottom: solid 1px black;
|
||||||
|
border-top: solid 1px black;
|
||||||
|
width: 100%;
|
||||||
|
height: 75mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-post {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="page-break">
|
||||||
|
<h1>Paper Challenge</h1>
|
||||||
|
<h2>Shootoff</h2>
|
||||||
|
|
||||||
|
<div class="preview">
|
||||||
|
{% for i in range(target_count) %}
|
||||||
|
{% if i == target_count-1 %}
|
||||||
|
<div class="post preview-post"
|
||||||
|
style="width: {{ preview_scale * 150}}mm; height: {{ preview_scale * 550 }}mm; left: {{i * preview_scale * 1000}}mm">
|
||||||
|
<div class="target circle" style="
|
||||||
|
width: {{ preview_scale * 300 }}mm;
|
||||||
|
height: {{ preview_scale * 300 }}mm;
|
||||||
|
bottom: {{ (preview_scale * 550) - ((preview_scale * 300)/2) }}mm;
|
||||||
|
right: {{ (preview_scale * (300/2)) - (preview_scale * 150 * 1.5) }}mm;
|
||||||
|
">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="post preview-post"
|
||||||
|
style="width: {{ preview_scale * 100}}mm; height: {{ preview_scale * 360 }}mm; left: {{i * preview_scale * 1000}}mm">
|
||||||
|
<div class="target circle" style="
|
||||||
|
width: {{ preview_scale * 200 }}mm;
|
||||||
|
height: {{ preview_scale * 200 }}mm;
|
||||||
|
bottom: {{ (preview_scale * 360) - ((preview_scale * 200)/2) }}mm;
|
||||||
|
right: {{ (preview_scale * (200/2)) - (preview_scale * 100 * 1.5) }}mm;
|
||||||
|
">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Wymagana długość ściany: {{ wall_length|round(1,'ceil') }}cm</p>
|
||||||
|
<p>Odległość od ściany: {{ distance|round(1,'ceil') }}cm</p>
|
||||||
|
<p>Przygotowanie toru:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Umieść z lewej lub prawej strony ściany pierwszy cel ze znacznikiem "punkt ZERO"</li>
|
||||||
|
<li>Wyznacz pole startowe {{ box_position|round(1,'ceil') }}cm od punktu "zero" (wzdłuż ściany) oraz w odległości {{distance}}cm od ściany</li>
|
||||||
|
<li>Upewnij się, że pole startowe znjaduje się w dogodnym miejscu, pomieszczenia, tak aby nic nie
|
||||||
|
przeszkazdało
|
||||||
|
w swobodnym dobyciu i składaniu do celów na całej szerokości ściany
|
||||||
|
</li>
|
||||||
|
<li>W razie potrzeby dostosuj pierwszy cel wraz z punktem ZERO i powtórz dwa powyższe kroki</li>
|
||||||
|
<li>Umieść na ścianie pozostałe cele zgodnie z odległościami podanymi na znacznikach pozycji na dole każdego
|
||||||
|
celu. Upewnij się, że wszystkie cele są umieszczone w jednej linii równoległej do podłoża</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% for i in range(target_count) %}
|
||||||
|
<div class="page-break">
|
||||||
|
<div class="content">
|
||||||
|
{% if i == target_count-1 %}
|
||||||
|
|
||||||
|
<div class="post"
|
||||||
|
|
||||||
|
style="width: {{ scale * 150}}mm; height: {{ scale * 550 }}mm;">
|
||||||
|
<div class="target circle" style="
|
||||||
|
width: {{ scale * 300 }}mm;
|
||||||
|
height: {{ scale * 300 }}mm;
|
||||||
|
bottom: {{ (scale * 550) - ((scale * 300)/2) }}mm;
|
||||||
|
right: {{ (scale * (300/2)) - (scale * 150 * 1.5) }}mm;
|
||||||
|
">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="post"
|
||||||
|
style="width: {{ scale * 100}}mm; height: {{ scale * 360 }}mm;">
|
||||||
|
<div class="target circle" style="
|
||||||
|
width: {{ scale * 200 }}mm;
|
||||||
|
height: {{ scale * 200 }}mm;
|
||||||
|
bottom: {{ (scale * 360) - ((scale * 200)/2) }}mm;
|
||||||
|
right: {{ (scale * (200/2)) - (scale * 100 * 1.5) }}mm;
|
||||||
|
">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% if i==0 %}
|
||||||
|
<div class="mounting-info">punkt ZERO (Shootoff)</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="mounting-info">{{ i * gap|round(1,'ceil') }}cm od punktu ZERO (Shootoff)</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="mounting-point"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
79
templates/sc.html
Normal file
79
templates/sc.html
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Steel Challenge{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<form class="" action="/generate-pdf" method="post">
|
||||||
|
{% include 'setup.html' %}
|
||||||
|
|
||||||
|
<div class="mb-6 max-w-2xl mx-auto">
|
||||||
|
<h2>Tor</h2>
|
||||||
|
<div id="stage" class="grid grid-cols-1 gap-4">
|
||||||
|
<div>
|
||||||
|
<label for="five_to_go">
|
||||||
|
<p>Five To Go</p>
|
||||||
|
<img src="{{ url_for('static', filename='images/five_to_go.png') }}" alt="Five To Go">
|
||||||
|
<input type="radio" id="five_to_go" name="stage" value="five_to_go" required>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="showdown_left">
|
||||||
|
<p>Showdown (left box)</p>
|
||||||
|
<img src="{{ url_for('static', filename='images/showdown_left.png') }}"
|
||||||
|
alt="Showdown (left box)">
|
||||||
|
<input type="radio" id="showdown_left" name="stage" value="showdown_left">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="showdown_right">
|
||||||
|
<p>Showdown (right box)</p>
|
||||||
|
<img src="{{ url_for('static', filename='images/showdown_right.png') }}"
|
||||||
|
alt="Showdown (right box)">
|
||||||
|
<input type="radio" id="showdown_right" name="stage" value="showdown_right">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="smoke_and_hope">
|
||||||
|
<p>Smoke & Hope</p>
|
||||||
|
<img src="{{ url_for('static', filename='images/smoke_and_hope.png') }}" alt="Smoke & Hope">
|
||||||
|
<input type="radio" id="smoke_and_hope" name="stage" value="smoke_and_hope">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="accelerator">
|
||||||
|
<p>Accelerator</p>
|
||||||
|
<img src="{{ url_for('static', filename='images/accelerator.png') }}" alt="Accelerator">
|
||||||
|
<input type="radio" id="accelerator" name="stage" value="accelerator">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="pendulum">
|
||||||
|
<p>Pendulum</p>
|
||||||
|
<img src="{{ url_for('static', filename='images/pendulum.png') }}" alt="Pendulum">
|
||||||
|
<input type="radio" id="pendulum" name="stage" value="pendulum">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="speed_option">
|
||||||
|
<p>Speed Option</p>
|
||||||
|
<img src="{{ url_for('static', filename='images/speed_option.png') }}" alt="Speed Option">
|
||||||
|
<input type="radio" id="speed_option" name="stage" value="speed_option">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="roundabout">
|
||||||
|
<p>Roundabout</p>
|
||||||
|
<img src="{{ url_for('static', filename='images/roundabout.png') }}" alt="RoundAbout">
|
||||||
|
<input type="radio" id="roundabout" name="stage" value="roundabout">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit"
|
||||||
|
class="bg-green-500 text-white py-2 px-4 rounded-md hover:bg-green-600 transition-colors">
|
||||||
|
Generuj
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
40
templates/setup.html
Normal file
40
templates/setup.html
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<div class="mb-6 max-w-2xl mx-auto mt-10">
|
||||||
|
<h2>Wybierz rodzaj kalkulacji ze względu na ograniczoną długość ściany lub ograniczoną odległość stanowiska od ściany</h2>
|
||||||
|
<div class="flex gap-6 place-content-center">
|
||||||
|
<label for="floor"
|
||||||
|
class="cursor-pointer border-2 border-transparent rounded-lg overflow-hidden transition-all hover:border-blue-400">
|
||||||
|
<img src="{{ url_for('static', filename='images/floor.png') }}" alt="Odległość od ściany"
|
||||||
|
class="w-40 h-auto">
|
||||||
|
<input type="radio" id="floor" name="distance_type" value="floor" required>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label for="wall"
|
||||||
|
class="cursor-pointer border-2 border-transparent rounded-lg overflow-hidden transition-all hover:border-blue-400">
|
||||||
|
<img src="{{ url_for('static', filename='images/wall.png') }}" alt="Długość ściany"
|
||||||
|
class="w-40 h-auto">
|
||||||
|
<input type="radio" id="wall" name="distance_type" value="wall" required>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mb-6 max-w-2xl mx-auto mt-4">
|
||||||
|
<h2>dystans [cm]</h2>
|
||||||
|
<input type="number" id="distance" name="distance" min="100" max="700" class="w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-6 max-w-2xl mx-auto mt-10">
|
||||||
|
<h2>Format druku</h2>
|
||||||
|
<div id="size" class="flex place-content-center">
|
||||||
|
<label for="a4"
|
||||||
|
class="cursor-pointer border-2 border-transparent rounded-lg overflow-hidden transition-all hover:border-blue-400">
|
||||||
|
<img src="{{ url_for('static', filename='images/a4.png') }}" alt="A4 (210mm x 297mm)"
|
||||||
|
class="w-40 h-auto">
|
||||||
|
<input type="radio" id="a4" name="size" value="a4" required>
|
||||||
|
</label>
|
||||||
|
<label for="a3"
|
||||||
|
class="cursor-pointer border-2 border-transparent rounded-lg overflow-hidden transition-all hover:border-blue-400">
|
||||||
|
<img src="{{ url_for('static', filename='images/a3.png') }}" alt="A3 (297mm x 420mm)"
|
||||||
|
class="w-40 h-auto">
|
||||||
|
<input type="radio" id="a3" name="size" value="a3" required>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
22
templates/shootoff.html
Normal file
22
templates/shootoff.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}Shootoff{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<form class="" action="/generate-pdf-shootoff" method="post">
|
||||||
|
{% include 'setup.html' %}
|
||||||
|
|
||||||
|
<div class="mb-6 max-w-2xl mx-auto">
|
||||||
|
<h2>Shootoff</h2>
|
||||||
|
|
||||||
|
<div class="mb-6 max-w-2xl mx-auto mt-4">
|
||||||
|
<img src="{{ url_for('static', filename='images/shootoff.png') }}" alt="Shootoff">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit"
|
||||||
|
class="bg-green-500 text-white py-2 px-4 rounded-md hover:bg-green-600 transition-colors">
|
||||||
|
Generuj
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user