0


5个前端练手项目(html css js canvas)

前言:

首先祝大家端午节快乐。本篇文章有5个练手项目
对于刚学完前端三剑客的你们。应该是一个很好的实践


1.跑马灯

1.1效果图:


1.2思路解析

在这个项目中,在html中创立20个span标签

每个span标签设置style为--i:数字的样式用于

在css中动态分配圆圈分几份,transform: rotate(calc(18deg*var(--i)))

利用filter属性结合关键帧动态切换颜色。同时设置每一个span标签进行

旋转


1.3源码

  1. <style>
  2. * {
  3. padding: 0;
  4. margin: 0;
  5. box-sizing: border-box;
  6. }
  7. main{
  8. display: flex;
  9. background-color: #2c3a47;
  10. /*用于设置图像居中 */
  11. align-items: center;
  12. justify-content: center;
  13. width: 1920px;
  14. height: 1000px;
  15. animation: animate1 10s linear infinite;
  16. }
  17. /* 用于设置动画属性 其中filter用于做利镜其中的hue-rotate属性让图像运用色相旋转*/
  18. @keyframes animate1 {
  19. 0% {
  20. filter: hue-rotate(0deg);
  21. }
  22. 100% {
  23. filter: hue-rotate(360deg);
  24. }
  25. }
  26. main .cube {
  27. position: relative;
  28. height: 120px;
  29. width: 120px;
  30. }
  31. main .cube span {
  32. position: absolute;
  33. top: 0;
  34. left: 0;
  35. width: 100%;
  36. height: 100%;
  37. /* 用于设置一个圆圈被分成几份 */
  38. transform: rotate(calc(18deg*var(--i)));
  39. }
  40. /* :before用于设置在给定的属性之前添加效果 */
  41. main .cube span::before {
  42. content: '';
  43. position: absolute;
  44. top: 0;
  45. left: 0;
  46. width: 15px;
  47. height: 15px;
  48. border-radius: 50%;
  49. background-color: aqua;
  50. box-shadow: 0 0 10px aqua ,0 0 20px aqua,0 0 40px aqua,0 0 80px aqua,0 0 100px aqua;
  51. animation: animate 2s linear infinite;
  52. animation-delay: calc(0.1s*var(--i));
  53. }
  54. @keyframes animate {
  55. 0% {
  56. transform: scale(1);
  57. }
  58. 80%,
  59. 100% {
  60. transform: scale(0);
  61. }
  62. }
  63. .loading{
  64. color:#fff;
  65. font-size: 20px;
  66. position: relative;
  67. top:100px;
  68. right:100px;
  69. }
  70. @media (min-width:765px){
  71. }
  72. </style>
  73. </head>
  74. <body>
  75. <main>
  76. <div class="cube">
  77. <span style="--i:1;"></span>
  78. <span style="--i:2;"></span>
  79. <span style="--i:3;"></span>
  80. <span style="--i:4;"></span>
  81. <span style="--i:5;"></span>
  82. <span style="--i:6;"></span>
  83. <span style="--i:7;"></span>
  84. <span style="--i:8;"></span>
  85. <span style="--i:9;"></span>
  86. <span style="--i:10;"></span>
  87. <span style="--i:11;"></span>
  88. <span style="--i:12;"></span>
  89. <span style="--i:13;"></span>
  90. <span style="--i:14;"></span>
  91. <span style="--i:15;"></span>
  92. <span style="--i:16;"></span>
  93. <span style="--i:17;"></span>
  94. <span style="--i:18;"></span>
  95. <span style="--i:19;"></span>
  96. <span style="--i:20;"></span>
  97. </div>
  98. <div class="loading">
  99. <p>loading</p>
  100. </div>
  101. </main>
  102. </body>

2.彩虹爱心


2.1效果图


2.2思路解析

搭建基本的html结构,采用的svg技术

通过js动态改变颜色,以及动态实现切换图形


