Laser stand
This commit is contained in:
BIN
src/assets/images/laser-stand/assembled.jpg
Normal file
BIN
src/assets/images/laser-stand/assembled.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 MiB |
BIN
src/assets/images/laser-stand/close.jpg
Normal file
BIN
src/assets/images/laser-stand/close.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 MiB |
BIN
src/assets/images/laser-stand/design.png
Normal file
BIN
src/assets/images/laser-stand/design.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
@@ -1,66 +0,0 @@
|
||||
---
|
||||
import LinkButton from "./LinkButton.astro";
|
||||
import socialIcons from "@assets/socialIcons";
|
||||
|
||||
const URL = Astro.url;
|
||||
|
||||
const shareLinks = [
|
||||
{
|
||||
name: "WhatsApp",
|
||||
href: "https://wa.me/?text=",
|
||||
linkTitle: `Share this post via WhatsApp`,
|
||||
},
|
||||
{
|
||||
name: "Facebook",
|
||||
href: "https://www.facebook.com/sharer.php?u=",
|
||||
linkTitle: `Share this post on Facebook`,
|
||||
},
|
||||
{
|
||||
name: "X",
|
||||
href: "https://x.com/intent/post?url=",
|
||||
linkTitle: `Share this post on X`,
|
||||
},
|
||||
{
|
||||
name: "Telegram",
|
||||
href: "https://t.me/share/url?url=",
|
||||
linkTitle: `Share this post via Telegram`,
|
||||
},
|
||||
{
|
||||
name: "Pinterest",
|
||||
href: "https://pinterest.com/pin/create/button/?url=",
|
||||
linkTitle: `Share this post on Pinterest`,
|
||||
},
|
||||
{
|
||||
name: "Mail",
|
||||
href: "mailto:?subject=See%20this%20post&body=",
|
||||
linkTitle: `Share this post via email`,
|
||||
},
|
||||
] as const;
|
||||
---
|
||||
|
||||
<div class={`social-icons`}>
|
||||
<span class="italic">Share this post on:</span>
|
||||
<div class="text-center">
|
||||
{
|
||||
shareLinks.map(social => (
|
||||
<LinkButton
|
||||
href={`${social.href + URL}`}
|
||||
className="link-button"
|
||||
title={social.linkTitle}
|
||||
>
|
||||
<Fragment set:html={socialIcons[social.name]} />
|
||||
<span class="sr-only">{social.linkTitle}</span>
|
||||
</LinkButton>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.social-icons {
|
||||
@apply flex flex-col flex-wrap items-center justify-center gap-1 sm:items-start;
|
||||
}
|
||||
.link-button {
|
||||
@apply scale-90 p-2 hover:rotate-6 sm:p-1;
|
||||
}
|
||||
</style>
|
||||
34
src/content/blog/laser-stand.md
Normal file
34
src/content/blog/laser-stand.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
pubDatetime: 2025-01-17T00:00:00Z
|
||||
title: Laser stand 3d print
|
||||
draft: false
|
||||
tags:
|
||||
- 3d-print
|
||||
description: First 3d print of 2025
|
||||
---
|
||||
|
||||
I've had a 3d printer for a fair few years now. It's a Prusa mk3 and it's starting to show it's age. I might consider a replacement in the next year or so - the Bambu Labs printers are looking pretty good.
|
||||
|
||||
Anyway, before I replace it I need to prove to myself that I'll use it.
|
||||
|
||||
This is a print that I've been wanting to do for a while. I bought a cheap Magnusson laser level a while back (it was around 40% of the cost of others I could find) and it's really good for drawing level lines, but what it lacks is a convenient way of placing it at just the right level.
|
||||
|
||||
We suffered for quite a while with balancing the level on stacks of random objects - not the best.
|
||||
|
||||
Later on I found a cheap camera tripod in a local charity shop. Now I just needed a way of connecting them together...
|
||||
|
||||
3d printer to the rescue
|
||||
|
||||
I fired up Fusion and designed a little plate to interface between the quick-release that the tripod has, and the 1/4-20 thread that the laser has.
|
||||
|
||||

|
||||
|
||||
A quick print later and it's ready to go!
|
||||
|
||||

|
||||
|
||||
The (laser)disc is to enable me to point the laser in different directions without moving the tripod. Without it the laser doesn't line up with the quick-release, and this was apparently unacceptable to myself.
|
||||
|
||||

|
||||
|
||||
Functional prints are the best!
|
||||
@@ -6,7 +6,6 @@ import Tag from "@components/Tag.astro";
|
||||
import Datetime from "@components/Datetime";
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import { slugifyStr } from "@utils/slugify";
|
||||
import ShareLinks from "@components/ShareLinks.astro";
|
||||
import { SITE } from "@config";
|
||||
import {render} from 'astro:content'
|
||||
|
||||
@@ -92,7 +91,7 @@ const nextPost =
|
||||
</article>
|
||||
|
||||
<ul class="my-8">
|
||||
{tags.map(tag => <Tag tag={slugifyStr(tag)} />)}
|
||||
{tags.map(tag => <Tag tag={tag} />)}
|
||||
</ul>
|
||||
|
||||
<div
|
||||
@@ -110,7 +109,6 @@ const nextPost =
|
||||
<span>Back to Top</span>
|
||||
</button>
|
||||
|
||||
<ShareLinks />
|
||||
</div>
|
||||
|
||||
<hr class="my-6 border-dashed" />
|
||||
|
||||
@@ -21,8 +21,8 @@ const { page } = Astro.props;
|
||||
<Main pageTitle="Posts" pageDesc="All the articles I've posted.">
|
||||
<ul>
|
||||
{
|
||||
page.data.map(({ data, slug }) => (
|
||||
<Card href={`/posts/${slug}/`} frontmatter={data} />
|
||||
page.data.map(({ data, id }) => (
|
||||
<Card href={`/posts/${id}/`} frontmatter={data} />
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
|
||||
@@ -28,8 +28,8 @@ const { page, tag, tagName } = Astro.props;
|
||||
<h1 slot="title" transition:name={tag}>{`Tag:${tag}`}</h1>
|
||||
<ul>
|
||||
{
|
||||
page.data.map(({ data, slug }) => (
|
||||
<Card href={`/posts/${slug}/`} frontmatter={data} />
|
||||
page.data.map(({ data, id }) => (
|
||||
<Card href={`/posts/${id}/`} frontmatter={data} />
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import getSortedPosts from "./getSortedPosts";
|
||||
import { slugifyAll } from "./slugify";
|
||||
|
||||
const getPostsByTag = (posts: CollectionEntry<"blog">[], tag: string) =>
|
||||
getSortedPosts(
|
||||
posts.filter(post => slugifyAll(post.data.tags).includes(tag))
|
||||
);
|
||||
getSortedPosts(posts.filter(post => post.data.tags.includes(tag)));
|
||||
|
||||
export default getPostsByTag;
|
||||
|
||||
@@ -11,7 +11,7 @@ const getUniqueTags = (posts: CollectionEntry<"blog">[]) => {
|
||||
const tags: Tag[] = posts
|
||||
.filter(postFilter)
|
||||
.flatMap(post => post.data.tags)
|
||||
.map(tag => ({ tag: slugifyStr(tag), tagName: tag }))
|
||||
.map(tag => ({ tag: tag, tagName: tag }))
|
||||
.filter(
|
||||
(value, index, self) =>
|
||||
self.findIndex(tag => tag.tag === value.tag) === index
|
||||
|
||||
Reference in New Issue
Block a user