Compare commits

...

4 Commits

11 changed files with 2283 additions and 2730 deletions

View File

@ -23,16 +23,21 @@ class Generator:
GENERATOR_SCAD_FILE_NAME = "generator.scad" GENERATOR_SCAD_FILE_NAME = "generator.scad"
GENERATED_STL_FILE_NAME = "generated.stl" GENERATED_STL_FILE_NAME = "generated.stl"
def __init__(self, name: str, tempdir: Path | str): def __init__(self, name: str, tempdir: Path | str, logo: str = None):
self._name = name self._name = name
self._tempdir = Path(tempdir) self._tempdir = Path(tempdir)
# sanitize input
if "/" in logo:
raise ValueError("invalid logo name")
self._logo = Path(logo).name
def _generate_scad_template(self) -> str: def _generate_scad_template(self) -> str:
return f""" return f"""
use <bottle-clip.scad> use <bottle-clip.scad>
$fn=180; $fn=180;
// one name tag for 0.5l Club Mate and similar bottles // one name tag for 0.5l Club Mate and similar bottles
bottle_clip(name="{self._name}", logo="thing-logos/fablab-cube2.dxf"); bottle_clip(name="{self._name}", logo="thing-logos/{self._logo}.dxf");
""" """
def _generate_files_in_temp_dir(self): def _generate_files_in_temp_dir(self):
@ -83,6 +88,7 @@ async def generate():
raise ValueError raise ValueError
name = data["name"] name = data["name"]
logo = data.get("logo", None)
except (TypeError, KeyError, ValueError): except (TypeError, KeyError, ValueError):
abort(400) abort(400)
@ -90,7 +96,7 @@ async def generate():
async with semaphore: async with semaphore:
with tempfile.TemporaryDirectory(prefix="fablab-bottle-clip-generator-") as tempdir: with tempfile.TemporaryDirectory(prefix="fablab-bottle-clip-generator-") as tempdir:
generator = Generator(name, tempdir) generator = Generator(name, tempdir, logo)
generated_stl_file_name = await generator.generate_stl() generated_stl_file_name = await generator.generate_stl()

View File

