首页

node 模块简述

seo达人

Node 的os模块是操作系统的

Node 的内置模块 fs


内置模块在下载node的时候就自带的,使用 require()方法来导入

语法 :require(‘模块fs’)



在内置模块中的方法

1 fs.readFile() —》用来专门 异步 读取文件的方法 三个参数

语法 :fs.readFile(‘要读取的文件’,读取文件的格式,读取成功的回调函数)

Eg : fs.readFIle(‘a’,’utf8’,’function(err,data){ })



2 fs.readFileSync()-– 专门用来 同步 读取的方法, 两个参数

语法: fs.readFileSync(‘要读取的文件’,读取格式)



3 fs.writeFIle() —>用来写入 异步 文件的方法 三个参数

语法: fs.writeFile(‘写入到哪个文件’,写入的内容,成功的回调函数)

Eg: fs.writeFile(‘./text.tex’,”内容”, function(){ })

注意:再次写入的内容会完全覆盖 。如果文件夹没有 会自动创建一个文件夹



4 fs.writeFileSync() --> 同步写入的方法

语法: fs.writeFileSync(‘写入到文件’,“写入的内容”)



Node的http模块

这个模块专门用来创建服务的

只能支持http协议。

也是使用require()方法

Const http= require(“http”)



方法

1 http.createServer(function(req,res){ }) 两个形参

Req=request 代表每次的请求信息

Res=response 代表每次请求的响应

返回值是一个服务,当服务监听端口号的时候,就变成了服务器。

2 监听端口号

创建的服务.listen(监听的端口号,监听成功的回调函数(选填))

server.listen(8080,function(){ 端口号0-65535 建议0-1023不使用 })

此时浏览器就可以执行localhost进行访问了



自定义模块

每一个js文件都是一个独立的模块,他们都自带一个 module 是一个对象,

其中 module里面的 exports,是一个对象 这个 module.exports 就是这个文件向外导出的内容,也就是说,只有导出,才能导入



Eg: function fn1(){console.log() }

Module.exports.fn1=fn1

这样,才能是另一个js文件到入这个文件 同样也是require(‘./js’)方法


教你用面向对象编程写一个烟花爆炸的

前端达人

点击查看原图



想要学会这个漂亮的烟花吗?快来跟着学习吧~

结构

<div class="container"></div>

我们只需要一个盒子表示烟花爆炸范围就可以了

样式

fire是烟花 注意添加绝对定位

 <style>
    .container{
        margin: 0 auto;
        height: 500px;
        width: 1200px;
        background: black;
        position: relative;
        overflow: hidden;
    }
    .fire{
        width: 10px;
        background: white;
        height: 10px;
        /* border-radius: 50%; */
        position: absolute;
        bottom: 0;
    }
    </style>



行为

编写构造函数Firework

需要用到一个鼠标点击的位置,一个div选择器,一个爆炸样式

 function Firework(x,y,selector,type){
        //此处获取对象的方式为单例的思想,避免重复获取相同的元素
        if(Firework.box && selector === Firework.box.selector){
            this.box =  Firework.box.ele;
        }else{
            Firework.box = {
                ele:document.querySelector(selector),
                selector:selector
            }
            this.box = Firework.box.ele;
        }
        this.type = type;
        this.init(x,y)
    }



封装一个运动的方法
function animation(ele,attroptions,callback){
    for(var attr in attroptions){
        attroptions[attr] ={
            target:attroptions[attr],
            inow:parseInt(getComputedStyle(ele)[attr])
        } 
    }
    clearInterval(ele.timer);
    ele.timer = setInterval(function(){
        for(var attr in attroptions ){
            var item = attroptions[attr]
            var target = item.target;
            var inow = item.inow;
            var speed = (target - inow)/10;
            speed = speed>0?Math.ceil(speed):Math.floor(speed);
            if(Math.abs(target - inow) <= Math.abs(speed)){
                ele.style[attr] = target+"px";
                delete attroptions[attr];
                for(var num  in attroptions){
                    return false;
                }
                clearTimeout(ele.timer);
                if(typeof callback === "function")callback();
            }else{
                attroptions[attr].inow += speed;
                ele.style[attr]  = attroptions[attr].inow+"px";
            }
        }
    },30)
}



编写原型方法
Firework.prototype = {
        constructor:Firework,
        //初始化
        init:function(x,y){
            //创建一个烟花
            this.ele = this.createFirework();
            //xy为鼠标落点
            this.x = x ;
            this.y = y;
            //maxXy为最大运动范围
            this.maxX = this.box.offsetWidth - this.ele.offsetWidth;
            this.maxY = this.box.offsetHeight - this.ele.offsetHeight;
            //初始化结束后  烟花随机颜色
            this.randomColor(this.ele);
            //烟花升空
            this.fireworkUp(this.ele);
        },
        //创造烟花
        createFirework:function(){
            var ele = document.createElement("div");
            ele.className = "fire";
            this.box.appendChild(ele);
            return ele;
        },
        //烟花升空
        fireworkUp:function(ele){
            ele.style.left = this.x + "px";
            //此处用到刚刚封装的运动方法
            animation(ele,{top:this.y},function(){
                ele.remove();
                this.fireworkBlast()
            }.bind(this));
        },
        //烟花爆炸
        fireworkBlast:function(){
            for(var i = 0 ; i < 20; i++){
                var ele = document.createElement("div");
                ele.className = "fire";
                ele.style.left = this.x + "px";
                ele.style.top = this.y + "px";
                this.box.appendChild(ele);
                ele.style.borderRadius = "50%";
                this.randomColor(ele);
                //判定一下输入的爆炸方式是原型烟花 还是散落烟花 由此更改获取的烟花位置
                animation(ele,this.type === "circle"?this.circleBlast(i,20): this.randomPosition(),function(cale){
                    cale.remove();
                }.bind(this,ele))
            }
        },
        //圆形爆炸位置
        circleBlast:function(i,total){
            var r = 200;
            var reg = 360 / total *i;
            var deg = Math.PI / 180 *reg;
            return {
                left:r * Math.cos(deg) + this.x ,
                top:r * Math.sin(deg) + this.y 
            }
        },
        //随机颜色
        randomPosition:function(){
            return {
                left : Math.random()*this.maxX,
                top : Math.random()*this.maxY
            }
        },
        randomColor:function(ele){
            var color =  "#" + parseInt(parseInt("ffffff",16)*Math.random()).toString(16).padStart(6,0);
            return ele.style.backgroundColor = color;
        }
    }



绑定事件
document.querySelector(".container").addEventListener("click",function(evt){
    var e = evt||event;
    new Firework(e.offsetX,e.offsetY,".container","circle")
    new Firework(e.offsetX,e.offsetY,".container")
})

全部代码

<!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>
    <style>
    .container{
        margin: 0 auto;
        height: 500px;
        width: 1200px;
        background: black;
        position: relative;
        overflow: hidden;
    }
    .fire{
        width: 10px;
        background: white;
        height: 10px;
        /* border-radius: 50%; */
        position: absolute;
        bottom: 0;
    }
    </style>
