当前位置: 首页 > news >正文

JavaScript使用渐变来美化对象!

我们的目标是渐变!渐变!

        首先了解,渐变分为线性渐变和径向渐变,线性渐变可以是从左上角到右下角的渐变,径向渐变是从中心向外的渐变。

        JavaScript中实现渐变可以使用addColorStop的方法,例如创建一个线性渐变的代码为:

// 创建线性渐变
var linearGradient = ctx.createLinearGradient(0, 0, 200, 0);
linearGradient.addColorStop("0", "green");
linearGradient.addColorStop("1", "white");// 应用渐变到矩形
ctx.fillStyle = linearGradient;
ctx.fillRect(10, 10, 180, 80);

        我们使用createLinearGradient(x1, y1, x2, y2)创建一个线性渐变。参数定义了渐变的开始和结束位置。

        径向渐变也是类似的:

// 创建径向渐变
var radialGradient = ctx.createRadialGradient(100, 50, 10, 100, 50, 50);
radialGradient.addColorStop("0", "red");
radialGradient.addColorStop("0.5", "yellow");
radialGradient.addColorStop("1", "green");// 应用渐变到矩形
ctx.fillStyle = radialGradient;
ctx.fillRect(10, 10, 180, 80);

        使用createRadialGradient(x1, y1, r1, x2, y2, r2)创建一个径向渐变。参数定义了内外圆的位置和半径。

        接下去我希望区分填充渐变和描边渐变,并且把这些代码写在一个函数里。创建drawCircle函数,包括circle和isFill参数,传入一个圆,如果isFill为true则填充,否则描边。

function drawCircle(circle, isFill) {var canvas = document.getElementById("myCanvas");var ctx = canvas.getContext("2d");// 创建径向渐变var radialGradient = ctx.createRadialGradient(circle.x, circle.y, 0, circle.x, circle.y, circle.radius);radialGradient.addColorStop("0", "red");radialGradient.addColorStop("0.5", "yellow");radialGradient.addColorStop("1", "green");if (isFill) {// 应用渐变填充ctx.fillStyle = radialGradient;ctx.beginPath();ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);ctx.fill();} else {// 应用渐变描边ctx.strokeStyle = radialGradient;ctx.lineWidth = 10; // 可以根据需要调整线宽ctx.beginPath();ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);ctx.stroke();}
}// 圆的参数
var circle = {x: 100,y: 100,radius: 50
};// 画一个填充的圆
drawCircle(circle, true);// 画一个描边的圆
// drawCircle(circle, false);

        不过,这个代码只实现了径向渐变,有兴趣可以在这里停下来自己实现一下填充渐变。完成的代码如下:

function drawCircle(circle, isFill, gradientType) {var canvas = document.getElementById("myCanvas");var ctx = canvas.getContext("2d");// 根据渐变类型创建渐变var gradient;if (gradientType === 'linear') {// 创建线性渐变gradient = ctx.createLinearGradient(circle.x, circle.y - circle.radius, circle.x + circle.radius, circle.y + circle.radius);gradient.addColorStop("0", "red");gradient.addColorStop("1", "green");} else if (gradientType === 'radial') {// 创建径向渐变gradient = ctx.createRadialGradient(circle.x, circle.y, 0, circle.x, circle.y, circle.radius);gradient.addColorStop("0", "red");gradient.addColorStop("0.5", "yellow");gradient.addColorStop("1", "green");}if (isFill) {// 应用渐变填充ctx.fillStyle = gradient;} else {// 应用渐变描边ctx.strokeStyle = gradient;ctx.lineWidth = 10; // 可以根据需要调整线宽}ctx.beginPath();ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);if (isFill) {ctx.fill();} else {ctx.stroke();}
}// 圆的参数
var circle = {x: 100,y: 100,radius: 50
};// 画一个填充的线性渐变圆
drawCircle(circle, true, 'linear');// 画一个描边的径向渐变圆
// drawCircle(circle, false, 'radial');

拆分函数:

        此时我们发现,这个drawCircle函数已经很大了,为了项目的可拓展性和可维护性,我们应该进行一下区分。

