Closed titoworlddev closed 1 year ago
Unfortunately, I did not find a way to automatically fill the paper with a background image.
But you can calculate the total height in advance and set it in CSS to ensure that the last page can be fully filled. In this way, the background image can also fill the paper.
You can add an extra div element (<div class="brochure-background"/>
) that will act as the background to fill the entire page.
div.brochure-background {
position: fixed;
z-index: -1;
top: var(--brochure-header-height);
width: 100%;
height: calc(100% - var(--brochure-footer-height) - var(--brochure-header-height));
background-color: hsl(var(--background));
page-break-after: always;
}
Just make sure it's inserted below the footer element (if you have it).
You can add an extra div element (
<div class="brochure-background"/>
) that will act as the background to fill the entire page.div.brochure-background { position: fixed; z-index: -1; top: var(--brochure-header-height); width: 100%; height: calc(100% - var(--brochure-footer-height) - var(--brochure-header-height)); background-color: hsl(var(--background)); page-break-after: always; }
Just make sure it's inserted below the footer element (if you have it).
That's perfect friend!!
Thank you very much, you have helped me a lot. I would even give you a kiss hahaha
It would also be interesting to add an option to the package that would do it automatically, but for the moment it works fine for me.
Thanks again.
It would also be interesting to add an option to the package that would do it automatically
PRs are always welcome, though not sure we would want to introduce opinionated style props. However, would be happy to see something about this added to the README style tips section
It would also be interesting to add an option to the package that would do it automatically
PRs are always welcome, though not sure we would want to introduce opinionated style props. However, would be happy to see something about this added to the README style tips section
I'll be happy to add in a PR as soon as I have time. At the moment this website takes up all my time but I keep it in mind.
top: var(--brochure-header-height);
You can add an extra div element (
<div class="brochure-background"/>
) that will act as the background to fill the entire page.div.brochure-background { position: fixed; z-index: -1; top: var(--brochure-header-height); width: 100%; height: calc(100% - var(--brochure-footer-height) - var(--brochure-header-height)); background-color: hsl(var(--background)); page-break-after: always; }
Just make sure it's inserted below the footer element (if you have it).
Good job!! This is really a brilliant approach. I will study later how it was implemented.
top: var(--brochure-header-height);
Puede agregar un elemento div adicional (
<div class="brochure-background"/>
) que actuará como fondo para llenar toda la página.div.brochure-background { position: fixed; z-index: -1; top: var(--brochure-header-height); width: 100%; height: calc(100% - var(--brochure-footer-height) - var(--brochure-header-height)); background-color: hsl(var(--background)); page-break-after: always; }
Solo asegúrese de que esté insertado debajo del elemento de pie de página (si lo tiene).
¡¡Buen trabajo!! Este es realmente un enfoque brillante. Más adelante estudiaré cómo se implementó.
@siaikin
Actually my solution was to use the same thing that @Tpuljak said, but since I was not clear where the var() that he uses in the css come from, I did it with values.
Here my jsx
import { useContext, useEffect, useState } from 'react';
import { useGetExercises } from '../../services/getExercises';
import './WorkoutToPrint.css';
import { LocalStorageContext } from '../../contexts/LocalStorage/LocalStorageContext';
import BarbellIcon from '../Icons/BarbellIcon';
import GymPersonIcon from '../Icons/GymPersonIcon';
import { useAppLanguageStore } from '../../stores/appLanguageStore';
import { languages } from '../../languages/languages';
/**
*
* @param {Object} props
* @param {React.MutableRefObject<any>} props.useRef Ref of the object to handlePrint
*/
export default function WorkoutToPrint({ useRef }) {
const { pdfImageURL, userClients, currentClientIndex, currentClient } =
useContext(LocalStorageContext);
const { getExercises } = useGetExercises();
const { appLanguage } = useAppLanguageStore(state => state);
const weekDays = languages[appLanguage].weekDays;
/**
* @type {[Workout, React.Dispatch<React.SetStateAction<Workout>>]}
*/
const [currentWorkout, setCurrentWorkout] = useState(
userClients[currentClientIndex].workouts[
userClients[currentClientIndex].currentWorkoutIndex
]
);
useEffect(() => {
setCurrentWorkout(
userClients[currentClientIndex].workouts[
userClients[currentClientIndex].currentWorkoutIndex
] || {}
);
}, [userClients]);
return (
<div
ref={useRef}
className="workout-to-print"
// @ts-ignore
style={{ '--background-image': `url(${pdfImageURL})` }}
>
<div className="pdf-content">
<div className="pdf-title">
<div className="title-1">
<BarbellIcon />
<div className="hr"></div>
{/* <h1>{currentClient.clientName}</h1> */}
</div>
<h1>{currentClient.clientName}</h1>
{/* <div className="hr"></div> */}
<div className="title-2">
{/* <h1>{currentWorkout.workoutName}</h1> */}
<div className="hr"></div>
<GymPersonIcon />
</div>
</div>
{currentWorkout.workoutDays
? currentWorkout.workoutDays.map((day, index) => (
<div className="workout-to-print-day" key={day.dayName + index}>
<h2 className="workout-to-print-day-title">{`${weekDays[index]} - ${day.dayName}`}</h2>
<div className="workout-to-print-day-exercises">
{day.dayExercises.map((exercise, index) => {
const exer = getExercises().find(
exer => exer.id === exercise.exerciseId
);
return (
<div
key={exercise.exerciseId + index}
className="workout-to-print-day-exercise"
>
<img alt="img" src={exer?.gifUrl} />
<div className="exercise-texts">
<h3>
{exer?.name
// @ts-ignore
.capitalize()}
</h3>
<p>
Target:{' '}
{exer?.target
// @ts-ignore
.capitalize()}
</p>
<p>Sets: {exercise.sets}</p>
<p>Reps: {exercise.reps}</p>
</div>
</div>
);
})}
</div>
</div>
))
: null}
<div className="brochure-background"></div>
</div>
</div>
);
}
And here my css
@media print {
@page {
size: portrait;
}
html,
body {
margin: 0 !important;
padding: 0 !important;
background-color: white;
}
}
.workout-to-print {
color: #000;
flex-direction: column;
gap: 1rem;
font-size: 9px;
padding: 1rem;
position: relative;
height: 100%;
.pdf-content {
display: flex;
flex-direction: column;
gap: 1rem;
position: relative;
z-index: 1;
height: 100%;
.pdf-title {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
gap: 1rem;
border: 1px solid black;
border-radius: 4px;
.title-1,
.title-2 {
display: flex;
gap: 1rem;
}
& svg {
stroke: black;
stroke-width: 0.01px;
transform: scale(1.75);
}
.hr {
height: 24px;
width: 2px;
background-color: black;
}
}
& h1 {
font-size: 24px;
text-align: center;
margin: 0;
padding: 0;
}
.workout-to-print-day {
break-inside: avoid;
.workout-to-print-day-title {
margin-top: 1rem;
font-size: 14px;
margin-bottom: 0.25rem;
}
.workout-to-print-day-exercises {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 110px));
gap: 1rem;
.workout-to-print-day-exercise {
border: 1px solid rgba(0, 0, 0, 0.25);
border-radius: 4px;
background-color: white;
& img {
width: 100%;
border-radius: 4px;
}
.exercise-texts {
padding: 0 6px 6px 6px;
display: flex;
flex-direction: column;
gap: 4px;
& h3 {
font-size: 9px;
}
}
}
}
}
.brochure-background {
position: fixed;
z-index: -1;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
page-break-after: always;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: var(--background-image);
background-size: cover;
filter: grayscale(100%);
opacity: 0.05;
z-index: 0;
}
}
}
}
I hope this can be of some use to you and to everyone who comes in looking for help.
I have the print component that is like a gym workout and I want an image to be seen in the background, but this image is not displayed on all the complete pages. No matter how much I try to set
height: 100%
anywhere, it doesn't work and I would like the content to go as far as it needs to go, but if when it is final there is still half a page of the pdf, I want the body to extend until the end of that page so that the image that I put in the background can be seen in full throughout the pdf, since right now it is cut off, the photo is visible and in the middle of the page everything is white until the end.You can see the example in these images:
As I said, in the end it cuts off and looks white and I can't stretch the bodysuit so that it fills everything with the image. Any idea how to fix this?
I put my component code and the CSS in case it helps me.
WorkoutToPrins.jsx
WorkoutToPrint.css
I greatly appreciate any help.
I know my code isn't the best, but I'm still learning :)