</head>
<body>
    <div class="container"></div>
    <script src="./utils.js"></script>
    <script>

    function animation(ele,attroptions,callback){
        for(var attr in attroptions){
            attroptions[attr] ={
                target:attroptions[attr],
                inow:parseInt(getComputedStyle(ele)[attr])
            } 
        }
        clearInterval(ele.timer);
        ele.timer = setInterval(function(){
            for(var attr in attroptions ){
                var item = attroptions[attr]
                var target = item.target;
                var inow = item.inow;
                var speed = (target - inow)/10;
                speed = speed>0?Math.ceil(speed):Math.floor(speed);
                if(Math.abs(target - inow) <= Math.abs(speed)){
                    ele.style[attr] = target+"px";
                    delete attroptions[attr];
                    for(var num  in attroptions){
                        return false;
                    }
                    clearTimeout(ele.timer);
                    if(typeof callback === "function")callback();
                }else{
                    attroptions[attr].inow += speed;
                    ele.style[attr]  = attroptions[attr].inow+"px";
                }
            }
        },30)
    }  

        function Firework(x,y,selector,type){
            if(Firework.box && selector === Firework.box.selector){
                this.box =  Firework.box.ele;
            }else{
                Firework.box = {
                    ele:document.querySelector(selector),
                    selector:selector
                }
                this.box = Firework.box.ele;
            }
            this.type = type;
            this.init(x,y)
        }

        Firework.prototype = {
            constructor:Firework,
            //初始化
            init:function(x,y){
                this.ele = this.createFirework();
                this.x = x ;
                this.y = y;
                this.maxX = this.box.offsetWidth - this.ele.offsetWidth;
                this.maxY = this.box.offsetHeight - this.ele.offsetHeight;
                this.randomColor(this.ele);
                this.fireworkUp(this.ele);
            },
            //创造烟花
            createFirework:function(){
                var ele = document.createElement("div");
                ele.className = "fire";
                this.box.appendChild(ele);
                return ele;
            },
            fireworkUp:function(ele){
                ele.style.left = this.x + "px";
                animation(ele,{top:this.y},function(){
                    ele.remove();
                    this.fireworkBlast()
                }.bind(this));
            },
            //烟花爆炸
            fireworkBlast:function(){
                for(var i = 0 ; i < 20; i++){
                    var ele = document.createElement("div");
                    ele.className = "fire";
                    ele.style.left = this.x + "px";
                    ele.style.top = this.y + "px";
                    this.box.appendChild(ele);
                    ele.style.borderRadius = "50%";
                    this.randomColor(ele);
                    animation(ele,this.type === "circle"?this.circleBlast(i,20): this.randomPosition(),function(cale){
                        cale.remove();
                    }.bind(this,ele))
                }
            },
            circleBlast:function(i,total){
                var r = 200;
                var reg = 360 / total *i;
                var deg = Math.PI / 180 *reg;
                return {
                    left:r * Math.cos(deg) + this.x ,
                    top:r * Math.sin(deg) + this.y 
                }
            },
            randomPosition:function(){
                return {
                    left : Math.random()*this.maxX,
                    top : Math.random()*this.maxY
                }
            },
            randomColor:function(ele){
                var color =  "#" + parseInt(parseInt("ffffff",16)*Math.random()).toString(16).padStart(6,0);
                return ele.style.backgroundColor = color;
            }
        }

        document.querySelector(".container").addEventListener("click",function(evt){
            var e = evt||event;
            new Firework(e.offsetX,e.offsetY,".container","circle")
            new Firework(e.offsetX,e.offsetY,".container")
        })
    </script>
</body>
</html>

————————————————
版权声明:本文为CSDN博主「SpongeBooob」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41383900/article/details/105026768


NodeJS服务总是崩溃的解决办法

seo达人

许多人都有这样一种映像,NodeJS比较快; 但是因为其是单线程,所以它不稳定,有点不安全,不适合处理复杂业务; 它比较适合对并发要求比较高,而且简单的业务场景。 

在Express的作者的TJ Holowaychuk的 告别Node.js一文中列举了以下罪状: 

Farewell NodeJS (TJ Holowaychuk) 

•   you may get duplicate callbacks 
•   you may not get a callback at all (lost in limbo) 
•   you may get out-of-band errors 
•   emitters may get multiple “error” events 
•   missing “error” events sends everything to hell 
•   often unsure what requires “error” handlers 
•   “error” handlers are very verbose 
•   callbacks suck 

其实这几条主要吐嘈了两点: node.js错误处理很扯蛋,node.js的回调也很扯蛋。

 

 

事实上呢?

 


事实上NodeJS里程确实有“脆弱”的一面,单线程的某处产生了“未处理的”异常确实会导致整个Node.JS的崩溃退出,来看个例子, 这里有一个node-error.js的文件: 

 

var http = require('http');

var server = http.createServer(function (req, res) {

  //这里有个错误,params 是 undefined
  var ok = req.params.ok;

  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World
');
});

server.listen(8080, '127.0.0.1');

console.log('Server running at http://127.0.0.1:8080/');


启动服务,并在地址栏测试一下发现 http://127.0.0.1:8080/  不出所料,node崩溃了 


 

$ node node-error
Server running at http://127.0.0.1:8080/

c:githubscript
ode-error.js:5
  var ok = req.params.ok;
                     ^
TypeError: Cannot read property 'ok' of undefined
    at Server.<anonymous> (c:githubscript
ode-error.js:5:22)
    at Server.EventEmitter.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2108:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)
    at Socket.socket.ondata (http.js:1966:22)
    at TCP.onread (net.js:525:27)



 

怎么解决呢?


其实Node.JS发展到今天,如果连这个问题都解决不了,那估计早就没人用了。 

 

使用uncaughtException


我们可以uncaughtException来全局捕获未捕获的Error,同时你还可以将此函数的调用栈打印出来,捕获之后可以有效防止node进程退出,如: 

 

process.on('uncaughtException', function (err) {
  //打印出错误
  console.log(err);
  //打印出错误的调用栈方便调试
  console.log(err.stack);
});


这相当于在node进程内部进行守护, 但这种方法很多人都是不提倡的,说明你还不能完全掌控Node.JS的异常。 

 

使用 try/catch


我们还可以在回调前加try/catch,同样确保线程的安全。 

 

var http = require('http');

