小工具知识网

当前位置: 首页 > 行业知识 > 5个前端练手项目(html css js canvas)

行业知识

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

2026-11-13 11:14:26 来源:互联网转载

�index.php/tags-41973.html" >�前言:

首先祝大家端午节快乐。本篇文章有5个练手项目

对于刚学完前端三剑客的你们。应该是一个很好的实践

目录

.跑马灯

1.1效果图:

1.2思路解析

1.3源码

.彩虹爱心

2.1效果图

2.2思路解析

2.3源码

.闹钟

3.1效果图

3.2思路解析

3.3源码

.自制笔记本

4.1效果展示

4.2思路解析

4.3源码

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

5.1效果展示

 5.2思路解析

5.3源码



1.跑马灯

1.1效果图:


1.2思路解析

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

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

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

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

旋转


1.3源码

* {padding: 0;margin: 0;box-sizing: border-box;}main{display: flex;    background-color: #2c3a47;/*用于设置图像居中 */align-items: center;justify-content: center;width: 1920px;height: 1000px;animation: animate1 10s linear infinite;}/* 用于设置动画属性 其中filter用于做利镜其中的hue-rotate属性让图像运用色相旋转*/@keyframes animate1 {0% {filter: hue-rotate(0deg);}100% {filter: hue-rotate(360deg);}}main .cube {position: relative;height: 120px;width: 120px;    }main .cube span {position: absolute;top: 0;left: 0;width: 100%;height: 100%;/* 用于设置一个圆圈被分成几份 */transform: rotate(calc(18deg*var(--i)));}/* :before用于设置在给定的属性之前添加效果 */main .cube span::before {content: '';position: absolute;top: 0;left: 0;width: 15px;height: 15px;border-radius: 50%;background-color: aqua;box-shadow: 0 0 10px aqua ,0 0 20px aqua,0 0 40px aqua,0 0 80px aqua,0 0 100px aqua;animation: animate 2s linear infinite;animation-delay: calc(0.1s*var(--i));}@keyframes animate {0% {transform: scale(1);}80%,100% {    transform: scale(0);}}.loading{color:#fff;font-size: 20px;position: relative;top:100px;right:100px;          }@media (min-width:765px){ }        

loading


2.彩虹爱心


2.1效果图


2.2思路解析

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

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


2.3源码

const colors = ["#e03776","#8f3e98","#4687bf","#3bab6f","#f9c25e","#f47274"];const SVG_NS = 'http://www.w3.org/2000/svg';const SVG_XLINK = "http://www.w3.org/1999/xlink";let heartsRy = []function useTheHeart(n){  let use = document.createElementNS(SVG_NS, 'use');  use.n = n;  use.setAttributeNS(SVG_XLINK, 'xlink:href', '#heart');  use.setAttributeNS(null, 'transform', `scale(${use.n})`);  use.setAttributeNS(null, 'fill', colors[n%colors.length]);  use.setAttributeNS(null, 'x', -69);  use.setAttributeNS(null, 'y', -69);  use.setAttributeNS(null, 'width', 138);  use.setAttributeNS(null, 'height', 138);    heartsRy.push(use)  hearts.appendChild(use);}for(let n = 18; n >= 0; n--){useTheHeart(n)}function Frame(){  window.requestAnimationFrame(Frame);  for(let i = 0; i  

3.闹钟


3.1效果图


3.2思路解析

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

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

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


3.3源码

html:

  Dark mode                                         

css:

@import url('https://fonts.googleapis.com/css?family=Heebo:300&display=swap');* {  box-sizing: border-box;}:root {  --primary-color: #000;  --secondary-color: #fff;}html {  transition: all 0.5s ease-in;}html.dark {  --primary-color: #fff;  --secondary-color: #333;}html.dark {  background-color: #111;  color: var(--primary-color);}body {  font-family: 'Heebo', sans-serif;  display: flex;  align-items: center;  justify-content: center;  height: 100vh;  overflow: hidden;  margin: 0;}.toggle {  cursor: pointer;  background-color: var(--primary-color);  color: var(--secondary-color);  border: 0;  border-radius: 4px;  padding: 8px 12px;  position: absolute;  top: 100px;}.toggle:focus {  outline: none;}.clock-container {  display: flex;  flex-direction: column;  justify-content: space-between;  align-items: center;}.clock {  position: relative;  width: 200px;  height: 200px;}.needle {  background-color: var(--primary-color);  position: absolute;  top: 50%;  left: 50%;  height: 65px;  width: 3px;  transform-origin: bottom center;  transition: all 0.5s ease-in;}.needle.hour {  transform: translate(-50%, -100%) rotate(0deg);}.needle.minute {  transform: translate(-50%, -100%) rotate(0deg);  height: 100px;}.needle.second {  transform: translate(-50%, -100%) rotate(0deg);  height: 100px;  background-color: #e74c3c;}.center-point {  background-color: #e74c3c;  width: 10px;  height: 10px;  position: absolute;  top: 50%;  left: 50%;  transform: translate(-50%, -50%);  border-radius: 50%;}.center-point::after {  content: '';  background-color: var(--primary-color);  width: 5px;  height: 5px;  position: absolute;  top: 50%;  left: 50%;  transform: translate(-50%, -50%);  border-radius: 50%;}.time {  font-size: 60px;}.date {  color: #aaa;  font-size: 14px;  letter-spacing: 0.3px;  text-transform: uppercase;}.date .circle {  background-color: var(--primary-color);  color: var(--secondary-color);  border-radius: 50%;  height: 18px;  width: 18px;  display: inline-flex;  align-items: center;  justify-content: center;  line-height: 18px;  transition: all 0.5s ease-in;  font-size: 12px;}

js:

const hourEl = document.querySelector('.hour')const minuteEl = document.querySelector('.minute')const secondEl = document.querySelector('.second')const timeEl = document.querySelector('.time')const dateEl = document.querySelector('.date')const toggle = document.querySelector('.toggle')const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];toggle.addEventListener('click', (e) => {    const html = document.querySelector('html')    if (html.classList.contains('dark')) {        html.classList.remove('dark')        e.target.innerHTML = 'Dark mode'    } else {        html.classList.add('dark')        e.target.innerHTML = 'Light mode'    }})function setTime() {    const time = new Date();    const month = time.getMonth()    const day = time.getDay()    const date = time.getDate()    const hours = time.getHours()    const hoursForClock = hours >= 13 ? hours % 12 : hours;    const minutes = time.getMinutes()    const seconds = time.getSeconds()    const ampm = hours >= 12 ? 'PM' : 'AM'    hourEl.style.transform = `translate(-50%, -100%) rotate(${scale(hoursForClock, 0, 12, 0, 360)}deg)`    minuteEl.style.transform = `translate(-50%, -100%) rotate(${scale(minutes, 0, 60, 0, 360)}deg)`    secondEl.style.transform = `translate(-50%, -100%) rotate(${scale(seconds, 0, 60, 0, 360)}deg)`    timeEl.innerHTML = `${hoursForClock}:${minutes  {    return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;}setTime()setInterval(setTime, 1000)

4.自制笔记本


4.1效果展示


4.2思路解析

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

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

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


4.3源码

html:

       Add note          

 css:

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap');* {  box-sizing: border-box;  outline: none;}body {  background-color: #7bdaf3;  font-family: 'Poppins', sans-serif;  display: flex;  flex-wrap: wrap;  margin: 0;  padding-top: 3rem;}.add {  position: fixed;  top: 1rem;  right: 1rem;  background-color: #9ec862;  color: #fff;  border: none;  border-radius: 3px;  padding: 0.5rem 1rem;  cursor: pointer;}.add:active {  transform: scale(0.98);}.note {  background-color: #fff;  box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1);  margin: 30px 20px;  height: 400px;  width: 400px;  overflow-y: scroll;}.note .tools {  background-color: #9ec862;  display: flex;  justify-content: flex-end;  padding: 0.5rem;}.note .tools button {  background-color: transparent;  border: none;  color: #fff;  cursor: pointer;  font-size: 1rem;  margin-left: 0.5rem;}.note textarea {  outline: none;  font-family: inherit;  font-size: 1.2rem;  border: none;  height: 400px;  width: 100%;  padding: 20px;}.main {  padding: 20px;}.hidden {  display: none;}

js:

const addBtn = document.getElementById('add')const notes = JSON.parse(localStorage.getItem('notes'))if(notes) {    notes.forEach(note => addNewNote(note))}addBtn.addEventListener('click', () => addNewNote())function addNewNote(text = '') {    const note = document.createElement('p')    note.classList.add('note')    note.innerHTML = `                                    `    const editBtn = note.querySelector('.edit')    const deleteBtn = note.querySelector('.delete')    const main = note.querySelector('.main')    const textArea = note.querySelector('textarea')    textArea.value = text    main.innerHTML = marked(text)    deleteBtn.addEventListener('click', () => {        note.remove()        updateLS()    })    editBtn.addEventListener('click', () => {        main.classList.toggle('hidden')        textArea.classList.toggle('hidden')    })    textArea.addEventListener('input', (e) => {        const { value } = e.target        main.innerHTML = marked(value)        updateLS()    })    document.body.appendChild(note)}function updateLS() {    const notesText = document.querySelectorAll('textarea')    const notes = []    notesText.forEach(note => notes.push(note.value))    localStorage.setItem('notes', JSON.stringify(notes))}

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


5.1效果展示


 5.2思路解析

搭建html结构,创建canvas标签,

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

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

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

颜色的属性


5.3源码

html:

 - 10 +  X

css:

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');* {  box-sizing: border-box;}body {  background-color: #f5f5f5;  font-family: 'Roboto', sans-serif;  display: flex;  flex-direction: column;  align-items: center;  justify-content: center;  height: 100vh;  margin: 0;}canvas {  border: 2px solid steelblue;}.toolbox {  background-color: steelblue;  border: 1px solid slateblue;  display: flex;  width: 804px;  padding: 1rem;}.toolbox > * {  background-color: #fff;  border: none;  display: inline-flex;  align-items: center;  justify-content: center;  font-size: 2rem;  height: 50px;  width: 50px;  margin: 0.25rem;  padding: 0.25rem;  cursor: pointer;}.toolbox > *:last-child {  margin-left: auto;}

js:

const canvas = document.getElementById('canvas');const increaseBtn = document.getElementById('increase');const decreaseBtn = document.getElementById('decrease');const sizeEL = document.getElementById('size');const colorEl = document.getElementById('color');const clearEl = document.getElementById('clear');const ctx = canvas.getContext('2d');let size = 10let isPressed = falsecolorEl.value = 'black'let color = colorEl.valuelet xlet ycanvas.addEventListener('mousedown', (e) => {    isPressed = true    x = e.offsetX    y = e.offsetY})document.addEventListener('mouseup', (e) => {    isPressed = false    x = undefined    y = undefined})canvas.addEventListener('mousemove', (e) => {    if(isPressed) {        const x2 = e.offsetX        const y2 = e.offsetY        drawCircle(x2, y2)        drawLine(x, y, x2, y2)        x = x2        y = y2    }})function drawCircle(x, y) {    ctx.beginPath();    ctx.arc(x, y, size, 0, Math.PI * 2)    ctx.fillStyle = color    ctx.fill()}function drawLine(x1, y1, x2, y2) {    ctx.beginPath()    ctx.moveTo(x1, y1)    ctx.lineTo(x2, y2)    ctx.strokeStyle = color    ctx.lineWidth = size * 2    ctx.stroke()}function updateSizeOnScreen() {    sizeEL.innerText = size}increaseBtn.addEventListener('click', () => {    size += 5    if(size > 50) {        size = 50    }    updateSizeOnScreen()})decreaseBtn.addEventListener('click', () => {    size -= 5    if(size  color = e.target.value)clearEl.addEventListener('click', () => ctx.clearRect(0,0, canvas.width, canvas.height))

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

上一篇:宝塔面板插件怎么换服务器?

下一篇:微信 服务器 哪里?