function createLinearGradient(ctx, circle) {return ctx.createLinearGradient(0, 0, circle.x * 2, circle.y * 2);
}function createRadialGradient(ctx, circle) {return ctx.createRadialGradient(circle.x, circle.y, 0, circle.x, circle.y, circle.radius);
}function applyGradient(ctx, gradient, isFill) {if (isFill) {ctx.fillStyle = gradient;} else {ctx.strokeStyle = gradient;ctx.lineWidth = 10; // 可以根据需要调整线宽}
}function drawCircleWithGradient(ctx, circle, isFill, gradient) {ctx.beginPath();ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);if (isFill) {ctx.fill();} else {ctx.stroke();}
}function drawCircle(circle, isFill, gradientType) {var canvas = document.getElementById("myCanvas");var ctx = canvas.getContext("2d");var gradient;if (gradientType === 'linear') {gradient = createLinearGradient(ctx, circle);gradient.addColorStop("0", "red");gradient.addColorStop("1", "green");} else if (gradientType === 'radial') {gradient = createRadialGradient(ctx, circle);gradient.addColorStop("0", "red");gradient.addColorStop("0.5", "yellow");gradient.addColorStop("1", "green");}applyGradient(ctx, gradient, isFill);drawCircleWithGradient(ctx, circle, isFill, gradient);
}// 圆的参数
var circle = {x: 200,y: 200,radius: 100
};// 画一个填充的线性渐变圆
drawCircle(circle, true, 'linear');// 画一个描边的径向渐变圆
// drawCircle(circle, false, 'radial');

拆分为四个函数: 

        createLinearGradient: 创建线性渐变。

        createRadialGradient: 创建径向渐变。

        applyGradient: 应用渐变到填充或描边。

        drawCircleWithGradient: 使用给定的渐变绘制圆。

        drawCircle 函数: 根据传入的 gradientType 参数调用相应的函数创建渐变。

代码的拓展

        上面我们已经初步实现了一个圆的渐变,但是也许还可以传入正方形?矩形?三角形?甚至是更多的类型?

        首先需要来实现这几种类型:

// 绘制圆形
function drawCircle(ctx, x, y, radius, isFill) {ctx.beginPath();ctx.arc(x, y, radius, 0, Math.PI * 2);ctx.fill();ctx.stroke();
}// 绘制矩形
function drawRect(ctx, x, y, width, height, isFill) {ctx.beginPath();ctx.rect(x, y, width, height);ctx.fill();ctx.stroke();
}// 绘制三角形
function drawTriangle(ctx, x1, y1, x2, y2, x3, y3, isFill) {ctx.beginPath();ctx.moveTo(x1, y1);ctx.lineTo(x2, y2);ctx.lineTo(x3, y3);ctx.closePath();ctx.fill();ctx.stroke();
}

        绘制的时候,就要根据形状来选择分支。我们创建函数drawShape:

