@jjlmoya/utils-audiovisual 1.17.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/category/index.ts +2 -0
- package/src/entries.ts +4 -1
- package/src/index.ts +1 -0
- package/src/pages/[locale]/[slug].astro +28 -12
- package/src/tests/locale_completeness.test.ts +2 -36
- package/src/tests/shared-test-helpers.ts +56 -0
- package/src/tests/tool_exports.test.ts +34 -0
- package/src/tests/tool_validation.test.ts +2 -2
- package/src/tool/chromaticLens/bibliography.ts +12 -0
- package/src/tool/chromaticLens/entry.ts +2 -0
- package/src/tool/chromaticLens/i18n/de.ts +1 -15
- package/src/tool/chromaticLens/i18n/en.ts +1 -15
- package/src/tool/chromaticLens/i18n/es.ts +1 -13
- package/src/tool/chromaticLens/i18n/fr.ts +1 -13
- package/src/tool/chromaticLens/i18n/id.ts +1 -15
- package/src/tool/chromaticLens/i18n/it.ts +1 -15
- package/src/tool/chromaticLens/i18n/ja.ts +1 -15
- package/src/tool/chromaticLens/i18n/ko.ts +1 -15
- package/src/tool/chromaticLens/i18n/nl.ts +1 -15
- package/src/tool/chromaticLens/i18n/pl.ts +1 -15
- package/src/tool/chromaticLens/i18n/pt.ts +1 -15
- package/src/tool/chromaticLens/i18n/ru.ts +1 -15
- package/src/tool/chromaticLens/i18n/sv.ts +1 -15
- package/src/tool/chromaticLens/i18n/tr.ts +1 -15
- package/src/tool/chromaticLens/i18n/zh.ts +1 -15
- package/src/tool/chromaticLens/seo.astro +1 -1
- package/src/tool/collageMaker/bibliography.ts +8 -0
- package/src/tool/collageMaker/entry.ts +2 -0
- package/src/tool/collageMaker/i18n/de.ts +1 -11
- package/src/tool/collageMaker/i18n/en.ts +1 -11
- package/src/tool/collageMaker/i18n/es.ts +1 -9
- package/src/tool/collageMaker/i18n/fr.ts +1 -9
- package/src/tool/collageMaker/i18n/id.ts +1 -11
- package/src/tool/collageMaker/i18n/it.ts +1 -11
- package/src/tool/collageMaker/i18n/ja.ts +1 -11
- package/src/tool/collageMaker/i18n/ko.ts +1 -11
- package/src/tool/collageMaker/i18n/nl.ts +1 -11
- package/src/tool/collageMaker/i18n/pl.ts +1 -11
- package/src/tool/collageMaker/i18n/pt.ts +1 -11
- package/src/tool/collageMaker/i18n/ru.ts +1 -11
- package/src/tool/collageMaker/i18n/sv.ts +1 -11
- package/src/tool/collageMaker/i18n/tr.ts +1 -11
- package/src/tool/collageMaker/i18n/zh.ts +1 -11
- package/src/tool/collageMaker/seo.astro +1 -1
- package/src/tool/depthOfFieldCalculator/bibliography.astro +15 -0
- package/src/tool/depthOfFieldCalculator/bibliography.ts +20 -0
- package/src/tool/depthOfFieldCalculator/component.astro +341 -0
- package/src/tool/depthOfFieldCalculator/depth-of-field-calculator.css +417 -0
- package/src/tool/depthOfFieldCalculator/entry.ts +52 -0
- package/src/tool/depthOfFieldCalculator/i18n/de.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/en.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/es.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/fr.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/id.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/it.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/ja.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/ko.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/nl.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/pl.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/pt.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/ru.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/sv.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/tr.ts +141 -0
- package/src/tool/depthOfFieldCalculator/i18n/zh.ts +141 -0
- package/src/tool/depthOfFieldCalculator/index.ts +10 -0
- package/src/tool/depthOfFieldCalculator/logic.ts +91 -0
- package/src/tool/depthOfFieldCalculator/seo.astro +15 -0
- package/src/tool/exifCleaner/bibliography.ts +12 -0
- package/src/tool/exifCleaner/entry.ts +2 -0
- package/src/tool/exifCleaner/i18n/de.ts +1 -15
- package/src/tool/exifCleaner/i18n/en.ts +1 -15
- package/src/tool/exifCleaner/i18n/es.ts +1 -15
- package/src/tool/exifCleaner/i18n/fr.ts +1 -15
- package/src/tool/exifCleaner/i18n/id.ts +1 -15
- package/src/tool/exifCleaner/i18n/it.ts +1 -15
- package/src/tool/exifCleaner/i18n/ja.ts +1 -15
- package/src/tool/exifCleaner/i18n/ko.ts +1 -15
- package/src/tool/exifCleaner/i18n/nl.ts +1 -15
- package/src/tool/exifCleaner/i18n/pl.ts +1 -15
- package/src/tool/exifCleaner/i18n/pt.ts +1 -15
- package/src/tool/exifCleaner/i18n/ru.ts +1 -15
- package/src/tool/exifCleaner/i18n/sv.ts +1 -15
- package/src/tool/exifCleaner/i18n/tr.ts +1 -15
- package/src/tool/exifCleaner/i18n/zh.ts +1 -15
- package/src/tool/exifCleaner/seo.astro +2 -5
- package/src/tool/imageCompressor/bibliography.ts +12 -0
- package/src/tool/imageCompressor/entry.ts +2 -0
- package/src/tool/imageCompressor/i18n/de.ts +1 -15
- package/src/tool/imageCompressor/i18n/en.ts +1 -15
- package/src/tool/imageCompressor/i18n/es.ts +1 -13
- package/src/tool/imageCompressor/i18n/fr.ts +1 -13
- package/src/tool/imageCompressor/i18n/id.ts +1 -15
- package/src/tool/imageCompressor/i18n/it.ts +1 -15
- package/src/tool/imageCompressor/i18n/ja.ts +1 -15
- package/src/tool/imageCompressor/i18n/ko.ts +1 -15
- package/src/tool/imageCompressor/i18n/nl.ts +1 -15
- package/src/tool/imageCompressor/i18n/pl.ts +1 -15
- package/src/tool/imageCompressor/i18n/pt.ts +1 -15
- package/src/tool/imageCompressor/i18n/ru.ts +1 -15
- package/src/tool/imageCompressor/i18n/sv.ts +1 -15
- package/src/tool/imageCompressor/i18n/tr.ts +1 -15
- package/src/tool/imageCompressor/i18n/zh.ts +1 -15
- package/src/tool/imageCompressor/seo.astro +1 -1
- package/src/tool/printQualityCalculator/bibliography.ts +12 -0
- package/src/tool/printQualityCalculator/entry.ts +2 -0
- package/src/tool/printQualityCalculator/i18n/de.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/en.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/es.ts +1 -13
- package/src/tool/printQualityCalculator/i18n/fr.ts +1 -13
- package/src/tool/printQualityCalculator/i18n/id.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/it.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/ja.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/ko.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/nl.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/pl.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/pt.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/ru.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/sv.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/tr.ts +1 -15
- package/src/tool/printQualityCalculator/i18n/zh.ts +1 -15
- package/src/tool/printQualityCalculator/seo.astro +2 -5
- package/src/tool/privacyBlur/bibliography.ts +8 -0
- package/src/tool/privacyBlur/entry.ts +2 -0
- package/src/tool/privacyBlur/i18n/de.ts +1 -11
- package/src/tool/privacyBlur/i18n/en.ts +1 -11
- package/src/tool/privacyBlur/i18n/es.ts +1 -9
- package/src/tool/privacyBlur/i18n/fr.ts +1 -9
- package/src/tool/privacyBlur/i18n/id.ts +1 -11
- package/src/tool/privacyBlur/i18n/it.ts +1 -11
- package/src/tool/privacyBlur/i18n/ja.ts +1 -11
- package/src/tool/privacyBlur/i18n/ko.ts +1 -11
- package/src/tool/privacyBlur/i18n/nl.ts +1 -11
- package/src/tool/privacyBlur/i18n/pl.ts +1 -11
- package/src/tool/privacyBlur/i18n/pt.ts +1 -11
- package/src/tool/privacyBlur/i18n/ru.ts +1 -11
- package/src/tool/privacyBlur/i18n/sv.ts +1 -11
- package/src/tool/privacyBlur/i18n/tr.ts +1 -11
- package/src/tool/privacyBlur/i18n/zh.ts +1 -11
- package/src/tool/privacyBlur/seo.astro +1 -1
- package/src/tool/subtitleSync/bibliography.ts +12 -0
- package/src/tool/subtitleSync/entry.ts +2 -0
- package/src/tool/subtitleSync/i18n/de.ts +1 -13
- package/src/tool/subtitleSync/i18n/en.ts +1 -13
- package/src/tool/subtitleSync/i18n/es.ts +1 -13
- package/src/tool/subtitleSync/i18n/fr.ts +1 -13
- package/src/tool/subtitleSync/i18n/id.ts +1 -13
- package/src/tool/subtitleSync/i18n/it.ts +1 -13
- package/src/tool/subtitleSync/i18n/ja.ts +1 -13
- package/src/tool/subtitleSync/i18n/ko.ts +1 -13
- package/src/tool/subtitleSync/i18n/nl.ts +1 -13
- package/src/tool/subtitleSync/i18n/pl.ts +1 -13
- package/src/tool/subtitleSync/i18n/pt.ts +1 -13
- package/src/tool/subtitleSync/i18n/ru.ts +1 -13
- package/src/tool/subtitleSync/i18n/sv.ts +1 -13
- package/src/tool/subtitleSync/i18n/tr.ts +1 -13
- package/src/tool/subtitleSync/i18n/zh.ts +1 -13
- package/src/tool/subtitleSync/seo.astro +1 -1
- package/src/tool/timelapseCalculator/bibliography.ts +20 -0
- package/src/tool/timelapseCalculator/entry.ts +2 -0
- package/src/tool/timelapseCalculator/i18n/de.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/en.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/es.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/fr.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/id.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/it.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/ja.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/ko.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/nl.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/pl.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/pt.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/ru.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/sv.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/tr.ts +1 -21
- package/src/tool/timelapseCalculator/i18n/zh.ts +1 -21
- package/src/tool/timelapseCalculator/seo.astro +2 -5
- package/src/tool/tvDistance/bibliography.ts +12 -0
- package/src/tool/tvDistance/entry.ts +2 -0
- package/src/tool/tvDistance/i18n/de.ts +1 -13
- package/src/tool/tvDistance/i18n/en.ts +1 -13
- package/src/tool/tvDistance/i18n/es.ts +1 -13
- package/src/tool/tvDistance/i18n/fr.ts +1 -13
- package/src/tool/tvDistance/i18n/id.ts +1 -13
- package/src/tool/tvDistance/i18n/it.ts +1 -13
- package/src/tool/tvDistance/i18n/ja.ts +1 -13
- package/src/tool/tvDistance/i18n/ko.ts +1 -13
- package/src/tool/tvDistance/i18n/nl.ts +1 -13
- package/src/tool/tvDistance/i18n/pl.ts +1 -13
- package/src/tool/tvDistance/i18n/pt.ts +1 -13
- package/src/tool/tvDistance/i18n/ru.ts +1 -13
- package/src/tool/tvDistance/i18n/sv.ts +1 -13
- package/src/tool/tvDistance/i18n/tr.ts +1 -13
- package/src/tool/tvDistance/i18n/zh.ts +1 -13
- package/src/tool/tvDistance/seo.astro +1 -1
- package/src/tool/videoFrameExtractor/bibliography.ts +8 -0
- package/src/tool/videoFrameExtractor/entry.ts +2 -0
- package/src/tool/videoFrameExtractor/i18n/de.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/en.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/es.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/fr.ts +1 -8
- package/src/tool/videoFrameExtractor/i18n/id.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/it.ts +1 -8
- package/src/tool/videoFrameExtractor/i18n/ja.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/ko.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/nl.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/pl.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/pt.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/ru.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/sv.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/tr.ts +1 -9
- package/src/tool/videoFrameExtractor/i18n/zh.ts +1 -9
- package/src/tool/videoFrameExtractor/seo.astro +1 -1
- package/src/tools.ts +2 -0
- package/src/types.ts +0 -2
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
.dof-root {
|
|
2
|
+
width: 100%;
|
|
3
|
+
max-width: 64rem;
|
|
4
|
+
margin: 0 auto;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.dof-grid {
|
|
8
|
+
display: grid;
|
|
9
|
+
grid-template-columns: 1fr 1fr;
|
|
10
|
+
border-radius: 1.5rem;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
border: 1px solid #e2e8f0;
|
|
13
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.theme-dark .dof-grid {
|
|
17
|
+
border-color: #334155;
|
|
18
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@media (max-width: 768px) {
|
|
22
|
+
.dof-grid {
|
|
23
|
+
grid-template-columns: 1fr;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.dof-inputs-panel {
|
|
28
|
+
padding: 2rem 3rem;
|
|
29
|
+
background: #f8fafc;
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
gap: 1.75rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.theme-dark .dof-inputs-panel {
|
|
36
|
+
background: rgba(15, 23, 42, 0.5);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@media (max-width: 768px) {
|
|
40
|
+
.dof-inputs-panel {
|
|
41
|
+
padding: 2rem;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.dof-panel-title {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: 0.5rem;
|
|
49
|
+
font-size: 1.25rem;
|
|
50
|
+
font-weight: 900;
|
|
51
|
+
color: #1e293b;
|
|
52
|
+
margin: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.theme-dark .dof-panel-title {
|
|
56
|
+
color: #f8fafc;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.dof-panel-icon {
|
|
60
|
+
width: 1.25rem;
|
|
61
|
+
height: 1.25rem;
|
|
62
|
+
color: #6366f1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.dof-field-group {
|
|
66
|
+
display: flex;
|
|
67
|
+
flex-direction: column;
|
|
68
|
+
gap: 0.6rem;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.dof-group-label {
|
|
72
|
+
font-size: 0.7rem;
|
|
73
|
+
font-weight: 700;
|
|
74
|
+
text-transform: uppercase;
|
|
75
|
+
letter-spacing: 0.08em;
|
|
76
|
+
color: #64748b;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.dof-sensor-buttons {
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-wrap: wrap;
|
|
82
|
+
gap: 0.5rem;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.dof-sensor-btn {
|
|
86
|
+
padding: 0.4rem 0.9rem;
|
|
87
|
+
border-radius: 0.5rem;
|
|
88
|
+
border: 2px solid #e2e8f0;
|
|
89
|
+
background: #fff;
|
|
90
|
+
font-size: 0.8rem;
|
|
91
|
+
font-weight: 700;
|
|
92
|
+
color: #475569;
|
|
93
|
+
cursor: pointer;
|
|
94
|
+
transition: border-color 0.15s, background 0.15s, color 0.15s;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.theme-dark .dof-sensor-btn {
|
|
98
|
+
background: #1e293b;
|
|
99
|
+
border-color: #334155;
|
|
100
|
+
color: #94a3b8;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.dof-sensor-btn:hover {
|
|
104
|
+
border-color: #6366f1;
|
|
105
|
+
color: #6366f1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.dof-sensor-btn.dof-sensor-btn-active {
|
|
109
|
+
border-color: #6366f1;
|
|
110
|
+
background: #eef2ff;
|
|
111
|
+
color: #4338ca;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.theme-dark .dof-sensor-btn.dof-sensor-btn-active {
|
|
115
|
+
background: rgba(99, 102, 241, 0.2);
|
|
116
|
+
color: #a5b4fc;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.dof-sensor-row {
|
|
120
|
+
display: flex;
|
|
121
|
+
align-items: center;
|
|
122
|
+
gap: 0.5rem;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.dof-select-wrapper {
|
|
126
|
+
position: relative;
|
|
127
|
+
flex: 1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.dof-select {
|
|
131
|
+
appearance: none;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
width: 100%;
|
|
134
|
+
background: #fff;
|
|
135
|
+
border: 2px solid #e2e8f0;
|
|
136
|
+
border-radius: 0.75rem;
|
|
137
|
+
padding: 0.45rem 2rem 0.45rem 0.75rem;
|
|
138
|
+
font-size: 0.8rem;
|
|
139
|
+
font-weight: 600;
|
|
140
|
+
color: #475569;
|
|
141
|
+
outline: none;
|
|
142
|
+
transition: border-color 0.15s;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.theme-dark .dof-select {
|
|
146
|
+
background: #1e293b;
|
|
147
|
+
border-color: #334155;
|
|
148
|
+
color: #94a3b8;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.dof-select:focus {
|
|
152
|
+
border-color: #6366f1;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.dof-select-arrow {
|
|
156
|
+
position: absolute;
|
|
157
|
+
right: 0.5rem;
|
|
158
|
+
top: 50%;
|
|
159
|
+
transform: translateY(-50%);
|
|
160
|
+
width: 1rem;
|
|
161
|
+
height: 1rem;
|
|
162
|
+
color: #94a3b8;
|
|
163
|
+
pointer-events: none;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.dof-slider-group {
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-direction: column;
|
|
169
|
+
gap: 0.5rem;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.dof-slider-header {
|
|
173
|
+
display: flex;
|
|
174
|
+
justify-content: space-between;
|
|
175
|
+
align-items: baseline;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.dof-slider-value {
|
|
179
|
+
font-size: 1.1rem;
|
|
180
|
+
font-weight: 700;
|
|
181
|
+
color: #6366f1;
|
|
182
|
+
font-variant-numeric: tabular-nums;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.theme-dark .dof-slider-value {
|
|
186
|
+
color: #a5b4fc;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.dof-slider {
|
|
190
|
+
-webkit-appearance: none;
|
|
191
|
+
appearance: none;
|
|
192
|
+
width: 100%;
|
|
193
|
+
height: 5px;
|
|
194
|
+
border-radius: 3px;
|
|
195
|
+
background: linear-gradient(to right, #6366f1 var(--pct, 33%), #e2e8f0 var(--pct, 33%));
|
|
196
|
+
outline: none;
|
|
197
|
+
cursor: pointer;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.theme-dark .dof-slider {
|
|
201
|
+
background: linear-gradient(to right, #818cf8 var(--pct, 33%), #334155 var(--pct, 33%));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.dof-slider::-webkit-slider-thumb {
|
|
205
|
+
-webkit-appearance: none;
|
|
206
|
+
width: 20px;
|
|
207
|
+
height: 20px;
|
|
208
|
+
background: #6366f1;
|
|
209
|
+
border-radius: 50%;
|
|
210
|
+
cursor: pointer;
|
|
211
|
+
box-shadow: 0 2px 6px rgba(99, 102, 241, 0.4);
|
|
212
|
+
transition: transform 0.1s;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.dof-slider::-webkit-slider-thumb:hover {
|
|
216
|
+
transform: scale(1.15);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.dof-slider::-moz-range-thumb {
|
|
220
|
+
width: 20px;
|
|
221
|
+
height: 20px;
|
|
222
|
+
background: #6366f1;
|
|
223
|
+
border-radius: 50%;
|
|
224
|
+
border: none;
|
|
225
|
+
cursor: pointer;
|
|
226
|
+
box-shadow: 0 2px 6px rgba(99, 102, 241, 0.4);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* Distance slider with unit toggle */
|
|
230
|
+
.dof-distance-header {
|
|
231
|
+
display: flex;
|
|
232
|
+
justify-content: space-between;
|
|
233
|
+
align-items: center;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.dof-unit-toggle {
|
|
237
|
+
display: flex;
|
|
238
|
+
border-radius: 0.5rem;
|
|
239
|
+
overflow: hidden;
|
|
240
|
+
border: 2px solid #e2e8f0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.theme-dark .dof-unit-toggle {
|
|
244
|
+
border-color: #334155;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.dof-unit-btn {
|
|
248
|
+
padding: 0.2rem 0.6rem;
|
|
249
|
+
font-size: 0.7rem;
|
|
250
|
+
font-weight: 700;
|
|
251
|
+
border: none;
|
|
252
|
+
background: transparent;
|
|
253
|
+
color: #94a3b8;
|
|
254
|
+
cursor: pointer;
|
|
255
|
+
transition: background 0.15s, color 0.15s;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.dof-unit-btn.dof-unit-btn-active {
|
|
259
|
+
background: #6366f1;
|
|
260
|
+
color: #fff;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.dof-results-panel {
|
|
264
|
+
padding: 2rem 3rem;
|
|
265
|
+
background: linear-gradient(135deg, #4f46e5, #7c3aed);
|
|
266
|
+
color: #fff;
|
|
267
|
+
display: flex;
|
|
268
|
+
flex-direction: column;
|
|
269
|
+
gap: 1.5rem;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
@media (max-width: 768px) {
|
|
273
|
+
.dof-results-panel {
|
|
274
|
+
padding: 2rem;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.dof-results-title {
|
|
279
|
+
display: flex;
|
|
280
|
+
align-items: center;
|
|
281
|
+
gap: 0.5rem;
|
|
282
|
+
font-size: 1.25rem;
|
|
283
|
+
font-weight: 900;
|
|
284
|
+
color: #c7d2fe;
|
|
285
|
+
margin: 0;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.dof-results-icon {
|
|
289
|
+
width: 1.25rem;
|
|
290
|
+
height: 1.25rem;
|
|
291
|
+
color: #a5b4fc;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.dof-primary {
|
|
295
|
+
display: flex;
|
|
296
|
+
flex-direction: column;
|
|
297
|
+
gap: 0.25rem;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.dof-primary-label {
|
|
301
|
+
font-size: 0.7rem;
|
|
302
|
+
font-weight: 700;
|
|
303
|
+
text-transform: uppercase;
|
|
304
|
+
letter-spacing: 0.1em;
|
|
305
|
+
color: #c7d2fe;
|
|
306
|
+
margin: 0;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.dof-primary-value {
|
|
310
|
+
font-size: clamp(3rem, 8vw, 4.5rem);
|
|
311
|
+
font-weight: 900;
|
|
312
|
+
letter-spacing: -0.03em;
|
|
313
|
+
line-height: 1;
|
|
314
|
+
font-variant-numeric: tabular-nums;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.dof-bar-wrapper {
|
|
318
|
+
display: flex;
|
|
319
|
+
flex-direction: column;
|
|
320
|
+
gap: 0.25rem;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.dof-bar-svg {
|
|
324
|
+
width: 100%;
|
|
325
|
+
height: 80px;
|
|
326
|
+
overflow: visible;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.dof-error {
|
|
330
|
+
display: none;
|
|
331
|
+
padding: 0.75rem 1rem;
|
|
332
|
+
background: rgba(239, 68, 68, 0.25);
|
|
333
|
+
border: 1px solid rgba(239, 68, 68, 0.5);
|
|
334
|
+
border-radius: 0.75rem;
|
|
335
|
+
font-size: 0.85rem;
|
|
336
|
+
font-weight: 600;
|
|
337
|
+
color: #fca5a5;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.dof-stats-grid {
|
|
341
|
+
display: grid;
|
|
342
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
343
|
+
gap: 1rem;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.dof-stat {
|
|
347
|
+
display: flex;
|
|
348
|
+
flex-direction: column;
|
|
349
|
+
gap: 0.2rem;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.dof-stat-label {
|
|
353
|
+
font-size: 0.6rem;
|
|
354
|
+
font-weight: 700;
|
|
355
|
+
text-transform: uppercase;
|
|
356
|
+
letter-spacing: 0.1em;
|
|
357
|
+
color: #c7d2fe;
|
|
358
|
+
margin: 0;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.dof-stat-value {
|
|
362
|
+
font-size: 1.1rem;
|
|
363
|
+
font-weight: 700;
|
|
364
|
+
font-variant-numeric: tabular-nums;
|
|
365
|
+
margin: 0;
|
|
366
|
+
line-height: 1.2;
|
|
367
|
+
color: #e0e7ff;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.dof-details {
|
|
371
|
+
border-top: 1px solid rgba(165, 180, 252, 0.3);
|
|
372
|
+
padding-top: 1rem;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.dof-details-toggle {
|
|
376
|
+
background: none;
|
|
377
|
+
border: none;
|
|
378
|
+
color: #a5b4fc;
|
|
379
|
+
font-size: 0.75rem;
|
|
380
|
+
font-weight: 600;
|
|
381
|
+
cursor: pointer;
|
|
382
|
+
display: flex;
|
|
383
|
+
align-items: center;
|
|
384
|
+
gap: 0.4rem;
|
|
385
|
+
padding: 0;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.dof-details-toggle:hover {
|
|
389
|
+
color: #c7d2fe;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.dof-details-icon {
|
|
393
|
+
width: 1rem;
|
|
394
|
+
height: 1rem;
|
|
395
|
+
transition: transform 0.2s;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.dof-details-icon-open {
|
|
399
|
+
transform: rotate(180deg);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.dof-details-content {
|
|
403
|
+
display: none;
|
|
404
|
+
margin-top: 0.75rem;
|
|
405
|
+
font-size: 0.8rem;
|
|
406
|
+
color: #c7d2fe;
|
|
407
|
+
line-height: 1.6;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.dof-details-content-visible {
|
|
411
|
+
display: block;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.dof-coc-value {
|
|
415
|
+
font-weight: 700;
|
|
416
|
+
color: #a5b4fc;
|
|
417
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AudiovisualToolEntry, ToolLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export interface DepthOfFieldUI {
|
|
4
|
+
title: string;
|
|
5
|
+
paramsTitle: string;
|
|
6
|
+
sensorLabel: string;
|
|
7
|
+
moreLabel: string;
|
|
8
|
+
apertureLabel: string;
|
|
9
|
+
focalLabel: string;
|
|
10
|
+
distanceLabel: string;
|
|
11
|
+
metersLabel: string;
|
|
12
|
+
feetLabel: string;
|
|
13
|
+
resultsTitle: string;
|
|
14
|
+
totalDofLabel: string;
|
|
15
|
+
infiniteLabel: string;
|
|
16
|
+
nearLimitLabel: string;
|
|
17
|
+
farLimitLabel: string;
|
|
18
|
+
hyperfocalLabel: string;
|
|
19
|
+
cocLabel: string;
|
|
20
|
+
cocUnit: string;
|
|
21
|
+
showDetailsLabel: string;
|
|
22
|
+
hideDetailsLabel: string;
|
|
23
|
+
errorBelowFocal: string;
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type DepthOfFieldLocaleContent = ToolLocaleContent<DepthOfFieldUI>;
|
|
28
|
+
|
|
29
|
+
export const depthOfFieldCalculator: AudiovisualToolEntry<DepthOfFieldUI> = {
|
|
30
|
+
id: 'depth-of-field-calculator',
|
|
31
|
+
icons: {
|
|
32
|
+
bg: 'mdi:lens',
|
|
33
|
+
fg: 'mdi:image-filter-center-focus',
|
|
34
|
+
},
|
|
35
|
+
i18n: {
|
|
36
|
+
de: async () => (await import('./i18n/de')).content as unknown as DepthOfFieldLocaleContent,
|
|
37
|
+
en: async () => (await import('./i18n/en')).content as unknown as DepthOfFieldLocaleContent,
|
|
38
|
+
es: async () => (await import('./i18n/es')).content as unknown as DepthOfFieldLocaleContent,
|
|
39
|
+
fr: async () => (await import('./i18n/fr')).content as unknown as DepthOfFieldLocaleContent,
|
|
40
|
+
id: async () => (await import('./i18n/id')).content as unknown as DepthOfFieldLocaleContent,
|
|
41
|
+
it: async () => (await import('./i18n/it')).content as unknown as DepthOfFieldLocaleContent,
|
|
42
|
+
ja: async () => (await import('./i18n/ja')).content as unknown as DepthOfFieldLocaleContent,
|
|
43
|
+
ko: async () => (await import('./i18n/ko')).content as unknown as DepthOfFieldLocaleContent,
|
|
44
|
+
nl: async () => (await import('./i18n/nl')).content as unknown as DepthOfFieldLocaleContent,
|
|
45
|
+
pl: async () => (await import('./i18n/pl')).content as unknown as DepthOfFieldLocaleContent,
|
|
46
|
+
pt: async () => (await import('./i18n/pt')).content as unknown as DepthOfFieldLocaleContent,
|
|
47
|
+
ru: async () => (await import('./i18n/ru')).content as unknown as DepthOfFieldLocaleContent,
|
|
48
|
+
sv: async () => (await import('./i18n/sv')).content as unknown as DepthOfFieldLocaleContent,
|
|
49
|
+
tr: async () => (await import('./i18n/tr')).content as unknown as DepthOfFieldLocaleContent,
|
|
50
|
+
zh: async () => (await import('./i18n/zh')).content as unknown as DepthOfFieldLocaleContent,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { bibliography } from '../bibliography';
|
|
2
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
3
|
+
import type { DepthOfFieldUI, DepthOfFieldLocaleContent } from '../index';
|
|
4
|
+
|
|
5
|
+
const slug = 'scharfentiefe-rechner';
|
|
6
|
+
const title = 'Schärfentiefe Rechner: Echtzeit DoF für jede Kamera';
|
|
7
|
+
const description = 'Berechnen Sie Schärfentiefe, Hyperfokaldistanz und Fokusgrenzen in Echtzeit. Unterstützt alle Sensorgrößen mit 1/3 Blendenpräzision.';
|
|
8
|
+
|
|
9
|
+
const ui: DepthOfFieldUI = {
|
|
10
|
+
title: 'Schärfentiefe Rechner',
|
|
11
|
+
paramsTitle: 'Parameter',
|
|
12
|
+
sensorLabel: 'Kamerasensor',
|
|
13
|
+
moreLabel: 'Weitere Sensoren…',
|
|
14
|
+
apertureLabel: 'Blende',
|
|
15
|
+
focalLabel: 'Brennweite',
|
|
16
|
+
distanceLabel: 'Motivabstand',
|
|
17
|
+
metersLabel: 'm',
|
|
18
|
+
feetLabel: 'ft',
|
|
19
|
+
resultsTitle: 'Ergebnisse',
|
|
20
|
+
totalDofLabel: 'Gesamte Schärfentiefe',
|
|
21
|
+
infiniteLabel: 'Unendlich',
|
|
22
|
+
nearLimitLabel: 'Nahgrenze',
|
|
23
|
+
farLimitLabel: 'Ferngrenze',
|
|
24
|
+
hyperfocalLabel: 'Hyperfokal',
|
|
25
|
+
cocLabel: 'Zerstreuungskreis',
|
|
26
|
+
cocUnit: 'mm',
|
|
27
|
+
showDetailsLabel: 'Technische Details anzeigen',
|
|
28
|
+
hideDetailsLabel: 'Technische Details ausblenden',
|
|
29
|
+
errorBelowFocal: 'Der Motivabstand muss größer als die Brennweite sein.',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const faq: DepthOfFieldLocaleContent['faq'] = [
|
|
33
|
+
{
|
|
34
|
+
question: 'Was ist Schärfentiefe?',
|
|
35
|
+
answer: 'Die Schärfentiefe (DoF) ist der Entfernungsbereich in einer Szene, der im fertigen Bild akzeptabel scharf erscheint. Sie wird durch Blende, Brennweite, Motivabstand und Sensorgröße bestimmt.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
question: 'Was ist die hyperfokale Distanz?',
|
|
39
|
+
answer: 'Die hyperfokale Distanz ist die kürzeste Fokusentfernung, bei der Objekte im Unendlichen noch akzeptabel scharf sind. Eine Fokussierung auf diese Distanz maximiert die Schärfentiefe.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
question: 'Warum verringert eine größere Blendenöffnung die Schärfentiefe?',
|
|
43
|
+
answer: 'Eine weitere Blendenöffnung sammelt Licht über einen größeren Bereich des Objektivs, was den Zerstreuungskreis für unscharfe Punkte vergrößert. Dies verengt die Zone der akzeptablen Schärfe.',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
question: 'Wie beeinflusst die Sensorgröße die Schärfentiefe?',
|
|
47
|
+
answer: 'Größere Sensoren verwenden einen größeren Zerstreuungskreis-Schwellenwert. Bei äquivalenten Bildwinkeln erzeugen größere Sensoren jedoch meist eine geringere Schärfentiefe, da sie längere Brennweiten erfordern.',
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const howTo: DepthOfFieldLocaleContent['howTo'] = [
|
|
52
|
+
{
|
|
53
|
+
name: 'Wählen Sie Ihren Kamerasensor',
|
|
54
|
+
text: 'Wählen Sie das Sensorformat aus, das Ihrem Kameragehäuse entspricht. Dies legt den Wert für den Zerstreuungskreis (CoC) fest.',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'Blende und Brennweite einstellen',
|
|
58
|
+
text: 'Wählen Sie die Blende in 1/3-Stufen-Schritten. Der Brennweiten-Schieberegler verwendet eine logarithmische Skala für mehr Granularität im Weitwinkelbereich.',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'Motivabstand festlegen',
|
|
62
|
+
text: 'Stellen Sie den Abstand zwischen Kamera und Hauptmotiv ein. Wechseln Sie bei Bedarf zwischen Metern und Fuß.',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'Ergebnisse ablesen',
|
|
66
|
+
text: 'Der Fokusbalken visualisiert den scharfen Bereich um Ihr Motiv. Nah- und Ferngrenze zeigen die genauen Grenzen der akzeptablen Schärfe.',
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
const seo: DepthOfFieldLocaleContent['seo'] = [
|
|
71
|
+
{ type: 'title', text: 'Schärfentiefe in Fotografie und Film verstehen', level: 2 },
|
|
72
|
+
{ type: 'paragraph', html: 'Die Schärfentiefe ist eines der mächtigsten kreativen Werkzeuge. Eine <strong>geringe Schärfentiefe</strong> isoliert Motive, während eine <strong>große Schärfentiefe</strong> weite Landschaften scharf hält. Dieser Rechner gibt Ihnen die volle Kontrolle.' },
|
|
73
|
+
|
|
74
|
+
{ type: 'title', text: 'Die drei Variablen der Schärfentiefe', level: 3 },
|
|
75
|
+
{ type: 'table', headers: ['Variable', 'Erhöhung →', 'Effekt auf DoF'], rows: [
|
|
76
|
+
['Blende', 'f/1.4 → f/16', 'Größere Blende = geringere Schärfentiefe'],
|
|
77
|
+
['Brennweite', '24mm → 200mm', 'Längere Brennweite = geringere Schärfentiefe'],
|
|
78
|
+
['Abstand', '1m → 10m', 'Größerer Abstand = größere Schärfentiefe'],
|
|
79
|
+
]},
|
|
80
|
+
|
|
81
|
+
{ type: 'title', text: 'Die hyperfokale Distanz: Maximale Schärfe', level: 3 },
|
|
82
|
+
{ type: 'paragraph', html: 'Wenn Sie auf die <strong>hyperfokale Distanz</strong> fokussieren, erscheint alles von der halben Distanz bis Unendlich scharf. Ideal für die Landschaftsfotografie.' },
|
|
83
|
+
{ type: 'tip', title: 'Praxistipp', html: 'Stellen Sie in der Straßenfotografie den Fokus auf die Hyperfokaldistanz ein. Mit einem 35mm-Objektiv an APS-C bei f/8 liegt diese bei ca. <strong>4 Metern</strong> – alles von 2m bis Unendlich wird scharf.' },
|
|
84
|
+
|
|
85
|
+
{ type: 'title', text: 'Sensorgröße und Zerstreuungskreis', level: 3 },
|
|
86
|
+
{ type: 'paragraph', html: 'Der <strong>Zerstreuungskreis (CoC)</strong> definiert die akzeptable Schärfe. Ein Vollformatsensor hat einen CoC von 0,030 mm; ein Smartphonesensor ca. 0,006 mm. Kleinere CoC-Werte bedeuten strengere Schärfekriterien.' },
|
|
87
|
+
{ type: 'stats', columns: 3, items: [
|
|
88
|
+
{ label: 'Vollformat', value: '0,030 mm', icon: 'mdi:camera' },
|
|
89
|
+
{ label: 'APS-C', value: '0,019 mm', icon: 'mdi:camera-outline' },
|
|
90
|
+
{ label: 'Smartphone', value: '0,006 mm', icon: 'mdi:cellphone' },
|
|
91
|
+
]},
|
|
92
|
+
|
|
93
|
+
{ type: 'title', text: 'DoF im Kino: Brennweite vs. Sensor', level: 3 },
|
|
94
|
+
{ type: 'paragraph', html: 'Cinematographen, die auf Super 35 drehen, nutzen oft längere Brennweiten für den typischen "Cinematic Look". Die Kombination aus lichtstarkem Objektiv und 85mm+ Brennweite ist der Klassiker.' },
|
|
95
|
+
{ type: 'diagnostic', variant: 'success', title: 'Die Fokus Verteilungsregel', icon: 'mdi:lightbulb-outline', badge: 'Profi Technik', html: 'Bei einem Motiv in 3m Entfernung mit 50mm bei f/2.8: Der Bereich hinter dem Motiv ist immer größer als der davor – etwa im <strong>Verhältnis 2:1</strong>.' },
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
99
|
+
'@context': 'https://schema.org',
|
|
100
|
+
'@type': 'FAQPage',
|
|
101
|
+
mainEntity: faq.map((item) => ({
|
|
102
|
+
'@type': 'Question',
|
|
103
|
+
name: item.question,
|
|
104
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
105
|
+
})),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const howToSchema: WithContext<HowTo> = {
|
|
109
|
+
'@context': 'https://schema.org',
|
|
110
|
+
'@type': 'HowTo',
|
|
111
|
+
name: title,
|
|
112
|
+
description,
|
|
113
|
+
step: howTo.map((step) => ({
|
|
114
|
+
'@type': 'HowToStep',
|
|
115
|
+
name: step.name,
|
|
116
|
+
text: step.text,
|
|
117
|
+
})),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
121
|
+
'@context': 'https://schema.org',
|
|
122
|
+
'@type': 'SoftwareApplication',
|
|
123
|
+
name: title,
|
|
124
|
+
description,
|
|
125
|
+
applicationCategory: 'UtilitiesApplication',
|
|
126
|
+
operatingSystem: 'Web',
|
|
127
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
128
|
+
inLanguage: 'de',
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const content: DepthOfFieldLocaleContent = {
|
|
132
|
+
slug,
|
|
133
|
+
title,
|
|
134
|
+
description,
|
|
135
|
+
ui,
|
|
136
|
+
seo,
|
|
137
|
+
faq,
|
|
138
|
+
bibliography,
|
|
139
|
+
howTo,
|
|
140
|
+
schemas: [faqSchema as any, howToSchema as any, appSchema],
|
|
141
|
+
};
|