diff --git a/4-The Message/index.html b/4-The Message/index.html new file mode 100644 index 0000000..b59eef6 --- /dev/null +++ b/4-The Message/index.html @@ -0,0 +1,20 @@ + + + + + + + The message + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/4-The Message/src/css/reset.css b/4-The Message/src/css/reset.css new file mode 100644 index 0000000..5bca465 --- /dev/null +++ b/4-The Message/src/css/reset.css @@ -0,0 +1,129 @@ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +input:focus { + outline: none; +} +a { + color: inherit; + text-decoration: none; +} diff --git a/4-The Message/src/css/style.css b/4-The Message/src/css/style.css new file mode 100644 index 0000000..8593d40 --- /dev/null +++ b/4-The Message/src/css/style.css @@ -0,0 +1,65 @@ +@import 'reset.css'; + +html, +body { + width: 100%; + height: 100vh; + overflow: hidden; +} + +.msg_page { + width: 100%; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background : linear-gradient(to bottom, #C0DEFC, #FCFEFF); +} + +.msg_form { + width: 500px; + height: 250px; + border-radius: 10px; + background-color: #F5F5F5; + box-shadow: 0px 0px 4px 4px #E2E2E2; +} + +.msg_form h2 { + font-size: 20px; + font-weight: bold; + padding: 30px 0px 15px calc(34%); +} + +.msg_form p { + width: 90%; + margin-left: 25px; + border-bottom: 2px solid rgba(211, 211, 211, 0.5); +} + +.msg_form h3 { + font-size: 15px; + padding: 20px 0px 15px calc(5%); +} + +.msg_form_btn { + margin-left: 20px; + border: 2px gray; +} + +.msg_form_input{ + border: 2px gray; + width: 420px; + height: 30px; +} + +.msg_form_submit { + margin-top: 30px; + margin-left: 10px; + width: 60px; + height: 30px; +} + +.msg_view { + margin-top: 15px; + text-align: center; +} \ No newline at end of file diff --git a/4-The Message/src/js/App.js b/4-The Message/src/js/App.js new file mode 100644 index 0000000..86f21fc --- /dev/null +++ b/4-The Message/src/js/App.js @@ -0,0 +1,49 @@ +import { TEXTS } from '../../utils/Constant.js' +import MessageForm from './MessageForm.js' +import MessageView from './MessageView.js' + +export default function App({ $target }) { + // 페이지는 전체 배경을 의미. + const $page = document.createElement('div') + $page.className = "msg_page" + $target.appendChild($page) + + this.state = { + message : '' + } + + this.setState = (nextState) => { + this.state = nextState + messageView.setState(this.state.message) + } + + const $container = document.createElement('div') + $container.className = 'msg_form' + $container.innerHTML = ` +

${TEXTS.TITLE_TEXT}

+

+

${TEXTS.INFO_TEXT}

+ ` + + new MessageForm({ + $target:$container, + onSubmit : (message) => { + this.setState({ + ...this.state, + message + }) + } + }) + + const messageView = new MessageView({ + $target: $container, + initialState: this.state.message + }) + + + $page.appendChild($container) + +} + +// 전체 UI를 담당해주는 메세지 쪽? +// 그리고 엔터를 받는 쪽을 해줘야하는건기? \ No newline at end of file diff --git a/4-The Message/src/js/MessageForm.js b/4-The Message/src/js/MessageForm.js new file mode 100644 index 0000000..101bc13 --- /dev/null +++ b/4-The Message/src/js/MessageForm.js @@ -0,0 +1,38 @@ +export default function MessageForm({$target, onSubmit}) { + const $form = document.createElement('form') + $target.appendChild($form) + + this.render = () => { + $form.innerHTML = ` +
+ +
+ + ` + } + + this.render() + + $form.addEventListener('submit', (e) => { + e.preventDefault() + + const input = $form.querySelector('.msg_form_input') + onSubmit(input.value) + + input.value = '' + }) + + + window.addEventListener('Enter', (e) => { + e.preventDefault() + + const input = $form.querySelector('.msg_form_input') + onSubmit(input.value) + + input.value = '' + }) + + +} \ No newline at end of file diff --git a/4-The Message/src/js/MessageView.js b/4-The Message/src/js/MessageView.js new file mode 100644 index 0000000..d48085e --- /dev/null +++ b/4-The Message/src/js/MessageView.js @@ -0,0 +1,20 @@ +export default function MessageView({$target, initialState}) { + const $msgView = document.createElement('div') + $msgView.className = 'msg_view' + $target.appendChild($msgView) + + this.state = initialState + + this.setState = (nextState) => { + this.state = nextState + this.render() + } + + this.render = () => { + $msgView.style.display = this.state ? 'block' : 'none' + $msgView.textContent = this.state + } + + this.render() + +} \ No newline at end of file diff --git a/4-The Message/src/main.js b/4-The Message/src/main.js new file mode 100644 index 0000000..f34dcd5 --- /dev/null +++ b/4-The Message/src/main.js @@ -0,0 +1,7 @@ +import App from './js/App.js' + +const $app = document.querySelector('.app') + +new App({ + $target: $app, +}) diff --git a/4-The Message/utils/Constant.js b/4-The Message/utils/Constant.js new file mode 100644 index 0000000..6df2a9e --- /dev/null +++ b/4-The Message/utils/Constant.js @@ -0,0 +1,4 @@ +export const TEXTS = { + TITLE_TEXT : 'Pass the Message', + INFO_TEXT : 'Enter the Message' +} \ No newline at end of file diff --git a/5-Counter/index.html b/5-Counter/index.html new file mode 100644 index 0000000..c659f72 --- /dev/null +++ b/5-Counter/index.html @@ -0,0 +1,20 @@ + + + + + + + Counter + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/5-Counter/src/css/reset.css b/5-Counter/src/css/reset.css new file mode 100644 index 0000000..5bca465 --- /dev/null +++ b/5-Counter/src/css/reset.css @@ -0,0 +1,129 @@ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +input:focus { + outline: none; +} +a { + color: inherit; + text-decoration: none; +} diff --git a/5-Counter/src/css/style.css b/5-Counter/src/css/style.css new file mode 100644 index 0000000..8aa169b --- /dev/null +++ b/5-Counter/src/css/style.css @@ -0,0 +1,52 @@ +@import 'reset.css'; + +html, +body { + width: 100%; + height: 100vh; + overflow: hidden; +} + +.count_page { + width: 100%; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background : #FCFC62 +} + +.counter_container { + display: flex; + flex-direction: column; + width: 600px; + height: 330px; + background-color: #FEFFEA; + border: 4px solid black; + align-items: center; + justify-content: space-around; +} + +.counter_container h2 { + font-size: 30px; + font-weight: bold; +} + +.counter_container h3 { + font-size: 130px; + font-weight: bold; +} + +.buttons_div button { + width: 80px; + height: 40px; + border-radius: 4px; + background-color: #FEFFEA; + font-size: 15px; +} + +.buttons_div button:hover { + background-color: black; + color: white; + cursor: pointer; +} \ No newline at end of file diff --git a/5-Counter/src/js/App.js b/5-Counter/src/js/App.js new file mode 100644 index 0000000..ad340a9 --- /dev/null +++ b/5-Counter/src/js/App.js @@ -0,0 +1,54 @@ +import { TEXTS } from '../../utils/Constant.js' +import CountView from './CountView.js' +import CountBtns from './CountBtns.js' + +export default function App({ $target }) { + // 페이지는 전체 배경을 의미. + const $page = document.createElement('div') + $page.className = "count_page" + $target.appendChild($page) + + this.state = { + count : 0 + } + + this.setState = (nextState) => { + this.state = nextState + countView.setState(this.state.count) + } + + const $container = document.createElement('div') + $page.appendChild($container) + $container.className = 'counter_container' + $container.innerHTML = ` +

${TEXTS.TITLE_TEXT}

+ ` + + const countView = new CountView({ + $target: $container, + initialState: this.state.count + }) + + new CountBtns({ + $target: $container, + onUpCount: () => { + const count = this.state.count + 1 + this.setState({ + ...this.state, + count + }) + }, + onDownCount : () => { + const count = this.state.count - 1 + this.setState({ + ...this.state, + count + }) + } + }) + + +} + +// 전체 UI를 담당해주는 메세지 쪽? +// 그리고 엔터를 받는 쪽을 해줘야하는건기? \ No newline at end of file diff --git a/5-Counter/src/js/CountBtns.js b/5-Counter/src/js/CountBtns.js new file mode 100644 index 0000000..9930754 --- /dev/null +++ b/5-Counter/src/js/CountBtns.js @@ -0,0 +1,25 @@ +export default function CountBtns({$target, onUpCount, onDownCount}) { + + const $buttons = document.createElement('div') + $buttons.className = 'buttons_div' + + $buttons.innerHTML = ` + + + ` + + $target.appendChild($buttons) + + $buttons.addEventListener('click', (e) => { + const { className } = e.target + + if ( className === 'increase_btn') { + onUpCount() + } else if ( className === 'decrease_btn') { + onDownCount() + } + + }) + + +} \ No newline at end of file diff --git a/5-Counter/src/js/CountView.js b/5-Counter/src/js/CountView.js new file mode 100644 index 0000000..007f645 --- /dev/null +++ b/5-Counter/src/js/CountView.js @@ -0,0 +1,17 @@ +export default function CountView({$target, initialState}) { + const $count = document.createElement('h3') + $target.appendChild($count) + + this.state = initialState + + this.setState = (nextState) => { + this.state = nextState + this.render() + } + + this.render = () => { + $count.textContent = this.state + } + + this.render() +} \ No newline at end of file diff --git a/5-Counter/src/main.js b/5-Counter/src/main.js new file mode 100644 index 0000000..f34dcd5 --- /dev/null +++ b/5-Counter/src/main.js @@ -0,0 +1,7 @@ +import App from './js/App.js' + +const $app = document.querySelector('.app') + +new App({ + $target: $app, +}) diff --git a/5-Counter/utils/Constant.js b/5-Counter/utils/Constant.js new file mode 100644 index 0000000..9cb61cc --- /dev/null +++ b/5-Counter/utils/Constant.js @@ -0,0 +1,3 @@ +export const TEXTS = { + TITLE_TEXT : 'COUNTER', +} \ No newline at end of file diff --git a/6-Carousel/index.html b/6-Carousel/index.html new file mode 100644 index 0000000..50e40bc --- /dev/null +++ b/6-Carousel/index.html @@ -0,0 +1,20 @@ + + + + + + + Carousel + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/6-Carousel/src/css/reset.css b/6-Carousel/src/css/reset.css new file mode 100644 index 0000000..5bca465 --- /dev/null +++ b/6-Carousel/src/css/reset.css @@ -0,0 +1,129 @@ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +input:focus { + outline: none; +} +a { + color: inherit; + text-decoration: none; +} diff --git a/6-Carousel/src/css/style.css b/6-Carousel/src/css/style.css new file mode 100644 index 0000000..4c7c2f5 --- /dev/null +++ b/6-Carousel/src/css/style.css @@ -0,0 +1,53 @@ +.CarouselPage { + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + justify-content: center; + align-items: center; +} + +.carouselImage { + width: 70%; + position: relative; +} + +.carouselImage__image { + width: 100%; +} + +.carouselImage__buttons { + position: absolute; + top: 50%; + width: 100%; + display: flex; + justify-content: space-between; +} + +.carouselImage__button { + color: white; + background: transparent; + border-radius: 0px; + border: 0; +} + +.carouselImage__button:hover { + background-color: black; + opacity: 0.5; +} + +.Carousel__indicators { + display: flex; + margin-top: 10px; +} +.Carousel__indicator-dot { + width: 10px; + height: 10px; + background-color: gray; + border-radius: 50%; + margin-right: 8px; +} + +.Carousel__indicator-dot--selected { + background-color: black; +} \ No newline at end of file diff --git a/6-Carousel/src/js/App.js b/6-Carousel/src/js/App.js new file mode 100644 index 0000000..71e45cb --- /dev/null +++ b/6-Carousel/src/js/App.js @@ -0,0 +1,62 @@ +import { images } from '../../utils/imageUrl.js' +import CaroselImage from './CarouselImage.js' +import Indicators from './Indicators.js'; + +const IMAGES_LENGTH = images.length; +export default function CarouselPage({ $target }) { + const $page = document.createElement('div') + $target.appendChild($page) + $page.className = 'CarouselPage' + + this.state = { + index: 0, + } + + const carouselImage = new CaroselImage({ + $target: $page, + initialState: { + index: this.state.index, + image: images[this.state.index], + }, + onPrevClick: () => { + const index = + this.state.index - 1 < 0 ? IMAGES_LENGTH - 1 : this.state.index - 1 + + this.setState({ + ...this.state, + index, + }) + }, + onNextClick: () => { + const index = (this.state.index + 1) % IMAGES_LENGTH + + this.setState({ + ...this.state, + index, + }) + }, + }) + + const indicators = new Indicators({ + $target: $page, + initialState: { + index: this.state.index, + }, + length: IMAGES_LENGTH, + }) + + + this.setState = (nextState) => { + this.state = nextState + const { index } = this.state + + carouselImage.setState({ + index, + image: images[index], + }) + + indicators.setState({ + index, + }) + } +} \ No newline at end of file diff --git a/6-Carousel/src/js/CarouselImage.js b/6-Carousel/src/js/CarouselImage.js new file mode 100644 index 0000000..b2a4fbf --- /dev/null +++ b/6-Carousel/src/js/CarouselImage.js @@ -0,0 +1,52 @@ +export default function ImageCarousel({$target, initialState, onPrevClick, onNextClick}) { + const $carouselImage = document.createElement('div') + $carouselImage.className = 'carouselImage' + + this.state = initialState + + $target.appendChild($carouselImage) + + const $image = document.createElement('img') + $image.className = 'carouselImage__image' + + const $buttons = document.createElement('div') + $buttons.className = 'carouselImage__buttons' + + $buttons.innerHTML = ` + + + + ` + + this.setState = (nextState) => { + this.state = nextState + this.render() + } + + this.render = () => { + $carouselImage.innerHTML = '' + + const { src, name } = this.state.image + $image.src = src + $image.alt = name + + $carouselImage.appendChild($image) + $carouselImage.appendChild($buttons) + } + + this.render() + + $buttons.addEventListener('click', (e) => { + const {className} = e.target.closest('button') + + if ( className === 'prevBtn') { + onPrevClick() + } else if ( className === 'nextBtn' ) { + onNextClick() + } + }) +} \ No newline at end of file diff --git a/6-Carousel/src/js/Indicators.js b/6-Carousel/src/js/Indicators.js new file mode 100644 index 0000000..bdd2367 --- /dev/null +++ b/6-Carousel/src/js/Indicators.js @@ -0,0 +1,27 @@ + +export default function Indicators({ $target, initialState, length }) { + const $indicators = document.createElement('div') + $indicators.className = 'Carousel__indicators' + $target.appendChild($indicators) + + this.state = initialState + + this.setState = (nextState) => { + this.state = nextState + this.render() + } + + this.render = () => { + const checkedIndicators = Array.from(new Array(length), (_) => _) + .map((_, index) => ``, + ) + .join('') + + $indicators.innerHTML = checkedIndicators + } + + this.render() +} \ No newline at end of file diff --git a/6-Carousel/src/main.js b/6-Carousel/src/main.js new file mode 100644 index 0000000..f34dcd5 --- /dev/null +++ b/6-Carousel/src/main.js @@ -0,0 +1,7 @@ +import App from './js/App.js' + +const $app = document.querySelector('.app') + +new App({ + $target: $app, +}) diff --git a/6-Carousel/utils/imageUrl.js b/6-Carousel/utils/imageUrl.js new file mode 100644 index 0000000..35df98b --- /dev/null +++ b/6-Carousel/utils/imageUrl.js @@ -0,0 +1,34 @@ +export const images = [ + { + name: 'Lam0', + src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam0.jpg', + }, + { + name: 'Lam1', + src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam1.jpg', + }, + { + name: 'Lam2', + src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam2.jpg', + }, + { + name: 'Lam3', + src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam3.jpg', + }, + { + name: 'Lam4', + src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam4.jpg', + }, + { + name: 'Lam5', + src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam5.jpg', + }, + { + name: 'Lam5', + src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam6.jpg', + }, + { + name: 'Lam7', + src: 'https://iamcodefoxx.github.io/ImageCarousel/Lam7.jpg', + }, +] \ No newline at end of file diff --git a/README.md b/README.md index 8e7c12a..e0cf3c4 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,18 @@ - [Project1/리아] 프로젝트명 - 예) [Project1/리아] Colors +## 2회차(~9/21) +### Project 4 The message +![image](https://user-images.githubusercontent.com/64760270/133061934-b99e60d5-fc6f-4705-a9a4-02015d728f4e.png) +### Project 5 Counter +![image](https://user-images.githubusercontent.com/64760270/133061971-6eaa17ab-cd0e-4aec-b1b4-2e998f8d8548.png) +### Project 6 Image carousel +![image](https://user-images.githubusercontent.com/64760270/133062053-5786ef19-7375-4481-9e7f-a871ee563d54.png) +### Project 7 Digital clock +![image](https://user-images.githubusercontent.com/64760270/133062123-f6177858-f738-4a66-b2d2-000c43787276.png) + + + ## 1회차(~9/12) ### Project 1 Colors ![image](https://user-images.githubusercontent.com/64760270/132218819-23e9edb1-9596-4a31-9618-5e7e6adeecb0.png)