mirror of
https://github.com/timmypidashev/web.git
synced 2026-04-14 02:53:51 +00:00
Animations
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
// src/components/resources/presentation.astro
|
||||||
<button id="presentation-button" class="presentation-hidden" type="button"
|
<button id="presentation-button" class="presentation-hidden" type="button"
|
||||||
>Start Presentation</button
|
>Start Presentation</button
|
||||||
>
|
>
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
let slides = Array.from(document.querySelectorAll(".presentation-slide"));
|
let slides = Array.from(document.querySelectorAll(".presentation-slide"));
|
||||||
|
|
||||||
let slide = 0;
|
let slide = 0;
|
||||||
|
let step = 0; // Current step within the slide
|
||||||
let presenter = false;
|
let presenter = false;
|
||||||
|
|
||||||
const presentationId = window.location.href;
|
const presentationId = window.location.href;
|
||||||
@@ -20,7 +22,6 @@
|
|||||||
if (slide === slides.length - 1) {
|
if (slide === slides.length - 1) {
|
||||||
return slide;
|
return slide;
|
||||||
}
|
}
|
||||||
|
|
||||||
return slide + 1;
|
return slide + 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,7 +29,6 @@
|
|||||||
if (slide === 0) {
|
if (slide === 0) {
|
||||||
return slide;
|
return slide;
|
||||||
}
|
}
|
||||||
|
|
||||||
return slide - 1;
|
return slide - 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,9 +38,182 @@
|
|||||||
|
|
||||||
const transitionClasses = [nextClass, currClass, prevClass];
|
const transitionClasses = [nextClass, currClass, prevClass];
|
||||||
|
|
||||||
const keyHandlers: Record<string, () => number> = {
|
// Animation classes for step-through content
|
||||||
ArrowRight: nextSlide,
|
const animationClasses = {
|
||||||
ArrowLeft: prevSlide,
|
'fade-in': 'animate-fade-in-step',
|
||||||
|
'slide-in-left': 'animate-slide-in-left-step',
|
||||||
|
'slide-in-right': 'animate-slide-in-right-step',
|
||||||
|
'slide-in-up': 'animate-slide-in-up-step',
|
||||||
|
'slide-in-down': 'animate-slide-in-down-step',
|
||||||
|
'type-in': 'animate-type-in-step',
|
||||||
|
'scale-in': 'animate-scale-in-step',
|
||||||
|
'bounce-in': 'animate-bounce-in-step'
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCurrentSlideSteps = () => {
|
||||||
|
const currentSlide = slides[slide];
|
||||||
|
return Array.from(currentSlide.querySelectorAll('[step]'))
|
||||||
|
.sort((a, b) => {
|
||||||
|
const stepA = parseInt((a as HTMLElement).getAttribute('step') || '0');
|
||||||
|
const stepB = parseInt((b as HTMLElement).getAttribute('step') || '0');
|
||||||
|
return stepA - stepB;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMaxSteps = () => {
|
||||||
|
const steps = getCurrentSlideSteps();
|
||||||
|
if (steps.length === 0) return 0;
|
||||||
|
const lastStep = steps[steps.length - 1] as HTMLElement;
|
||||||
|
return parseInt(lastStep.getAttribute('step') || '0');
|
||||||
|
};
|
||||||
|
|
||||||
|
const showStepsUpTo = (targetStep: number, isReverse: boolean = false) => {
|
||||||
|
const steps = getCurrentSlideSteps();
|
||||||
|
|
||||||
|
steps.forEach((stepElement) => {
|
||||||
|
const element = stepElement as HTMLElement;
|
||||||
|
const elementStep = parseInt(element.getAttribute('step') || '0');
|
||||||
|
const animationType = element.getAttribute('animation') || 'fade-in';
|
||||||
|
|
||||||
|
// Remove all animation classes first
|
||||||
|
Object.values(animationClasses).forEach(cls => {
|
||||||
|
element.classList.remove(cls);
|
||||||
|
element.classList.remove(cls.replace('-step', '-reverse-step'));
|
||||||
|
});
|
||||||
|
element.classList.remove('step-hidden', 'step-visible');
|
||||||
|
|
||||||
|
if (elementStep <= targetStep) {
|
||||||
|
// Show this step with animation
|
||||||
|
element.classList.add('step-visible');
|
||||||
|
if (elementStep === targetStep) {
|
||||||
|
// Apply animation only to the current step
|
||||||
|
const baseAnimationClass = animationClasses[animationType as keyof typeof animationClasses] || animationClasses['fade-in'];
|
||||||
|
const animationClass = isReverse ? baseAnimationClass.replace('-step', '-reverse-step') : baseAnimationClass;
|
||||||
|
|
||||||
|
// Special handling for type-in animation
|
||||||
|
if (animationType === 'type-in') {
|
||||||
|
if (isReverse) {
|
||||||
|
startTypeAnimation(element, false);
|
||||||
|
} else {
|
||||||
|
startTypeAnimation(element, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
element.classList.add(animationClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Hide this step
|
||||||
|
element.classList.add('step-hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const startTypeAnimation = (element: HTMLElement, isForward: boolean) => {
|
||||||
|
const text = element.textContent || '';
|
||||||
|
const duration = isForward ? 1500 : 1000; // ms
|
||||||
|
const steps = Math.max(text.length, 1);
|
||||||
|
const stepDuration = duration / steps;
|
||||||
|
|
||||||
|
if (isForward) {
|
||||||
|
// Type in: reveal characters one by one
|
||||||
|
element.textContent = '';
|
||||||
|
element.style.opacity = '1';
|
||||||
|
|
||||||
|
let currentIndex = 0;
|
||||||
|
const typeInterval = setInterval(() => {
|
||||||
|
if (currentIndex < text.length) {
|
||||||
|
element.textContent = text.substring(0, currentIndex + 1);
|
||||||
|
currentIndex++;
|
||||||
|
} else {
|
||||||
|
clearInterval(typeInterval);
|
||||||
|
}
|
||||||
|
}, stepDuration);
|
||||||
|
|
||||||
|
// Store interval reference for cleanup
|
||||||
|
(element as any)._typeInterval = typeInterval;
|
||||||
|
} else {
|
||||||
|
// Type out: hide characters one by one from the end
|
||||||
|
let currentLength = text.length;
|
||||||
|
const typeInterval = setInterval(() => {
|
||||||
|
if (currentLength > 0) {
|
||||||
|
element.textContent = text.substring(0, currentLength - 1);
|
||||||
|
currentLength--;
|
||||||
|
} else {
|
||||||
|
clearInterval(typeInterval);
|
||||||
|
element.style.opacity = '0';
|
||||||
|
}
|
||||||
|
}, stepDuration);
|
||||||
|
|
||||||
|
// Store interval reference for cleanup
|
||||||
|
(element as any)._typeInterval = typeInterval;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetSlideSteps = () => {
|
||||||
|
const steps = getCurrentSlideSteps();
|
||||||
|
steps.forEach((stepElement) => {
|
||||||
|
const element = stepElement as HTMLElement;
|
||||||
|
|
||||||
|
// Clear any running type animations
|
||||||
|
if ((element as any)._typeInterval) {
|
||||||
|
clearInterval((element as any)._typeInterval);
|
||||||
|
(element as any)._typeInterval = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.values(animationClasses).forEach(cls => {
|
||||||
|
element.classList.remove(cls);
|
||||||
|
element.classList.remove(cls.replace('-step', '-reverse-step'));
|
||||||
|
});
|
||||||
|
element.classList.remove('step-hidden', 'step-visible');
|
||||||
|
element.classList.add('step-hidden');
|
||||||
|
|
||||||
|
// Reset text content and styles for type-in elements
|
||||||
|
if (element.getAttribute('animation') === 'type-in') {
|
||||||
|
element.style.opacity = '0';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const nextStep = () => {
|
||||||
|
const maxSteps = getMaxSteps();
|
||||||
|
|
||||||
|
if (step < maxSteps) {
|
||||||
|
step++;
|
||||||
|
showStepsUpTo(step, false);
|
||||||
|
return { slide, step };
|
||||||
|
} else {
|
||||||
|
// Move to next slide
|
||||||
|
if (slide < slides.length - 1) {
|
||||||
|
const nextSlideIndex = nextSlide();
|
||||||
|
return { slide: nextSlideIndex, step: 0 };
|
||||||
|
}
|
||||||
|
return { slide, step };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const prevStep = () => {
|
||||||
|
if (step > 0) {
|
||||||
|
step--;
|
||||||
|
showStepsUpTo(step, true);
|
||||||
|
return { slide, step };
|
||||||
|
} else {
|
||||||
|
// Move to previous slide
|
||||||
|
if (slide > 0) {
|
||||||
|
const prevSlideIndex = prevSlide();
|
||||||
|
// Set to max steps of previous slide
|
||||||
|
const tempSlide = slide;
|
||||||
|
slide = prevSlideIndex;
|
||||||
|
const maxSteps = getMaxSteps();
|
||||||
|
slide = tempSlide;
|
||||||
|
return { slide: prevSlideIndex, step: maxSteps };
|
||||||
|
}
|
||||||
|
return { slide, step };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const keyHandlers: Record<string, () => { slide: number, step: number }> = {
|
||||||
|
ArrowRight: nextStep,
|
||||||
|
ArrowLeft: prevStep,
|
||||||
};
|
};
|
||||||
|
|
||||||
const displaySlides = () => {
|
const displaySlides = () => {
|
||||||
@@ -49,8 +222,15 @@
|
|||||||
|
|
||||||
if (i === slide) {
|
if (i === slide) {
|
||||||
slides[i].classList.add("active", currClass);
|
slides[i].classList.add("active", currClass);
|
||||||
|
// Show steps for current slide
|
||||||
|
showStepsUpTo(step, false);
|
||||||
} else {
|
} else {
|
||||||
slides[i].classList.add("inactive");
|
slides[i].classList.add("inactive");
|
||||||
|
// Reset steps for non-current slides
|
||||||
|
const tempSlide = slide;
|
||||||
|
slide = i;
|
||||||
|
resetSlideSteps();
|
||||||
|
slide = tempSlide;
|
||||||
|
|
||||||
if (i > slide) {
|
if (i > slide) {
|
||||||
slides[i].classList.add(nextClass);
|
slides[i].classList.add(nextClass);
|
||||||
@@ -61,62 +241,89 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let presenting = false
|
let presenting = false;
|
||||||
const startPresentation = () => {
|
const startPresentation = () => {
|
||||||
button.innerHTML = "Resume presentation";
|
button.innerHTML = "Resume presentation";
|
||||||
document.body.classList.add("presentation-overflow-hidden");
|
document.body.classList.add("presentation-overflow-hidden");
|
||||||
|
|
||||||
presenting = true
|
presenting = true;
|
||||||
|
step = 0; // Reset step
|
||||||
displaySlides();
|
displaySlides();
|
||||||
setProgress();
|
setProgress();
|
||||||
initListeners()
|
initListeners();
|
||||||
};
|
};
|
||||||
|
|
||||||
const endPresentation = () => {
|
const endPresentation = () => {
|
||||||
document.body.classList.remove("presentation-overflow-hidden");
|
document.body.classList.remove("presentation-overflow-hidden");
|
||||||
|
|
||||||
presenting = false
|
presenting = false;
|
||||||
slides.map((s) =>
|
step = 0;
|
||||||
s.classList.remove("active", "inactive", ...transitionClasses)
|
slides.map((s) => {
|
||||||
);
|
s.classList.remove("active", "inactive", ...transitionClasses);
|
||||||
|
// Reset all steps
|
||||||
|
const tempSlide = slide;
|
||||||
|
slides.forEach((_, i) => {
|
||||||
|
slide = i;
|
||||||
|
resetSlideSteps();
|
||||||
|
});
|
||||||
|
slide = tempSlide;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const setPresenter = () => {
|
const setPresenter = () => {
|
||||||
presenter = true;
|
presenter = true;
|
||||||
document.body.classList.add("presentation-presenter")
|
document.body.classList.add("presentation-presenter");
|
||||||
};
|
};
|
||||||
|
|
||||||
const setProgress = () => {
|
const setProgress = () => {
|
||||||
const progress = ((slide+1)/slides.length)*100;
|
const maxSteps = getMaxSteps();
|
||||||
document.body.style.setProperty('--presentation-progress', `${progress}%`)
|
const totalSteps = slides.reduce((acc, _, i) => {
|
||||||
}
|
const tempSlide = slide;
|
||||||
|
slide = i;
|
||||||
|
const steps = getMaxSteps();
|
||||||
|
slide = tempSlide;
|
||||||
|
return acc + Math.max(1, steps);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
const transition = (nextSlide: number) => {
|
let currentProgress = 0;
|
||||||
|
for (let i = 0; i < slide; i++) {
|
||||||
|
const tempSlide = slide;
|
||||||
|
slide = i;
|
||||||
|
const steps = getMaxSteps();
|
||||||
|
slide = tempSlide;
|
||||||
|
currentProgress += Math.max(1, steps);
|
||||||
|
}
|
||||||
|
currentProgress += step;
|
||||||
|
|
||||||
|
const progress = (currentProgress / totalSteps) * 100;
|
||||||
|
document.body.style.setProperty('--presentation-progress', `${progress}%`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const transition = (nextSlide: number, nextStep: number = 0) => {
|
||||||
if (!presenting) {
|
if (!presenting) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slide === nextSlide) {
|
if (slide === nextSlide && step === nextStep) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
slides.forEach((s) => s.classList.remove(...transitionClasses));
|
slides.forEach((s) => s.classList.remove(...transitionClasses));
|
||||||
|
|
||||||
|
|
||||||
slide = nextSlide;
|
slide = nextSlide;
|
||||||
|
step = nextStep;
|
||||||
|
|
||||||
displaySlides();
|
displaySlides();
|
||||||
setProgress();
|
setProgress();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let listenersInitialized = false;
|
||||||
let listenersInitialized = false
|
|
||||||
const initListeners = () => {
|
const initListeners = () => {
|
||||||
if (listenersInitialized) {
|
if (listenersInitialized) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
listenersInitialized= true
|
listenersInitialized = true;
|
||||||
window.addEventListener("keyup", (ev) => {
|
window.addEventListener("keyup", (ev) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
const isEscape = ev.key === "Escape";
|
const isEscape = ev.key === "Escape";
|
||||||
@@ -131,19 +338,19 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSlide = keyHandlers[ev.key];
|
const getNextPosition = keyHandlers[ev.key];
|
||||||
|
|
||||||
if (!getSlide) {
|
if (!getNextPosition) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextSlide = getSlide();
|
const { slide: nextSlideIndex, step: nextStepIndex } = getNextPosition();
|
||||||
transition(nextSlide);
|
transition(nextSlideIndex, nextStepIndex);
|
||||||
});
|
});
|
||||||
|
|
||||||
let touchstartX = 0;
|
let touchstartX = 0;
|
||||||
let touchendX = 0;
|
let touchendX = 0;
|
||||||
const handleGesure = () => {
|
const handleGesture = () => {
|
||||||
const magnitude = Math.abs(touchstartX - touchendX);
|
const magnitude = Math.abs(touchstartX - touchendX);
|
||||||
|
|
||||||
if (magnitude < 40) {
|
if (magnitude < 40) {
|
||||||
@@ -152,10 +359,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (touchendX < touchstartX) {
|
if (touchendX < touchstartX) {
|
||||||
transition(nextSlide());
|
const { slide: nextSlideIndex, step: nextStepIndex } = nextStep();
|
||||||
|
transition(nextSlideIndex, nextStepIndex);
|
||||||
}
|
}
|
||||||
if (touchendX > touchstartX) {
|
if (touchendX > touchstartX) {
|
||||||
transition(prevSlide());
|
const { slide: prevSlideIndex, step: prevStepIndex } = prevStep();
|
||||||
|
transition(prevSlideIndex, prevStepIndex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -171,11 +380,11 @@
|
|||||||
"touchend",
|
"touchend",
|
||||||
(event) => {
|
(event) => {
|
||||||
touchendX = event.changedTouches[0].screenX;
|
touchendX = event.changedTouches[0].screenX;
|
||||||
handleGesure();
|
handleGesture();
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
// If there is no presentation on the page then we don't initialize
|
// If there is no presentation on the page then we don't initialize
|
||||||
if (slides.length) {
|
if (slides.length) {
|
||||||
@@ -189,6 +398,259 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Step animation styles */
|
||||||
|
.step-hidden {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-visible {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation keyframes */
|
||||||
|
@keyframes fadeInStep {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOutStep {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInLeftStep {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-30px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideOutLeftStep {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-30px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInRightStep {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(30px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideOutRightStep {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(30px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInUpStep {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideOutUpStep {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInDownStep {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-30px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideOutDownStep {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-30px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scaleInStep {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scaleOutStep {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounceInStep {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.3);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounceOutStep {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes typeInStep {
|
||||||
|
/* This is now unused - keeping for backward compatibility */
|
||||||
|
from { opacity: 1; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes typeOutStep {
|
||||||
|
/* This is now unused - keeping for backward compatibility */
|
||||||
|
from { opacity: 1; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation classes */
|
||||||
|
.animate-fade-in-step {
|
||||||
|
animation: fadeInStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in-reverse-step {
|
||||||
|
animation: fadeOutStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-left-step {
|
||||||
|
animation: slideInLeftStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-left-reverse-step {
|
||||||
|
animation: slideOutLeftStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-right-step {
|
||||||
|
animation: slideInRightStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-right-reverse-step {
|
||||||
|
animation: slideOutRightStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-up-step {
|
||||||
|
animation: slideInUpStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-up-reverse-step {
|
||||||
|
animation: slideOutUpStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-down-step {
|
||||||
|
animation: slideInDownStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-down-reverse-step {
|
||||||
|
animation: slideOutDownStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-scale-in-step {
|
||||||
|
animation: scaleInStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-scale-in-reverse-step {
|
||||||
|
animation: scaleOutStep 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-bounce-in-step {
|
||||||
|
animation: bounceInStep 0.8s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-bounce-in-reverse-step {
|
||||||
|
animation: bounceOutStep 0.8s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-type-in-step {
|
||||||
|
/* JavaScript-controlled animation - no CSS animation needed */
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-type-in-reverse-step {
|
||||||
|
/* JavaScript-controlled animation - no CSS animation needed */
|
||||||
|
}
|
||||||
|
|
||||||
.presentation-overflow-hidden {
|
.presentation-overflow-hidden {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|||||||
@@ -14,84 +14,99 @@ import Presentation from "@/components/resources/presentation.astro";
|
|||||||
<Slide large>
|
<Slide large>
|
||||||
# Welcome to Python! 🐍
|
# Welcome to Python! 🐍
|
||||||
|
|
||||||
**A beginner-friendly programming language**
|
<div step="1" animation="fade-in">**A beginner-friendly programming language**</div>
|
||||||
|
|
||||||
- Easy to learn and read
|
<div step="2" animation="slide-in-left">- Easy to learn and read</div>
|
||||||
- Powerful and versatile
|
<div step="3" animation="slide-in-left">- Powerful and versatile</div>
|
||||||
- Great for beginners
|
<div step="4" animation="slide-in-left">- Great for beginners</div>
|
||||||
- Used by major companies
|
<div step="5" animation="bounce-in">- Used by major companies</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## What is Python?
|
## What is Python?
|
||||||
|
|
||||||
Python is a **high-level programming language** that emphasizes:
|
<div step="1" animation="fade-in">Python is a **high-level programming language** that emphasizes:</div>
|
||||||
|
|
||||||
- **Readability** - Code that looks like English
|
<div step="2" animation="slide-in-up">- **Readability** - Code that looks like English</div>
|
||||||
- **Simplicity** - Easy to learn and use
|
<div step="3" animation="slide-in-up">- **Simplicity** - Easy to learn and use</div>
|
||||||
- **Versatility** - Can be used for many things
|
<div step="4" animation="slide-in-up">- **Versatility** - Can be used for many things</div>
|
||||||
|
|
||||||
### Created by Guido van Rossum in 1991
|
<div step="5" animation="scale-in">### Created by Guido van Rossum in 1991</div>
|
||||||
|
|
||||||
Named after "Monty Python's Flying Circus" 🎭
|
<div step="6" animation="type-in">Named after "Monty Python's Flying Circus" 🎭</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Why Learn Python?
|
## Why Learn Python?
|
||||||
|
|
||||||
|
<div step="1" animation="slide-in-left">
|
||||||
### 🌐 Web Development
|
### 🌐 Web Development
|
||||||
Build websites and web applications
|
Build websites and web applications
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div step="2" animation="slide-in-right">
|
||||||
### 🤖 Data Science & AI
|
### 🤖 Data Science & AI
|
||||||
Analyze data and build machine learning models
|
Analyze data and build machine learning models
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div step="3" animation="slide-in-left">
|
||||||
### 🎮 Game Development
|
### 🎮 Game Development
|
||||||
Create games and interactive applications
|
Create games and interactive applications
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div step="4" animation="slide-in-right">
|
||||||
### 🔧 Automation
|
### 🔧 Automation
|
||||||
Automate repetitive tasks
|
Automate repetitive tasks
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Your First Python Program
|
## Your First Python Program
|
||||||
|
|
||||||
Let's write the classic "Hello, World!" program:
|
<div step="1" animation="fade-in">Let's write the classic "Hello, World!" program:</div>
|
||||||
|
|
||||||
|
<div step="2" animation="scale-in">
|
||||||
```python
|
```python
|
||||||
print("Hello, World!")
|
print("Hello, World!")
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
### How to run it:
|
<div step="3" animation="slide-in-up">### How to run it:</div>
|
||||||
1. Open a text editor
|
<div step="4" animation="slide-in-up">1. Open a text editor</div>
|
||||||
2. Type the code above
|
<div step="5" animation="slide-in-up">2. Type the code above</div>
|
||||||
3. Save as `hello.py`
|
<div step="6" animation="slide-in-up">3. Save as `hello.py`</div>
|
||||||
4. Run with: `python hello.py`
|
<div step="7" animation="bounce-in">4. Run with: `python hello.py`</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Variables and Data Types
|
## Variables and Data Types
|
||||||
|
|
||||||
### Creating Variables
|
<div step="1" animation="fade-in">### Creating Variables</div>
|
||||||
|
<div step="2" animation="type-in">
|
||||||
```python
|
```python
|
||||||
name = "Alice" # String
|
name = "Alice" # String
|
||||||
age = 25 # Integer
|
age = 25 # Integer
|
||||||
height = 5.6 # Float
|
height = 5.6 # Float
|
||||||
is_student = True # Boolean
|
is_student = True # Boolean
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
### Python is **dynamically typed**
|
<div step="3" animation="slide-in-left">### Python is **dynamically typed**</div>
|
||||||
You don't need to declare the type!
|
<div step="4" animation="slide-in-left">You don't need to declare the type!</div>
|
||||||
|
|
||||||
|
<div step="5" animation="scale-in">
|
||||||
```python
|
```python
|
||||||
x = 42 # x is an integer
|
x = 42 # x is an integer
|
||||||
x = "Hello" # Now x is a string
|
x = "Hello" # Now x is a string
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Working with Strings
|
## Working with Strings
|
||||||
|
|
||||||
### String Operations
|
<div data-step="1" data-animation="fade-in">### String Operations</div>
|
||||||
|
<div data-step="2" data-animation="slide-in-up">
|
||||||
```python
|
```python
|
||||||
# Creating strings
|
# Creating strings
|
||||||
greeting = "Hello"
|
greeting = "Hello"
|
||||||
@@ -100,47 +115,72 @@ name = "World"
|
|||||||
# Concatenation
|
# Concatenation
|
||||||
message = greeting + ", " + name + "!"
|
message = greeting + ", " + name + "!"
|
||||||
print(message) # Output: Hello, World!
|
print(message) # Output: Hello, World!
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="3" data-animation="slide-in-up">
|
||||||
|
```python
|
||||||
# String methods
|
# String methods
|
||||||
text = "python programming"
|
text = "python programming"
|
||||||
print(text.upper()) # PYTHON PROGRAMMING
|
print(text.upper()) # PYTHON PROGRAMMING
|
||||||
print(text.capitalize()) # Python programming
|
print(text.capitalize()) # Python programming
|
||||||
print(text.replace("python", "Python")) # Python programming
|
print(text.replace("python", "Python")) # Python programming
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Numbers and Math
|
## Numbers and Math
|
||||||
|
|
||||||
### Basic Math Operations
|
<div data-step="1" data-animation="fade-in">### Basic Math Operations</div>
|
||||||
|
<div data-step="2" data-animation="type-in">
|
||||||
```python
|
```python
|
||||||
# Arithmetic operators
|
# Arithmetic operators
|
||||||
a = 10
|
a = 10
|
||||||
b = 3
|
b = 3
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="3" data-animation="slide-in-left">
|
||||||
|
```python
|
||||||
print(a + b) # Addition: 13
|
print(a + b) # Addition: 13
|
||||||
print(a - b) # Subtraction: 7
|
print(a - b) # Subtraction: 7
|
||||||
print(a * b) # Multiplication: 30
|
print(a * b) # Multiplication: 30
|
||||||
print(a / b) # Division: 3.333...
|
print(a / b) # Division: 3.333...
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="4" data-animation="slide-in-right">
|
||||||
|
```python
|
||||||
print(a // b) # Floor division: 3
|
print(a // b) # Floor division: 3
|
||||||
print(a % b) # Modulo (remainder): 1
|
print(a % b) # Modulo (remainder): 1
|
||||||
print(a ** b) # Exponentiation: 1000
|
print(a ** b) # Exponentiation: 1000
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Lists - Storing Multiple Values
|
## Lists - Storing Multiple Values
|
||||||
|
|
||||||
### Creating and Using Lists
|
<div data-step="1" data-animation="fade-in">### Creating and Using Lists</div>
|
||||||
|
<div data-step="2" data-animation="slide-in-up">
|
||||||
```python
|
```python
|
||||||
# Creating a list
|
# Creating a list
|
||||||
fruits = ["apple", "banana", "orange"]
|
fruits = ["apple", "banana", "orange"]
|
||||||
numbers = [1, 2, 3, 4, 5]
|
numbers = [1, 2, 3, 4, 5]
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="3" data-animation="slide-in-up">
|
||||||
|
```python
|
||||||
# Accessing items (indexing starts at 0)
|
# Accessing items (indexing starts at 0)
|
||||||
print(fruits[0]) # apple
|
print(fruits[0]) # apple
|
||||||
print(fruits[-1]) # orange (last item)
|
print(fruits[-1]) # orange (last item)
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="4" data-animation="slide-in-up">
|
||||||
|
```python
|
||||||
# Adding items
|
# Adding items
|
||||||
fruits.append("grape")
|
fruits.append("grape")
|
||||||
fruits.insert(1, "strawberry")
|
fruits.insert(1, "strawberry")
|
||||||
@@ -149,12 +189,14 @@ fruits.insert(1, "strawberry")
|
|||||||
print(len(fruits)) # Length of list
|
print(len(fruits)) # Length of list
|
||||||
print("apple" in fruits) # Check if item exists
|
print("apple" in fruits) # Check if item exists
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Control Flow - Making Decisions
|
## Control Flow - Making Decisions
|
||||||
|
|
||||||
### If Statements
|
<div data-step="1" data-animation="fade-in">### If Statements</div>
|
||||||
|
<div data-step="2" data-animation="type-in">
|
||||||
```python
|
```python
|
||||||
age = 18
|
age = 18
|
||||||
|
|
||||||
@@ -164,65 +206,89 @@ elif age >= 16:
|
|||||||
print("You can drive!")
|
print("You can drive!")
|
||||||
else:
|
else:
|
||||||
print("You're still young!")
|
print("You're still young!")
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="3" data-animation="bounce-in">
|
||||||
|
```python
|
||||||
# Comparison operators
|
# Comparison operators
|
||||||
# == (equal), != (not equal)
|
# == (equal), != (not equal)
|
||||||
# > (greater), < (less)
|
# > (greater), < (less)
|
||||||
# >= (greater or equal), <= (less or equal)
|
# >= (greater or equal), <= (less or equal)
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Loops - Repeating Actions
|
## Loops - Repeating Actions
|
||||||
|
|
||||||
### For Loops
|
<div data-step="1" data-animation="fade-in">### For Loops</div>
|
||||||
|
<div data-step="2" data-animation="slide-in-left">
|
||||||
```python
|
```python
|
||||||
# Loop through a list
|
# Loop through a list
|
||||||
fruits = ["apple", "banana", "orange"]
|
fruits = ["apple", "banana", "orange"]
|
||||||
for fruit in fruits:
|
for fruit in fruits:
|
||||||
print(f"I like {fruit}")
|
print(f"I like {fruit}")
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="3" data-animation="slide-in-right">
|
||||||
|
```python
|
||||||
# Loop through numbers
|
# Loop through numbers
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
print(f"Count: {i}") # 0, 1, 2, 3, 4
|
print(f"Count: {i}") # 0, 1, 2, 3, 4
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
### While Loops
|
<div data-step="4" data-animation="scale-in">### While Loops</div>
|
||||||
|
<div data-step="5" data-animation="slide-in-up">
|
||||||
```python
|
```python
|
||||||
count = 0
|
count = 0
|
||||||
while count < 3:
|
while count < 3:
|
||||||
print(f"Count is {count}")
|
print(f"Count is {count}")
|
||||||
count += 1 # Same as count = count + 1
|
count += 1 # Same as count = count + 1
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Functions - Organizing Your Code
|
## Functions - Organizing Your Code
|
||||||
|
|
||||||
### Creating Functions
|
<div data-step="1" data-animation="fade-in">### Creating Functions</div>
|
||||||
|
<div data-step="2" data-animation="type-in">
|
||||||
```python
|
```python
|
||||||
def greet(name):
|
def greet(name):
|
||||||
"""This function greets someone"""
|
"""This function greets someone"""
|
||||||
return f"Hello, {name}!"
|
return f"Hello, {name}!"
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="3" data-animation="slide-in-up">
|
||||||
|
```python
|
||||||
def add_numbers(a, b):
|
def add_numbers(a, b):
|
||||||
"""Add two numbers and return the result"""
|
"""Add two numbers and return the result"""
|
||||||
result = a + b
|
result = a + b
|
||||||
return result
|
return result
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
# Using functions
|
<div data-step="4" data-animation="bounce-in">### Using functions</div>
|
||||||
|
<div data-step="5" data-animation="slide-in-up">
|
||||||
|
```python
|
||||||
message = greet("Alice")
|
message = greet("Alice")
|
||||||
print(message) # Hello, Alice!
|
print(message) # Hello, Alice!
|
||||||
|
|
||||||
sum_result = add_numbers(5, 3)
|
sum_result = add_numbers(5, 3)
|
||||||
print(sum_result) # 8
|
print(sum_result) # 8
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide>
|
<Slide>
|
||||||
## Practice Exercise
|
## Practice Exercise
|
||||||
|
|
||||||
### Build a Simple Calculator
|
<div data-step="1" data-animation="fade-in">### Build a Simple Calculator</div>
|
||||||
|
<div data-step="2" data-animation="type-in">
|
||||||
```python
|
```python
|
||||||
def calculator():
|
def calculator():
|
||||||
print("Simple Calculator")
|
print("Simple Calculator")
|
||||||
@@ -231,7 +297,11 @@ def calculator():
|
|||||||
num1 = float(input("Enter first number: "))
|
num1 = float(input("Enter first number: "))
|
||||||
operation = input("Enter operation (+, -, *, /): ")
|
operation = input("Enter operation (+, -, *, /): ")
|
||||||
num2 = float(input("Enter second number: "))
|
num2 = float(input("Enter second number: "))
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="3" data-animation="slide-in-up">
|
||||||
|
```python
|
||||||
if operation == "+":
|
if operation == "+":
|
||||||
result = num1 + num2
|
result = num1 + num2
|
||||||
elif operation == "-":
|
elif operation == "-":
|
||||||
@@ -247,24 +317,29 @@ def calculator():
|
|||||||
return "Error: Invalid operation!"
|
return "Error: Invalid operation!"
|
||||||
|
|
||||||
return f"Result: {result}"
|
return f"Result: {result}"
|
||||||
|
```
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-step="4" data-animation="bounce-in">
|
||||||
|
```python
|
||||||
# Run the calculator
|
# Run the calculator
|
||||||
print(calculator())
|
print(calculator())
|
||||||
```
|
```
|
||||||
|
</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
<Slide >
|
<Slide >
|
||||||
## 🎉 Congratulations!
|
## 🎉 Congratulations!
|
||||||
|
|
||||||
You've learned the basics of Python programming!
|
<div data-step="1" data-animation="scale-in">You've learned the basics of Python programming!</div>
|
||||||
|
|
||||||
### What's Next?
|
<div data-step="2" data-animation="fade-in">### What's Next?</div>
|
||||||
- Practice with small projects
|
<div data-step="3" data-animation="slide-in-left">- Practice with small projects</div>
|
||||||
- Learn about modules and packages
|
<div data-step="4" data-animation="slide-in-left">- Learn about modules and packages</div>
|
||||||
- Explore Python libraries
|
<div data-step="5" data-animation="slide-in-left">- Explore Python libraries</div>
|
||||||
- Build something cool!
|
<div data-step="6" data-animation="slide-in-left">- Build something cool!</div>
|
||||||
|
|
||||||
**Ready to code? Let's build something amazing! 🚀**
|
<div data-step="7" data-animation="bounce-in">**Ready to code? Let's build something amazing! 🚀**</div>
|
||||||
</Slide>
|
</Slide>
|
||||||
|
|
||||||
## Course Materials
|
## Course Materials
|
||||||
@@ -291,4 +366,4 @@ By the end of this presentation, you'll be able to:
|
|||||||
- Create and use functions
|
- Create and use functions
|
||||||
- Build a simple calculator program
|
- Build a simple calculator program
|
||||||
|
|
||||||
The presentation automatically starts when you visit this page. Use arrow keys to navigate between slides, or escape to exit presentati
|
The presentation automatically starts when you visit this page. Use arrow keys to navigate between slides and steps, or escape to exit presentation mode.
|
||||||
|
|||||||
Reference in New Issue
Block a user