http.createServer(function(req, res) {
  try {
    handler(req, res);
  } catch(e) {
    console.log('
', e, '
', e.stack);
    try {
      res.end(e.stack);
    } catch(e) { }
  }
}).listen(8080, '127.0.0.1');

console.log('Server running at http://127.0.0.1:8080/');

var handler = function (req, res) {
  //Error Popuped
  var name = req.params.name;

  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello ' + name);
};


这种方案的好处是,可以将错误和调用栈直接输出到当前发生的网页上。 

 

集成到框架中


标准的HTTP响应处理会经历一系列的Middleware(HttpModule),最终到达Handler,如下图所示: 

\ 


这 些Middleware和Handler在NodeJS中都有一个特点,他们都是回调函数,而回调函数中是唯一会让Node在运行时崩溃的地方。根据这个 特点,我们只需要在框架中集成一处try/catch就可以相对完美地解决异常问题,而且不会影响其它用户的请求request。 

事实上现在的NodeJS WEB框架几乎都是这么做的,如 OurJS开源博客所基于的 WebSvr 

就有这么一处异常处理代码: 

 

Line: 207

  try {
    handler(req, res);
  } catch(err) {
    var errorMsg
      = '
'
      + 'Error ' + new Date().toISOString() + ' ' + req.url
      + '
'
      + err.stack || err.message || 'unknow error'
      + '
'
      ;

    console.error(errorMsg);
    Settings.showError
      ? res.end('<pre>' + errorMsg + '</pre>')
      : res.end();
  }


那么不在回调中产生的错误怎么办?不必担心,其实这样的node程序根本就起不起来。 

此外node自带的 cluster 也有一定的容错能力,它跟nginx的worker很类似,但消耗资源(内存)略大,编程也不是很方便,OurJS并没有采用此种设计。 

 

守护NodeJS进程和记录错误日志


现 在已经基本上解决了Node.JS因异常而崩溃的问题,不过任何平台都不是100%可靠的,还有一些错误是从Node底层抛出的,有些异常 try/catch和uncaughtException都无法捕获。之前在运行ourjs的时侯,会偶尔碰到底层抛出的文件流读取异常,这就是一个底层 libuv的BUG,node.js在0.10.21中进行了修复。 

面对这种情况,我们就应该为nodejs应用添加守护进程,让NodeJS遭遇异常崩溃以后能马上复活。 

另外,还应该把这些产生的异常记录到日志中,并让异常永远不再发生。 

 

使用node来守护node


node-forever 提供了守护的功能和LOG日志记录功能。 

安装非常容易 

 

[sudo] npm install forever


使用也很简单 

 

$ forever start simple-server.js
$ forever list
  [0] simple-server.js [ 24597, 24596 ]


还可以看日志 

 

forever -o out.log -e err.log my-script.js


 

使用shell启动脚本守护node


使用node来守护的话资源开销可能会有点大,而且也会略显复杂,OurJS直接在开机启动脚本来进程线程守护。 

如在debian中放置的 ourjs 开机启动文件: /etc/init.d/ourjs 

这个文件非常简单,只有启动的选项,守护的核心功能是由一个无限循环 while true; 来实现的,为了防止过于密集的错误阻塞进程,每次错误后间隔1秒重启服务 

 

WEB_DIR='/var/www/ourjs'
WEB_APP='svr/ourjs.js'

#location of node you want to use
NODE_EXE=/root/local/bin/node

while true; do
    {
        $NODE_EXE $WEB_DIR/$WEB_APP config.magazine.js
        echo "Stopped unexpected, restarting 

"
    } 2>> $WEB_DIR/error.log
    sleep 1
done


 

错误日志记录也非常简单,直接将此进程控制台当中的错误输出到error.log文件即可: 2>> $WEB_DIR/error.log  这一行, 2 代表 Error。

产品分析方法之:情绪版在设计中的运用

ui设计分享达人

视觉设计师可能会花很长时间产出了精致的,高品质的设计,得到的却是用户或客户的一句话:“这不是我想要的!”

视觉设计师可能会花很长时间产出了精致的,高品质的设计,得到的却是用户或客户的一句话:“这不是我想要的!”一般来说,在没有实物前,人们并不清楚自己要的是什么。但是在看到成品后,他们可以轻易地判断是否符合自己的喜好或期望。因此,在为错误的设计方向投入过多前,了解用户对风格的期望和需求,从而确定整个网站或产品的视觉风格是有必要的。  而情绪版可以很好的解决以上问题。




什么是情绪版?

情绪版是一种启发式和探索性的方法,可以对如下问题进行研究:图像风格(photography style)、色彩(color palettes)、文字排版(typography)、图案(pattern)以及整体外观以及感觉。视觉设计和人的情绪紧密相连,不同的设计总是会引发不同的情感。




情绪版分为:拼贴式情绪版、参考式情绪版和模版式情绪版



拼贴式情绪版

直接将可以运用到项目中的图片素材拼合在一起。下图是NIKE MECURIAL系列的一个拼贴式情绪版,里面的图片都是来自官方的海报、图片和影像,这些素材都能够直接运用到我们的设计中。


参考式情绪版

将与设计主题风格相关或功能类似的真实项目拼接在一起。下图是一个以多彩和现代视觉风格的情绪版,里面选取的素材都是真实项目的界面。


模版式情绪版

灵感图片素材和概念控件的结合。概念控件是指概念设计中的一些核心组件,它可以是色彩搭配、按钮、卡片、图形或者是信息排版等,它们是概念设计的雏形。


情绪版作为可视化的沟通工具,可以快速地向他人传达设计师想要表达的整体感觉。


设计师要帮助用户发掘其真正需求,情绪版作为一个工具可以很好的帮助了解用户所希望展现的调性,从而提高生产效率和满意度。


对于设计师:是定义视觉风格和指导设计方向的依据;对团队:在团队之间传递设计灵感与设计思路,从而使想法充分融合,深化设计。


1.情绪版可以让客户参与我们的设计流程中,提高我们的工作效率。客户的加入,能够让我们更好的了解业务本身以及客户对项目的期待。尽早的让客户参与整个设计流程,还能够避免在错误的设计方向上投入过多。

2.情绪版是设计与客户沟通的可视化沟通工具,可以减少设计师和客户之间由于认知不同导致的沟通障碍。



情绪版的推导过程







在制作情绪版过程中,原生关键词的作用相当重要:

获得原生关键词是情绪版的第一项工作,一般从内部涉众(相关的产品和设计人员)及外部用户两种渠道获得。

自涉众访谈和用户研究中,可以收集大量的体验词样本。在获得这些样本后,可以内部进行讨论,通过归纳整理精简为几个关键词。

原生关键词提取好之后,可以在内部使用情绪版,也可以招募用户来完成。





01.明确原生关键词


访谈及用研结果导入产生原生体验关键词

原生关键词(Primary keywords)的产生是一个糅合的过程,它需要综合企业文化、用户研究成果、品牌/营销策略,行业特征、目标用户群、产品的价值定位等因素来界定,通常,这也会是一个商业决定。

涉及的访谈受众可以是产品、运营、交互、视觉、用户等,根据产品是0—1还是改版现有版本设置不同问题,以改版为案例,产品使用的感受、期望产品更新的样子等。以此得出的关键词,一般是很抽象的词汇。例如:亲切、熟悉、温度,一般一个产品的关键词不易过多3~5个为佳。




项目案例(示例)

某手机银行是以服务客户日常金融业务办理及投资理财需求为主的综合金融服务APP。面向30-40岁为主要年龄段的中青年用户群体。目前产品处于成长期向成熟期过渡。








02.挖掘衍生关键词


如果仅通过单纯对原生关键词的搜索,很容易导致不同参与者提供图片素材出现同质化的问题。所以,首先头脑风暴画出关键词的思维导图。一方面,合理地引导调研对象发散思路;另一方面,也在过程中深挖原生关键词在他们心中的定义。


衍生关键词(Derived keywords)是原生关键词的发散和提炼,主要通过部门内部头脑风暴或用户访谈得出。


将所有“衍生关键词”按照三个维度去分类整理。这个过程的目的是帮助项目组成员从用户的角度去理解“抽象关键词”的“具象诠释”。所有的关键词可按照以下三个维度分类:


访谈对象会根据主观印象以及过往亲身经历给出一些看法或答案,而很多时候并不可以把访谈对象的答案直接作为关键词,我们需要了解为什么,直到觉得用户的答疑非常清晰具体,然后提炼关键词。


例如衍生关键词访谈:

自由发散问题—看到“品质”你想到了什么?

引导发散问题—如果“品质”是一种颜色,你觉得是什么?为什么?

如果“品质”是一种食物,你觉得是什么?为什么?

如果“品质”是……



衍生关键词的分析—分维诠释

根据原生关键词的的定义,从视觉映射、心境映射、物化映射三个维度去理解“抽象关键词”的“具象诠释”。





03.搜集图片素材


根据“原生关键词”及发散的“衍生关键词”搜集素材,对应视觉映射、心理映射、物化映射三大维度。在素材搜集时具体以「具象」和「抽象」两个方向搜集。

1.搜集图片

根据已有关键词,搜集具象图片(具体的实物场景)—风格感受;根据已有的关键词,搜集抽象图片(包含色彩、质感、图形等元素)—设计元素。


2.素材整理

将收集到的图片素材,按照衍生关键词进行分类并提取生成情绪版。


3.邀请用户参与情绪版创建



1.主持人需要不断询问被访者,去探究选择图片背后的原因:“为什么你会选择这张图片?能否和大家分享一下你的想法?”

2.注意差异的挖掘。注意挖掘被访者之间的观点差异,一百个人心中有一百个哈雷姆特,同一张图片对于不同被访者可能会有不同的解释,如果好几位被访者同时选择一张图片代表他们各自对某个品牌的感觉,注意询问他们选择这张图片的原因是否一样。

3.可以呈现给用户的图片有限的,因此,在挑选图片时,需要内部研究和设计人员协同,根据视觉设计所需要考虑的几个维度结合已有的关键词进行图片的筛选。一般来说,在将图片呈现给用户之前,内部人员已经明确了每一张图片所代表的意义,在用户选择和访谈结束后,两方面的数据综合分析才能获得最终的结果。





04.创建生成情绪版


归纳和整理图片,进行排版组成情绪版,得到设计主题相关的内容。建立几个统一风格的情绪版,以便更好的捕捉产品相关的感觉,为探索设计方向提供灵感。 




05.确定视觉设计策略


综合情绪版制定风格

提取图片主要颜色,明确主色。结合衍生关键词分析结果,将情绪版中高频物化纹理和材质提取出来。



1.色彩提取

通过对色彩的分析发现,高明度低饱和度的色彩搭配,能让画面保持丰富的同时显得干净和协调,可以达到「」「简洁」的效果,例如:邻近色、类似色、低饱和度对比色。


电子化情绪版对“色彩分析”是比较方便的

1.图片在PS中进行高斯模糊或马赛克处理,使用颜色滴管提取大色块;2.图片导入PS中,选择存储为Web所用格式-选择Gif仿色。当然,现在已经有很多用户配色方案提取的网站和软件,这样更事半功倍。


通过对情绪版中颜色提取并结合品牌色及对当下流行趋势的把握,确定如下颜色运用:




2.图形提取

通过对图形分析发现,基本几何形具有肯定、纯粹的特点,可以很好的体现「品质」与「精简」的特征。例如:方形、圆形等。


融入图形符号 强化视觉语言

图标使用深色+渐变色的展现,对比突出、品牌属性统一、信息层级分明。简约笔挺的线性图标更符合平台信息架构清晰,内容易懂的特征。



图标设计




3.字体提取

通过对字体的研究发现,中文字体端庄匀称、字体方正。例如:思源宋体、方正宋体等,英文字体线条简洁、字形严谨。例如:Helvetica、Avenir、DIN等,都比较符合「品质」和「简洁」的特征。

笔画有粗细变化,而且一般是横细竖粗,末端有装饰部分,给人正式、正规感觉,既可以区分标题与模块内容的差别,也可以增加产品的差异化。





4.构成提取

通过对构成的研究发现,并置型和九宫格型构成比较严谨和秩序,满版型和通栏型构成,视觉传达直观而强烈,给人大方、舒展的感受;这与「」的特征是匹配的。






5.质感提取

在质感的选择方面,大多与当下流行风格趋势相贴近,例如:圆角卡片、弥散投影、渐变、轻拟物、毛玻璃等,可以有效地表达出「精简」「品质」的情绪感受。





总结

情绪版是一种设计方法论,可以指导设计方向,传递设计灵感与思路。

制作情绪版时,首先要明确原生关键词、然后头脑风暴挖掘衍生关键词,接着搜集相关图片并提取生成情绪版,另外访谈用户收集衍生关键词映射,最后通过情绪版和关键词映射来提取视觉风格。

在项目前期,我们可以通过情绪板来定义产品整体的设计风格和产品主色调,设计过程中,界面排版、图标的颜色、形状和设计细节都可以使用情绪板来定义。

无论我们做什么样的设计,情绪板都无疑是一个很好的工具,它不仅可以帮助我们明确设计需求,做出更容易被大众所接受的设计,也可以帮助我们更好地去与领导和其他需求方沟通,向他们传达设计的价值主张,最终达成共识,提高设计效率。


再总结一下情绪板的作用:

首先:它是整个设计项目的宝贵资源;

其次:它是低成本的设计工具;

再次:它是有效沟通的保障;

最后:它是团队协作的方法。


转自:站酷-体验为王UX

JSP的刨根问底

前端达人

JSP的刨根问底

  • 一.概念
  • 二.原理
  • 三.脚本
  • 四.内置对象
  • 五.注释
  • 六.编译指令
  • 七.动作指令


  • 点击查看原图


    这篇文章从一个初学者的角度,复习一波JSP。






    一.概念
    Java Server Pages: java服务器端页面

    可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
    用于简化书写!!!
    二.原理
    本质是一个Servlet

    三.脚本
    定义:Jsp定义java代码的方式

    <% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
    <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
    <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
    四.内置对象
    对象名 实现接口或继承类 作用
    PageContext 当前页面共享数据,还可以获取其他八个内置对象
    request HttpServletRequest 一次请求访问的多个资源(转发)
    session HttpSession 一次会话的多个请求间
    application ServletContext 所有用户间共享数据
    response HttpServletResponse 响应对象
    page Object 当前页面(Servlet)的对象 this
    out JspWriter 输出对象,数据输出到页面上
    config ServletConfig Servlet的配置对象
    expection Throwable 异常对象
    五.注释
    1.html注释
    <!-- -->:只能注释html代码片段
    2.jsp注释
    <%-- --%>:可以注释所有

    六.编译指令
    作用
    用于配置JSP页面,导入资源文件

    格式
    <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
    分类
    1.page
    配置JSP页面的
    1. contentType:等同于response.setContentType()
    *设置响应体的mime类型以及字符集
    * 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
    2.import:导包
    3. errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
    4.isErrorPage:标识当前也是是否是错误页面。
    * true:是,可以使用内置对象exception
    * false:否。默认值。不可以使用内置对象exception
    2.include
    页面包含的。导入页面的资源文件

     <%@include file="top.jsp"%>
    3.导入资源
    导入资源

     <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      prefix:前缀,自定义的
    1
    七.动作指令
    作用
    动作指令与编译指令不间,编译指令是通知 Servlet 引擎的处理消息,而动作指令只是运行时的脚本动作。编译指令在将JSP 编译成 Servlet 时起作用:处理指令通常可替换成 Java脚本,是 JSP脚本的标准化写法。

    分类
    指令 作用
    jsp:forward 执行页面转向,将请求的处理转发到下一个页面。
    jsp:param 用于传递参数,必须与其他支持参数曲标签一起使用。
    jsp:include 用于动态引入一个 JSP 页面。
    jsp:plugin 用于下载 JavaBean 或 Applet 到客户端执行。
    jsp:useBean 使用 JavaBean。
    jsp:setProperty 修改 JavaBean 实例的属性值。
    jsp:getProperty 获取 JavaBean 实例的属性值。
    具体细节:
    jsp:forward:
    动作把请求转到另外的页面。可以转发静态的HTML页面,也可以转发动态的JSP页面,或者转发到容器中的servlet jsp:forward标记只有一个属性page。 page属性包含的是一个相对URL。 page的值既可以直接给出,也可以在请求的时候动态计算。

    jsp:param
    用于设定参数值,这个指令不能单独使用 可以与以下三个指令结合使用:
    jsp:include :用于将参数值出入被导入页面
    jsp:forword : 用于将参数值传入被转向页面
    jsp:plugin : 用于将参数值传入页面中javaBean的实例

    jsp:include
    (拿目标页面插入原有页面)该动作是一个动态的include指令,也用于带入某个页面,他不会导入被include页面的编译指令,仅仅导入页面的body内容插入到本页面
    该动作把指定文件插入正在生成的页面。其语法如下:   flush:用于指定输出缓存是否转移到被导入的文件中, true:包含在被导入的文件中 false:包含在源文件中
    前面已经介绍过include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。j
    sp:include动作的文件引入时间决定了它的效率要稍微差一点,而且被引用文件不能包含某些JSP代码(例如不能设置HTTP头),但它的灵活性却要好得多。
    jsp:plugin

    用于下载服务器端的javaBean或applet到客户端)
    jsp:plugin动作用来根据浏览器的类型,插入通过Java插件运行Java Applet所必需的OBJECT或EMBED元素。

    <jsp:plugin  
      type="bean | applet"   : 被执行的java程序的类型
      code="classFileName" :被执行的文件名,必须以  .class 结尾
      codebase="classFileDirectoryName"   :被执行文件的所在目录
      [ name="instanceName" ] :给程序起一个名字用来标识该程序
      [ archive="URIToArchive, ..." ] :指向一些要预先载入的将要使用到的类
      [ align="bottom | top | middle | left | right" ] :
      [ height="displayPixels" ]
      [ width="displayPixels" ]
      [ hspace="leftRightPixels" ] 
      [ vspace="topBottomPixels" ]
      [ jreversion="JREVersionNumber | 1.1" ]   :能正确运行改程序必须的JRE的版本
      [ nsplug inurl="URLToPlugin" ]  
      [ iepluginurl="URLToPlugin" ] >
      [ <jsp:params>
      [ <jsp:param name="parameterName" value="{parameterValue | <%= expression %>}" /> ]+
      </jsp:params> ]
      [ <jsp:fallback> text message for user </jsp:fallback> ]  :当不能正确显示该Applet时,显示该指令中的文本提示
     <jsp:plugin>
    



    jsp:useBean
    useBean:用于在jsp页面中初始化一个java实例(如果多个jsp中需要重复使用某段代码,可以把这段代码定义成java类在页面中引用)
    jsp:useBean动作用来装载一个将在JSP页面中使用的JavaBean。这个功能非常有用,因为它使得我们既可以发挥Java组件重用的优势,同时也避免了损失JSP区别于Servlet的方便性。
    jsp:useBean动作最简单的语法为:<jsp:useBean id=“JavaBean的名称” class=“package.class"包名.类名” scope=“有效范围”/>

    这行代码的含义是:“创建一个由class属性指定的类的实例,然后把它绑定到其名字由id属性给出的变量上”。不过,就象我们接下来会看到的,定义一个scope属性可以让Bean关联到更多的页面,它可接受四个值:request、session、page、application。此时,jsp:useBean动作只有在不存在同样id和scope的Bean时才创建新的对象实例,同时,获得现有Bean的引用就变得很有必要。
    获得Bean实例之后,要修改Bean的属性既可以通过jsp:setProperty动作进行,也可以在Scriptlet中利用id属性所命名的对象变量,通过调用该对象的方法显式地修改其属性。这使我们想起,当我们说“某个Bean有一个类型为X的属性foo”时,就意味着“这个类有一个返回值类型为X的getFoo方法,还有一个setFoo方法以X类型的值为参数”。  有关jsp:setProperty动作的详细情况在后面讨论。但现在必须了解的是,我们既可以通过jsp:setProperty动作的value属性直接提供一个值,也可以通过param属性声明Bean的属性值来自指定的请求参数,还可以列出Bean属性表明它的值应该来自请求参数中的同名变量。
    在JSP表达式或Scriptlet中读取Bean属性通过调用相应的getXXX方法实现,或者更一般地,使用jsp:getProperty动作。
    注意,包含Bean的类文件应该放到服务器正式存放Java类的目录下,而不是保留给修改后能够自动装载的类的目录。例如,对于Java Web
    Server来说,Bean和所有Bean用到的类都应该放入classes目录,或者封装进jar文件后放入lib目录,但不应该放到servlets下。
    id:javaBean的实例名 class: javaBean的实现类 scope:指定javaBean实例的生存范围
    page:javaBean仅在该页面有效 request:javaBean在本次请求中有效 session:
    javaBean在本次session内有效 application:
    javaBean在本应用内一直有效  下面是一个很简单的例子,它的功能是装载一个Bean,然后设置/读取它的message属性。
    关于jsp:useBean的进一步说明   使用Bean最简单的方法是先用下面的代码装载Bean:   <jsp:useBean id=“name” class=“package.class” />
    然后通过jsp:setProperty和jsp:getProperty修改和提取Bean的属性。 不过有两点必须注意。   第一,我们还可以用下面这种格式实例化Bean: <jsp:useBean …>   Body   </jsp:useBean>
    它的意思是,只有当第一次实例化Bean时才执行Body部分,如果是利用现有的Bean实例则不执行Body部分。正如下面将要介绍的,jsp:useBean并非总是意味着创建一个新的Bean实例。
    第二,除了id和class外,jsp:useBean还有其他三个属性,即:scope、type、beanName。
    id:命名引用该Bean的变量。如果能够找到id和scope相同的Bean实例,jsp:useBean动作将使用已有的Bean实例而不是创建新的实例。
    class:指定Bean的完整包名。
    scope:指定Bean在哪种上下文内可用,可以取下面的四个值之一:page、request、session和application。  默认值是page,表示该Bean只在当前页面内可用(保存在当前页面的PageContext内)。
    request表示该Bean在当前的客户请求内有效(保存在ServletRequest对象内)。
    session表示该Bean对当前HttpSession内的所有页面都有效。
    最后,如果取值application,则表示该Bean对所有具有相同ServletContext的页面都有效。
    scope之所以很重要,是因为jsp:useBean只有在不存在具有相同id和scope的对象时才会实例化新的对象;
    如果已有id和scope都相同的对象则直接使用已有的对象,此时jsp:useBean开始标记和结束标记之间的任何内容都将被忽略。
    type:指定引用该对象的变量的类型,它必须是Bean类的名字、超类名字、该类所实现的接口名字之一。请记住变量的名字是由id属性指定的。
    beanName:指定Bean的名字。如果提供了type属性和beanName属性,允许省略class属性。

    jsp:setProperty
    jsp:setProperty用来设置已经实例化的Bean对象的属性,有两种用法。
    首先,你可以在jsp:useBean元素的外面(后面)使用jsp:setProperty,    …

    第二种用法是把jsp:setProperty放入jsp:useBean元素的内部, …

    jsp:setProperty动作有下面四个属性:name:表示要设置属性的是哪个Bean。  property:表示要设置哪个属性。有一个特殊用法:如果property的值是"",表示所有名字和Bean属性名字匹配的请求参数都将被传递给相应的属性set方法。  value:value属性是可选的。该属性用来指定Bean属性的值。字符串数据会在目标类中通过标准的valueOf方法自动转换成数字、boolean、Boolean、byte、Byte、char、Character。例如,boolean和Boolean类型的属性值(比如“true”)通过Boolean.valueOf转换,int和Integer类型的属性值(比如"42")通过Integer.valueOf转换。  value和param不能同时使用,但可以使用其中任意一个。  Param:param是可选的。它指定用哪个请求参数作为Bean属性的值。如果当前请求没有参数,则什么事情也不做,系统不会把null传递给Bean属性的set方法。因此,你可以让Bean自己提供默认属性值,只有当请求参数明确指定了新值时才修改默认属性值。  例如,下面的代码片断表示:如果存在numItems请求参数的话,把numberOfItems属性的值设置为请求参数numItems的值;否则什么也不做。    如果同时省略value和param,其效果相当于提供一个param且其值等于property的值。进一步利用这种借助请求参数和属性名字相同进行自动赋值的思想,你还可以在property(Bean属性的名字)中指定“”,然后省略value和param。此时,服务器会查看所有的Bean属性和请求参数,如果两者名字相同则自动赋值。  下面是一个利用JavaBean计算素数的例子。如果请求中有一个numDigits参数,则该值被传递给Bean的numDigits属性;numPrimes也类似。  JspPrimes.jsp

    20200321215032100.jpg
    jsp:getProperty
    jsp:getProperty动作提取指定Bean属性的值,转换成字符串,然后输出。
    jsp:getProperty有两个必需的属性,即:name,表示Bean的名字;property,表示要提取哪个属性的值。

    END!!!有什么意见可以提出来!
    长路漫漫,JAVA为伴!!!
    ————————————————
    版权声明:本文为CSDN博主「福尔摩东」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_43688587/article/details/105017469

