mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-24 11:03:17 -04:00
feat(curriculum): add moon orbit lab (#55670)
Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com>
This commit is contained in:
@@ -1869,7 +1869,12 @@
|
||||
"yqma": { "title": "119", "intro": [] },
|
||||
"dorc": { "title": "120", "intro": [] },
|
||||
"adzu": { "title": "121", "intro": [] },
|
||||
"cdzo": { "title": "122", "intro": [] },
|
||||
"lab-moon-orbit": {
|
||||
"title": "Build a Moon Orbit",
|
||||
"intro": [
|
||||
"For this lab, you will create an animation of the moon orbiting the earth."
|
||||
]
|
||||
},
|
||||
"lugl": { "title": "123", "intro": [] },
|
||||
"mtcg": { "title": "124", "intro": [] },
|
||||
"lvqc": { "title": "125", "intro": [] },
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Introduction to the Learn CSS Animation by Creating a Moon Orbit
|
||||
block: lab-moon-orbit
|
||||
superBlock: front-end-development
|
||||
---
|
||||
|
||||
## Introduction to the Learn CSS Animation by Creating a Moon Orbit
|
||||
|
||||
This is a test for the new project-based curriculum.
|
||||
12
curriculum/challenges/_meta/lab-moon-orbit/meta.json
Normal file
12
curriculum/challenges/_meta/lab-moon-orbit/meta.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "Build a Moon Orbit",
|
||||
"isUpcomingChange": true,
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": false,
|
||||
"dashedName": "lab-moon-orbit",
|
||||
"order": 122,
|
||||
"superBlock": "front-end-development",
|
||||
"challengeOrder": [{ "id": "66a37f37ef5823a313de8c26", "title": "Build a Moon Orbit" }],
|
||||
"helpCategory": "HTML-CSS",
|
||||
"blockType": "lab"
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
---
|
||||
id: 66a37f37ef5823a313de8c26
|
||||
title: Build a Moon Orbit
|
||||
challengeType: 14
|
||||
dashedName: build-a-moon-orbit
|
||||
demoType: onClick
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this lab, you will create a simple animation of the Moon's orbit around the Earth using HTML and CSS. The Earth will be at the center of the system, and the Moon will orbit around it.
|
||||
|
||||
**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.
|
||||
|
||||
**User Stories:**
|
||||
|
||||
1. You should align all the elements to the center of the page by setting the height to `100%` of the viewport and setting a flexbox layout in the `body` element.
|
||||
|
||||
2. You should have a `div` with the class `space`.
|
||||
|
||||
3. Inside the `.space` `div`, there should be two more `div` elements with the class `earth` and `orbit`, respectively, in order.
|
||||
|
||||
4. Inside the `.orbit` `div`, there should be another `div` with the class `moon`.
|
||||
|
||||
5. The `space` `div` should be centered on the page and have a width and height of `200px`.
|
||||
|
||||
6. The `earth` `div` should use `absolute` positioning. Position the center of the `earth` `div` at the halfway point of its parent on both the vertical (top) and horizontal (left) axes. After that, shift the `earth` `div` back by half its own width and height, to center it within its parent, `.space`.
|
||||
|
||||
7. The `earth` `div` should have a width and height of `100px`.
|
||||
|
||||
8. The `orbit` `div` should have a width and height of `200px`.
|
||||
|
||||
9. The `orbit` `div` should be positioned using `absolute` positioning. Its bottom right corner should be at the center of the `space` `div` using a `transform` property that shifts it by `-50%` on both the vertical and horizontal axes.
|
||||
|
||||
10. The orbit path for the moon around the Earth should be a circle.
|
||||
|
||||
11. The moon `div` should be positioned using `absolute` positioning and have a width and height of `30px`. The moon `div` should position itself at the top of the `orbit` `div` and be centered horizontally.
|
||||
|
||||
12. You should further adjust the horizontal positioning of the `moon` by moving the element to the left by half of its width.
|
||||
|
||||
13. Your `.earth` and `.moon` `div` elements should have a background color and a `border-radius` of `50%` to make them look like planets.
|
||||
|
||||
14. You should define a `@keyframes orbit` animation that rotates the `.orbit` element 360 degrees around its center. You should apply this animation to the `.orbit` element with a duration of `5` seconds, a linear timing function, and infinite iterations.
|
||||
|
||||
**Note:** Be sure to link your stylesheet in your HTML and apply your CSS.
|
||||
|
||||
# --hints--
|
||||
|
||||
The contents of the `body` element should be centered on the page by setting the height to `100%` of the viewport height, `display` to `flex`, `justify-content`, and `align-items` to `center`.
|
||||
|
||||
```js
|
||||
|
||||
assert(new __helpers.CSSHelp(document).getStyle('body')?.height === '100vh' && new __helpers.CSSHelp(document).getStyle('body')?.display === 'flex' && new __helpers.CSSHelp(document).getStyle('body')?.justifyContent === 'center'&& new __helpers.CSSHelp(document).getStyle('body')?.alignItems === 'center');
|
||||
```
|
||||
|
||||
You should have a main `div` with the class `space`.
|
||||
|
||||
```js
|
||||
assert(document.querySelector('div')?.getAttribute('class') === 'space');
|
||||
```
|
||||
|
||||
The `space` `div` should have a width and height of `200px`.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.space')?.width === '200px' && new __helpers.CSSHelp(document).getStyle('.space')?.height === '200px');
|
||||
```
|
||||
|
||||
You should have a `div` with the class `earth` inside the `.space` `div`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('div.space div.earth'));
|
||||
```
|
||||
|
||||
The `earth` div should be the first child of the `space` `div`.
|
||||
|
||||
```js
|
||||
assert(document.querySelector('.space > div')?.getAttribute('class') === 'earth');
|
||||
```
|
||||
|
||||
The `earth` `div` should have a width and height of `100px`.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.earth')?.width === '100px' && new __helpers.CSSHelp(document).getStyle('.earth')?.height === '100px');
|
||||
```
|
||||
|
||||
The `earth` `div` should use `absolute` positioning.
|
||||
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.earth')?.position === 'absolute');
|
||||
```
|
||||
|
||||
The `earth` `div` should have a `top` and `left` position of `50%`.
|
||||
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.earth')?.top === '50%' && new __helpers.CSSHelp(document).getStyle('.earth')?.left === '50%');
|
||||
```
|
||||
|
||||
The `earth` `div` should be moved back and up by `50%` by setting the `transform` property to `translate(-50%, -50%)`.
|
||||
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.earth')?.transform === 'translate(-50%, -50%)');
|
||||
```
|
||||
|
||||
You should have a `div` with the class `orbit` inside the `.space` `div`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('div.space div.orbit'));
|
||||
```
|
||||
|
||||
The `orbit` class `div` should come after the `earth` class `div`.
|
||||
|
||||
```js
|
||||
assert(document.querySelector('.earth')?.nextElementSibling?.classList?.contains('orbit'));
|
||||
```
|
||||
|
||||
The `orbit` `div` should have a width and height of `200px`.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.orbit')?.width === '200px' && new __helpers.CSSHelp(document).getStyle('.orbit')?.height === '200px');
|
||||
```
|
||||
|
||||
The `orbit` `div` should use `absolute` positioning.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.orbit')?.position === 'absolute');
|
||||
```
|
||||
|
||||
The `orbit` `div` should be positioned at the center of the `space` `div` using a `transform` property that shifts it by `-50%` on both the vertical and horizontal axes.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.orbit')?.transform === 'translate(-50%, -50%)');
|
||||
```
|
||||
|
||||
You should have a `div` with the class `moon` inside the `.orbit` `div`.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('div.space div.orbit div.moon'));
|
||||
```
|
||||
|
||||
The `moon` `div` should have a width and height of `30px`.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.moon')?.width === '30px' && new __helpers.CSSHelp(document).getStyle('.moon')?.height === '30px');
|
||||
```
|
||||
|
||||
The `moon` `div` should be positioned using `absolute` positioning.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.moon')?.position === 'absolute');
|
||||
```
|
||||
|
||||
The top edge of the `.moon` element should be aligned with the top edge of its containing block.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.moon')?.top === '0px');
|
||||
```
|
||||
|
||||
You should move the left edge of the `.moon` element to the center of the containing block (`50%` from the left side).
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.moon')?.left === '50%');
|
||||
```
|
||||
|
||||
The `.moon` `div` should be adjusted horizontally by translating it to `-50%` across the x-axis.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.moon')?.transform === 'translateX(-50%)');
|
||||
```
|
||||
|
||||
Your `.earth` `div` element should have a background color.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.earth')?.backgroundColor);
|
||||
```
|
||||
|
||||
Your `.earth` element should have `border-radius` of `50%` to make it look like a circle.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.earth')?.borderRadius === '50%');
|
||||
```
|
||||
|
||||
Your `.moon` `div` element should have a background color.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.moon')?.backgroundColor);
|
||||
```
|
||||
|
||||
Your `.moon` element should have `border-radius` of `50%` to make it look like a circle.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getStyle('.moon')?.borderRadius === '50%');
|
||||
```
|
||||
|
||||
You should have a `@keyframes` rule.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getCSSRules('keyframes')?.length === 1);
|
||||
```
|
||||
|
||||
Your new `@keyframes` rule should be named `orbit`.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getCSSRules('keyframes')?.[0]?.name === 'orbit');
|
||||
```
|
||||
|
||||
Your `@keyframes orbit` rule should have a `0%` selector.
|
||||
|
||||
```js
|
||||
const rules = new __helpers.CSSHelp(document).getCSSRules('keyframes')?.[0]?.cssRules
|
||||
assert(rules?.[0]?.keyText === '0%' || rules?.[0]?.keyText === '0%');
|
||||
```
|
||||
|
||||
Your `@keyframes orbit` rule should have a `100%` selector.
|
||||
|
||||
```js
|
||||
const rules = new __helpers.CSSHelp(document).getCSSRules('keyframes')?.[0]?.cssRules
|
||||
assert(rules?.[0]?.keyText === '100%' || rules?.[1]?.keyText === '100%');
|
||||
```
|
||||
|
||||
Your `0%` selector should have a `transform` property set to `rotate(0deg) translate(-50%, -50%)`.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getCSSRules('keyframes')?.[0]?.cssRules?.[0]?.style?.transform === 'rotate(0deg) translate(-50%, -50%)');
|
||||
```
|
||||
|
||||
Your `100%` selector should come after your `0%` selector.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getCSSRules('keyframes')?.[0]?.cssRules?.[1]?.keyText === '100%')
|
||||
```
|
||||
|
||||
Your `100%` selector should have a `transform` property set to `rotate(360deg) translate(-50%, -50%)`.
|
||||
|
||||
```js
|
||||
assert(new __helpers.CSSHelp(document).getCSSRules('keyframes')?.[0]?.cssRules?.[1]?.style?.transform === 'rotate(360deg) translate(-50%, -50%)')
|
||||
```
|
||||
|
||||
Your `.orbit` selector should have an `animation` property set to `orbit 5s linear infinite`.
|
||||
|
||||
```js
|
||||
|
||||
const orbitStyles = new __helpers.CSSHelp(document).getStyle('.orbit');
|
||||
assert(
|
||||
orbitStyles?.animationName === "orbit" &&
|
||||
orbitStyles?.animationDuration === "5s" &&
|
||||
orbitStyles?.animationTimingFunction === "linear" &&
|
||||
orbitStyles?.animationIterationCount === "infinite"
|
||||
);
|
||||
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Moon Orbit</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Moon Orbiting Earth</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="space">
|
||||
<div class="earth"></div>
|
||||
<div class="orbit">
|
||||
<div class="moon"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.space {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.earth {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: blue;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 255, 0.5);
|
||||
}
|
||||
|
||||
.orbit {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
animation: orbit 5s linear infinite;
|
||||
}
|
||||
|
||||
.moon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: gray;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
box-shadow: 0 0 10px rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
|
||||
@keyframes orbit {
|
||||
0% {
|
||||
transform: rotate(0deg) translate(-50%, -50%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg) translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user