2.3源码

  1. <svg id="hearts" viewBox="-600 -400 1200 800" preserveAspectRatio="xMidYMid slice">
  2. <defs>
  3. <symbol id="heart" viewBox="-69 -16 138 138">
  4. <path d="M0,12
  5. C 50,-30 110,50 0,120
  6. C-110,50 -50,-30 0,12z"/>
  7. </symbol>
  8. </defs>
  9. </svg>
  10. const colors = ["#e03776","#8f3e98","#4687bf","#3bab6f","#f9c25e","#f47274"];
  11. const SVG_NS = 'http://www.w3.org/2000/svg';
  12. const SVG_XLINK = "http://www.w3.org/1999/xlink";
  13. let heartsRy = []
  14. function useTheHeart(n){
  15. let use = document.createElementNS(SVG_NS, 'use');
  16. use.n = n;
  17. use.setAttributeNS(SVG_XLINK, 'xlink:href', '#heart');
  18. use.setAttributeNS(null, 'transform', `scale(${use.n})`);
  19. use.setAttributeNS(null, 'fill', colors[n%colors.length]);
  20. use.setAttributeNS(null, 'x', -69);
  21. use.setAttributeNS(null, 'y', -69);
  22. use.setAttributeNS(null, 'width', 138);
  23. use.setAttributeNS(null, 'height', 138);
  24. heartsRy.push(use)
  25. hearts.appendChild(use);
  26. }
  27. for(let n = 18; n >= 0; n--){useTheHeart(n)}
  28. function Frame(){
  29. window.requestAnimationFrame(Frame);
  30. for(let i = 0; i < heartsRy.length; i++){
  31. if(heartsRy[i].n < 18){heartsRy[i].n +=.01
  32. }else{
  33. heartsRy[i].n = 0;
  34. hearts.appendChild(heartsRy[i])
  35. }
  36. heartsRy[i].setAttributeNS(null, 'transform', `scale(${heartsRy[i].n})`);
  37. }
  38. }
  39. Frame()

3.闹钟


3.1效果图


3.2思路解析

搭建基本的html结构,动态得到实时的时,分,秒

通过Date()函数获得。将得到的数字根据逻辑,绑定

给各div结构,实行动态旋转。点击按钮,改变背景颜色


3.3源码

html:

  1. <body>
  2. <button class="toggle">Dark mode</button>
  3. <div class="clock-container">
  4. <div class="clock">
  5. <div class="needle hour"></div>
  6. <div class="needle minute"></div>
  7. <div class="needle second"></div>
  8. <div class="center-point"></div>
  9. </div>
  10. <div class="time"></div>
  11. <div class="date"></div>
  12. </div>
  13. </body>