label和span标签设置宽度width无效的解决办法

前端达人

如何用CSS使label标签等宽?

<div><label>密码</label><input type="password" /></div>
<div><label>确认密码</label><input type="password" /></div>
如何对齐呢?加空格的方法不好哦。(因为label中的字数不一样,所以页面显示效果不对齐)
问题原因及解决办法:

label默认为内联元素,元素前后没有换行符,并且不可以设置宽度。

如果要为label设置宽度,则需要改变label的display属性,使其变为一个块级元素。

方法如下:

1.增加inline-block属性值,将label标签变为行内块元素(css2.1新增)

     {display:inline-block;}

2.增加width属性,如将宽度设置为100px
    label{width:100px;display:inline-block;}

3.添加好后页面上所有的label标签会变为100pxv



JavaScript中的混淆器

随着 AJAX 和富界面技术的发展,Javascript 在 Web 应用上的重要性越来越高,Javascript 代码的复杂性、功能和技术含量也越来越高,对Javascript 代码保护的需要也越来越迫切。



压缩 compress: 去掉空格,换行,注释等,格式紧凑,节约存储空间。



混淆 obfuscate/garble:替换变量名或方法名,让js不容易看懂。也做到了压缩的效果。



加密 encrypt:一般用eval方法加密,效果与混淆相似。也做到了压缩的效果。