@ -11,6 +11,25 @@
include <write/Write.scad> include <write/Write.scad>
/**
* Module for multi colored print.
* All children are the given color.
* Using the global CURRENT_COLOR it is possible to only render and export everything of one color.
* Doing this for all colors the resulting stls can be put together again to a multi filament print in the slicer.
* If CURRENT_COLOR is set to "ALL" all colors are displayed.
* If color is "DEFAULT", it is not colored in the preview.
* Inspired by https://erik.nygren.org/2018-3dprint-multicolor-openscad.html
*/
module multicolor(color) {
if (is_undef(CURRENT_COLOR) || CURRENT_COLOR == "ALL" || CURRENT_COLOR == color) {
if (color != "DEFAULT") {
color(color) children();
} else {
children();
}
}
}
/** /**
* Creates one instance of a bottle clip name tag. The default values are * Creates one instance of a bottle clip name tag. The default values are
* suitable for 0.5l Club Mate bottles (and similar bottles). By default, logo * suitable for 0.5l Club Mate bottles (and similar bottles). By default, logo
@ -21,38 +40,41 @@ include <write/Write.scad>
* rl: the radius on the lower side of the clip * rl: the radius on the lower side of the clip
* ht: the height of the clip * ht: the height of the clip
* width: the thickness of the wall. Values near 2.5 usually result in a good * width: the thickness of the wall. Values near 2.5 usually result in a good
* clippiness for PLA prints. * clippiness for PLA prints.
* name: the name that is printed on your name tag. For the default ru/rt/ht * name: the name that is printed on your name tag. For the default ru/rt/ht
* values, this string should not exceed 18 characters to fit on the name tag. * values, this string should not exceed 18 characters to fit on the name tag.
* gap: width of the opening gap, in degrees. For rigid materials this value * gap: width of the opening gap, in degrees. For rigid materials this value
* usually needs to be near 180 (but if you set it to >= 180, you won't have * usually needs to be near 180 (but if you set it to >= 180, you won't have
* anything left for holding the clip on the bottle). For flexible materials * anything left for holding the clip on the bottle). For flexible materials
* like Ninjaflex, choose something near 0. For springy materials like PLA or * like Ninjaflex, choose something near 0. For springy materials like PLA or
* ABS, 90 has proven to be a good value. * ABS, 90 has proven to be a good value.
* logo: the path to a DXF file representing a logo that should be put above * logo: the path to a DXF file representing a logo that should be put above
* the name. Logo files should be no larger than 50 units in height and should * the name. Logo files should be no larger than 50 units in height and should
* be centered on the point (25,25). Also all units in the DXF file should be * be centered on the point (25,25). Also all units in the DXF file should be
* in mm. This parameter can be empty; in this case, the text uses the total * in mm. This parameter can be empty; in this case, the text uses the total
* height of the name tag. * height of the name tag.
* font: the path to a font for Write.scad. * font: the path to a font for Write.scad.
* bg_color: The color of the background (the clip itself)
* text_color: The color of the text
* logo_color: The color of the logo
*/ */
module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name="", gap=90, module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name="", gap=90,
logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") { logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf",
bg_color="DEFAULT", text_color="DEFAULT", logo_color="DEFAULT") {
e=100; // should be big enough, used for the outer boundary of the text/logo e=100; // should be big enough, used for the outer boundary of the text/logo
difference() { difference() {
rotate([0,0,-45]) union() { rotate([0,0,-45]) union() {
// main cylinder // main cylinder
cylinder(r1=rl+width, r2=ru+width, h=ht); multicolor(bg_color) cylinder(r1=rl+width, r2=ru+width, h=ht);
// text and logo // text and logo
if(logo == "") { if(logo == "") {
writecylinder(name, [0,0,3], rl+0.5, ht/13*7, h=ht/13*8, t=max(rl,ru), multicolor(text_color) writecylinder(name, [0,0,3], rl+0.5, ht/13*7, h=ht/13*8, t=max(rl,ru),
font=font); font=font);
} else { } else {
writecylinder(name, [0,0,0], rl+0.5, ht/13*7, h=ht/13*4, t=max(rl,ru), multicolor(text_color) writecylinder(name, [0,0,0], rl+0.5, ht/13*7, h=ht/13*4, t=max(rl,ru),
font=font); font=font);
translate([0,0,ht*3/4-0.1]) multicolor(logo_color) translate([0,0,ht*3/4-0.1])
rotate([90,0,0]) rotate([90,0,0])
scale([ht/100,ht/100,1]) scale([ht/100,ht/100,1])
translate([-25,-25,0.5]) translate([-25,-25,0.5])
@ -89,9 +111,10 @@ module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name="", gap=90,
* bottle_clip(), see there for their documentation. * bottle_clip(), see there for their documentation.
*/ */
module bottle_clip_longneck(name="", width=2.5, gap=90, module bottle_clip_longneck(name="", width=2.5, gap=90,
logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") { logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf",
bg_color="DEFAULT", text_color="DEFAULT", logo_color="DEFAULT") {
bottle_clip(name=name, ru=13, rl=15, ht=26, width=width, logo=logo, gap=gap, bottle_clip(name=name, ru=13, rl=15, ht=26, width=width, logo=logo, gap=gap,
font=font); font=font, bg_color=bg_color, text_color=text_color, logo_color=logo_color);
} }
/** /**
@ -100,9 +123,10 @@ module bottle_clip_longneck(name="", width=2.5, gap=90,
* reasons, there is no logo, but all other parameters are passed to the module * reasons, there is no logo, but all other parameters are passed to the module
* bottle_clip(), see there for their documentation. * bottle_clip(), see there for their documentation.
*/ */
module bottle_clip_steinie(name="", width=2.5, gap=90, font="write/orbitron.dxf") { module bottle_clip_steinie(name="", width=2.5, gap=90, font="write/orbitron.dxf",
bg_color="DEFAULT", text_color="DEFAULT", logo_color="DEFAULT") {
bottle_clip(name=name, ru=13, rl=17.5, ht=13, width=width, logo="", gap=gap, bottle_clip(name=name, ru=13, rl=17.5, ht=13, width=width, logo="", gap=gap,
font=font); font=font, bg_color=bg_color, text_color=text_color, logo_color=logo_color);
} }
/* /*
@ -111,9 +135,10 @@ module bottle_clip_steinie(name="", width=2.5, gap=90, font="write/orbitron.dxf"
* passed to the module bottle_clip(), see there for their documentation. * passed to the module bottle_clip(), see there for their documentation.
*/ */
module bottle_clip_euro2(name="", width=2.5, gap=90, module bottle_clip_euro2(name="", width=2.5, gap=90,
logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") { logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf",
bottle_clip(name=name, ru=13, rl=22.5, ht=26, width=width, logo=logo, gap=gap, bg_color="DEFAULT", text_color="DEFAULT", logo_color="DEFAULT") {
font=font); bottle_clip(name=name, ru=13, rl=22.5, ht=26, width=width, logo=logo, gap=gap,
font=font, bg_color=bg_color, text_color=text_color, logo_color=logo_color);
} }
// vim: set noet ts=2 sw=2 tw=80: // vim: set noet ts=2 sw=2 tw=80:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
/* Version 3 /* Version 4
Added bold property bold=0 (not bold) bold=1(bolder by 1.1) bold=2(bolder by 1.2)
Added support for font selection (default is Letters.dxf) Added support for font selection (default is Letters.dxf)
Added WriteCube module Added WriteCube module
Added Rotate for text (rotates on the plane of the text) Added Rotate for text (rotates on the plane of the text)
@ -26,6 +27,7 @@
// defaults. // defaults.
//default settings //default settings
bold=0;
center=false; center=false;
h = 4; //mm letter height h = 4; //mm letter height
t = 1; //mm letter thickness t = 1; //mm letter thickness
@ -73,19 +75,19 @@ module writecylinder(text,where,radius,height){
if (face=="top" ){ if (face=="top" ){
if (center==true){ if (center==true){
writecircle(text,where+[0,0,height/2],radius-h,rotate=rotate,font=font,h=h,t=t, writecircle(text,where+[0,0,height/2],radius-h,rotate=rotate,font=font,h=h,t=t,
space=space,east=east,west=west,middle=middle,ccw=ccw); space=space,east=east,west=west,middle=middle,ccw=ccw,bold=bold);
}else{ }else{
writecircle(text,where+[0,0,height],radius-h,rotate=rotate,font=font,h=h,t=t, writecircle(text,where+[0,0,height],radius-h,rotate=rotate,font=font,h=h,t=t,
space=space,east=east,west=west,middle=middle,ccw=ccw); space=space,east=east,west=west,middle=middle,ccw=ccw,bold=bold);
} }
}else{ }else{
rotate(180,[1,0,0]) rotate(180,[1,0,0])
if (center==true){ if (center==true){
writecircle(text,where+[0,0,height/2],radius-h,rotate=rotate,font=font,h=h,t=t, writecircle(text,where+[0,0,height/2],radius-h,rotate=rotate,font=font,h=h,t=t,
space=space,east=east,west=west,middle=middle,ccw=ccw); space=space,east=east,west=west,middle=middle,ccw=ccw,bold=bold);
}else{ }else{
writecircle(text,where+[0,0,0],radius-h,rotate=rotate,font=font,h=h,t=t, writecircle(text,where+[0,0,0],radius-h,rotate=rotate,font=font,h=h,t=t,
space=space,east=east,west=west,middle=middle,ccw=ccw); space=space,east=east,west=west,middle=middle,ccw=ccw,bold=bold);
} }
} }
@ -96,13 +98,13 @@ module writecylinder(text,where,radius,height){
translate(where) translate(where)
writethecylinder(text,where,radius,height,r1=radius,r2=radius,h=h, writethecylinder(text,where,radius,height,r1=radius,r2=radius,h=h,
rotate=rotate,t=t,font=font,face=face,up=up,down=down, rotate=rotate,t=t,font=font,face=face,up=up,down=down,
east=east,west=west,center=center,space=space,rounded=rounded); east=east,west=west,center=center,space=space,rounded=rounded,bold=bold);
} else{ } else{
rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1]) rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1])
translate(where+[0,0,height/2]) translate(where+[0,0,height/2])
writethecylinder(text,where,radius,height,r1=radius,r2=radius,h=h, writethecylinder(text,where,radius,height,r1=radius,r2=radius,h=h,
rotate=rotate,t=t,font=font,face=face,up=up,down=down, rotate=rotate,t=t,font=font,face=face,up=up,down=down,
east=east,west=west,center=center,space=space,rounded=rounded); east=east,west=west,center=center,space=space,rounded=rounded,bold=bold);
} }
// the remarked out code is for cone shaped cylinders (not complete) // the remarked out code is for cone shaped cylinders (not complete)
// }else{ // }else{
@ -140,7 +142,7 @@ module writecircle(text,where,radius){
//rotate(90,[1,0,0]) //rotate(90,[1,0,0])
//rotate(90,[0,1,0]) //rotate(90,[0,1,0])
rotate(-270,[0,0,1]) // flip text (botom out = -270) rotate(-270,[0,0,1]) // flip text (botom out = -270)
write(text[r],center=true,h=h,t=t,font=font); write(text[r],center=true,h=h,t=t,font=font,bold=bold);
} }
} }
} }
@ -154,7 +156,7 @@ module writecircle(text,where,radius){
//rotate(90,[1,0,0]) //rotate(90,[1,0,0])
//rotate(90,[0,1,0]) //rotate(90,[0,1,0])
rotate(270,[0,0,1]) // flip text (botom out = -270) rotate(270,[0,0,1]) // flip text (botom out = -270)
write(text[r],center=true,h=h,t=t,font=font); write(text[r],center=true,h=h,t=t,font=font,bold=bold);
} }
} }
} }
@ -176,7 +178,7 @@ module writethecylinder(text,where,radius,height,r1,r2){
translate([radius,0,-r*((rotate)/90*wid)+(len(text)-1)/2*((rotate)/90*wid)]) translate([radius,0,-r*((rotate)/90*wid)+(len(text)-1)/2*((rotate)/90*wid)])
rotate(90,[1,0,0]) rotate(90,[1,0,0])
rotate(90,[0,1,0]) rotate(90,[0,1,0])
write(text[r],center=true,h=h,rotate=rotate,t=t,font=font); write(text[r],center=true,h=h,rotate=rotate,t=t,font=font,bold=bold);
//echo("zloc=",height/2-r*((rotate)/90*wid)+(len(text)-1)/2*((rotate)/90*wid)); //echo("zloc=",height/2-r*((rotate)/90*wid)+(len(text)-1)/2*((rotate)/90*wid));
} }
@ -204,7 +206,7 @@ module writesphere(text,where,radius){
translate([radius,0,0]) translate([radius,0,0])
rotate(90,[1,0,0]) rotate(90,[1,0,0])
rotate(90,[0,1,0]) rotate(90,[0,1,0])
write(text[r],center=true,h=h,rotate=rotate,t=t,font=font); write(text[r],center=true,h=h,rotate=rotate,t=t,font=font,bold=bold);
} }
}else{ }else{
difference(){ difference(){
@ -214,7 +216,7 @@ module writesphere(text,where,radius){
translate([radius,0,0]) translate([radius,0,0])
rotate(90,[1,0,0]) rotate(90,[1,0,0])
rotate(90,[0,1,0]) rotate(90,[0,1,0])
write(text[r],center=true,h=h,rotate=rotate,t=t*2+h,font=font); write(text[r],center=true,h=h,rotate=rotate,t=t*2+h,font=font,bold=bold);
} }
difference(){ //rounded outside difference(){ //rounded outside
sphere(radius+(t*2+h)*2); sphere(radius+(t*2+h)*2);
@ -232,12 +234,12 @@ module writecube(text,where,size){
if (str(size)[0] != "["){ if (str(size)[0] != "["){
// its a square cube (size was not a matrix so make it one) // its a square cube (size was not a matrix so make it one)
writethecube(text,where,[size,size,size],h=h,rotate=rotate,space=space, writethecube(text,where,[size,size,size],h=h,rotate=rotate,space=space,
t=t,font=font,face=face,up=up,down=down,right=right,left=left); t=t,font=font,face=face,up=up,down=down,right=right,left=left,bold=bold);
}else{ }else{
// its not square // its not square
writethecube(text,where,size,h=h,rotate=rotate,space=space, writethecube(text,where,size,h=h,rotate=rotate,space=space,
t=t,font=font,face=face,up=up,down=down,right=right,left=left); t=t,font=font,face=face,up=up,down=down,right=right,left=left,bold=bold);
} }
} }
// I split the writecube module into 2 pieces.. easier to add features later // I split the writecube module into 2 pieces.. easier to add features later
@ -245,34 +247,34 @@ module writethecube(text,where,size){
if (face=="front") { if (face=="front") {
translate([where[0]+right-left,where[1]-size[1]/2,where[2]+up-down]) translate([where[0]+right-left,where[1]-size[1]/2,where[2]+up-down])
rotate(90,[1,0,0]) rotate(90,[1,0,0])
write(text,center=true,h=h,rotate=rotate,t=t,font=font); write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold);
} }
if (face=="back") { if (face=="back") {
translate([where[0]+right-left,where[1]+size[1]/2,where[2]+up-down]) translate([where[0]+right-left,where[1]+size[1]/2,where[2]+up-down])
rotate(90,[1,0,0]) // rotate around the x axis rotate(90,[1,0,0]) // rotate around the x axis
rotate(180,[0,1,0]) // rotate around the y axis (z before rotation) rotate(180,[0,1,0]) // rotate around the y axis (z before rotation)
write(text,center=true,h=h,rotate=rotate,t=t,font=font); write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold);
} }
if (face=="left") { if (face=="left") {
translate([where[0]-size[0]/2,where[1]-right+left,where[2]+up-down ]) translate([where[0]-size[0]/2,where[1]-right+left,where[2]+up-down ])
rotate(90,[1,0,0]) // rotate around the x axis rotate(90,[1,0,0]) // rotate around the x axis
rotate(90,[0,-1,0]) // rotate around the y axis (z before rotation) rotate(90,[0,-1,0]) // rotate around the y axis (z before rotation)
write(text,center=true,h=h,rotate=rotate,t=t,font=font); write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold);
} }
if (face=="right") { if (face=="right") {
translate([where[0]+size[0]/2,where[1]+right-left,where[2] +up-down]) translate([where[0]+size[0]/2,where[1]+right-left,where[2] +up-down])
rotate(90,[1,0,0]) // rotate around the x axis rotate(90,[1,0,0]) // rotate around the x axis
rotate(90,[0,1,0]) // rotate around the y axis (z before rotation) rotate(90,[0,1,0]) // rotate around the y axis (z before rotation)
write(text,center=true,h=h,rotate=rotate,t=t,font=font); write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold);
} }
if (face=="top") { if (face=="top") {
translate([where[0]+right-left,where[1]+up-down,where[2]+size[2]/2 ]) translate([where[0]+right-left,where[1]+up-down,where[2]+size[2]/2 ])
write(text,center=true,h=h,rotate=rotate,t=t,font=font); write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold);
} }
if (face=="bottom") { if (face=="bottom") {
translate([where[0]+right-left,where[1]-up+down,where[2]-size[2]/2 ]) translate([where[0]+right-left,where[1]-up+down,where[2]-size[2]/2 ])
rotate(180,[1,0,0]) rotate(180,[1,0,0])
write(text,center=true,h=h,rotate=rotate,t=t,font=font); write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold);
} }
} }
@ -283,7 +285,9 @@ module write(word){
echo ("There are " ,len(word) ," letters in this string"); echo ("There are " ,len(word) ," letters in this string");
// echo ("The second letter is ",word[1]); // echo ("The second letter is ",word[1]);
// echo (str(word[0],"_")); // echo (str(word[0],"_"));
minkowski() {
rotate(rotate,[0,0,-1]){ rotate(rotate,[0,0,-1]){
for (r = [0:len(word)]){ // count off each character for (r = [0:len(word)]){ // count off each character
// if the letter is lower case, add an underscore to the end for file lookup // if the letter is lower case, add an underscore to the end for file lookup
if ((word[r] == "a" ) || (word[r]== "b") || (word[r]== "c") if ((word[r] == "a" ) || (word[r]== "b") || (word[r]== "c")
@ -299,18 +303,20 @@ rotate(rotate,[0,0,-1]){
translate([0,-h/2,0]){ translate([0,-h/2,0]){
scale([.125*h,.125*h,t]){ scale([.125*h,.125*h,t]){
translate([ (-len(word)*5.5*space/2) + (r*5.5*space),0,0]) translate([ (-len(word)*5.5*space/2) + (r*5.5*space),0,0])
//offset(delta = 20, join_type = "round") {
linear_extrude(height=1,convexity=10,center=true){ linear_extrude(height=1,convexity=10,center=true){
import(file = font,layer=str(word[r],"_")); import(file = font,layer=str(word[r],"_"));
} }//}
} }
} }
}else{ }else{
translate([0,0,t/2]){ translate([0,0,t/2]){
scale([.125*h,.125*h,t]){ scale([.125*h,.125*h,t]){
translate([r*5.5*space,0,0]) translate([r*5.5*space,0,0])
//offset(delta = 20, join_type = "round") {
linear_extrude(height=1,convexity=10,center=true){ linear_extrude(height=1,convexity=10,center=true){
import(file = font,layer=str(word[r],"_")); import(file = font,layer=str(word[r],"_"));
} }//}
} }
} }
} }
@ -320,24 +326,28 @@ rotate(rotate,[0,0,-1]){
translate([0,-h/2,0]){ translate([0,-h/2,0]){
scale([.125*h,.125*h,t]){ scale([.125*h,.125*h,t]){
translate([ (-len(word)*5.5*space/2) + (r*5.5*space),0,0]) translate([ (-len(word)*5.5*space/2) + (r*5.5*space),0,0])
//offset(delta = 20, join_type = "round") {
linear_extrude(height=1,convexity=10,center=true){ linear_extrude(height=1,convexity=10,center=true){
import(file = font,layer=str(word[r])); import(file = font,layer=str(word[r]));
} }//}
} }
} }
}else{ }else{
translate([0,0,t/2]){ translate([0,0,t/2]){
scale([.125*h,.125*h,t]){ scale([.125*h,.125*h,t]){
translate([r*5.5*space,0,0]) translate([r*5.5*space,0,0])
//offset(delta = 20, join_type = "round") {
linear_extrude(height=1,convexity=10,center=true){ linear_extrude(height=1,convexity=10,center=true){
import(file = font,layer=str(word[r])); import(file = font,layer=str(word[r]));
} }//}
} }
} }
} }
} }
} }
} }
cube([bold*.1*h,bold*.1*h,.00001]);
}
} }
/*writecylinder test /*writecylinder test

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -1,8 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="de" xmlns="http://www.w3.org/1999/html" data-theme="dark"> <html lang="de" xmlns="http://www.w3.org/1999/html" data-theme="dark">
<head> <head>
<title>FabLab Bottle Clip Generator</title> <title>FabLab Bottle Clip Generator</title>
<link rel="stylesheet" href="{{ url_for('static', filename='pico.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/pico.css') }}">
<style> <style>
.error { .error {
background-color: rgb(183, 28, 28); background-color: rgb(183, 28, 28);
@ -16,15 +17,16 @@
<body> <body>
<script src="{{ url_for('static', filename='download.js') }}"></script> <script src="{{ url_for('static', filename='js/download.js') }}"></script>
<script type="module"> <script type="module">
import {createApp} from '{{ url_for("static", filename="vue.esm-browser.js") }}' import {createApp} from '{{ url_for("static", filename="js/vue.esm-browser.js") }}'
createApp({ createApp({
data() { data() {
return { return {
name: "", name: "",
logo: "fablab",
fetching: false, fetching: false,
error: false, error: false,
} }
@ -49,6 +51,7 @@
method: "post", method: "post",
body: JSON.stringify({ body: JSON.stringify({
"name": this.name, "name": this.name,
"logo": this.logo,
}), }),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@ -74,7 +77,7 @@
<main class="container"> <main class="container">
<center> <center>
<img src="{{ url_for('static', filename='logo.svg') }}" style="max-width: 350px; margin-bottom: 30px;"> <img src="{{ url_for('static', filename='img/logo.svg') }}" style="max-width: 350px; margin-bottom: 30px;">
<h1>FabLab Bottle Clip Generator</h1> <h1>FabLab Bottle Clip Generator</h1>
@ -86,6 +89,10 @@
<form ref="form" action="{{ url_for('generate') }}" method="post"> <form ref="form" action="{{ url_for('generate') }}" method="post">
<label for="name">Name:</label> <label for="name">Name:</label>
<input type="text" id="name" name="name" style="text-align: center;" placeholder="Name" v-model="name" :disabled="fetching" :aria-invalid="name === ''"> <input type="text" id="name" name="name" style="text-align: center;" placeholder="Name" v-model="name" :disabled="fetching" :aria-invalid="name === ''">
<select id="logo" name="logo" v-model="logo" :disabled="fetching" aria-label="Logo auswählen" required>
<option value="fablab">FabLab</option>
<option value="thw">THW</option>
</select>
<button v-if="!fetching" ref="submitButton" type="submit" @click="generate" :disabled="name === ''">Generieren</button> <button v-if="!fetching" ref="submitButton" type="submit" @click="generate" :disabled="name === ''">Generieren</button>
<button v-if="fetching" style="display: none" v-show="true" type="button" disabled="true" aria-busy="true">Generiere...</button> <button v-if="fetching" style="display: none" v-show="true" type="button" disabled="true" aria-busy="true">Generiere...</button>
</form> </form>
@ -95,4 +102,5 @@
</main> </main>
</body> </body>
</html> </html>