css:

  1. @import url('https://fonts.googleapis.com/css?family=Heebo:300&display=swap');
  2. * {
  3. box-sizing: border-box;
  4. }
  5. :root {
  6. --primary-color: #000;
  7. --secondary-color: #fff;
  8. }
  9. html {
  10. transition: all 0.5s ease-in;
  11. }
  12. html.dark {
  13. --primary-color: #fff;
  14. --secondary-color: #333;
  15. }
  16. html.dark {
  17. background-color: #111;
  18. color: var(--primary-color);
  19. }
  20. body {
  21. font-family: 'Heebo', sans-serif;
  22. display: flex;
  23. align-items: center;
  24. justify-content: center;
  25. height: 100vh;
  26. overflow: hidden;
  27. margin: 0;
  28. }
  29. .toggle {
  30. cursor: pointer;
  31. background-color: var(--primary-color);
  32. color: var(--secondary-color);
  33. border: 0;
  34. border-radius: 4px;
  35. padding: 8px 12px;
  36. position: absolute;
  37. top: 100px;
  38. }
  39. .toggle:focus {
  40. outline: none;
  41. }
  42. .clock-container {
  43. display: flex;
  44. flex-direction: column;
  45. justify-content: space-between;
  46. align-items: center;
  47. }
  48. .clock {
  49. position: relative;
  50. width: 200px;
  51. height: 200px;
  52. }
  53. .needle {
  54. background-color: var(--primary-color);
  55. position: absolute;
  56. top: 50%;
  57. left: 50%;
  58. height: 65px;
  59. width: 3px;
  60. transform-origin: bottom center;
  61. transition: all 0.5s ease-in;
  62. }
  63. .needle.hour {
  64. transform: translate(-50%, -100%) rotate(0deg);
  65. }
  66. .needle.minute {
  67. transform: translate(-50%, -100%) rotate(0deg);
  68. height: 100px;
  69. }
  70. .needle.second {
  71. transform: translate(-50%, -100%) rotate(0deg);
  72. height: 100px;
  73. background-color: #e74c3c;
  74. }
  75. .center-point {
  76. background-color: #e74c3c;
  77. width: 10px;
  78. height: 10px;
  79. position: absolute;
  80. top: 50%;
  81. left: 50%;
  82. transform: translate(-50%, -50%);
  83. border-radius: 50%;
  84. }
  85. .center-point::after {
  86. content: '';
  87. background-color: var(--primary-color);
  88. width: 5px;
  89. height: 5px;
  90. position: absolute;
  91. top: 50%;
  92. left: 50%;
  93. transform: translate(-50%, -50%);
  94. border-radius: 50%;
  95. }
  96. .time {
  97. font-size: 60px;
  98. }
  99. .date {
  100. color: #aaa;
  101. font-size: 14px;
  102. letter-spacing: 0.3px;
  103. text-transform: uppercase;
  104. }
  105. .date .circle {
  106. background-color: var(--primary-color);
  107. color: var(--secondary-color);
  108. border-radius: 50%;
  109. height: 18px;
  110. width: 18px;
  111. display: inline-flex;
  112. align-items: center;
  113. justify-content: center;
  114. line-height: 18px;
  115. transition: all 0.5s ease-in;
  116. font-size: 12px;
  117. }

js:

  1. const hourEl = document.querySelector('.hour')
  2. const minuteEl = document.querySelector('.minute')
  3. const secondEl = document.querySelector('.second')
  4. const timeEl = document.querySelector('.time')
  5. const dateEl = document.querySelector('.date')
  6. const toggle = document.querySelector('.toggle')
  7. const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  8. const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
  9. toggle.addEventListener('click', (e) => {
  10. const html = document.querySelector('html')
  11. if (html.classList.contains('dark')) {
  12. html.classList.remove('dark')
  13. e.target.innerHTML = 'Dark mode'
  14. } else {
  15. html.classList.add('dark')
  16. e.target.innerHTML = 'Light mode'
  17. }
  18. })
  19. function setTime() {
  20. const time = new Date();
  21. const month = time.getMonth()
  22. const day = time.getDay()
  23. const date = time.getDate()
  24. const hours = time.getHours()
  25. const hoursForClock = hours >= 13 ? hours % 12 : hours;
  26. const minutes = time.getMinutes()
  27. const seconds = time.getSeconds()
  28. const ampm = hours >= 12 ? 'PM' : 'AM'
  29. hourEl.style.transform = `translate(-50%, -100%) rotate(${scale(hoursForClock, 0, 12, 0, 360)}deg)`
  30. minuteEl.style.transform = `translate(-50%, -100%) rotate(${scale(minutes, 0, 60, 0, 360)}deg)`
  31. secondEl.style.transform = `translate(-50%, -100%) rotate(${scale(seconds, 0, 60, 0, 360)}deg)`
  32. timeEl.innerHTML = `${hoursForClock}:${minutes < 10 ? `0${minutes}` : minutes} ${ampm}`
  33. dateEl.innerHTML = `${days[day]}, ${months[month]} <span class="circle">${date}</span>`
  34. }
  35. // StackOverflow https://stackoverflow.com/questions/10756313/javascript-jquery-map-a-range-of-numbers-to-another-range-of-numbers
  36. const scale = (num, in_min, in_max, out_min, out_max) => {
  37. return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  38. }
  39. setTime()
  40. setInterval(setTime, 1000)

4.自制笔记本


4.1效果展示


4.2思路解析

通过js实现动态添加DOM结构,绑定创建出DOM结构的

添加,删除按钮。实现监听事件。实现动态改变DOM结构