我们可以通过工具进行混淆,通过工具也是目前最好的方式。推荐一个很好的混淆工具: JSObfuscator By Unest


20200321102359879.png


————————————————

版权声明:本文为CSDN博主「刘亦枫」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/liuyifeng0000/article/details/105004732




科学的 UI 配色方法

资深UI设计者

各行各业的设计师每天都在和颜色打交道,UI 设计师设计用户界面也不例外。

用户界面是一个设计师用理性思维解决用户感性需求的窗口。如果对色彩的运用不加以克制,界面可能会显得花哨而没有主次;但过于拘谨又容易使界面保守,难以激发用户情绪。所以如何让色彩的搭配平衡,是 UI 设计师需要修炼的一课。

但色彩毕竟是感性的元素,我们总是仰慕一些对色彩天赋异禀的设计师,总能不拘绳墨给作品带来惊艳的视觉效果。我们难以偷习他们的天赋,但或许你有没有想过,干脆我们另辟蹊径,用理性推导来制定一套色彩系统?

那么今天我用我的项目示例,教给大家一个科学推导颜色搭配的方法。也许能够带你发现一些色彩背后的数学秘密。

区分颜色模式

在此之前我们需要先熟悉一下颜色模式。

在 PS 菜单栏的「图像-模式」下可以看到非常多的颜色模式:RGB、CMYK、Lab 等等。那是因为 PS 是一个需要满足设计行业水平领域的软件,要解决各类设计师需求,所以涵盖的颜色模式非常丰富。