// 绘制形状
function drawShape(ctx, shape, isFill) {let gradient;switch (shape.type) {case 'circle':gradient = createRadialGradient(ctx, shape.x, shape.y, shape.radius);applyGradient(ctx, gradient, isFill);drawCircle(ctx, shape.x, shape.y, shape.radius, isFill);break;case 'rect':gradient = createLinearGradient(ctx, 0, 0, shape.width, shape.height);applyGradient(ctx, gradient, isFill);drawRect(ctx, shape.x, shape.y, shape.width, shape.height, isFill);break;case 'triangle':gradient = createLinearGradient(ctx, shape.x1, shape.y1, shape.x3, shape.y3);applyGradient(ctx, gradient, isFill);drawTriangle(ctx, shape.x1, shape.y1, shape.x2, shape.y2, shape.x3, shape.y3, isFill);break;// 可以添加更多形状}
}

         布豪!发现圆形的渐变似乎有问题!我们来修改一下,并且我们发现js文件已经太大了,我们来拆分一下,下面给出一个完整案例:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Canvas 绘图示例</title><!-- 引用外部CSS --><link rel="stylesheet" href="styles.css">
</head>
<body><div class="container"><canvas id="myCanvas" width="600" height="600">您的浏览器不支持 HTML5 Canvas 标签。</canvas></div><!-- 引用外部JavaScript文件 --><script src="js/gradients.js"></script><script src="js/shapes.js"></script><script src="js/main.js"></script>
</body>
</html>
/* styles.css */body {margin: 0;padding: 0;font-family: Arial, sans-serif;background-color: #f0f0f0;
}.container {display: flex;justify-content: center;align-items: center;height: 100vh;
}canvas {border: 2px solid #000;background-color: #fff;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
// gradients.js// 创建线性渐变
function createLinearGradient(ctx, x1, y1, x2, y2) {const gradient = ctx.createLinearGradient(x1, y1, x2, y2);gradient.addColorStop(0, "red");gradient.addColorStop(1, "green");return gradient;
}// 创建径向渐变
function createRadialGradient(ctx, x, y, r) {const gradient = ctx.createRadialGradient(x, y, 0, x, y, r);gradient.addColorStop(0, "red");gradient.addColorStop(0.5, "yellow");gradient.addColorStop(1, "green");return gradient;
}

// shapes.js// 应用渐变
function applyGradient(ctx, gradient, isFill) {if (isFill) {ctx.fillStyle = gradient;} else {ctx.strokeStyle = gradient;ctx.lineWidth = 5; // 可以根据需要调整线宽}
}// 绘制圆形
function drawCircle(ctx, x, y, radius, isFill) {ctx.beginPath();ctx.arc(x, y, radius, 0, Math.PI * 2);if (isFill) {ctx.fill();} else {ctx.stroke();}
}// 绘制矩形
function drawRect(ctx, x, y, width, height, isFill) {ctx.beginPath();ctx.rect(x, y, width, height);if (isFill) {ctx.fill();} else {ctx.stroke();}
}// 绘制三角形
function drawTriangle(ctx, x1, y1, x2, y2, x3, y3, isFill) {ctx.beginPath();ctx.moveTo(x1, y1);ctx.lineTo(x2, y2);ctx.lineTo(x3, y3);ctx.closePath();if (isFill) {ctx.fill();} else {ctx.stroke();}
}// 绘制形状
function drawShape(ctx, shape, isFill) {let gradient;switch (shape.type) {case 'circle':gradient = createRadialGradient(ctx, shape.x, shape.y, shape.radius);applyGradient(ctx, gradient, isFill);drawCircle(ctx, shape.x, shape.y, shape.radius, isFill);break;case 'rect':gradient = createLinearGradient(ctx, shape.x, shape.y, shape.x + shape.width, shape.y + shape.height);applyGradient(ctx, gradient, isFill);drawRect(ctx, shape.x, shape.y, shape.width, shape.height, isFill);break;case 'triangle':gradient = createLinearGradient(ctx, shape.x1, shape.y1, shape.x3, shape.y3);applyGradient(ctx, gradient, isFill);drawTriangle(ctx, shape.x1, shape.y1, shape.x2, shape.y2, shape.x3, shape.y3, isFill);break;// 可以添加更多形状default:console.warn(`未知的形状类型: ${shape.type}`);}
}

 

// main.js// 确保所有依赖的脚本已经加载
window.addEventListener('DOMContentLoaded', () => {// 获取Canvas上下文const canvas = document.getElementById("myCanvas");if (!canvas.getContext) {console.error("浏览器不支持 Canvas!");return;}const ctx = canvas.getContext("2d");// 定义要绘制的形状const shapes = [{ type: 'circle', x: 300, y: 300, radius: 100, isFill: true },{ type: 'rect', x: 150, y: 150, width: 200, height: 100, isFill: false },{ type: 'triangle', x1: 50, y1: 50, x2: 150, y2: 50, x3: 100, y3: 150, isFill: false }];// 绘制所有形状shapes.forEach(shape => {drawShape(ctx, shape, shape.isFill);});
});

 这个项目已经初步搭建了一个有意思的canvas页面,当然我希望它更有意思!

main.js文件上的花活

我们只需要修改main.js文件即可,我们使用随机循环等方式创建各类对象:

// main.js// 确保所有依赖的脚本已经加载
window.addEventListener('DOMContentLoaded', () => {// 获取Canvas上下文const canvas = document.getElementById("myCanvas");if (!canvas.getContext) {console.error("浏览器不支持 Canvas!");return;}const ctx = canvas.getContext("2d");// 随机颜色生成函数function getRandomColor() {const letters = '0123456789ABCDEF';let color = '#';for (let i = 0; i < 6; i++) {color += letters[Math.floor(Math.random() * 16)];}return color;}// 定义循环生成形状的函数function generateShapes() {const shapes = [];// 生成圆形:随机大小和位置,大小范围拉大for (let i = 0; i < 100; i++) {const radius = 1 + Math.random() * 30;  // 随机大小,30-130const x = Math.random() * (canvas.width - radius * 2) + radius;const y = Math.random() * (canvas.height - radius * 2) + radius;shapes.push({ type: 'circle', x, y, radius, isFill: true, color: getRandomColor() });}// 生成矩形:随机旋转,渐变颜色,大小和位置随机for (let i = 0; i < 30; i++) {const width = 60 + Math.random() * 40;const height = 40 + Math.random() * 30;const x = Math.random() * (canvas.width - width);const y = Math.random() * (canvas.height - height);const angle = Math.random() * Math.PI;  // 随机旋转角度shapes.push({ type: 'rect', x, y, width, height, isFill: false, angle });}// 生成三角形:顶点随机,颜色随机for (let i = 0; i < 20; i++) {const x1 = Math.random() * canvas.width;const y1 = Math.random() * canvas.height;const x2 = x1 + Math.random() * 100;const y2 = y1 + Math.random() * 100;const x3 = x1 + Math.random() * 50;const y3 = y1 - Math.random() * 100;shapes.push({ type: 'triangle', x1, y1, x2, y2, x3, y3, isFill: true, color: getRandomColor() });}return shapes;}// 获取生成的形状const shapes = generateShapes();// 绘制所有形状shapes.forEach(shape => {// 如果是矩形,先旋转后绘制if (shape.type === 'rect') {ctx.save();ctx.translate(shape.x + shape.width / 2, shape.y + shape.height / 2);ctx.rotate(shape.angle);ctx.translate(-(shape.x + shape.width / 2), -(shape.y + shape.height / 2));drawShape(ctx, shape, shape.isFill);ctx.restore();} else if (shape.type === 'triangle') {ctx.fillStyle = shape.color;  // 使用随机颜色填充三角形drawShape(ctx, shape, shape.isFill);} else if (shape.type === 'circle') {ctx.fillStyle = shape.color;  // 使用随机颜色填充圆形drawShape(ctx, shape, shape.isFill);}});
});

        当然,这个项目看上去依然存在问题,还可以进一步拓展等,更多奇妙的故事等你自己去探索吧~

相关文章:

JavaScript使用渐变来美化对象!

我们的目标是渐变&#xff01;渐变&#xff01; 首先了解&#xff0c;渐变分为线性渐变和径向渐变&#xff0c;线性渐变可以是从左上角到右下角的渐变&#xff0c;径向渐变是从中心向外的渐变。 JavaScript中实现渐变可以使用addColorStop的方法&#xff0c;例如创建一个线性渐…...

Linux之实战命令24:od应用实例(五十八)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…...

【CKA】一、基于角色的访问控制-RBAC

1、基于角色的访问控制-RBAC 1. 考题内容&#xff1a; 2. 答题思路&#xff1a; 这道题就三条命令&#xff0c;建议直接背熟就行。 也可以查看帮助 kubectl create clusterrole -h kubectl create serviceaccount -h kubectl create rolebinding -h 注意&#xff1a; 1、资…...

【华为HCIP实战课程三】动态路由OSPF的NBMA环境建立邻居及排错,网络工程师

一、NBMA环境下的OSPF邻居建立问题 上节我们介绍了NBMA环境下OSPF邻居建立需要手动指定邻居,因为NBMA环境是不支持广播/组播的 上一节AR1的配置: ospf 1 peer 10.1.1.4 //手动指定邻居的接口地址,而不是RID peer 10.1.1.5 area 0.0.0.0 手动指定OSPF邻居后抓包查看OSP…...

初始Kafka

1、Kafka是什么&#xff1f; Kafka是由Scala语言开发的一个多分区、多副本&#xff0c;基于Zookeeper集群协调的系统。 那这个所谓的系统又是什么系统呢&#xff1f; 回答这个问题要从发展的角度来看&#xff1a;起初Kafka的定位是分布式消息系统。但是目前它的定位是一个分布…...

学会使用maven工具看这一篇文章就够了

文章目录 概述一、定义与功能二、核心组件三、主要作用四、仓库管理 settings.xml说明一、文件位置与优先级二、主要配置元素三、配置示例 pom.xml文件说明一、pom.xml的基本结构二、pom.xml的主要元素及其说明三、依赖管理四、常用插件五、其他配置 maven安装配置一、下载Mave…...

如何创建虚拟环境并实现目标检测及验证能否GPU加速

创建虚拟环境&#xff1a; 先创建一个虚拟python环境&#xff0c;敲如下代码 然后再到该虚拟环境里面安装自己想要的包 激活虚拟环境 然后再聚类训练这些 验证GPU加速 阿里源 pip install torch torchvision -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mir…...

<STC32G12K128入门第十三步>驱动W5500进行TCP_Client通信

前言 最近本人接触到了一个消费类产品需要用到以太网,并且需要连接服务器,同时需要发送https协议。本文就是讲解如何运行TCP客户端, 一、W5500讲解? W5500是一款10/100M的以太网转换芯片,内部集成了TCP/IP协议栈。并且支持SPI/I2C协议。我在STC32上面使用的是软件SPI。…...

【Go语言】Ergo:构建分布式系统的现代化 Erlang 框架

Ergo 是一个基于 Go 语言的开源框架&#xff0c;专门用于构建分布式系统。它为开发人员提供了与 Erlang/OTP 类似的编程模型和功能。Ergo 通过将 Erlang 的强大分布式并发编程模型带入 Go 语言的生态中&#xff0c;使得开发者能够轻松创建高度可靠、可扩展的分布式应用程序。 …...

教资备考--高中数学(仅为高中数学梳理)

按照高中学习数学梳理的方案进行整理...

Qt 学习第十一天:QTableWidget 的使用

一、创建QTableWidget对象&#xff0c;设置大小&#xff0c;在窗口的位置 //创建tablewidgetQTableWidget *table new QTableWidget(this);table->resize(550, 300);table->move(100, 100); //移动 二、设置表头 //设置表头QStringList headerList; //定义headerList…...

【Linux】基础指令 1

Linux中各个指令是相互联系的&#xff0c;所以一开始学习Linux时&#xff0c;对指令很陌生是正常的&#xff0c;不用花费大量的时间去刻意的记忆&#xff0c;在我们一次次的使用当中&#xff0c;这些指令自然会烂熟于心。 简单看看各个指令的功能 ls指令 显示当前目录下的文…...

Linux_kernel字符设备驱动12

一、字符设备的编程框架 在Linux_kernel驱动开发11中&#xff0c;我们介绍的系统调用。只是为了做一个实验&#xff0c;在真正开发时&#xff0c;我们并不会直接在内核中添加一个新的系统调用&#xff0c;这样做会导致内核体积变大。 1、字符设备结构体 我们实现一个硬件字符设…...

服务保护sentinel

线程隔离 - 线程池隔离&#xff1a;给每个服务调用业务分配一个线程池&#xff0c;利用线程池本身实现隔离效果。 - 信号量隔离&#xff1a;不创建线程池&#xff0c;而是计数器模式&#xff0c;记录业务使用的线程数量&#xff0c;达到信号量上限时&#xff0c;禁止新的请求。…...

【ubuntu】Ubuntu20.04安装中文百度输入法

1.download 百度Linux输入法-支持全拼、双拼、五笔 2.unzip unzip Ubuntu_Deepin-fcitx-baidupinyin-64.zip 3.setting 3.1 setting fcitx sudo apt install aptitude sudo aptitude install fcitx-bin fcitx-table fcitx-config-gtk fcitx-frontend-all sudo aptitude in…...

蓝桥杯【物联网】零基础到国奖之路:十八. 扩展模块之光敏和AS312

蓝桥杯【物联网】零基础到国奖之路:十八.扩展模块之光敏和AS312 第一节 硬件解读第二节 CubeMX配置第二节 代码 第一节 硬件解读 光敏和AS312如下图&#xff1a; 光敏电阻接到了扩展模块的5号引脚&#xff0c;5号引脚接了2个电阻&#xff0c;R8和光敏电阻。我们通过ADC读取这…...

如何在微信小程序中实现分包加载和预下载

如何在微信小程序中实现分包加载和预下载 概述 微信小程序提供了分包加载和预下载功能&#xff0c;这有助于优化应用的加载时间&#xff0c;提升用户体验。本文将详细介绍如何在微信小程序中配置分包加载和预下载。 步骤一&#xff1a;配置分包加载 修改app.json文件&#x…...

初识TCP/IP协议

回顾上文 来回顾一下TCP协议的特性&#xff0c;有一道比较经典的题&#xff1a;如何使用UDP实现可靠传输&#xff0c;通过应用程序的代码&#xff0c;完成可靠传输的过程&#xff1f; 原则&#xff0c;TCO有啥就吹啥&#xff0c;引入滑动窗口&#xff0c;引入流量控制&#x…...

使用 classification_report 评估 scikit-learn 中的分类模型

介绍 在机器学习领域&#xff0c;评估分类模型的性能至关重要。scikit-learn 是一个功能强大的 Python 机器学习工具&#xff0c;提供了多种模型评估工具。其中最有用的函数之一是 classification_report&#xff0c;它可以全面概述分类模型的关键指标。在这篇文章中&#xff…...

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(十)高翔书中的细节:参考链接;卫星导航;ESKF

一、 参考链接 我认真查找了好多地方:结果在最后一页。 作者GITHUB链接如下: https://github.com/gaoxiang12/slam_in_autonomous_driving 全书所有参考链接 :如下 1 https://www.sae.org/standards/content/j3016_202104 2 http://www.evinchina.com/articleshow-217.htm…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...