其他的就是设置css的相关属性,


4.3源码

html:

  1. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
  2. </head>
  3. <body>
  4. <button class="add" id="add">
  5. <i class="fas fa-plus"></i> Add note
  6. </button>
  7. <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/1.2.2/marked.min.js"></script>
  8. </body>

css:

  1. @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap');
  2. * {
  3. box-sizing: border-box;
  4. outline: none;
  5. }
  6. body {
  7. background-color: #7bdaf3;
  8. font-family: 'Poppins', sans-serif;
  9. display: flex;
  10. flex-wrap: wrap;
  11. margin: 0;
  12. padding-top: 3rem;
  13. }
  14. .add {
  15. position: fixed;
  16. top: 1rem;
  17. right: 1rem;
  18. background-color: #9ec862;
  19. color: #fff;
  20. border: none;
  21. border-radius: 3px;
  22. padding: 0.5rem 1rem;
  23. cursor: pointer;
  24. }
  25. .add:active {
  26. transform: scale(0.98);
  27. }
  28. .note {
  29. background-color: #fff;
  30. box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1);
  31. margin: 30px 20px;
  32. height: 400px;
  33. width: 400px;
  34. overflow-y: scroll;
  35. }
  36. .note .tools {
  37. background-color: #9ec862;
  38. display: flex;
  39. justify-content: flex-end;
  40. padding: 0.5rem;
  41. }
  42. .note .tools button {
  43. background-color: transparent;
  44. border: none;
  45. color: #fff;
  46. cursor: pointer;
  47. font-size: 1rem;
  48. margin-left: 0.5rem;
  49. }
  50. .note textarea {
  51. outline: none;
  52. font-family: inherit;
  53. font-size: 1.2rem;
  54. border: none;
  55. height: 400px;
  56. width: 100%;
  57. padding: 20px;
  58. }
  59. .main {
  60. padding: 20px;
  61. }
  62. .hidden {
  63. display: none;
  64. }

js:

  1. const addBtn = document.getElementById('add')
  2. const notes = JSON.parse(localStorage.getItem('notes'))
  3. if(notes) {
  4. notes.forEach(note => addNewNote(note))
  5. }
  6. addBtn.addEventListener('click', () => addNewNote())
  7. function addNewNote(text = '') {
  8. const note = document.createElement('div')
  9. note.classList.add('note')
  10. note.innerHTML = `
  11. <div class="tools">
  12. <button class="edit"><i class="fas fa-edit"></i></button>
  13. <button class="delete"><i class="fas fa-trash-alt"></i></button>
  14. </div>
  15. <div class="main ${text ? "" : "hidden"}"></div>
  16. <textarea class="${text ? "hidden" : ""}"></textarea>
  17. `
  18. const editBtn = note.querySelector('.edit')
  19. const deleteBtn = note.querySelector('.delete')
  20. const main = note.querySelector('.main')
  21. const textArea = note.querySelector('textarea')
  22. textArea.value = text
  23. main.innerHTML = marked(text)
  24. deleteBtn.addEventListener('click', () => {
  25. note.remove()
  26. updateLS()
  27. })
  28. editBtn.addEventListener('click', () => {
  29. main.classList.toggle('hidden')
  30. textArea.classList.toggle('hidden')
  31. })
  32. textArea.addEventListener('input', (e) => {
  33. const { value } = e.target
  34. main.innerHTML = marked(value)
  35. updateLS()
  36. })
  37. document.body.appendChild(note)
  38. }
  39. function updateLS() {
  40. const notesText = document.querySelectorAll('textarea')
  41. const notes = []
  42. notesText.forEach(note => notes.push(note.value))
  43. localStorage.setItem('notes', JSON.stringify(notes))
  44. }

5.自定义写字台(也可自定义字的样式)


5.1效果展示


5.2思路解析

搭建html结构,创建canvas标签

绑定设置的结构比如+,-,颜色改变

动态设置并获取他的值,然后将这些值动态的

设置为canvas语法中设置渲染的宽度,以及设置

颜色的属性


5.3源码