但 UI 大多数时候需要关注的是线上场景,成果的展示渠道一般是自发光设备。所以弄明白垂直领域软件 Sketch 中的几种颜色模式,其实就足够了,分别是 RGB、HSB 和 HSL。

RGB 是指通过 R(Red:红)、G(Green:绿)、B(Blue:蓝)三个颜色通道的变化以及它们相互之间的叠加得到各式各样的颜色。三个通道分别有「0-255」这 256 个值,这些值分别代表着各通道的亮度层级。

虽然 RGB 在机器表现上很友好,但并不够人性化。因为人们判断颜色,往往是通过「这是什么颜色?是不是太鲜艳了?亮了还是暗了?」这样的感官维度,而很难通过红绿蓝的亮度层级去判断。所以人们后来基于 RGB 衍生出了 HSB 模式和 HSL 模式。

HSB 是指通过 H(Hue:色相)、S(Saturation:饱和度)、B(Brightness:明度)来控制颜色。Hue(色相)的取值范围是色环上 0-360° 的圆心角度;而 Saturation(饱和度)与 Brightness(明度)是在 0-100% 的量占比。

HSL 中的 H、S 与 HSB 相同,都是指 Hue(色相)、Saturation(饱和度)。但 L 所指的则是 Lightness(亮度)。

HSL 和 HSB 稍微有一些不同,我们在两个颜色模式下输入相同的数值,会发现颜色实际是不一样的。虽然 H、S 指代的都是色相和饱和度,但 L(Lightness:亮度)与 B(Brightness:明度)分别被认为是「颜色中白色的量」和「颜色中光线的量」。

Lightness 和 Brightness 的概念要深度研究下去的话其实是计算机算法领域的问题了,感兴趣的朋友可以查阅更多资料,但我个人认为对于 UI 来说没有太大必要。

关于 HSB、HSL 的使用场景,记住以下两点即可:

  • 前端 CSS 代码里支持的是 HSL,而不是 HSB。如果和前端对接时,UI 给到的是 HSB 的色值,那么最终落地的颜色效果会与设计稿有出入。
  • 我们接下来讲到的配色推导,是基于 HSB 颜色模式的,因为它更容易理解,数值变化在色系坐标中的产生的结果更加直观。

配色推导

支付宝 Alipay Design 团队提出过一个配色原则:

以同色系配色为主导,多色搭配为辅。

同色系为统一的色相,使用中可以加深品牌色的感知,可以让界面更有层次,同时可以让界面保持色彩上的一致性;由于业务的多样化,我们需要多色搭配为辅;多色的辅助颜色,也可称之为功能色,可设定不同的任务属性和情感表达;再搭配中性色黑白灰,赋予更多的变化和层次。两种配色通过主次、使用比例,可灵活运用在业务的各个场景中,具有非常好的延展性。

那么知道了这个原则,我们又该如何科学、合理地得出产品的色彩系统呢?接下来我就用我的一个项目示例给大家做讲解。

步骤一:找到符合产品调性的品牌色

我负责的该项目主要业务与高校支付、缴费相关,所以希望整个产品视觉风格首先要给用户带来安全感。又因为主要用户群体是高校师生居多,新潮、年轻化是主要用户的一大标签,所以我们选择了用饱和度较高的蓝色来作为品牌色。

最终选择品牌色的 Hex 值为 #1585FF ,HSB = (211,92,100)。

步骤二:提取24色

选定了品牌色之后,以品牌色的 H(色相)为基础,不断地递增、递减 15,在 0-360 之间可以得出 24 个颜色,也就是将 360° 色环分割为 24 份,可以得到 24 色。

为什么要提取 24 色,并且以 15 为公差呢?

我们知道,想得到邻近色、类似色、互补色这一系列的颜色,我们就会使用到色环。

  • 邻近色:色相差值 15° 以内的颜色为邻近色;
  • 类似色:色相差值 30° 以内的颜色为类似色;
  • 互补色:色相差值 180° 的颜色为互补色。

而 24 色色板是帮助我们提取辅助色的便捷工具。

步骤三:找到同色系配色

同色系是指与品牌色 H(色相)一致,通过改变 S(饱和度)与 B(明度)变化产生的色组。同色系色组的推导需要借助拾色板坐标。

我们建立一个基于 S(饱和度)与 B(明度)的平面坐标系,设定当前品牌色为色值为(S₀,B₀),连接品牌色色值点与右上纯白点(0,100)、右下纯黑点(100,0),得到两条线段。

我们各在两条线段上均分取得 5 个点坐标(包含首位两点)。这样两条线段一共就会产生 11 个(S,B)坐标值,对应着 11 个同色系色组。

经过上图的计算,我们可以得到基于品牌色的同色系色阶。

步骤四:多色搭配

用于搭配的辅助色应满足以下两个条件:

  • 和品牌色有明显区分:尽量避免所选辅助色感官上给用户视觉区别与品牌色差距不大,传递的调性太过一致;
  • 不能过于突兀:根据色彩原理来说,互补色是最能与品牌色本色产生视觉感官对比的颜色,但可能会有些突兀。为了让颜色的辅助起到丰富画面的作用,而不是反而让整个版面显得不和谐,所以我们选择互补色的邻近色作为辅助色,而不要直接使用互补色。

于是根据以上条件,基于品牌色可衍生出 3 个辅助色:一个与品牌色传递调性有明显区分的类似色;两个互补色的邻近色。

步骤五:感官明度校准

经过计算后,我们已经得出了品牌色和三个辅助色。

可以看出,虽然我们提取出的辅助色明度色值都一致,但因为颜色本身自带的感官明度属性有所区别。为了让辅助色和品牌色的感官明度尽量一致,我们要对第一次提取出的辅助色进行感官明度校准。

校准方式是:依次在辅助色上叠加一层纯黑图层,将该纯黑图层颜色模式调整为 Hue(色相),就可以通过无彩色系下的明度色值,进行对比。

这样我们终于得到以品牌色为基准的 3 个辅助色了。

步骤六:全色系输出

将得到的辅助色依次进行步骤三的计算,可以得到辅助色的同色系色阶。

但因为明度过低时,颜色已经非常接近于黑色,色相在肉眼上几乎已经趋于一致。所以删除最左边的三种同色系颜色。最后得到基于品牌色推导出的全色系色阶色板。

总结

完成了以上的工作,当然还不算结束。一套标准的色彩系统还会包含中性色规范、颜色的使用规范等等。但相信解决了大部分的需求,剩下的工作也难不倒大家了。毕竟以上的方式只是给大家提供了一个理性科学的方法,色彩的使用最终还是要融合设计师个人的共情能力。

比如许多产品有了一套自己的色彩方案后,设计师还会根据具体的业务场景去赋予 icon、卡片背景等元素不一样的色彩方案。

希望这个方法能够带你发现一些色彩背后的数学秘密。

文章来源:优设    作者:UCD耍家

大厂设计师的草稿本里画的都是什么?!

资深UI设计者

很多同学投票想看看设计师的草稿本,今天就来满足大家了!我们来看看六位淘宝设计师的草稿本们,有些是纸质派,有些是电子党,Here we go!

草稿本是设计师工作生活必不可少的工具,比起正儿八经的作品集,设计师的草稿本其实也是十分有趣的,它是设计师脑海里千奇百怪想法的随手记录。

