在我上一篇写的Node.js实现简单的POST请求
里面POST请求接受参数需要写两个事件,这难免有些不太方便
如果我们用formidable来接受参数的话,会变得特别方便。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form class="upload" action="shangchuan" enctype="multipart/form-data" method="post"><!-- 上传接口是/shangchuan --> <p> 请上传一个头像 <input type="file" name="wenjian"> </p> <p> <input type="submit" value="提交"> </p> </form> </body> </html>
![]()
安装依赖,执行下面这三句npm语句
npm install finalhandler --save
npm install serve-static --save
npm install formidable --save
之后会自动生成下面这个package.json文件
{
"dependencies": {
"finalhandler": "^1.1.1",
"formidable": "^1.2.1",
"serve-static": "^1.13.2"
}
}
var finalhandler = require('finalhandler') var http = require('http') var serveStatic = require('serve-static') var url = require('url') var fs = require('fs') var querystring = require('querystring') var formidable = require('formidable') var path = require('path') // Serve up public/ftp folder //配置静态资源服务器,将public文件夹静态化出来 var serve = serveStatic('public', {'index': ['index.html', 'index.htm']}) // Create server var server = http.createServer(function onRequest (req, res) { //路由 var pathname = url.parse(req.url).pathname; if(pathname == '/shangchuan'){ //创建一个表单的实例,formidable var form = new formidable.IncomingForm(); //设置上传的文件存放在哪里 form.uploadDir = './uploads'; //处理表单 form.parse(req,(err,fields,files) => { //fields 表示普通控件 //files 表示文件控件 if(!files.wenjian){ return; } if(!files.wenjian.name){ return; } var extname = path.extname(files.wenjian.name);获取文件的扩展名,便于下面修改上传后的文件名字 //改名 fs.rename(files.wenjian.path, files.wenjian.path + extname,() => { res.end('上传成功') }) // console.log(fields); }) return; } serve(req, res, finalhandler(req, res)) }) // Listen server.listen(3000); console.log('服务已经启动在3000端口');
![]()
会看到这个页面
然后选择任意文件点击提交
会发现在很短的时间内你的文件会提交成功在你的uploads文件夹下。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
model
: 绑定整个表单model值
rules
: 整个表单校验规则
ref
:获取该表单form组件
prop
: 绑定每个表单的规则,写在el-form-item
上
validate
: 对整个表单进行校验的方法
valid
: 每个必填表单项都提交为true,否则为false
//使用element-ui 页面组件 <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="活动名称" prop="name"> <el-input v-model="ruleForm.name"></el-input> </el-form-item> <el-form-item label="活动区域" prop="region"> <el-select v-model="ruleForm.region" placeholder="请选择活动区域"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> </el-form> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button> </el-form-item> //data中定义form表单中每项表单model值、和每个表单校验的规则 <script> export default { data() { return { ruleForm: { name: '', region: '', }, rules: { name: [ { required: true, message: '请输入活动名称', trigger: 'blur' }, { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' } ], region: [ { required: true, message: '请选择活动区域', trigger: 'change' } ], }; }, //定义表单提交方法 methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, } }
<el-form v-if="fromHtmlList.deviceInfo.sitsb.length" :model="fasj" :rules="rules" label-position="left" label-width="125px" ref='sitsb'> <el-form-item label-width="100%" > <div slot="label" class="titleInfo">局端设备</div> </el-form-item> <el-form-item v-for="(item, i) in fromHtmlList.deviceInfo.sitsb" :key="`F_key_${i}`" :label="`${item.label}:`" :class="item.class" :label-width="item.labelWidth" :prop="`${item.rule ? 'deviceInfo.sitsb.'+item.rule : ''}`"> <el-select v-if="item.el === 'slt'" v-model="fasj.deviceInfo.sitsb[item.model]" placeholder="请选择" style="width:200px;" clearable> <el-option v-for="(op, n) in options[item.option]" :key="`vop_key_${n}`" :label="op.label" :value="op.value"> </el-option> </el-select> <el-input v-if="item.el === 'ipt'" v-model="fasj.deviceInfo.sitsb[item.model]" @focus="()=>{ item.focus && handleFocus('sitsb', item.model)}" :placeholder="`${item.placeholder ? item.placeholder : '请输入'}`" style="width:200px;"></el-input> <span v-if="item.el === 'txt'">{{fasj.base[item.model]}}</span> </el-form-item> </el-form> <div class="btn-list"> <el-button type="primary" @click="checkRequired">提 交</el-button> </div> <script> export default { data() { return { fasj: { base: {}, // 基本信息 deviceInfo: {}, }, //定义 页面表单结构 fromHtmlList: { baseInfo: [], deviceInfo: { ywzsb: [], sitsb: [] } }, //定义 表单校验规则 rules: { 'deviceInfo.sitsb.IPType': [ { required: true, message: '请输入', trigger: 'blur' } ], 'deviceInfo.sitsb.IPAddr': [ { required: true, message: '请输入', trigger: 'blur' } ], 'deviceInfo.sitsb.netmask': [ { required: true, message: '请输入', trigger: 'blur' } ], 'deviceInfo.sitsb.vlanId': [ { required: true, message: '请输入', trigger: 'blur' } ], }, options: { IPType: [ {label: 'ipv4', value: 'ipv4'}, {label: 'ipv6', value: 'ipv6'} ], rmSite: [], room: [], }, } }, created(){ const orderType = '业务开通' ;//页面初始加载用到的变量值,可通过组件传值获取 //created中初始定义页面表单结构 this.fromHtmlList = { baseInfo: orderType === '业务开通' ? [ {label: '接入方式', labelWidth: '100px', rule: '' , model: 'serviceType', option: '', el: 'txt', class: 'w2'}, {label: '标准九级地址', labelWidth: '120px', rule: '', model: 'aendAdreesName', option: '', el: 'txt', class: 'w2'}, {label: '城乡类型', labelWidth: '100px', rule: 'cityType', model: 'cityType', option: 'cityType', el: 'slt', class: 'w2'}, {label: '方案设计附件', labelWidth: '120px', rule: '', model: 'fileId', option: '', el: 'btn', class: 'w2'}, ] : orderType === '移机' ? [ {label: '接入方式', labelWidth: '100px', rule: '' , model: 'serviceType', option: '', el: 'txt', class: 'w2'}, {label: '标准九级地址', labelWidth: '120px', rule: '', model: 'aendAdreesName', option: '', el: 'txt', class: 'w2'}, {label: '城乡类型', labelWidth: '100px', rule: 'cityType', model: 'cityType', option: 'cityType', el: 'slt', class: 'w2'}, {label: '方案设计附件', labelWidth: '120px', rule: '', model: 'fileId', option: '', el: 'btn', class: 'w2'}, {label: '移机场景', labelWidth: '100px', rule: 'moveScene', model: 'moveScene', option: 'moveScene', el: 'slt', class: 'w2'}, {label: '是否需要网络调整', labelWidth: '', rule: 'netChange', model: 'netChange', option: 'netChange', el: 'slt', class: 'w2'} ] : [ {label: '接入方式', labelWidth: '100px', rule: '' , model: 'serviceType', option: '', el: 'txt', class: 'w2'}, {label: '标准九级地址', labelWidth: '120px', rule: '', model: 'aendAdreesName', option: '', el: 'txt', class: 'w2'}, {label: '城乡类型', labelWidth: '100px', rule: 'cityType', model: 'cityType', option: 'cityType', el: 'slt', class: 'w2'}, {label: '方案设计附件', labelWidth: '120px', rule: '', model: 'fileId', option: '', el: 'btn', class: 'w2'}, {label: '是否需要网络调整', labelWidth: '', rule: 'netChange', model: 'netChange', option: 'netChange', el: 'slt', class: 'w2'}, {label: '是否更换末端设备', labelWidth: '', rule: 'devChange', model: 'devChange', option: 'devChange', el: 'slt', class: 'w2'} ], deviceInfo: { ywzsb: serviceType === 'PON' ? [ // 默认PON {label: '机房', labelWidth: '90px', rule: '' , model: 'siteRoom', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '设备名称', labelWidth: '90px', rule: '', model: 'deviceName', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '设备端口', labelWidth: '90px', rule: '', model: 'devicePort', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '延伸设备', labelWidth: '90px', rule: '', model: 'deviceExtend', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'} ] : [ // 裸光纤、传输下沉、传输延伸(ywzsb) {label: '机房', labelWidth: '', rule: '' , model: 'siteRoom', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '站点', labelWidth: '', rule: '', model: 'site', option: '', el: 'ipt', class: 'w2'}, {label: '设备名称', labelWidth: '', rule: '', model: 'deviceName', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '设备端口', labelWidth: '', rule: '', model: 'devicePort', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, ], sitsb: serviceType === 'PON' ? [ {label: '机房名称', labelWidth: '', rule: '' , model: 'siteRoom', option: '', el: 'ipt', class: 'w2'}, {label: '站点名称', labelWidth: '', rule: '', model: 'site', option: '', el: 'ipt', class: 'w2'}, {label: '汇聚交换机', labelWidth: '', rule: '', model: 'switch', option: '', el: 'ipt', class: 'w2'}, {label: '汇聚交换机端口', labelWidth: '', rule: '', model: 'switchPort', option: '', el: 'ipt', class: 'w2'}, {label: 'SR/BARS', labelWidth: '', rule: '' , model: 'srbars', option: '', el: 'ipt', class: 'w2'}, {label: 'SR/BARS端口', labelWidth: '', rule: '', model: 'srbarsPort', option: '', el: 'ipt', class: 'w2'}, {label: 'IP地址类型', labelWidth: '', rule: 'IPType', model: 'IPType', option: 'IPType', el: 'slt', class: 'w2'}, {label: 'IP地址', labelWidth: '', rule: 'IPAddr', model: 'IPAddr', option: '', el: 'ipt', class: 'w2'}, {label: '子网掩码', labelWidth: '', rule: 'netmask', model: 'netmask', option: '', el: 'ipt', class: 'w2'}, {label: 'VLAN ID', labelWidth: '', rule: 'vlanId', model: 'vlanId', option: '', el: 'ipt', class: 'w2'} ] : serviceType === '裸光纤' ? [ // 裸光纤 {label: '机房名称', labelWidth: '', rule: '' , model: 'siteRoom', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: '站点名称', labelWidth: '', rule: '', model: 'site', option: '', el: 'ipt', class: 'w2'}, {label: 'SR', labelWidth: '', rule: '', model: 'SR', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: 'SR端口', labelWidth: '', rule: '', model: 'SRPort', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: 'BARS', labelWidth: '', rule: '' , model: 'BARS', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, {label: 'BARS端口', labelWidth: '', rule: '', model: 'BARSPort', option: '', el: 'ipt', class: 'w2', focus: true, placeholder: '点击查询'}, ] : [ // 传输下沉、传输延伸 ] } } }, methods:{ async checkRequired() { let checkName = ['base','sitsb'];//表单校验定义ref let text; for(let key of checkName){ if(this.$refs[key]){ this.$refs[key].validate((valid) => { if(!valid){ text = '请检查必填项'; }else { return false; } }); } } if(text){ this.$message.warning(text); return false; } let _res_ = await this.saveFasjData('', true);//页面表单要保存后才能提交 if(!!_res_ && _res_.code === 200){ this.commit(_param, _url);//保存表单再提交 }else{ this.$message.error(_res_.msg) } }, async commit(param, url) { this.loadings.body = true; let _res = await postDataRequest(url, param); this.loadings.body = false; if (_res && _res.code === 200) { this.$message.success("提交成功"); this.$router.go(-1); } } } } </script>
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
Vite 是 vue 的作者尤雨溪在开发 vue3.0 的时候开发的一个 web 开发构建工具。由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。
Vite 优势:
Vite 劣势:
其他区别:
1. 打包原理的区别
2. 项目入口文件的区别
项目根目录的 index.html 是 Vite 项目的入口文件,而 webpack 的入口文件是 webpack 配置 entry 中指定的 js 文件。
Esbuild
是一款基于 Go
语言开发的 javascript
打包工具,最大的一个特征就是快。
通过官网提供的一张图,我们可以清晰的看到 Esbuild
的表现是多么优秀:
Esbuild
之所以能这么快,主要原因有两个:
Go
语言开发,可以多线程打包,代码直接编译成机器码;
Webpack
一直被人诟病构建速度慢,主要原因是在打包构建过程中,存在大量的 resolve
、load
、transform
、parse
操作(详见 为什么有人说 vite 快,有人却说 vite 慢?- 快速的冷启动 ),而这些操作通常是通过 javascript
代码来执行的。要知道,javascript
并不是什么高效的语言,在执行过程中要先编译后执行,还是单线程并且不能利用多核 cpu
优势,和 Go
语言相比,效率很低。
可充分利用多核 cpu
优势;
关键 API - transfrom & build
Esbuild
并不复杂,它对外提供了两个 API:
transform
和 build
,使用起来非常简单。
transfrom
,转换的意思,将 ts
、jsx
、tsx
等格式的内容转化为 js
。 transfrom
只负责文件内容转换,并不会生成一个新的文件。
build
,构建的意思,根据指定的单个或者多个入口,分析依赖,并使用 loader
将不同格式的内容转化为 js 内容,生成一个或多个 bundle
文件。
我们来看看Vite
是怎么利用 Esbuild
来做预构建和内容转换的。
预构建
为什么要做预构建?原因有两点:
将非 ESM
规范的代码转换为符合 ESM
规范的代码;
将第三方依赖内部的多个文件合并为一个,减少 http
请求数量;
middlewares 中内容转换
Vite
中源文件的转换是在 dev server
启动以后通过 middlewares
实现的。
当浏览器发起请求以后,dev sever
会通过相应的 middlewares
对请求做处理,然后将处理以后的内容返回给浏览器。
middlewares
对源文件的处理,分为 resolve
、load
、transform
、parser
四个过程:
resolve
- 解析 url
,找到源文件的绝对路径;
load
- 加载源文件。如果是第三方依赖,直接将预构建内容返回给浏览器;如果是业务代码,继续 transform
、parser
。
transfrom
- 对源文件内容做转换,即 ts
-> js
, less
-> css
等。转换完成的内容可以直接返回给浏览器了。
parser
- 对转换以后的内容做分析,找到依赖模块,对依赖模块做预转换 - pre transform
操作,即重复 1
- 4
。
pre transform
是 Vite
做的一个优化点。预转换的内容会先做缓存,等浏览器发起请求以后,如果已经完成转换,直接将缓存的内容返回给浏览器。
Vite
在处理步骤 3
时,是通过 esbuild.transform
实现的,对比 Webpack
使用各个 loader
处理源文件,那是非常简单、快捷的。
经验法则:对于应用使用 webpack,对于类库使用 Rollup。
如果你需要代码拆分(Code Splitting),或者你有很多静态资源需要处理,再或者你构建的项目需要引入很多CommonJS模块的依赖,那么 webpack 是个很不错的选择。
如果您的代码库是基于 ES2015 模块的,而且希望你写的代码能够被其他人直接使用,你需要的打包工具可能是 Rollup 。
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
-
<div class="add">
-
<p>商品名称: <input type="text" class="productName"></p>
-
<p>商品价格: <input type="number" class="price" ></p>
-
<!-- multiple: 允许同时上传多张图片 -->
-
<!-- <p>商品图片: <input type="file" class="file" multiple="multiple"></p> -->
-
<p>商品图片: <input type="file" class="file"></p>
-
<p><button class="add-btn">添加商品</button></p>
-
</div>
-
<script src="js/axios.js"></script>
-
<script src="js/util.js"></script>
-
<script src="js/upload.js"></script>
-
// 新建表单数据对象,用来存储上传的文件及上传的其它数据
-
let param = new FormData()
-
-
$(".file").onchange = function(){
-
//获取图片信息
-
let file = this.files[0]
-
//"file"为前后端约定vb的属性名
-
param.append("file",file)
-
}
-
$(".add-btn").onclick = function(){
-
let productName = $(".productName").value;
-
let price = $(".price").value;
-
param.append("productName",productName)
-
param.append("price",price)
-
-
axios.post("/product",param,{
-
headers: {
-
// 默认提交的类型
-
// "content-type": "application/json"
-
// 复杂的表单数据(只要上传文件,就必须是下面的类型)
-
"content-type": "multipart/form-data"
-
}
-
})
-
.then((res)=>{
-
console.log(res.data);
-
})
-
}
下载
npm i multer -S
引入
-
const multer = require("multer")
-
const path = require("path")
配置
注意: 该文件在/router文件夹中,而uploads存放上传图片文件夹在根目录
-
var storage = multer.diskStorage({
-
// 配置文件上传后存储的路径
-
destination: function (req, file, cb) {
-
// NodeJS的两个全局变量
-
// console.log(__dirname); //获取当前文件在服务器上的完整目录
-
// console.log(__filename); //获取当前文件在服务器上的完整路径
-
cb(null, path.join(__dirname,'../uploads'))
-
},
-
// 配置文件上传后存储的路径和文件名
-
filename: function (req, file, cb) {
-
console.log('file',file);
-
cb(null, Date.now() + path.extname(file.originalname))
-
}
-
})
-
var upload = multer({ storage: storage })
在路由中使用
-
//添加商品
-
router.post("/product",upload.single("file1"),(req,res)=>{
-
//接收普通文本参数
-
let {productName,price} = req.body;
-
、接收上传文件数据 -->
-
let imgUrl = req.file.filename;
-
let sql = "insert into product (productName,price,imgUrl) values (?,?,?)"
-
conn.query(sql,[productName, price , imgUrl],(err,result)=>{
-
if (err){
-
console.log('增加失败');
-
return;
-
}
-
let data;
-
if (result.affectedRows === 1){
-
data = {
-
code: 0,
-
msg: '添加成功'
-
}
-
}else{
-
data = {
-
code: 1,
-
msg: '添加失败'
-
}
-
}
-
res.send(data)
-
})
-
})
如果抽离路由模块中的处理函数upload.single("file1")写在Router模块
实现写在抽取的模块
如果req.body为空,可以用nodejs后台文件上传模块connect-multiparty
使用方法如下:
1. 安装模块
npm install connect-multiparty --save
2. 引入模块
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
3. 使用模块
const express = require('express')
const router = express.Router()
router.post('/formdata',multipartMiddleware, function (req,res) {
console.log(req.query)
//分别返回body,文件属性,以及文件存放地址
});
————————————————
原文链接:https://blog.csdn.net/zjwengyidong/article/details/51407903
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
在HappyBirthday/HappyBirthday.html中的title换成相应人的名字
-
<head>
-
<meta charset="utf-8">
-
<title>XXX生日快乐</title>
-
-
<style>
-
html,body{
-
margin:0px;
-
width:100%;
-
height:100%;
-
overflow:hidden;
-
background:linear-gradient(to left top,blue, #ffc0cb);
-
}
-
</style>
-
<link href="favicon.ico" rel="shortcut icon">
-
</head>
在粒子展示祝福的名字进行更换
在HappyBirthday/js/index.js#44行处修改
-
if (i !== -1) {
-
S.UI.simulate(decodeURI(action).substring(i + 3));
-
} else {
-
S.UI.simulate('|#countdown 3||祝|XXX|生日快乐|祝你|生日快乐|祝你幸福|祝你健康|前途光明|祝你|生日快乐!|#icon heart|#icon heart-empty|#icon heart');
-
}
修改粒子动画展示的颜色,视频中使用了粉色(255,192,203)
HappyBirthday/js/index.js#417行处修改
-
S.Dot = function (x, y) {
-
this.p = new S.Point({
-
x: x,
-
y: y,
-
z: 5,
-
a: 1,
-
h: 0
-
});
-
-
this.e = 0.07;
-
this.s = true;
-
-
this.c = new S.Color(255, 192, 203, this.p.a);
-
-
this.t = this.clone();
-
this.q = [];
-
};
在原版代码中,仅仅在电脑浏览器有一个较为好的展示效果,在手机浏览器上字显示效果不佳以及延时不足,但是无法正常显示,主要调整了粒子间距和延时时间
粒子间距:先设置默认间距为8(手机较好显示),然后判断屏幕是否大于手机一般尺寸,调整大一点13(平板和电脑较好显示)。
粒子间距变小,数量变多,加载起来就慢。
HappyBirthday/js/index.js#525行处修改
-
if ((window.innerWidth>500 && window.innerHeight>500)){
-
gap = 13;
-
}
延时时间:当粒子数量变多,加载慢, 按照原作者设置的时间来展示,可能上一个字没展示完就要去展示下一个字,导致变成一坨。
HappyBirthday/js/index.js#119行处修改
HappyBirthday/js/index.js#177行处修改
-
// 118行
-
var delay1,delay2;
-
delay1 = 3000;
-
delay2 = 5000;
-
-
-
// 177行
-
if (window.innerWidth>500 && window.innerHeight>500){
-
delay1 = 1000;
-
delay2 = 2000;
-
}
由于在某些设备上,无法自动播放音乐,需要通过点击触发,增加点击爱心,开始播放。
通过部署在阿里云,可以通过网址进行访问。
我租了一个阿里云,通过简单部署静态页面就可以访问。
(如果有兄弟紧急使用,也可以叫我帮忙部署一下,哈
找到自己的实例,点击完全组,配置开放一个80端口
开放80端口
yum -y install httpd
-
service httpd start
-
service httpd status
启动之后可以看到如下画面
默认会发布var/www/html下面的网页
cp /etc/httpd/conf/httpd.conf /var/www/html
# 解压压缩包 unzip HappyBirthday.zip # 删除压缩包 rm -rf HappyBirthday.zip
service httpd restart
http://8.130.106.21/HappyBirthday/HappyBirthday.html
分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
B 端设计离不开设计规范这个话题,而做好设计规范是一个庞大复杂工程,很多人对这些处于一知半解状态,在这个系列文章里我通过结合自己平时的项目案例来谈谈自己对 B 端设计规范的一些理解,希望可以带来一些启发。
本篇先谈谈设计规范制作的指导思想--设计原则,后续文章再展开讲一下常见各种组件的设计规范。
设计规范作为 B 端设计中非常重要的一环,它的作用主要体现在以下三个方面:
在日常工作中,当项目组收到一个新的需求时,如果已经具备了成熟的设计规范体系,其工作效率往往会得到很好的提升。最后上线的页面不用走查还原度。以下是具体工作流程:
通过前面内容我们知道了设计规范对于产品设计意义重大,那么制定设计规范制定依据又是什么呢?这里就要引出设计原则这个话题,设计原则是设计规范的总的纲领,所有的设计规范都应当以设计原则为基准。设计原则主要包含以下内容:
接下来就围绕设计原则清晰、高效、友好、可控这四个方面展开讲解。
清晰原则主要从视觉角度让界面信息传达合理,提高用户信息获取效率。主要包含对比,亲密,对齐,重复四个方面。
① 对比:
对比是指界面中为了区分信息层级,强化元素对比度,使用的很常见的一种手段,例如下图中利用大色块按钮与线框按钮形成对比来凸显关键按钮;又比如通过对文字字号加大,字体加粗,颜色加深来与弱文案形成对比,凸显关键文字信息。
② 亲密:
如果信息之间关联性越高,它们之间的距离就应该越接近,也越像一个视觉单元;反之,则它们的距离就应该越远,也越像多个视觉单元。亲密性的根本目的是实现组织性,让用户对页面结构和信息层次一目了然。
③ 对齐:
在界面设计中,将元素进行对齐,既符合了用户的认知特点(我们往往倾向使知觉对象的直线延续还是直线,曲线延续还是曲线),也能引导视用户视觉流,让用户更流畅地接收信息。
④ 重复:
重复是指相同的元素在项目中重复引用,作用是可以有效降低用户的学习成本,同时提高这些元素之间的关联性。
高效原则体现在便捷、轻量、简化、一致几个方面,目的是通过合理的方式让产品操作更加便捷;交互体验与内容更加轻量和简化;以及产品风格保持一致。下面结合几个常见案例说明如何应用这一原则。
① 合理利用拖拽--便捷、轻量:
在涉及到诸如上传文件,排序,滑动输入,搭建等需求时,合理采用拖拽交互往往可以打造更加便捷用户体验。
② 尽量减少不必要的跳转--便捷、轻量:
用户操作过程尽量减少跳转,以实现交互减步长,从而使用户操作更高效轻量。例如能用原位操作就不考虑展开收起;能用展开收起就不用气泡...依次类推(优先级从高到低:原位 > 展开收起 > 气泡 > 弹窗 > 抽屉 > 新页面)
③ 放大点击热区--便捷:
放大可点击按钮热区,相对于较小点击热区,具备更丝滑操作体验。
④ 悬停即现--轻量:
利用悬停即现,避免信息过于重复啰嗦,简化页面提高阅读体验。
⑤ 折叠次要功能--简化:
页面功能按钮过多时,可将次要按钮收纳到一起,点击时再展开,外面只展示高频操作或重要按钮,保证页面内容简洁。
⑥ 统一样式--一致:
一致性是指在不同页面中相同操作应保持一致视觉与交互样式,可有降低用户学习成本与企业开发成本。
友好原则应贯穿用户操作前,操作中以及操作后三个阶段,给予用户及时反馈与帮助。
① 操作前:
在用户操作前给到合适的引导与帮助,有效减少用户迷茫感。
② 操作中:
通过交互效果以及页面样式让用户可以清晰感知到自己当前操作。
③ 操作后:
利用界面中元素变化清晰直观展示当前的状态
可控主要体现在自由和导航两个方面。
① 自由:
自由即指用户可以自由完成一些操作,例如回退,撤销,终止等。
② 导航:
导航是指用户随时知晓当前所在位置,而且可以利用导航随意到达目标页面。
通过本篇内容我们大概知道了制作设计规范主要方向,那么具体到每个组件上,我们该如何去设计呢?后续篇章将细分聊聊如何去设计 B 端常见组件的一些内容。
部分参考资料:
作者:huang。亮 来源:优设网
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
希望得到建议咨询、商务合作,也请与我们联系01063334945。
分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
谈到 B 端组件,很多人的印象是多且杂,想要全面准确的熟悉这些它们,需要我们对它有个合理的归纳总结。可能每个人会从不同的视角去做这件事情,我一般是按照使用场景去对组件分类整理。
下面我们根据这个分类框架来逐个聊聊这些组件。
说到基础组件,我想再将其细分成两个大类:一类是通用组件;一类是栅格/导航。怎么去更深刻的理解这两类的区别呢,我们可以打个这样的形象比方:
通过这个比方我们不难理解,栅格/导航是先给页面定下了基本框架,而通用组件则是在这个框架基础上搭建页面的所用到基本元素。
常见通用组件一般包含:色彩/字体/间距/圆角/分割线/按钮。需要注意的是,通用组件看起来似乎很简单,但却是决定产品品牌调性、界面细节品质的重要因素,在设计过程中需要引起我们的高度重视。
色彩
色彩可分为主色,功能色,中性色三类。下面谈谈这三类颜色如何配置,以及如何定义这些颜色梯度。
① 主色
主色的选取
主色作为产品的主要色调,在选取时应当优先选择品牌色,但有一点要注意的是 B 端和 C 端不一样,B 端一般不适合采用暖色系作为主色,如果品牌色为暖色调,则尽量考虑另选取一个冷色系作为主色,原因有两点:一是为了避免和警告、错误色冲突,产生歧义;二是冷色系带有商务、专业、冷静的情感,更符合 B 端产品调性。
同时主色选取应避免高亮、荧光色、灰调高的颜色。
主色的应用
主色在设计中常见的应用包括可交互、选中状态、可视化、插图、图标等场景。
② 功能色
功能色主要用于页面表征状态,常见有成功色、警告色、报错色等。
成功色
主要用于操作结果成功提示以及标签配色等。
警告色
主要用于警告提醒功能以及标签配色等。
报错色
主要用于系统报错提示、圆点提示、以及标签配色等。
③ 中性色
中性色在页面设计中应用非常广泛,从线条到文字再到图形等等都可以见到它的影子。
Tips:无论我们主色调是什么,中性色在调色时建议可加入适量的蓝色调,可让页面观感更清爽。
④ 颜色梯度
选取好了颜色后,怎么去更合理的定义每个颜色的梯度呢?(这里主要指对主色以及功能色定义梯度)
我的方法是给颜色加一层半透明黑/白遮罩,当我们需要浅色,通过调整白色遮罩透明度得到合适颜色;而当我们需要深色时,则通过调整黑色遮罩透明度得到合适颜色。
这样定义颜色梯优点是后续如果需要更改配色,只需一键替换全局色即可,大大提高工作效率。
文字
文字规范包含字体、字号、字重、行高等。
① 字体/字重
B 端字体/字重一般按照如下规范即可:
② 字号
不同于 C 端,B 端在字号选择上应当尽量保持克制。研究表明,Web 端上正文字号为 14 时,可以带来最佳阅读体验。因此在字号选取上应尽量优先选取 14 号字。如果想要区分文字层级,优先级从高到低的手法应该是颜色、字重、字号,也就是说一般尽量不采用字号大小区分文字层级。
③ 行高
行高可以参照下面的公式或行高参照表快速获得,如果通过公式算出行高非整数或非偶数,可就近取偶整数。
间距
关于间距取值,在目前主流屏幕分辨率下,只有 4 或 8 被整除率最高,考虑到 4 的颗粒度偏小,因此可优先考虑 8px 的倍数作为间距值,在一些特殊场景可采用 4px 的倍数间距值。
分割线
分割线宽度一般统一为 1px 即可,同时注意颜色不可过深,以免干扰主体信息。如果需要不同层级分割线,可用颜色深浅来区分。
圆角
圆角大小一般根据使用场景控制在 2-3 个梯度即可,既不能全部统一一个圆角值,同时也不适合出现过多圆角值。同时圆角值不要过大,建议控制在 2-6px,以符合 B 端产品严谨专业调性。
按钮
这里从按钮的大小/状态/排放位置几个纬度来讲。
① 按钮尺寸
按钮高度一般情况下可以设置 3-4 种尺寸按钮,足以满足各种使用场景。至于按钮宽度,我们一般定义一个最小值,当超过最小值时,可设置 padding 值,按钮宽度根据内容自适应。
② 按钮状态
操作按钮过程中,按钮会呈现不同的交互状态。
③ 按钮位置
对于主次按钮组合,主次按钮排放位置应该怎么规定呢?可分为两种场景:一是当为从左到右阅读顺序时,主要按钮应当排在次要按钮左侧。二是当为从右到左阅读顺序时,主要按钮应当排在次要按钮右侧。而当一些特殊场景与这个原则冲突时,应权衡优先级做出取舍。
熟悉通用组件后,我们要通栅格/导航来确定产品页面框架。
栅格
栅格可以有效地保证设计的一致性、让页面布局更具规律,并提高团队协作效率。应该如何设计栅格呢?
① 栅格区域的划定
我们一般习惯将页面从下到上划分为背景层、全局控制层、内容层、临时层,而栅格区应当用在内容层。以下为常见几种页面布局栅格区的划定。
② 栅格自适应规则
随着页面宽度变化,一般来说是通过栏宽变化实现自适应。
③ 栅格栏数的确定
根据页面内容丰富程度,栅格栏数一般定 12 或者 24 栏,考虑到 B 端产品功能往往比较复杂,建议采用 24 栏即可。
④ 上下布局栅格
⑤ 左右布局栅格
导航
导航可分为全局导航与局部导航。
① 全局导航
全局导航包含顶部导航、侧边导航、混合导航。
这三种导航样式各具特点,应结合产品特性选择合适的导航样式。这里要注意的一点是,当产品可用性和用户体验产生冲突时,应优先保证产品可用性。
② 局部导航
局部导航包含面包屑、标签页、步骤条、分页器。
面包屑
面包屑导航的作用是告诉用户当前页面在系统层级结构中的位置以及父子级页面间的关系,并且可以快速回到上几级导航。
标签页
标签页可以帮助用户在一个页面实现快速切换不同内容,提升单个页面内容扩展性。可分为基本样式、标签样式、卡片样式。
步骤条
当任务复杂或者存在先后关系时,可将其分解成一系列步骤,这里就会用上步骤条。步骤条是引导用户按照流程完成任务的导航条,作用包含 3 点:一是让用户对操作流程长度和步骤有个预期,二是明确知道自己目前所在步骤,三是可以对用户的任务完成度有明确的度量。
步骤条一般分为横向与纵向两种样式。
步骤条小 Tips:当步骤条中有操作难度偏大的内容时,为了提高用户操作完成率,我们可以考虑把其放在靠后的步骤中,原因是用户前面已经完成了大部分简单操作,后面碰到高难度操作后,出于损失厌恶心理,不会轻易放弃操作。
分页器
当有大量内容需要展现时进行分页加载处理,分页器作用是可以让用户清楚的知道自己所要浏览的内容有多少页、当前所在页码、快捷前往目标页码。
分页器一般分为迷你、简易、自定义三种样式。
妙用分页器小 Tips:当表格中需要对数据全选操作时,为了提高操作效率,可将自定义每页跳数调到最大。例如一共 100 条数据,默认每页 10 条数据,要完成全选需要点击 9 次翻页,10 次全选(表格的全选框勾选后一般只选中当前页面全部数据,而不是所有页面总数据),当把每页条数调整为 50 后,则只需翻页 1 次,点击 2 次全选即可。
到这里关于 B 端的基础组件就全部梳理完了,后续我们就来揭开展示组件的神秘面纱。
部分参考资料:
作者:huang。亮 来源:优设网
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
希望得到建议咨询、商务合作,也请与我们联系01063334945。
分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
SaaS,英文全称 Software as a Service,意思为软件即服务。是通过网络提供软件服务,可以理解为一种软件交付模式,因为交付模式的不同也决定了和传统软件的差别。
在Saas之前传统软件需要购买后本地化部署,两者最大的区别在于,卖软件是将软件作为一个软件实体卖给客户了;而卖SaaS 软件的所有权还在厂商所有,提供的是“软件服务”。
Saas模式的提出者是Salesforce创始人——马克·贝尼奥夫(Marc Benioff) 在98年的时候提出。有两个原因促使马克·贝尼奥夫思考并提出Saas:
1. 传统软件部署实施交付的失败率非常高;
2. 软件的售卖价格非常高,很多中型、中小企业有需求但无法承担高昂的费用。
基于以上两个痛点及当时的现状卖软件给企业造成的影响,已经形成了恶性循环,市场受到严重的阻碍(据Gartner 高德纳公司(美国咨询公司)的调查研究曾表明:在所有CRM项目中大约55%没有达到软件用户的完整交付和预期目的,通俗的说是实施失败。)
从卖软件变成卖服务,其中的技术方式的改变、交易模式的改变,促成了软件时代的变革,对于传统软件公司来说,是一次大革命。原来卖软件给客户,一次性(或者分几次)收到钱了;改为卖服务后,这笔钱就不能在短周期内一次性收了,现行的SaaS模式通常是按照用户的使用年费来收取。
两者差别在于,软件商需要先主动改变可以短期的一次性高收入,从短期收入向长期收入的转变;
所以SaaS是长期主义的事情。
失败的Saas生意会出现一个问题:把长期生意做成了短期不可持续的生意;而短期生意带来的就是经营成本的剧增,导致生意不可持续。
所以,Saas模式决定了需要客户长期使用你的产品,才可以长期可持续赚钱,也就是通常意义上的客户终身价值(LTV)。
那如何做到客户长期使用,其实只有一种方式:长期为客户创造价值,做到帮客户成功(帮助客户的业务成功),从而持续续约。
吴昊老师,在《SaaS创业路线图》中的讲到:SaaS的本质是续费。这个观点我比较赞同,SaaS的经营本质在于可持续。
那么,决定SaaS的成功因素是什么呢?
我认为决定性因素有三个方面:产品强大且灵活、用户体验优质、服务的有效支持。产品强大和服务的有效支持不言而喻,具体我们来聊聊用户体验的价值。
传统软件在一次交付实施后,客户付80%的钱,剩下的20%能不能收回来就不那么重要。但SaaS模式,客户每年进行续费,若产品使用及用户体验满意度低,带来的影响和后果可能是客户终止续费。
因此,和传统软件相比SaaS的用户体验的价值就更为重要,它直接影响SaaS的续费和流失。
相信“用户体验”这个词大家应该非常熟悉,接下来我们从新认识什么是用户体验?
官方的定义是:用户在使用产品过程中建立起来的一种主观感受。“用户体验”这一概念是唐纳德·诺曼(Donald Norman)在20世纪90年代中期提出的。产品大神俞军老师说过用户体验的本质是“ 用户最小成本满足需求 ”。
基于俞军老师的定义、我的理解和思考,我认为是帮助产品和用户:最小成本满足需求,同时创造「美·好」体验。
怎么理解,因为用户体验是满足商业目标的一种行为手段,我们来看下用户体验的需要考虑的双边关系,就比较好理解了。
如下图:左边是用户最小成本满足需求,右边是我们企业最高效的服务用户。
企业的本质就是创造商业价值,商业价值来源于用户价值,同时考虑实现商业价值的效果和效率。我们常常会听到“投入产出比”或者叫“投资回报率”;对于商业行为中的一环用户体验也如此。
所以,用户体验的核心的就是:平衡用户最小成本满足需求,及企业最小成本服务用户。完成价值交换同时,满足持续性。
由此,可以看出在SaaS的产品设计中,用户体验其实承担着一个比较重要的责任,因为它关系到成本的边际和规模化的影响,一头是产品一头是用户。
那么作为产品体验设计师,我们需要具备一定成本意识,做好“成本管控的设计”,更本质来说设计过程中我们应该:把复杂留给自己,把简单留给用户。
因为我们在设计的过程中把握产品的交互方式、使用流程,在用户认知和效率层面有较强的把控空间,充分做到的以“用户体验”出发;那后续销售、交付、客户成功的全链路服务过程的学习效率和服务效率会呈指数级上升。
产品设计,应该把复杂留给自己、把简单留给用户。
关于用户体验,就不得不介绍一下“ 用户体验要素”模型,个人认为这是所有产品经理和设计师可以贯穿整个职业生涯中都需要经常性、反复对照思考的设计模型。
用户体验设计的价值远不止于让产品的视觉、颜值提升,设计更大的价值在于深入业务、洞察用户,帮助业务梳理产品信息架构、任务流程、交互体验。
构建系统的用户使用方式和工作模式,从而达成用户目标;通过达成用户目标完成价值交换、以此完成商业交易达成商业目标。
回顾Saas的商业模式,Saas的商业模式决定我们提供的这个服务不是靠人海战术,因为Saas软件即服务的含义是所提供的软件就等于提供自助化的服务,应该提供的是自助服务、开箱即用、开箱易用的服务。
那么Saas服务设计策略上,应该从降低系统使用门槛和提升用户的自主化服务两维度出发,根据这两个核心维度,我们构建了每刻SaaS产品体验的设计策略模型。
第一,设计“系统服务自动化”,这里的服务是功能使用的操作,符合“低认知、易上手”,那么从设计整个体系 需要遵守“易发现、低认知、高效率、有温度”的设计原则展开,以用户使用行为出发设计符合用户心智认知的功能形态和交互流程。
第二,设计“系统帮助自助化”,什么意思在全系统中构建帮助引导的自助化体系,用户需要帮助的时候提供人性化的引导帮助,我们从发现的维度、认知的维度,系统认知的维度,综合考虑用户系统的帮助引导。
设计原则,是指导我们做正确设计的方针。
设计原则的建立基于对用户使用体验全流程的基础上,以每刻报销的设计原则,围绕用户旅程、认知及行为出发构建。
1. 当用户接触系统从看出发,看见系统界面、发现操作入口;(发现)
2. 带着操作任务用户进入系统、看见导航、看见文字、看见按钮,都需要理解认知;(认知)
3.用户从何开始、如何操作,在完成整个业务事项的过程需要进行填写、选择、交互过程就产生了生产效率问题;(操作)
4. 当出现误操作或系统出错时,需要系统纠错提醒、容错的设计、帮助及引导,当完成整个业务事项后,用户产生一种的情绪感受,这个感受即是印象、评价、口碑。(感受)
紧紧围绕产品业务、用户处理特性业务的基础上,以终为始,回归到用户、业务、系统进行思考归纳的产物。
设计策略,是指导我们如何进行做正确的设计。
在SaaS产品分类上,常见的SaaS产品主要分为3类,行业SaaS、职能SaaS和通用SaaS。
每刻报销产品从核心业务来说是职能类Saas,从提升财务人员报销的发票审批、费用审核等效率展开,但报销的来源又源于普通员工的业务报销,业务报销发生又和所在行业的费用发生行为特征有一定相关性,所以是结合职能和行业Saas的属性,从用户体验的设计上需要考虑不同角色用户对于系统的业务理解、功能交织使用的不同诉求,这个设计过程探索研究是相对比较有难度的,以后有机会可以展开聊。
下图是每刻系统经过6年过程中统计的问题分布,分布比率呈现:认知问题 60%,效率问题 30%、情感问题10%。
我们在访谈客户调研发现,企业服务虽然客户已经用了好几年我们的系统,但财务部门还是经常性会碰到新入职员工的系统使用问题,甚至财务部门来新人时 以前系统发生的使用问题会从新出现一遍,所以企业服务有一个现象,客户是老客户,但新用户不断增加,新人一旦增加第一个遇到的问题就是认知问题,也辅证了我们对于Saas系统认知问题是用户体验的第一大问题。
帮助体系建立可以从系统层面体系化有效降低用户使用的认知成本,围绕用户角色的核心业务操作使用流程、洞察用户旅程上的疑惑和障碍点。用户首次进入系统要建立介绍和引导,足够简单、降低陌生感,来减少人力咨询回复的投入。
相比人,系统的自助化和自动化的服务,更具有复用性和规模效应。
SaaS的商业模式,按年使用账号来收费和传统软件的付费模式区别非常大,因为需要先主动放弃自己本来可以唾手可得的收入,从短期收入向长期收入的转变。
在SaaS模式的时代,商业模式决定其必须关注客户成功、客户持续续费、LTV客户长期价值。
SaaS的产品更需要重视用户体验,用户体验的优劣决定其产品的长期发展,SaaS的用户体验设计则关注用户使用认知和行为效率,以及系统服务自主化设计和系统帮助自动化设计,用户体验将在产品成长期后半程,逐渐成为SaaS商业模式不可或缺的产品竞争力。
作者:周大虾07 来源:站酷
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
希望得到建议咨询、商务合作,也请与我们联系01063334945。
分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
图标在界面设计中,虽然很小,但是却是界面中重要组成部分之一。通过将显示物体图形化的形式,将功能本意高度浓缩成一个图标,再通过视觉隐喻更快地让用户理解功能,同时图形与文字相比,图形更加生动形象,视觉能力更强、更便于记忆,用户可以根据图形快速定位功能位置。而顺着时代的发展,图标不再仅仅以工具的形式出现,更多的起到装饰页面,也不断延伸出不同的图标类型与图标设计风格。
图形与复杂的文字相比,更加简洁,相应的识别效率也会更高。图标可以将复杂的文字描述高度浓缩成一个图标,通过视觉隐喻的方式让用户联想到现实生活中的物体,更直观地呈现图标代表的功能,更快理解功能的意义
1.2 减轻页面负担
像一些通用常见的图标,如搜索、播放按钮、更多等,仅需要一个图标就能清晰地传递功能意义给用户,省文字的描述,节省更多的页面空间与阅读压力。
1.3 更快定位功能位置
图标与文字相比有更丰富的表现形式与颜色,所以视觉冲击也就更强,也能更快地被识别出来,当用户熟悉了产品后,只需要通过图标就能快速找到想要的功能,当功能位置发生变化时,不需再重新阅读枯燥的文字找到对应的功能,只需从图标形状、颜色上区别,找到对应的功能。
2.装饰层面
2.1 传递品牌调性
随着互联网的发展,同类型的产品越来越多,要在各个产品中突围,除好用的功能外还要有特色的外观。在图标中融入能代表产品品牌的符号,强化品牌调性,保持图标的独特性,给用户留下深刻的印象,一看图标就知道是哪个产品。
2.2 增强产品吸引力
如今用户对产品的要求除了要有好用、有用的功能外,还希望有更好的视觉享受。一组好看、有趣的图标可以带给用户更好的第一印象,增强产品对用户的吸引力。
2.3 渲染气氛
根据不同的节日或运营活动,设计相应氛围的图标,帮助产品渲染节日氛围或加强用户对产品主题运营活动的感知力度
二、图标绘制的基本原则
1. 可识别性
图标与文字在一定程度上起到相同的作用,都是通过特定的表现形式来传达某种信息给用户。顺着时代发展,图标的设计更精细化,产生了更多的设计风格,但图标的本质还是没变的,是用户进入功能的入口。因此,一个能被用户快速识别、快速理解的图标相当重要,是图标设计的基本要求。我们绘制图标时要尽量去掉辅助、无用的元素,保留最清晰、直接、有代表性的元素。
2. 风格统一
设计师在设计图标时,除了会根据产品类型、用户群体、品牌调性等因素决定使用哪种图标风格外,还要根据图标的具体使用位置,因此在一个产品中,常常会出现多种风格类型的图标,而风格统一指的是在某个特定功能模块内的图标风格要保持一致,是面性的图标就是面性,是毛玻璃效果就是毛玻璃效果。
3. 大小统一
圆形、正方形、三角形,在这三个图形虽然高度相同,但是整体上三个图形的视觉重量并不相同。在实际的操作中,界面图标不会由单一的形状组合,所以形状各异导致每一个图标的视觉体积都会有所区别,因此不能单纯地利用统一的宽高或线去界别图标的大小,要根据图标的的特征去判断。在平常的设计中,我通常会利用正方形来辅助图标绘制,在保持形状特征下,让正方形内的区域占满,哪个方向缺得越多,就往那个方向移动一点。
4. 色彩统一
色彩的统一指的是图标色彩在饱和度与明度上保持特征统一,数值在一定的范围内发生改变;而在色相的选择上保持匹配度,像一些单色系的图标,通常使用的都是产品的主题色,而多彩图标,常会以主题色为主,拓展出临近色、相似色、对比色,目前市面上大多数的图标颜色会使用同类色与邻近色。对于饱和度与明度的调节,我通过利用灰度模式进行辅助,使图标视觉更统一柔和,不会出现其中一个亮眼或暗沉。
5. 占比统一
5.1 正负形占比统一
正负形的合理使用是图标能否传达准确意思的关键,因此也是常会出现的组成元素。在绘制图标的正负形,注意保持占比统一,其中某个图形正负形太大或太小,会显得突兀、别扭,失去统一性,界面整体质感会大大降低。
5.2 颜色占比统一
在绘制图标时,确定图标中的主色和辅色,绘制时尽量保证主色和辅色占比相同,保持图标的统一性。
6. 疏密统一
有规律地将线条组织在一起,利于形成统一的视觉风格。同时,线条间可以保持一定的留白,不需要太密集,太密集的线性图标,缩小后反而会影响识别。同时,给图标留出一些空间,使线与线之间不会太挤,增强图标的呼吸感。
安利一个国外的图标大神Myicons✨,简单的线性图标一样可以很精致。
三、不同风格的图标
目前市面上的图标主要有四种类型,分别是:线性图标、面性图标、写实拟物图标和三维立体图标。而不同的图标中组合的元素都会有一些差异,相同类型的图标中也会有不同的图标风格。
1. 线性图标
线性图标主要还是由线性组成,设计师可以通过改变线的粗细、线的端点、圆角大小或加入一些面性元素在里面来使线性图标更加丰富、有趣,但整体来说纯线性图标更纤细、简洁,使得视觉冲击力稍微弱了些。
1.1.1 单色
单色是线性最基础的表达方式,这种设计风格单调、视觉冲击较差,但是制作难度低,设计所耗费的时间页更断,因此常常会出现在个人中心页中,仅需要有图标显示功能入口,设计要求并不高的功能模块中。
1.1.2 双色
双色图标与单色图标相比,视觉冲击力更强,应用范围更广,通常会融入品牌主色,是除了线面图标外出现在首页中的线性图标。因为双色图标可以加入品牌色,增强品牌感的同时,使图标增加了设计感,不会像单色图标那么单调乏味,因此双色图标也会以“次要功能”的形式出现在首页当中。
像在“去哪儿旅行App”和“平安银行App”中,页面已经存在一组视觉冲击、视觉层级更高的一组面性图标,但是因为业务需求露出更多功能入口,因此就可以使用线性图标这种视觉冲击力弱一点的图标搭配,既不会抢走主视觉,也能满足业务需求。
1.1.3 断点图标
断点图标在目前的app图标设计上较少使用。虽然断点风格图标在表达上有一定的局限性,但是图标设计感更强,图标更有趣味性。
断点图标并不是随便删除某个描点,在断点的位置选择上和断点的大小都是要注意的地方。断点位置的选择要注意两点:
1 ) 保持相同角度,能更好地增强图标的协调性,避免造成图标的视觉混乱降低用户的视觉体验。
2 ) 选择在线的拐角处,利用连续性原理,在一定的路径下使这种线的断裂保持视觉连贯性,保持图形整体性。
1.1.4 线面结合
在原本的线性图标上加入色块,就会产生新的设计风格--线面图标。线面图标比较特殊,图标的视觉层级会随着图标中包含的色块大小而变化,色块越大,视觉冲击力也越强。因此在设计线面结合图标时,要先确定图标在该页面中的重要程度,如果是主要功能则将色块的占比加大。
1.2 线的影响
图标中的线主要由两个元素组成,一个是线的粗细,一个是线的端点,而这两个元素也是主要控制线性图标的性格。以常用的48px图标盒子为例,常用线的粗细有2px、3px、4px,图标的线越粗图标越有力量感反之图标越纤细;而图标的圆角越小时图标越稳重、专业,像一些办公软件、金融产品,图标的圆角就比较小。圆角越大图标越饱满亲和力更强,像一些儿童学习类软件就会使用大圆角的图标设计。
因此,图标的线粗细与圆角大小,都根据不同产品类型与目标用户确定。而大多数线性图标主要有四种基础造型:纤细+小圆角、纤细+大圆角、粗描边+小圆角/无圆角、粗描边+大圆角。
1.2.1 纤细+小圆角
精致、严谨,多用在银行、新闻类APP。没有圆角,会使图标更加尖锐,对于银行类APP会给人一种威胁,但是太大的圆角,显得有点轻浮、可爱,不符合银行庄严的感觉,所以稍微添加一些圆角,使图标更有亲和力的同时,也保留一些庄严的感觉。
1.2.2 纤细+大圆角
更加精致、有亲和力,这种风格是目前市面上软件使用得最多的一种线性图标风格。
1.2.3 粗描边+无圆角/小圆角
粗旷、个性、有很强的力量感。更多的用在运动、汽车这类主要用户倾向男性的软件,同时也会在一些潮流类电商软件中出现,凸显更有个性的设计风格。
1.2.4 粗描边+大圆角
圆润、可爱、亲和力强,常用在偏向儿童的产品
2. 面性图标
面性图标时软件使用的最多的一种图标类型,设计师通过改变色块、图形圆角、正负形和底托等元素,让面性图标呈现不同的设计风格,但无论是哪种设计风格,面性图标设计冲击力相比面性图标更强,因此市面上大多数核心功能都会用到面性图标来提高功能的设计层级,让功能在页面中更加突出。
2.1 扁平风格扁平风格的图标常为单色图标,图标整体没有渐变、高光、阴影等装饰性设计效果,因此更加简洁,更突出功能本身,图标功能性更强,图标制作成本低,曾经也是风靡一时。但扁平风格的图标缺少亮点与制作成本的原因,导致图标同质化严重,缺少特点,很难被人记住,因此现在很少被使用。
2.2 渐变色块
在扁平风的基础上,在色块上添加渐变色,在保留了扁平图标的功能性外,使图标色彩更加丰富,在不同类型的软件中都可以使用这种风格,算是一个比较百搭的图标风格。同时渐变色块也是很多面性图标的组合基础,在渐变色块这个基础上还可以添加不同的效果形成不同设计风格。
在设计渐变色块风格的图标时要注意两点:
1 ) 市面上的app都会选择同类色作为渐变色,然后通过改变颜色的饱和度,使渐变色的明亮对比更加明显的同时,颜色过渡也更加柔和舒服,使图标更有通透感,增加视觉冲击力。
2 ) 在设计这种有白色色块在顶部的图标时,可以给色块添加一个浅浅的透明渐变,让色块过渡自然一些,同时也可以添加一层浅浅的阴影,增加层次感。
2.3 图层叠加
图层叠加风格的图标看上去像两个透明图层叠加在一起的感觉,图标层次感强,细节也更加丰富,图标风格更新颖、更年轻化,因此如果在设计一个年轻人使用或者希望打造年轻化页面感受的时候,可以尝试使用图层叠加风格。
绘制图层叠加风格的图标时要注意:
1 ) 重叠在一起的那个色块是通过布尔运算得到的,并不是通过简单的透明图层得到的。而重叠在一起的那个色块也不宜过于显眼,毕竟看的是图标的整体。因此可以参考一下“智行火车票”,通过改变饱和度5%到10%和使用15%左右的同类色,就可以让用户看得清图标的变化,同时也不会是色块太突兀影响观感。
2 ) 尽量统一叠加部分图形与图标之间的占比。
2.4 毛玻璃
毛玻璃是近年最火的一种设计风格,不仅设计风格新颖、特别,而且还有很强的质感表现,因此不仅在金融产品,还是生鲜产品或票务产品,都有毛玻璃风格的图标。
而在设计毛玻璃图标时,里面也有很多细节需要注意:
1 ) 背景模糊效果不需要太大,有一种若隐若现的感觉就可以。如果调太大,可能就看不出是毛玻璃效果了。
2 ) 添加背景模糊效果的图层不需要用纯白色。像百度这种同类色配色的毛玻璃图标,只需要将图标的主色调低饱和度后,就可以使用。这样的好处是不仅让图标颜色过渡更加自然,同时有更多的组合方式、更多的层次。
3 ) 使用边缘光。毛玻璃图标有很多相互重叠的图形,如果重叠的图形颜色相近的话,图形边缘就会被弱化,使用边缘光可以明确图形边界,增加层次感。同时使用边缘光,还可以为图形塑造类似玻璃的厚度,细节更加丰富。
2.5 晶白风格
晶白类图标利用圆角正方形或圆形作为底托再在上面添加一个主色为白色的图标,然后通过调节透明度、投影、渐变给图标添加一些质感,是常见的图标风格,也是使用了很久的一种设计风格。
后面也延伸出了另一种设计风格图标主题通常不会是统一的造型,像喜马拉雅这种图标,图标本身元素复杂、细节较多,形状也更加不可控,因此用一个浅色圆形底托,将他们统一起来。不仅可以将复杂的图形统一起来,还可以添加吸引人眼球的渐变色更好地增加图标的视觉占比,有更强的视觉冲击感。
在绘制晶白风格时,注意两点:
1 ) 可以适当改变底托图形的形状,增强差异化。
2 ) 统一光源,越白的地方越亮,注意控制好透明度的变化与角度。
2.6 实物展示
这类图标会出现在生鲜类、药品类、潮流电商类产品中,因为使用图标很难将这些类型概括起来,直接使用图片展示更加直观,但因为图片细节、元素更多更复杂,如果使用太多会使图标看起来很杂乱。
3. 写实向图标
写实向图标模拟现实中的物体,更贴近生活,用户对这类图标理解能力也更强,绘制难度也更高,绘制时间也更长。写实向图标除了基本的色块组合、颜色搭配外,还有更多的透视与光影来增强实感。常常用在运营设计上,或用在一些特殊界面模块从而增强视觉层级。
3.1 轻拟物图标
轻拟物图标是最近很好的的设计风格,但是轻拟物图标出现在界面设计上还是比较少的。因为轻拟物图标元素比较复杂,视觉冲击力强,放在界面上有可能抢走用户对核心内容的关注度,通常会运用在运营设计长图、弹窗、核心功能等。
而绘制轻拟物图标,主要注意的是光影的打造。光影主要由这几个元素组成:亮面、暗面、明暗交接线、反光。在绘制轻拟物图标时,主要注意以下几点:
1 ) 在绘制轻拟物图标时,不一定需要使用统一色相中的颜色,可以通过改变颜色的饱和度明度的对比和冷暖色的对比来营造光影,使图标色彩更丰富、对比更明显。
2 ) 反光可以使用图标主色的对比色,降低饱和度,提高明度,运用在轻拟物图标边缘,使边缘更更清晰,不会糊在一起,图标整体立体感更强。
3 ) 明暗对比越明显,轻拟物图标越显通透、立体。
3.2 2.5D图标
2.5D曾经是很火的一种设计风格,但是现在已经逐渐被轻拟物与建模替代。2.5D图标固定展示了三个面,有很强的立体感,常常运用在科技类的网站设计中。
在绘制2.5D风格图标时,要注意:
1)统一好图标的厚度。
3.3 3D图标
随着时代进步,3D逐渐成为一个主流的设计风格。通过专业软件给予了图形材质质感、真实的光影,更加贴近生活真实物件,同时还可以配合动效的设计,有很强的视觉冲击力和新鲜感。常常出现在网页设计中、运营设计中。目前绘制3D图标主要用blender和C4D,C4D在渲染方面有oc的加持,渲染效果直接拉满;Blender则是完全免费的软件,目前热度也是疯狂涨,在渲染方面虽然没有oc好,但是还是可以满足日常工作。
而在绘制3D图标需要注意以下几点:
1 ) 统一主光源方向。建模里面会出现很多打光类型,如主光、辅光(有时不止一个)、边缘光等。
2 ) 统一摄像机位置。摄像机与物体的距离、角度影响渲染的最终效果。
3 ) 用数值定义物体大小。建模软件不像绘图软件那样强调物体的数值大小,拉远看物体就是小,拉近看就是大,做一个物体时还好,但是要做一组3D图标时,就要定义好物体的大小,使图标更加统一。
四、如何确定使用哪种类型的图标
不同风格的图标有着不同的特点,设计师要根据图标放置位置和功能选择图标类型。其中最有决定性的因素就是图标的重量,而影响图标重量的因素有:占比、颜色、细节元素。线性图标在界面中占比较少,因此看起来会更加简洁,视觉冲击力弱,常用在重要程度低,不需要突出展示的功能上;面性图标占比更高,视觉上会更加饱满,同时颜色色块使图标更加显眼,视觉冲击力得到力增强,使用户对图标的感知力更高,是最常用的图标类型,用在各个重要功能入口上;轻拟物和3D图标除了占比高、颜色丰富,还有各种光影、材质的细节,图标元素更多,视觉冲击力也更强了,也因为图标复杂、视觉冲击力强,因此很少出现在界面上,通常运用在一些特殊运营入口或需要吸引用户的大模块中。
不同的类型在界面中也会搭配出现。
五、图标的绘制
1. 图标盒子
图标盒子是辅助绘制图标的一个工具,帮助设计师在设计图标时更好地规范好各个图标的尺寸大小。而图标盒子也有很多种,我最常用的是48*48px,这个尺寸对于线条的控制比较方便,通常用1px、2px、3px。
工具始终都是工具,界面图标不会由单一的形状组合,所以形状各异导致每一个图标的视觉体积都会有所区别,因此不能单纯地利用统一的宽高或线去界别图标的大小,要根据图标的的特征去判断。在平常的设计中,我通常会利用正方形来辅助图标绘制,在保持形状特征下,让正方形内的区域占满,哪个地方缺得越多,哪个地方就拉伸一点。
2. 图标的绘制方法
图标中会存在标准化图标,像删除就是一个垃圾桶、像首页通常是一个家的图标、还有搜索则是放大镜的图,照片是两个山一个太阳,这些图标都习惯以这种表达方式出现,用户已经习惯了这种表现形式,因此对于标准化图标,尽量维持以往的变现形式,让用户更好地理解图标意思。
非标准化图标可以细分为具象与抽象,对于具象类图标,现实中有实物可以参照。这类图标的设计较为简单,可以在某度上寻找相关照片,根据实物的造型进行提炼和简化。
抽象图标则较为复杂,通常是某些特定行为的名词,没有具体直接的参照物。因此在设计前,我们要先充分理解功能本身,这个功能是什么、用户怎么用,然后提炼关键词,接着根据关键词发散思维,寻找相关联的图形来表示含义。例如“社区”功能,功能目的是提供一个让用户互相交流的环境,同时吸引无目的的用户逛起来发现感兴趣的话题,让更多的信息流得到曝光从功能目的中提炼一下关键词:聚在一起、发现、交流。接着发散思维进行脑暴,聚在一起:一群人-圈子-同一个世界的人-星球,发现:看-眼睛;寻找-望远镜-雷达-指南针,交流:聊天-聊天气泡-声波。
六、图标的使用场景
图标运用在功能入口上是最基础的使用场景之一,如首页中的金刚区、个人中心都会用到很多图标作为功能入口。
1. 金刚区
目前国内的APP包含的功能有很多,而金刚区的作用就整合产品功能并放置在首页中,提高这些功能的曝光量,给其他功能引流,让更多用户知道或使用上产品功能,增强用户对产品的粘性。像美团,很多人对他的了解是一个外卖工具,但它里面还有很多其他功能,使用金刚区展示它多元化的服务。
金刚区图标通常会有1~3行,根据业务具体需求做调整,在每行中会有4~5个图标。尺寸范围一般在40px~48px左右(@1x),同时会根据具体的业务需求,调整大小,最终都是一预览效果为准。
2. 个人中心
个人中心是个人类型功能、运营活动入口和工具的集合地,是除了金刚区外,含图标最多的一个地方。个人中心中包含很多不同类型的功能,可以使用卡片式的设计,将功能图标更好地分类。在图标风格的选择上,个人类型功能是最重要的功能,通常会以面性风格放置在顶部,如果个人中心中需要展示运营入口时,需要减弱个人类型功能图标的视觉冲击,会使用线性风格图标。
3. 运营入口
运营入口主要作用是让用户点击后跳转到产品活动页,因此具有强视觉冲击力的图标,会更吸引用户眼球,从而提高点击运营入口的机会。
因此运营入口上,通常会使用面性图标、写实向图标或3d图标。因为写实向图标或3D图标可以提高视觉层级,因此经常运用在主要运营板块上,而面性图标相比下较弱,当页面已存在一个主视觉或主要功能时,运用在运营板块上。
4. 主题板块
在软件中会有很多不同主题的信息板块,同时信息板块间有较大的差异,如果全部展示出来会使页面样式不同统一、信息混乱导致降低用户的阅读体验。因此使用主题板块,将不同主题信息集中在一起,然后露出部分关键信息在页面中,保证视觉统一的同时,还可以起到流量分发的作用,让用户在茫茫信息流中快速找到自己感兴趣的方向,提供用户阅读体验。
纯文字的排版在信息流中略显枯燥,而图标在主题板块中起到润色主题的作用,渲染主题气氛,提高不同主题板块的识别度与差异化。对于一些长标题的主题板块,只需要记住图标就能快速定位主题板块位置。
5. 底部tab栏
底部tab栏功能数量通常在2~5个,在设计时,要设计点击前和点击后两个图标状态,同时帮助两个状态是有明显的变化。底部tab栏图标大小通常在22px(@1x)左右,而图标底下的文字时10px(@1x)。底部tab栏作为最常出现的区域,是传达产品品牌感、提升产品辨识度、记忆点的重要区域,很多产品都会在底部tab栏的图标设计上加入品牌元素,增强辨识度。
七、如何提高图标设计能力
1. 阶段一:临摹
临摹是人类学习一个新技能开始,就像婴儿学习父母说话一样。但是一开始很多都不会临摹,或者照着画也不会,那我们应该如何去做?
1.1 临摹效果不佳
1 ) 提高审美能力,多看一些主流的图标,可以上追波看看目前流行的设计风格,不行的话就去看看大厂都在画怎样的图标。
2 ) 明确自己的能力,对自己目前的设计水平有一个客观的评价,到一个怎样的水平。很多人都急于求成,最基础的线性图标都不会就上来搞轻拟物,画来画去都不好看,最后就放弃了。
3 ) 敢于支出自己的不足,许多人画了许多时间去画一组图标,就很容易被自己催眠,以为自己已经画得很好了,其实还会有很多不足。所以我们要敢于指出自己的不足,在前期临摹阶段,画完后多去对比原作,自 己有哪些地方没有原作做得好的
1.2 会了,但没完全会
什么是会了,指的是可以绘制出于优秀原作一样的图标;什么是没完全会,指的是不知道原作是怎么达到这个好看的效果的。而且很重要的一点是,你临摹的作品可能也有一些不好,需要改进的地方,以此在这个阶段我们要做的是:
1 ) 多看别人总结的知识点,知道如何去判断一个图标是否还有可以改进的地方,这样绘制是不是正确的
2 ) 懂得总结与思考,原作是用来什么样的手法让我觉得它是好看的,这些技法怎么用,还可以用在哪
2. 阶段二:半原创
临摹是一个提升自己的手法,但不代表可以直接用到自己的作品中,直接复制别人的设计,并不叫设计师,复制粘贴谁不会啊,所以在懂得如何临摹后,我们要敢于尝试半原创。这里说的半原创不是指在别人图标的基础上加上两笔就是半原创,而是要吸取了优秀图标的优点后,重新设计出一个有相同特点的图标。那我们应该如何半原创呢?
1 ) 还是多看,但是不同于临摹阶段,我们在临摹的时候还要多想,这个图标的特点是什么、怎么做、还能怎么用,积累图标不同的表现形式2 ) 多练,这个建立在多临摹上,目的知道别人的技法是什么做的,练习了不同的技法后,将它们再融合在一起
3. 阶段三:原创
第三个阶段,也是最难得阶段。目前很多情况都是只能成为融图设计师,将不同作品优秀的点组合起来。但如果要建立自己的风格也是要做融图设计师的基础上,多想、多尝试,敢于突破,在一次次的融图后,发现出自己的特点,为自己的作品打上自己标签,输出具有差异化特点的设计。最有印象的就是夸克的设计,品牌特色很明显,其实我们每个人也可以成为一个品牌,只要我们足够努力
作者:阿恒的设计笔记 来源:站酷
蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请加微信ban_lanlan,报下信息,蓝小助会请您入群。欢迎您加入噢~~
希望得到建议咨询、商务合作,也请与我们联系01063334945。
分享此文一切功德,皆悉回向给文章原作者及众读者. 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务、UI设计公司、界面设计公司、UI设计服务公司、数据可视化设计公司、UI交互设计公司、高端网站设计公司、UI咨询、用户体验公司、软件界面设计公司
蓝蓝设计的小编 http://www.lanlanwork.com