slidev
slidev copied to clipboard
feat: print templates, slide layers and rewrite export function
close #1509
This PR:
- Allow user to customize print template via the
--template
or-t
option. In dev mode, the option is called--print-template
.- User can add or override print template via
./pages/print/*.{vue,ts}
- Print page is no longer being bundled in the build mode
- The
export-notes
sub-command is removed. Use-t notes
instead. - Previously,
-t
was the alias of--theme
, but--theme
is quite uncommon.
- User can add or override print template via
- Add the "handout" print template (close #1421)
- Add new layers for each slide:
-
layouts/slide-top.vue
-
layouts/slide-bottom.vue
-
- Refactors DOM structure
The locations of the files and option names need some discussion.
Deploy Preview for slidev ready!
Name | Link |
---|---|
Latest commit | 75f0744d13311ae46a68dc9cc96d5530db1bb428 |
Latest deploy log | https://app.netlify.com/sites/slidev/deploys/663b2d0a1f118000082ba891 |
Deploy Preview | https://deploy-preview-1513--slidev.netlify.app |
Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site configuration.
In order to make the handout https://github.com/slidevjs/slidev/pull/1421 pull request work with this code I found that I need to be able to control the scaling factor (zoom) inside SlideWrapper.vue
Currently it is retrieved from the front matter
const zoom = computed(() => props.route.meta?.slide?.frontmatter.zoom ?? 1)
If that would be configurable from a template (e.g. via inject) it would solve the problem that I ran into when implementing a notes template (point 2) where one adjusts the width and height correctly to fit an A4 page but the scale of the content is not adjusted and the content overflows out of the slide.
Here is a current draft of the notes template
In order to make the handout #1421 pull request work with this code I found that I need to be able to control the scaling factor (zoom) inside SlideWrapper.vue
Currently it is retrieved from the front matter
const zoom = computed(() => props.route.meta?.slide?.frontmatter.zoom ?? 1)
If that would be configurable from a template (e.g. via inject) it would solve the problem that I ran into when implementing a notes template (point 2) where one adjusts the width and height correctly to fit an A4 page but the scale of the content is not adjusted and the content overflows out of the slide.
Here is a current draft of the notes template
About the debugging issue you said in #1421, there is a --print-template
option in this PR now.
About the slide scale, we can use <SlideContainer>
here (I will do this change).
I tried the latest commit. Seems like solving a lot of issues.
One thing I noted is that the page aligns well in Firefox but not in Chrome and when exporting on the command line.
Here is firefox on the left, chrome on the right
And a document npx slidev export -t handout
Maybe an issue with some css?
After a bit more testing, it seems that having a slide like this with transitions and renderwhen results in an empty slide.
---
# Test
<RenderWhen context="visible">
<transition appear name="outro">
<img class="h-80 mx-auto" src="https://github.com/slidevjs/themes/blob/main/screenshots/theme-seriph/01.png?raw=true" alt="">
</transition>
</RenderWhen>
<!--Test-->
<style>
.outro-enter-from {
opacity: 0;
transform: translate(-40px, 40px);
}
.outro-enter-active {
transition: all 0.5s ease-in-out;
}
.outro-enter-to {
transform: translate(0, 0);
}
.slidev-layout.outro {
@apply bg-bottom bg-right;
}
</style>
I spent 2 hours on this, trying to figure out why the page is (exactly) 1.5x larger than the expected size, but made no progress. The output is still like this:
I spent 2 hours on this, trying to figure out why the page is (exactly) 1.5x larger than the expected size, but made no progress. The output is still like this:
Yes I have also spend some time debugging. I have found that changing the scale factor to 1.5 in export.ts
works with your handout code, when exporting:
async function genPagePdfOnePiece() {
await go('print')
await page.pdf({
path: output,
scale: 1.5,
margin: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
printBackground: true,
preferCSSPageSize: true,
})
It might have to do with the DPI setting when exporting PDFs, here is a gist for debugging that tries to calculate the width and height according to the DPI (which is hardcoded for now): https://gist.github.com/oripka/36f4589df0fa72ed5758261c0a870264
The page breaks are now correct. The notes need a max-w-full in order to take the whole width.
t might have to do with the DPI setting when exporting PDFs
I tried to set this setting to 100%
and restart the browser:
, but the page is still 1.5x larger. I am worried that if we hard-code 1.5
in the code, it may not work on some machine🥺
Maybe this is related to these known issues (pupeteer and chrome):
https://issues.chromium.org/issues/40144973#comment9 https://github.com/puppeteer/puppeteer/issues/666 https://github.com/puppeteer/puppeteer/issues/2278
I tried this code to determine it dynamically, but I think this is the incorrect DPI for printing, as this is one just displaying the page, not while generating the PDF. In my case it is 96. In the docs I found that the default reference value for PDF should be 72, which does not result in the 1.5 scale. It also contradicts the DPI of 144 that I found using tinkering: https://gist.github.com/oripka/36f4589df0fa72ed5758261c0a870264
const dpi = await page.evaluate(() => {
const div = document.createElement('div');
div.style.position = 'absolute';
div.style.top = 0;
div.style.left = 0;
div.style.width = '1in';
div.style.height = '1in';
document.body.appendChild(div);
const height = div.offsetHeight;
div.remove();
return height;
});
Maybe we should provide a sane default, test on Windows, Linux and macOS, in case there are any differences and make it a command line option.
After some consideration I think I have to rewrite the export logic (this existing one is kind of messed up) Especially I am going to rewrite the --per-slide
option.