前言:
软件系统定制开发首先祝大家端午节快乐。软件系统定制开发本篇文章有5软件系统定制开发个练手项目
对于刚学完前端三剑客的你们。应该是一个很好的实践
目录
🥩
🍧
🌮
🍲
🍣
1.跑马灯
1.1效果图:
1.2思路解析
在这个项目中,在html中创立20个span标签
每个设置style为--i:数字的样式用于
在css中动态分配圆圈分几份,transform: rotate(calc(18deg*var(--i)))
利用filter属性结合关键帧动态切换颜色。同时设置每一个span标签进行
旋转
1.3源码
- <style>
- * {
- 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){
-
- }
-
- </style>
- </head>
- <body>
- <main>
- <div class="cube">
- <span style="--i:1;"></span>
- <span style="--i:2;"></span>
- <span style="--i:3;"></span>
- <span style="--i:4;"></span>
- <span style="--i:5;"></span>
- <span style="--i:6;"></span>
- <span style="--i:7;"></span>
- <span style="--i:8;"></span>
- <span style="--i:9;"></span>
- <span style="--i:10;"></span>
- <span style="--i:11;"></span>
- <span style="--i:12;"></span>
- <span style="--i:13;"></span>
- <span style="--i:14;"></span>
- <span style="--i:15;"></span>
- <span style="--i:16;"></span>
- <span style="--i:17;"></span>
- <span style="--i:18;"></span>
- <span style="--i:19;"></span>
- <span style="--i:20;"></span>
- </div>
- <div class="loading">
- <p>loading</p>
- </div>
- </main>
- </body>
2.彩虹爱心
2.1效果图
2.2思路解析
搭建基本的html结构,采用的svg技术,
通过js动态改变颜色,以及动态实现切换图形
2.3源码
- <svg id="hearts" viewBox="-600 -400 1200 800" preserveAspectRatio="xMidYMid slice">
-
- <defs>
-
- <symbol id="heart" viewBox="-69 -16 138 138">
-
- <path d="M0,12
- C 50,-30 110,50 0,120
- C-110,50 -50,-30 0,12z"/>
-
- </symbol>
-
- </defs>
-
- </svg>
-
-
- 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 < heartsRy.length; i++){
- if(heartsRy[i].n < 18){heartsRy[i].n +=.01
- }else{
- heartsRy[i].n = 0;
- hearts.appendChild(heartsRy[i])
- }
- heartsRy[i].setAttributeNS(null, 'transform', `scale(${heartsRy[i].n})`);
- }
- }
-
- Frame()
3.
3.1效果图
3.2思路解析
搭建基本的html结构,动态得到实时的时,分,秒
通过Date()函数获得。将得到的数字根据逻辑,绑定
给各div结构,实行动态旋转。点击按钮,改变背景颜色
3.3源码
html:
- <body>
- <button class="toggle">Dark mode</button>
- <div class="clock-container">
- <div class="clock">
- <div class="needle hour"></div>
- <div class="needle minute"></div>
- <div class="needle second"></div>
- <div class="center-point"></div>
- </div>
- <div class="time"></div>
- <div class="date"></div>
- </div>
- </body>
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 < 10 ? `0${minutes}` : minutes} ${ampm}`
- dateEl.innerHTML = `${days[day]}, ${months[month]} <span class="circle">${date}</span>`
- }
-
- // StackOverflow https://stackoverflow.com/questions/10756313/javascript-jquery-map-a-range-of-numbers-to-another-range-of-numbers
- const scale = (num, in_min, in_max, out_min, out_max) => {
- 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:
- <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" />
- </head>
- <body>
- <button class="add" id="add">
- <i class="fas fa-plus"></i> Add note
- </button>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/1.2.2/marked.min.js"></script>
-
- </body>
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('div')
- note.classList.add('note')
-
- note.innerHTML = `
- <div class="tools">
- <button class="edit"><i class="fas fa-edit"></i></button>
- <button class="delete"><i class="fas fa-trash-alt"></i></button>
- </div>
- <div class="main ${text ? "" : "hidden"}"></div>
- <textarea class="${text ? "hidden" : ""}"></textarea>
- `
-
- 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:
- <canvas id="canvas" width="800" height="700"></canvas>
- <div class="toolbox">
- <button id="decrease">-</button>
- <span id="size">10</span>
- <button id="increase">+</button>
- <input type="color" id="color">
- <button id="clear">X</button>
- </div>
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 = 10
- let isPressed = false
- colorEl.value = 'black'
- let color = colorEl.value
- let x
- let y
-
- canvas.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 < 5) {
- size = 5
- }
-
- updateSizeOnScreen()
- })
-
- colorEl.addEventListener('change', (e) => color = e.target.value)
-
- clearEl.addEventListener('click', () => ctx.clearRect(0,0, canvas.width, canvas.height))
✍在最后,如果觉得博主写的还行,期待🍟点赞 🍬评论 🍪收藏