Shiyu:本人是被胁迫公开草稿本的卑微设计师

手绘装备:iPad Pro+Procreate

以下是被迫营业现场对话

△ 给「老同学」的公众号形象草稿

老同学:「好久不见~我记得你画画挺好的~帮画个形象呗~我现在在做一个公众号,需要*&%¥#……你明白吧?你就简单画一画就好~谢谢啦」

我:「….」

△ 给「朋友」画的头像草稿

朋友:「好久不见~我记得你之前帮谁谁画的那个头像挺不错的~也帮我画一个呗~我现在在做blablabla,需要*&%¥#……你明白吧?很简单吧~谢谢啦」

我:「….」

Dajing:我的草稿本就是平时画画原型图或者需要做文档整理规范的时候拿出来画画草图,对我来说我的草稿本是帮我理清思路的一个很好的助手。

手绘装备:A4点格草稿本+马克笔

 △ 智能配色草稿

△ 中后台加框草稿

Dajing:里面有当时做中后台框架的时候导航的原型,还有之前做智能配色的时候HSB色环推演的草图,还有些文档维度整理草图,画出来方便查看也便于直观梳理自己的逻辑。

Wanru:画画是我记录生活、寻找灵感的一种方式。

手绘装备:MUJI笔记本、水彩、铅笔、马克笔等等…

△ 冲绳旅行水彩

Wanru:水彩是我最喜欢的绘画形式,非常浪漫,食物也是我擅长画的题材。这是在冲绳旅行时的第一顿晚餐,新鲜的海鲜和爽口的啤酒也具有明亮的颜色,让人忍不住想去表达。烧肉店的杯垫被我带了回来,日本的平面设计做得很好,是很好的素材~

△ 电影小漫画

用小漫画记日记的习惯已经很多年了,我是非常喜欢漫威的,这是13年《钢铁侠3》上映和两个朋友看电影的场景。这个场景必须用美漫的风格了!偶尔会尝试各种画画风格。

△ 随手小速写

偶尔会画些小速写,勾一些人物、小物品、小动物,速写可以很好地练习造型能力。

Zoey:作为一个热爱喝奶茶、追番和打手游的肥胖又无助的设计师,感觉累了就在草稿本上放空自己。

手绘装备:iPad Pro+Procreate & Sketches Pro

△ 记录日常生活的草稿

Zoey:我很喜欢用草稿本记录自己的生活(食物为主),喜欢的电影角色也会简单画下来。

△ 二次元小画

作为半个二次元 ,草稿本当然也被满屏的羞耻占领~ 这两张草稿是我画的Persona 5里面的人物,因为我个人真的特别喜欢P5 ,对于自己喜欢的事情即便996也会熬夜画下去~

Dribbble 十年重磅改版背后,值得关注的7大亮点

资深UI设计者

Dribbble 经历了资本入驻、创始人出走之后,最大的事情应该就是这次改版吧?这个全球最大、最有影响力的设计师社区的每一个动作都必然会牵扯着每个设计从业者的注意力,新版背后到底有哪些变化?这些变化又是出于什么样的想法来修改的?看看 Dribbble 的官博是怎么说的吧:

在过去的10年当中,Dribbble 已经成长成为一个全球性的社区,成千上万的人从这里获得启发和灵感,助力设计,而我们从最初分享设计作品小样的创意社区,逐步成长为一个全球设计师产品和作品集展示和社交的平台。在此,而我们也第一次开始问自己一个简单的问题:【我们到底是在做些什么?】

今天,我们很高兴宣布,我们在过去的10年当中首次进行了彻底的重设计。

Dribbble 的新时代

在过去十年当中,我们所设计的 Dribbble 页面的特点,是将设计师的作品和内容放在首位,所以叫我们不追随潮流,采用了极简风格的设计,即使潮流来来去去,它们也只是 Dribbble 展示内容的一部分。我们提供了一幅未经修饰的画布,这样就可以和最疯狂最激进的设计探索相辅相成。不过,这么多年来,Dribbble 这种「隐形」的设计,在视觉美学上确实和时代脱节了。这次,我们创建了一套有着一致样式的设计和代码库,用以替代以往不断修改、庞大且不一致的代码。

「我们新的设计系统旨在保持整个视觉和谐的同时,展示你的创造力。」

如今,我们正在改进 Dribbble 的界面,以更加干净的布局、统一的设计系统、更加简化的配色方案、更加轻便的代码库(加载也更加迅速),以及全新配置的文件,来更好地帮你将作品推到最前沿,正确而合理地展示你的创作和个性。

我们新的设计系统旨在保持整个视觉和谐的同时,展示你的创造力。它是你分享设计作品和创造力的理想画布,而新的美学特质也可以更好地反应此刻我们的公司的气质。

全新的设计师个人页面

在进行重设计的时候,我们明确知道,我们要完全重新思考社交化的设计师作品展示,并且将创意更大化地呈现。对于 Dribbble Pro 用户和 Pro Business 订阅者,你现在拥有一个全新的、经过全面修改的设置和配置页面,可以在 Dribbble 上充分展示自己的个性,

你的页面,你的个性

Pro 用户和 Pro Business 用户可以通过上传你自己的首图和定制化的欢迎语,来个性化你的个页面。

你还会注意到,你的个人页面还可以上传更大的照片,这可以让你的作品对于页面的访客、你的客户、招聘设计师的企业人事而言,看起来都是非常出挑的。新的网格布局是可以自定义的,因此你可以充分完美地设置和展示内容。

此外,我们还修改了「关于我们」这个部分,新版当中,这个部分你可以将所有的个人信息汇集到一起,以便完整而充分地展示你的个人经历、展示简历和技能。

寻求工作机会?

如果你正在寻求工作机会,新的信息发送组件,确保了你的客户或者招聘企业可以一键联系到你,他们可以直接从你的个人资料页向你发送信息,非常轻松地和你取得联系。

面向所有人的新个人页面

当然,并非是只有 Pro 和 Pro Business 用户才能拥有高度定制化的个人页面,无论你是普通用户、内容创作者还是内容策划人,Dribbble 上每个普通用户的个人页面也都会升级。尚未订阅 Pro 服务的设计师会注意到,他们的个人页面会更加简洁,而设计作品会以更加聚焦的形式,吸引到每一个访客的目光。

全新的收藏页

我们将以往的带有分享功能的收藏合集页(之前叫 Buckets)给翻新了,你可以精心策划整页内容和案例,从一个情绪板到完整的项目,这意味着,借助这个收藏页功能,你可以更加轻松地在 Dribbble 上寻找和搜集灵感。

给策划人的个人页面

现在,我们可以非常自豪地宣布,即使你并没有将 Dribbble 作品给分享出来,每个人也都会拥有一个策划人页面,你可以在其中搜集和整理自己喜欢的作品,来展示你的个人品味,通过保存别人的作品,来创建新的合集,我们会自动将它添加到你的个人页资料页当中,让全世界的同好因为品位而关注你。

升级发现页

我们在整个改版设计过程中,面临最大的挑战,其实是图片网格,因为这是绝大多数用户每天浏览图片、发现设计灵感的地方,我们有意识地去弱化 Dribbble 本身 UI,避免喧宾夺主,让每个用户的作品成为视觉焦点,减少噪音。

当然,我们还未完成…

2020 年才刚刚开始,我们迫不及待地想要展示我们计划中的一切。从案例研究到更好的视频支持,再到作品集展示,摆在我们眼前的改版路线图足以证明我们的雄心,所有的这一切都是为了让全球的设计师能够从中获益,走向成功。请期待我们进一步的改版升级吧!

文章来源:优设    作者:Dribbble

2020年最值得设计们保持关注的8个UI设计趋势

资深UI设计者

快速变化的技术每年都在影响着设计趋势。作为设计师,我们需要时刻保持关注,对设计趋势拥有较高的敏感度,不断学习,扩充自己的设计技能,目的是为了跟上的市场环境。基于我的调研,经验和观察,我甄选了在2020年你将会看到的最为关键的8个UI/UX设计趋势。让我们一起来看看吧。

动效插图