html:

  1. <canvas id="canvas" width="800" height="700"></canvas>
  2. <div class="toolbox">
  3. <button id="decrease">-</button>
  4. <span id="size">10</span>
  5. <button id="increase">+</button>
  6. <input type="color" id="color">
  7. <button id="clear">X</button>
  8. </div>

css:

  1. @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
  2. * {
  3. box-sizing: border-box;
  4. }
  5. body {
  6. background-color: #f5f5f5;
  7. font-family: 'Roboto', sans-serif;
  8. display: flex;
  9. flex-direction: column;
  10. align-items: center;
  11. justify-content: center;
  12. height: 100vh;
  13. margin: 0;
  14. }
  15. canvas {
  16. border: 2px solid steelblue;
  17. }
  18. .toolbox {
  19. background-color: steelblue;
  20. border: 1px solid slateblue;
  21. display: flex;
  22. width: 804px;
  23. padding: 1rem;
  24. }
  25. .toolbox > * {
  26. background-color: #fff;
  27. border: none;
  28. display: inline-flex;
  29. align-items: center;
  30. justify-content: center;
  31. font-size: 2rem;
  32. height: 50px;
  33. width: 50px;
  34. margin: 0.25rem;
  35. padding: 0.25rem;
  36. cursor: pointer;
  37. }
  38. .toolbox > *:last-child {
  39. margin-left: auto;
  40. }

js:

  1. const canvas = document.getElementById('canvas');
  2. const increaseBtn = document.getElementById('increase');
  3. const decreaseBtn = document.getElementById('decrease');
  4. const sizeEL = document.getElementById('size');
  5. const colorEl = document.getElementById('color');
  6. const clearEl = document.getElementById('clear');
  7. const ctx = canvas.getContext('2d');
  8. let size = 10
  9. let isPressed = false
  10. colorEl.value = 'black'
  11. let color = colorEl.value
  12. let x
  13. let y
  14. canvas.addEventListener('mousedown', (e) => {
  15. isPressed = true
  16. x = e.offsetX
  17. y = e.offsetY
  18. })
  19. document.addEventListener('mouseup', (e) => {
  20. isPressed = false
  21. x = undefined
  22. y = undefined
  23. })
  24. canvas.addEventListener('mousemove', (e) => {
  25. if(isPressed) {
  26. const x2 = e.offsetX
  27. const y2 = e.offsetY
  28. drawCircle(x2, y2)
  29. drawLine(x, y, x2, y2)
  30. x = x2
  31. y = y2
  32. }
  33. })
  34. function drawCircle(x, y) {
  35. ctx.beginPath();
  36. ctx.arc(x, y, size, 0, Math.PI * 2)
  37. ctx.fillStyle = color
  38. ctx.fill()
  39. }
  40. function drawLine(x1, y1, x2, y2) {
  41. ctx.beginPath()
  42. ctx.moveTo(x1, y1)
  43. ctx.lineTo(x2, y2)
  44. ctx.strokeStyle = color
  45. ctx.lineWidth = size * 2
  46. ctx.stroke()
  47. }
  48. function updateSizeOnScreen() {
  49. sizeEL.innerText = size
  50. }
  51. increaseBtn.addEventListener('click', () => {
  52. size += 5
  53. if(size > 50) {
  54. size = 50
  55. }
  56. updateSizeOnScreen()
  57. })
  58. decreaseBtn.addEventListener('click', () => {
  59. size -= 5
  60. if(size < 5) {
  61. size = 5
  62. }
  63. updateSizeOnScreen()
  64. })
  65. colorEl.addEventListener('change', (e) => color = e.target.value)
  66. clearEl.addEventListener('click', () => ctx.clearRect(0,0, canvas.width, canvas.height))

✍在最后,如果觉得博主写的还行,期待🍟点赞 🍬评论 🍪收藏

标签: css css3 html

本文转载自: https://blog.csdn.net/m0_51311990/article/details/125117079
版权归原作者 言不及行yyds 所有, 如有侵权,请联系我们删除。

“5个前端练手项目(html css js canvas)”的评论:

还没有评论