插图被应用到APP中已经有很长一段时间了,它们在最近几年的演变令人印象深刻。插图作为一种非常流行的设计元素,为我们产品的整体产品增加了情感化体验。插图非常能抓人眼球,尤其是在融入动效后会显得更加的自然,将产品带入生活的气息,使得产品功能更加突出,同时也增添了更多的细节和个性。

△ Welcome to Swiggy by Saptarshi Prakash

△ Onboarding animations — Virgil Pana

另一个好处是使用动效后,能抓住用户的注意力使其能够更加沉浸在你的产品中。动效同样是讲好品牌故事,产品或者服务最有影响力的途径之一。

微交互

微交互存在与每一个网页或者app界面中。每当打开你最喜欢的那些应用时,都有机会看到它们,比如像Facebook中就有大量不同的微交互,我认为「Like」功能就是一个完美的例子。有时,我们几乎意识不到它的存在,因为它们非常的不显眼,非常自然地融到界面中去了。但是,如果当你把这些微交互移除掉的话,你又会非常快的注意并能感受到一些非常重要的东西丢失了。

△ Menu toggle close animation — Aaron Iker

△ Tab bar active animation — Aaron Iker

一般来说,在UI/UX中即使非常小和细节处的设计都可能会带来巨大的冲击力。微交互就是完美的证明,细节和对它的关注能极大的改善产品的整体体验,并让产品体验上升一个台阶。每年,新设备的发布伴随着新的机会,能给产品塑造新品牌和创造富有创意的微交互。

3D图形

3D图形设计几乎无处不在,比如在电影,游戏或者运营广告里等等。3D图形设计早在10年前就出现了然后一直在不断提升和进化。手机和web技术进展迅猛,新的web浏览器能力打开了3D设计新世界的大门,这给了设计师们在web和手机界面中创造炫酷3D设计的机会。

△ 3D flip menu by Minh Pham

△ Car health report UI by Gleb Kuznetsov

创造并整合这些3D创意设计到web和手机界面中需要特殊的技能和花费大量的工作,但这些付出会得到回报。

△ Apple AirPods Pro landing page

3D设计对于产品和服务来说,具有非常大的吸引力,例如在交互上能够支持用户360度查看产品,从而大大提升整个的产品体验。

在2020年会有更多的品牌利用3D渲染模型的产品和服务去模仿线下购物体验。

VR设计

VR技术在2019年有一个巨大的飞跃。最近的一年我们激动地看到了头戴式设备有了非常大的发展,尤其是在游戏领域。我们需要记住的是,游戏行业经常在引领着新技术的发展并落地到实际的产品设计中。研究表明,VR也不例外,在Oculus Quest于2019年推出后,许多机会为其他行业打开了大门。Facebook CEO 扎克伯格已经测试了激动人心的手部交互功能,并正式宣布将在2020年初为Quest进行更新。

△ Oculus Quest — hand interaction feature

△ PlayStation Virtual Reality Website Design by Kazi Mohammed Erfan

索尼和微软计划在2020年夏季发布他们的新设备,这就给VR技术带来巨大的机会和发展空间。

学习VR 可以阅读优设这个专题:https://www.uisdc.com/zt/vr-design

AR设计

在最近几年,我们能看到在AR(增强现实)这块有了很大的进步和惊喜。世界引领着科技公司在AR开发方面进行了巨大的投入,所以我们应该期待这项技术在2020年有更大的成长和发展。苹果公司也发布了他们自己的AR套件叫AR KIT3来帮助设计师和开发者在他们的产品中打造AR体验。

△ Apple ARKit 3 by Apple

△ Public transit app by Yi Li

△ House of Plants AR Concept by Nathan Riley

在AR空间里会有无限的机会和创意去打造一个新的品牌和激动人心的体验。为AR做UI设计会在2020年成为一大趋势,这就要求设计师们在面对创造AR产品体验前,应该去准备和抓紧学习新的工具,原型之类的知识。

学习AR 可以阅读优设这个专题:https://www.uisdc.com/zt/ar-design

新拟物化设计

一般来说,拟物化设计是指以现实风格/方式创造出来与现实中的物体相匹配的设计元素。不断发展的VR/AR技术以及在各大最流行设计平台(Dribbble,Behance等)上展示的设计作品趋势来看,预示着拟物化的回归,但这次换了个更现代,更酷略微高大上的名字叫「新拟物风」(也叫Neumorphism)。

△ Skeuomorph Mobile Banking | Dark Mode by Alexander Plyuto

△ Simple Music Player by Filip Legierski

△ Sleep Cycle App — Neumorphism Redesign by Devanta Ebison

你可能注意到了:Neumorphism代表了丰富细节和明确的一种设计风格。高光,投影,发光,这些细节非常令人印象深刻。Neumorphism风格已经鼓舞了全世界一大批的设计师创作作品,它也会成为2020年最大的设计趋势。

学习新拟物风可以阅读优设这个专题:https://www.uisdc.com/zt/neumorphism

不对称布局

最近一年我们也注意到一种不对称风格正在快速发展。传统基于「模板」的布局肯定会消失。这种设计趋势给2020年的设计带来了更多的差异化。合适的不对称风格将会在我们的作品中增多一大批不同的性格,火力以及个性,所以设计不再单纯的基于模板。

△ Limnia Fine Jewelry Grid — Zhenya Rynzhuk

△ Carine fashion store — selection screen concept — Dawid Tomczyk

当设计这种不对称风格时,设计师拥有非常多的选项以及巨大的发挥空间。但是,想设计好这种不对称风格需要大量的练习,它绝不是将元素随机的摆放在网格中,而应该小心使用和实现它们,时刻需要把用户的诉求考虑到设计中。我们并不想让用户迷失在我们的产品中,对吗?

用户故事

故事在整个用户体验中扮演着非常重要的角色。你可能经常会在着落页看到它作为品牌介绍,产品或者一个新的服务。讲故事就是利用创意的形式把信息传递给用户。这可以通过强大的视觉元素来呈现(字体,插画,高清图片,颜色,动画,交互元素)。

△ A+WQ / Young Lab Page Story of The Week Animation by Zhenya Rynzhuk

△ Free Sketch Template :: Mimini by Tran Mau Tri Tam

讲故事可以帮助产品创造出品牌和用户之间积极的情感连接。讲故事可以为你的产品创造出非常多的记忆点,让用户感受到自己就是产品或服务的一部分,他们便会更加愿意使用你的产品。话虽如此,讲故事也是一种非常有效的营销手段,它可以极大地提高你的产品/服务的销量。讲故事作为一种非常成功的手段,将在2020年继续发扬光大。

总结在2020年非常值得关注的8个设计趋势

1. 动态插图

通过把动画和插图进行结合,我们可以使得设计变得更加突出,并把它带入用户的日常生活,为产品赋予了的细节和个性化。

2. 微交互

微交互被证明是可以在当用户注意到他们是能够带来非常大的惊喜体验,它能够有效的提升整个产品的用户体验并把产品的品质提升一个等级。

3. 3D图形的应用

新的浏览器技术打开了3D图形应用的大门,能够给设计师带来非常大的创意机会去打造让人惊叹的3D图形设计应用到网页和手机APP中。

4. 虚拟现实

游戏行业将迎来新的变革,新的技术能够应用到产品设计中。

5. 增强现实

在AR空间中拥有无限的机会去创造新的品牌和令人激动的新体验。为AR技术服务的UI设计将在2020年成为主要趋势,设计师需要位为之准备并去学习新的工具,原型,当真的需要你去做一款AR应用时就需要用到。

6. 新拟物风

AR/VR技术不断发展,以及在各大流行设计平台上大量涌现的写实设计作品预示着拟物风的回归,但只是这次换了个新的更加现代化的名字。

7. 不对称布局

运用不对称布局能让设计创意变得拥有更多选项和机会。虽然,设计一个成功的不对称布局需要投入大量的练习和时间。

8. 讲故事

讲故事就是利用创意形式把信息传递给用户。讲故事是一个非常好的营销工具,可能会大大增长产品的销售额或服务。

文章来源:优设    作者:彩云译设计

日历

链接

个人资料

蓝蓝设计的小编 http://www.lanlanwork.com

存档