今天给朋友们带来更改this指向的三种方法,以及它们的区别:
一:call用法
window.color = 'red';
document.color = 'yellow';
var s1 = {color: 'blue'};
function changeColor () {
console.log(this.color);
}
changeColor.call() //不传参数默认指向window
changeColor.call(window) //指向window
changeColor.call(document) //指向document
changeColor.call(this) //构造函数的this如果打括号调用默认指向window
changeColor.call(s1) //指向s1对象
//例二:
var Pet = {
words: '...',
speak: function (say) {
console.log(say + '' + this.words)
}
}
Pet.speak('123') //输出123...
var Dog = {
words: 'WangWangWang'
}
Pet.speak.call(Dog,'123') //输出123WangWangWang
二:apply用法:
window.number = 'one';
document.number = 'two';
var s1 = {number: 'three'};
function changeNum() {
console.log(this.number)
}
changeNum.apply(); //one
changeNum.apply(window); //one
changeNum.apply(document);//two
changeNum.apply(this);//one
changeNum.apply(s1);//three
//例二:
function Pet(words){
this.words = words;
this.speak = function(){
console.log(this.words)
}
}
function Dog(words){
Pet.call(this,words);//结果wang
// Pet.apply(this,arguments);//结果wang
}
var dog = new Dog('wang');
dog.speak(); //wang
apply与call的区别:
接收的参数不同
apply()方法接收俩个参数,一个是函数运行的作用域(this),另一个是参数数组。
call()方法第一个参数和apply()方法的一样,但是传递给函数的参数必须一 一列举出来。
语法:
apply([thisObj [,argArray]]);
调用一个对象的一个方法,另一个对象替换当前对象
call([thisObj [,arg1[,arg2[…,argn]]]]);
说明:
如果thisObj是null或者undefined的时候,默认指向window。
如果argArray不是一个有效数组或不是arguments对象,那么将导致一个TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。
call方法可以用来代替另一个对象的一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。
三:bind的用法:
var obj = {
name: 'WuXiaoDi'
}
function printName() {
console.log(this.name)
}
var wuXiaoDi = printName.bind(obj)
console.log(wuXiaoDi) //function(){...}
wuXiaoDi() //WuXiaoDi
//例二:
function fn(a, b, c) {
console.log(a, b, c);
}
var fn1 = fn.bind(null, 'Dot');
fn('A', 'B', 'C'); //A B C
fn1('A', 'B', 'C'); // Dot A B
fn1('B', 'C'); // Dot B C
fn.call(null, 'Dot'); // Dot undefined undefined
//例三:实现函数珂里化
var add = function(x) {
return function(y) {
return x + y;
};
};
var increment = add(1);
var addTen = add(10);
increment(2) //3
addTen(2) //12
小总结:
Function.prototype.bind(thisArg) - - ES5
能够返回一个新函数,该新函数的主体与原函数主体一致,但当新函数被调用执行时,函数体中的this指向的是thisArg所表示的对象。
Function.prototype.call(this.Arg,val1,val2, …)
调用函数执行,在函数执行时将函数体中的this指向修改为thisArg所表示的对象
val1, val2, … 表示传递给调用函数的实际参数列表
Function.prototype.apply(thisArg, array|arguments)
调用函数执行,在函数执行时将函数体中的this指向修改为thisArg所表示的对象,
array|arguments 表示调用函数的参数列表,使用数组或类数组的格式
区别:
bind与call和apply的区别:
返回值的区别:
bind的返回值是一个函数,而call和apply是立即调用。
参数使用的区别:
bind与call一样是从第二个参数开始将想要传递的参数一 一写入。但call是把第二个及以后的参数作为fn方法的实参传进去,而fn1方法的实参实则是在bind中参数的基础上再往后排。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务。
在我们平时的设计工作中,经常会需要做一些有动感的画面,去体现某些产品所具有的运动属性,比如汽车的速度感、球鞋的运动感等等。可是由于载体或是成本的原因,导致客户没办法投入动态画面的制作,所以就要求我们只能在静态的平面中去创造动感,让原本不会动的画面看上去好像也能动起来,这就是今天要为大家带来的内容。
我们先来看一组照片,这些猫的图片明明都是静态的,可是为什么我们看到这些照片的时候,却能够明显的感觉到猫在跳跃的动感呢,这个主要是因为我们的心理作用。
正如佛教里所讲的,不是风在动,也不是云在动,而是心在动。那些看上去带有动感的图片并不是真的在动,也不是屏幕在动,而是我们的心理作用。
所以我们做设计的时候,就可以很好的利用这一心理作用,去实现一些具有动感的画面。既然要做动感的画面,我们需要先了解,关于运动在物理学中的定义。
物理学中的运动,必须具备两个要素,分别是速度和能量。
那我们就可以总结出两种画面中的动势,第一种就是具备速度和方向的动势,比如画面中这两张图片,我们可以很明显地感觉到,图片中的主体是正在运动的,并且具有很快地速度和明确的运动方向。
第二种就是静止的,但具有强烈能量的动势。比如画面中这两张图片都没有在动,可是我们也能够感觉到它的动感。如果说前一种动势更注重于刻画运动的速度感,那么第二种则更加注重刻画一触即发的能量感。
那么,我们在平面中应该如何去创造动感呢?其实很简单,因为张力在画面中不平衡时,便会产生动感。
所谓张力就是画面中元素向外扩张的心理作用力。
这么解释可能有些抽象,我们可以将张力与万有引力进行类比。万有引力就是,任意两个物体具有通过连线方向上的力相互吸引。而我们可以将张力定义为画面中任意两个元素,通过连线方向上的力相互吸引。也就是说画面中的任意元素都有相互吸引的力。
比如我们在一个画面中的上下左右各放一个圆点,然后在画面的正中间放一个较大的点,中间这个点由于均衡地受到上下左右吸引力的作用,所以它所受到的张力是平衡的。
当我们将中间这个大点往上移动,大点受到的张力平衡就会被打破,产生了要往下坠的动势。
根据万有引力定律公式,物体所受的吸引力和质量是成正比的。
所以我们同样可以类比到张力中来,画面中打破平衡的那个元素的质量和面积越大,所带来的动感就会越强烈。
看完了刚才所讲的这些,相信大家现在心里大概都会想起一句话,就是听过很多道理,依然过不好这一生。的确,听了这么多的理论公式,难免会越听越懵。而且我们在做设计的时候,也不可能去测量画面中每一个元素的大小、间距、方向,也不可能把每一个元素之间的张力进行量化,然后再用公式去计算出动感的大小强弱。那大家肯定还会继续追问了,那么到底该如何去制造动感呢?
这里我总结了三点产生动感的原因,分别是基于生活经验与心理认知、诱导视线移动,以及非平衡状态下产生的视觉冲击。
我们先来看基于生活经验与心理认知,每个人在成长的过程中都会碰到许多人和事,并且对不同的事物会总结出一套规律和认知,也可以说是刻板印象,所以我们就能感觉到一件事物是运动的还是静止的。
比如这两个小人,虽然只是一个轮廓,但是我们却能感觉到左边的人是站立的,静止的,而右边的人正在走路,是运动中的。
这样的例子很多,例如书本是静,车子是动。
树懒是静,猴子是动的。
另外由于人类拥有一种组织倾向,所以当我们看到某一个运动的瞬间时,会自动脑补中出他运动的过程。比如这张静态图片,相信很多人看到时都会脑补出那个视频。
但是这里有一个问题,就是不同的人他的生活经验是不同的,对于事物的认知和理解也就不同,可能对于一部分人来说这是具有动感的,而对另一部分人来说却是静止的。比如刚才那个打篮球的图片,如果是没看过视频的人,当然就脑补不出他的动感了。所以对于这种刻板印象的利用,我们需要根据受众的具体特征具体分析,千万不要盲目使用。
接下来我们来讲讲第二种情况,诱导视线移动。由于运动是相对的,所以我们在看东西的时候,视线移动也可以理解为是物体相对视线发生了移动。
比如我们在看报纸的时候,从左上角往右下角看,在我们眼睛里出现的画面是这样的,从而便产生了好像报纸在动的动感。
最简单移动的案例就是箭头,例如这是一条水平的直线,我们会认为他是静止的,而当我们在一端加上箭头之后,我们的眼睛就会随着箭头所指方向移动,从而产生动感。
这两个都是通过一些指向性的图形进行引导视线移动的作品。
接下来我们来说一下第三种情况,非平衡状态下产生的视觉冲击。
比如在天平的两端各放一只猪,那么这个天平就是处于一个平衡的状态。
当我们在其中一边再加一只猪时,天平就会失去平衡,重量更大的一边会往下倒,直到找到一个新的平衡。
而我们的大脑其实也和天平相似,当我们看到一些不平衡的画面时,我们就会有把它转换为平衡状态的倾向,所以动感的产生,也就是大脑脑补不平衡到平衡的这个运动过程。
我们在半空中放一块石头,由于这块石头受到重力的作用,处于一个不平衡的状态,所以我们认为他有向下掉的趋势,直到与地面接触找到新的平衡状态。
如果我们把石头换成一个气球,那么情况就相反了,由于气球受到重力作用的同时也受到了更大的浮力,所以气球会有往上飘的趋势。
举一个更加能说明的例子,其实我们大多数人或多或少会有一些强迫症,比如看到这种一只铅笔没对齐的画面就会很难受,特别想把它怼回去。
所以我们就会脑补出这只铅笔往左移动的过程,从而产生了动感。
这两个海报都是通过创造一些不平衡的场景带来刺激感,从而产生动感。例如颠倒的房子和悬空的蒸笼。
经过前面的讲解,相信大家应该对动感是如何产生的,有了一定的认识,但是,我们刚刚只是从理论的角度去讲解了动感是如何产生的,运用到实际的设计中可能还是会一头雾水。那接下来的部分就是真正的干货环节了,去给大家讲一些比较实用的制造动感的技巧。
这里总结了 9 个小技巧,我们一个个来看。
我们在前面提到了当我们看到某一个运动瞬间时,我们就会脑补出整个运动过程。那我们就可以反过来,从运动过程中捕捉某一个瞬间,用这一个瞬间来表达平面中的动感。
这里可以分为两种情况,一个是捕捉运动刚开始的瞬间,强调运动刚开始的那种能量感。
这是两个捕捉运动开始瞬间的例子,两名运动员都穿好了装备,虽然还没开始动,但是却能感受到一触即发的紧张感。
第二种就是捕捉运动过程的某一瞬间,这种方式带来的动感会比上一种强烈得多。
例如这两个例子都是捕捉了运动员正在运动中的瞬间。
这种方式所传达的动感强弱是由运动物体的动作姿态所决定的,所以我们需要认真比较每一瞬间的动作,选出最适合的一帧。
第二种技巧是倾斜构图,一般横线和竖线都会给我们一种稳定平衡的感觉,而斜线相对于横线和竖线来说,则会给我们带来强烈的不平衡感。
例如这些图片,无论是迈克尔·杰克逊的经典舞蹈动作,还是比萨斜塔,都给我们带来一种不安定、危险、不平衡的视觉冲击。通过这种不平衡感从而产生动感。
我们观察这些线,会发现 45° 时的斜线相对于横线和竖线的倾斜角度最大,所以 45° 倾斜时不平衡感最强,动感也最强烈。
漫画中的倾斜构图
在漫画作品中经常会将剧情画在倾斜的格子中,目的是为了弥补漫画纸质作品的缺陷,强化漫画内容的动感。
电影中的倾斜镜头
在电影中也会故意用到倾斜的镜头,由于电影本身就是动态的,所以运用倾斜镜头一般是用来强调危机感、动荡不安的漂泊感等等。
摄影中的倾斜镜头
摄影作品中也会用到倾斜视角,这两张都是通过倾斜视角强化速度感的例子。
文字倾斜
那么我们看看倾斜在设计中是如何使用的,首先可以是文字倾斜,这两个海报的人物主体都是竖直的,通过文字倾斜来增加动感。
主体倾斜
这两张海报则是保持文字水平排列,将主体进行倾斜处理从而带出动感。
叠加倾斜色块
我们也可以将文字和主体都水平或者竖直放置,然后添加倾斜的色块强化动感。
画面整体倾斜
这种是将包括主体和文字在内的画面整体进行同一角度倾斜处理。
多角度倾斜
最后这种是难度比较高的,画面中出现了多个角度的倾斜对比,画面十分灵活且动感十足。
接下来看看第三种倾斜技巧,错位。什么是错位呢?就像这辆小车一样,他在运动的过程中,身后会产生的一些虚影错位,使得画面中的一部分被破坏了,视觉需要在脑子里想象补充这一被破坏的部分,使画面还原为原本的样貌,从而产生运动感。
重复
错位这种技巧我们也可以分为几种类型,首先第一种就是重复,通过重复的手法去模拟物体的运动轨迹,让人脑补运动的过程,从而产生动感。
模糊
第二种就是通过将背景或者是主体进行模糊,从而传达动感。第一张图片是通过模糊主体身后的背景去产生动感,而第二张则是通过模糊文字的外轮廓从而产生一种收放的动感。
错开
第三种是错开,就是将画面的某一个部分进行错开处理,让画面遭到破坏,需要人脑去修补这部分的破坏,从而产生运动感。
其他
除了上面三种还有许多别的类型,例如通过车辆行驶溅起的水花,融化往下低落的液体等等,都可以造成对画面的破坏,从而制造动感。
对于集中与发散我们可以分为两种,第一种是这种通过线条绘制的发射或是集中图案,从一个中心向某一方向或四周扩展,或者是四周向一个中心集中的线条图案,盯着看会出现一种光耀感,通过光学效果产生视觉幻想,从而产生视觉动感。
而第二种则是通过物体或图形的疏密节奏变化,从而产生出类似扩散或是集中的效果,这种效果会令我们联想到河流或是烟雾扩散的情形,从而产生了动感。
当扩散的图案配合上透视的效果,会使得动感变得更加的强烈。
背景
对于这种集中发散的图形,我们可以将它作为背景来烘托动感和氛围。
文字
也可以将文字编排成发射状,模拟出那种喷口而出的效果。
主体
或者是将图形作为主体去表达特殊的主题。
以透视作为发散
这两个海报是比较特别的例子,将放射状与透视相结合,体现了很强烈的动感。
接下来讲讲关于螺旋的技巧,因螺旋发展或内收形成的曲线,会让人联想到水的旋涡形,视觉上就形成动感,且螺旋曲线的旋转曲度越大,动感就会越强。
另外,密集的螺旋曲线也能给人带来一种集中或者是发散的效果,从而也能带来一定的动感。
这两张海报是将螺旋曲线作为主体使用,来表达其特定主题。
这张海报个人比较喜欢,非常灵活地将画面中的文字和图片沿着螺旋曲线排布,加上大小的变化,让画面产生了一种集中的动感。
这张海报则是将螺旋线作为背景,并将文字放在螺旋曲线间排列。
第六种技巧是波状曲线的使用。因为曲线的来回反复扭曲,会令人联想起翻滚的海浪。
而且由于曲线本身就具有不平衡的张力,他会有一种向直线转变的趋势,所以波状曲线特别适合用来表达动感。
波状曲线的曲度越大,他所产生的动感就会越强烈。
对于波状曲线,我们可以将其用来作为主体或者是背景进而表达动感。
也可以通过将文字做成这种扭曲的效果,从而产生一种文字在扭动的动态感。
第七种技巧则是对色彩的使用。因为色彩有前进感和后退感,所以我们可以利用这一点来制造动感。其中最容易理解的就是使用色彩的渐变,沿着色彩逐渐变化的方向,来诱导人们的视线移动,从而产生视觉上的动感。
这两个都是利用不同色彩的渐变来引导视线移动,从而产生动感。
我们在前面讲过运动是需要能量的,而象征高温的暖色调比象征低温的冷色调更具备能量感,所以暖色调比冷色调更适合表达动感。
这是一张日本新干线的海报,虽然用的是静止的列车作为主体,可是鲜红的背景却能很好地传达出列车的能量感。如果我们将红色的画面换成蓝色的话,那种能量感瞬间就没了,多了些科技的属性,画面变得冷静克制了。
接下来是重心偏移。一般我们编排版面时都会注意版面重心的均衡,将画面整体的重心放在画面中间。可是在塑造动感画面时,我们却可以将画面的重心偏离视觉中心,使画面形成一种不平衡感,从而产生动感。
我们来看看这两个海报,都是通过将画面的重心全都放在画面的一侧,从而产生了一种很强烈的不平衡感。
另外,由于视觉重力的原因,当画面重心偏上时,能很好地塑造出往下坠的动感。现在画面中的这两个作品都是将重心放在了画面的上方,我们能感受到画面中的主体会有一种往下掉的趋势。
最后一种是蒙太奇的手法。前面我们说过人类天生具有一种组织倾向,当我们看到运动的瞬间状态时,我们便能脑补出运动的过程。所以通过蒙太奇的手法,将一些不同时刻或状态的图片放在一起,便能使画面产生动感。蒙太奇手法比起单纯使用一张运动瞬间图片,能承载更长时间的运动和更多的运动内容。例如画面中的这两个动作,把他们放一起之后我们就可以联想到这个小哥从热身到起跑的过程。
其实漫画运用的就是蒙太奇原理,通过几个关键的情景,去传达一个完整的剧情。
这些都是运用蒙太奇手法的作品。
以上就是今天的理论部分,接下来我们进入案例实操的环节,这次我给大家带来了四个案例,分别运用到了倾斜、重心偏移、发散与集中,以及蒙太奇的手法去塑造动感。希望通过这些案例的演示,能够让大家更好地理解今天的内容,下面我们就来进入案例的部分。
案例一
首先确定好画面的页边距,并且将画面横向分为 6 份。
然后将主体,也就是科比的形象,放在画面正中间,横向占中间四栏。
接着在科比的下方叠加一个红色的倾斜色块,强化科比倾斜的体态和动感。
从球鞋的名字中提取出关键词叠在科比下层,并将球鞋的中文名放在英文下方。
将球鞋与介绍性文字做成文字组的形式放在画面下方 。
由于主标题英文被遮挡了一部分,缺失了一些可读性,所以我们将球鞋的英文名做一个重复放在左上角,并在右上角添加 logo。接下来我们在背景上叠加一个篮球场的场景。
并将画面的四周涂上黑色的渐变,强化主体形象。
由于现在画面和主体都有一些偏暗了,所以我们对整体画面进行稍微调亮,那么这个案例就完成了。
案例二
这个案例同样也是一双运动鞋,但是我们这次利用重心偏移的技巧去塑造动感。
同样的确定页边距,并将画面横向分为四栏,将主体放在画面左上角占上方两栏。
然后从球鞋的名字中提取出相关英文放到版面顶部,并置于主体下方。
因为我们要做一个重心偏移的版面,所以我们接下来将所有的介绍性文字按照主体的负空间排列在版面上方。
为了防止重心的过度偏移,同时和左上角的球鞋做一个对角线的呼应,所以我们在版面的右下方放置价格以及球鞋的型号等信息。
然后吸取球鞋的颜色做一个色彩上的呼应。这一张球鞋的海报就完成了。
案例三
这个案例我们来做一个放射光线的海报,这个海报内容是一款果汁软糖的促销海报。
首先确定好页边距。
然后我们从这款软糖的包装上提取出一个图形作为画面主体。然后将软糖的名字和介绍文案放到这个图形中。
把图形按照黄金比例和网格放到画面中间。
在主体图形后面叠加放射线条,底下留出一部分空间放置产品图片及其他信息。
将产品图片和促销信息以居中对齐形式排列在画面下方。
然后我们可以在放射线上添加一些表情愉悦的人物图片,去强化吃了这款软糖会很开心的这个动态过程。
还可以在画面周围添加一些可爱的小图形去烘托氛围。
最后加上 logo,这个软糖的促销海报就完成了。
我们也可以将这个海报做成不同的配色,每一款产品对应一个配色。
案例四
这是一个艺术展的海报,我们通过蒙太奇的手法来表现。
由于展览主题是过去、现在和中间的一切,所以我们将画面分成三份,并用运动过程中的三个不同动作来代表着三个阶段。
由于第一张图片的底色偏亮了,所以我们将它抠出来,做一个与另外两个图片的相同背景。
将主题和时间这两个比较重要的信息放在画面的左上角。
其余信息排列在右下角。那么这个案例就完成了,也是非常简单的,利用的就是蒙太奇的手法。
本期教程到这里就结束了,我们来简单地总结一下今天的内容。首先我们了解了动感是画面张力不平衡所造成的,以及强调速度感和强调能量感的两种动势。接下来我们讲解了三种产生动感的原因,分别为基于生活经验与心理认知、引导视线移动以及不平衡状态下带来的视觉冲击。最后我们总结了 9 点实用的小技巧,分别为捕捉动态瞬间、倾斜、错位、集中与发散、螺旋、波状曲线、色彩、重心偏移、蒙太奇。希望大家能够掌握好这些方法,让原本静态的画面也能带来全新的动感。
文章来源:优设
1.竞品分析的定义
从专业的角度来讲,竞品分析是通过系统的分析方法去全面了解市场上位于前列的竞争对手的产品,能够让设计师快速了解自家产品所处的位置,从而来针对性的改进自身产品的一个方法。简而言之,就是要站在巨人的肩膀上去思考,以竞品分析的形式去学习其他优秀的产品,从而解决自身产品所存在的问题。
2.为什么要去做竞品分析
做一件事情之前一定要思考做这件事的价值和意义,只有你明白其重要和必要性,你才会知道该怎样去做这件事情,而不是一提起竞品分析就找一大堆专业框架和术语然后去填内容,这样虽然产出了很多,但是关键性的内容点其实还是不清楚。
说直白点,你需要通过这篇竞品分析去解决你工作或者创作中遇到的什么问题,带着疑惑和目的去分析在我看来是更有效率的。因此特分为以下几种情况:
因此我们要学会根据自己的不同需求,去制定不同的竞品分析方案,让分析的内容更聚焦。作为UI设计师来讲,通过竞品分析为自己的设计方案提供科学的理论依据,为自己赢得话语权,能够更好地科学产出内容。
3. 如何寻找竞品:
竞品的选择非常重要,如果找到错误的竞品,那么你所分析的一切结论可能都引向了一个错误的方向。从而让自己的努力都白费。那么怎样才能找到合适的竞品呢?分为以下三类情况
A.核心服务与目标用户相同的产品(直接竞品):
这一点是广大设计师都能想到的范畴,也称为直接竞品。即提供的核心服务、市场目标方向、客户群体等与我们的产品基本一致,产品功能和用户需求相似度极高的产品 。往往是通过业务关键词就能直接搜索到的竞品,比如音乐类产品,那么直接在应用商店,或者通过专业网站(易观千帆等)搜索关键词“音乐”即可搜索出排行前列的竞品。
B.目标人群不同,但功能模块和服务接近的产品(间接竞品):
这类竞品可以找起来并不那么直接,可以通过对应功能去逆推拥有此功能的产品,并进行相关搜索。
如果想不到,可以通过“人人都是产品经理” “36氪“等关于产品资讯的网站进行查询,甚至可以通过百度指数来进行发散思维,看一下跟你关键功能相接近的都有哪些。比如你研究外卖产品,除去饿了么和美团等直接竞品,你还可以在分析用户下单和购买流程中,去分析淘宝和京东等购物产品,也能得到一定的帮助。
C.目标人群和服务都不同,但交互或者视觉有可以参考的产品(关联竞品):
这里所选择的产品,定位和领域可以都完全不同,但是你要从这款产品中得到启发,从而让你的产品能够拥有其他竞品不同的特点或者功能模块。有一个很典型也熟知的的案例,就是卫龙辣条的设计案例,在卫龙推出之前,可以说是没人会想到辣条会和高端扯上关系,但是卫龙就是借鉴与其领域完全不同的苹果设计去做,从而在包装上独树一帜,从而吸引人们注意取得成功。因此通过不同领域跨行业的产品有时候也可以找到不错的思维方向。
4.如何进行商业分析:
进行商业分析,这里只提及到三个基本选项:商业背景、产品盈利模式以及用户人群。通过这三个基本要素,你能对所研究的竞品有一个大概的了解。当然深入了解还需要其他平台(官网网站、36Kr等)来查阅更多的相关性资料,下列是对QQ音乐商业背景的简要分析。
5. 如何进行交互分析:
我们在做交互分析时,我们需要进行必要的两点分析:用户路径和交互维度。
用户路径:指用户从某个开始行为事件直到结束事件的行为路径,即用户在使用某个功能的完整流程称之为用户路径。我们需要去观察和体验在这一个完整路径中涉及到的页面、动效、视觉到底是怎样的。就拿登录页来说,我们看看排行前列的竞品是怎么做的。通过相应的体验和对比分析,我们就可以找出这其中符合我们产品性质的最优解,从而提高我们的登录注册效率。
交互维度:交互维度和用户路径有所区别。这一层需要弄清楚产品的核心路径,从而能够更好的解析产品各个层面的逻辑关系,这就需要我们以用户的角度去逐个体验,整体联系,随后记录下来。使用过程中我们也要去观察APP中的交互小细节,怎样分享的,怎样展示的,比如音乐软件进行截屏后和点击喜欢按钮后的反馈是怎样的。
6. 如何进行视觉设计:
在进行视觉分析时,有一点需要注意,如果你需要详细分析某一模块,请用手机尺寸截图后拿到设计软件中进行测量,不要光靠眼睛观察,很多时候的小细节我们只有在手动测量后才能感受到,比如控件的尺寸大小,间距的大小,以及颜色的取值,都需要精准测量后才能得出靠谱的结论。
怎样进行视觉分析呢,我比较推荐从一个app 视觉语言最基本的五个维度去分析,即“形色字构质”
最近以音乐APP进行了一次竞品分析,以QQ音乐APP来举例进行分析(当然竞品分析并不能只分析一个,而应该根据你需要的功能找多个竞品进行对比分析,才能看到更多的维度,这里只拿一个举例):
6.1 图形元素的分析
首先我们以形进行分析,形即图形元素,具体来讲即LOGO和图标。LOGO的更新在2018年10月以后已完成更新。新版的主要图标整理归纳如下:
可以看到整体的图标色调更加清新,造型设计更加圆润,未选中状态的线形图标则采用4px的描边,粗线形描边让整体界面风格显得更加稳重的同时对用户的干扰也较小。新版的图标界面让界面保持稳重的同时又富有活力。
6.2 色彩体系的分析
其次则是对色这一类别进行分析,颜色其实是对于品牌调性有很大的影响,比如一想起QQ音乐就知道主色是绿,一想起网易云音乐就知道主色是红,对用户的记忆点更深刻。通过截屏测量进行分析,得出整体的颜色如下(由于手机屏幕的色差原因,不可避免会有些许误差)
从局部来看,分析颜色最重要的一点就是能够弄清楚一个页面中哪些元素用的是同一种颜色,观察成熟的产品是怎样用颜色(和字重)去区分层级关系的。
可以看到,用主色和三种辅色即可区分界面的整个层级关系,由此思考我们在制作自己的界面时也避免用太多的颜色,造成界面太过花哨。(颜色的具体色值可能有些许误差,更重要的是看颜色层级关系)
6.3 字体体系的分析
接下来是字的分析,字即字体体系,可具体到字体和字号。设计中字体一般来讲是苹方,字号则根据设计师的定义来进行相应的规范。通过页面的测量分析,可以拿到其具体的字号大小层级分析。(以下定义基于750的设计尺寸)
对于单个界面的分析,个人觉得要带有思考的眼光去看待,比如在首页中字号其实分配过多,像“更多”这种按钮就不应该再分一个字号,字号太多整体就显得有一点点乱了。虽然大厂的设计能在一定程度上给予我们参考,但并不是说他的每一个设计都是正确的,我们要学会用审视的眼光去看待出现在身边的设计。
6.4 界面构成分析
界面构成即界面的元素大小以及他们的布局,例如有时候我们不知道一个标准的搜索框的长宽具体多少才是合适的,这就需要我们去分析其他成熟的商业产品,通过测量来知道具体的数值,从而督促自己进行正确的设计。这里选取了一个默认的首页进行分析。
将一个页面用右边的形式进行原型化,去掉干扰可以把结构看得更清楚。间距之类的也可以通过软件进行测量。可以看到QQ9.0版本的去线化设计,利用大间距来区分各个模块,去掉了其他的干扰元素,整体的界面模块看起来非常整洁轻盈以及富有呼吸感。统一的圆角化设计也让整体设计符合流行趋势,显得更活泼。
6.5 质感与风格分析
关于界面的质感则是不同于扁平化的一个设计,即有的页面在你看来细节会更丰富,层级会更深。界面质感通过渐变,叠加,透明度等不同方式来呈现,比如在QQ音乐中的会员界面卡片,则体现了微质感:
上方的会员卡片就加入了渐变和图案叠加的方式来为卡片增加质感,让整个界面显得更精致。当然,叠加的图案都是与内容相关的,不能为了叠加而叠加。包括下方的权益图标,也采用了渐变的方式来让整个图标显得更精致和有质感。我们再处理质感的时候也可以用这种方式来进行。
以上通过“形色字构质”来分析是属于单个分析,相当于去拆解一个成熟产品中的每一个细节点,从而去学习和吸收。我们还要学会进行对比分析。把单独某一个功能模块拎出来,通过不同类型的对比从而归纳出这一类的设计方法和样式,进而总结相应规律。
比如某一天你需要设计一个歌单列表,你此时就需要分析所有TOP排行的歌单列表,看看分别都有什么,从而总结归纳出结构来,再进行分类。
通过分析提炼,形成以下结论并进行相应的概念风格展示设计:
这样,我们最后制作出来的方案才能涵盖比较全的解决方案,从而能够更好的助力设计产出。上图的产出可能稍显简陋,但只是做一个简单的示例,真正的产出应该更加有细节和落地,也要结合自己的工作需求做相应调整。
7.关注竞品的版本迭代和用户评价:
关注版本更迭,阅读竞品版本更新的详细说明,你可以从中得出版解决了什么问题,提升了哪些体验,添加了哪些功能,融合了什么流行的设计趋势。产品迭代就是团队通过用户需求对某个产品不断完善的一个过程。迭代对于一个产品来说是至关重要的,一个产品如果不想被对手超越,就必须不断的对版本进行更新迭代。
除了关注具体的内容,你还可以观察版本更新的提示信息,例如夸克浏览器在每次更新时总会用富有趣味的文案来打动你,从而让你更加情愿去更新,提升新版的使用率。
用户评价则更不用说,产品的最终服务对象就是用户,用户评价的重要性自然不言而言。不过我们要客观辩证地去看待用户的评价,吸收好的建议,屏蔽无脑的意见,从而能够正确地迭代版本。用户评价的查看可以使用App Store或者用户评价网站(https://appbot.co/)去查询。
总结
以上的篇幅较长,看下来可能会有一些累,那么此篇文章提及到的点在这里回顾一次:
1.竞品分析的定义-站在巨人的肩膀上去学习;
2.为什么做-基于自己的目的去进行对应的竞品分析,分析的最终目的是解决自己在设计过程中遇到的问题;
3.竞品分析分为三个层面:视觉分析、交互分析以及商业分析;
4.怎样进行商业分析(商业背景、盈利模式、用户人群);
5.怎样进行交互分析 (用户路径、核心路径、交互细节);
6.怎样进行视觉分析 (从“形色字构质”五个维度去分析以及如何对比分析应用);
7.竞品的迭代和用户评价的重要性。
自己有一个小习惯,看完每一篇文章,总会告诉自己一定要在脑海里回顾一遍,思考一下这一篇文章到底有什么观点是自己之前没有想到的,哪怕只有一点是没触及到的知识盲区,那么这篇文章之于自己就是有意义的。所以希望大家看完能有些许收获那便是最好的了。
写这篇文章的目的是给自己的竞品练习做一个总结,以输出倒逼输入是一种比较有效的学习方法。但基于自己的水平有限,在某些分析的地方仍然存在不足和疏漏之处,希望大家谅解并及时交流。感谢大家看到这里,希望大家每天都进步~
转自:站酷-进击的M
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务。
弹窗在设计中运用的非常广泛,基本上每个应用都会涉及到。恰好这段时间我也在整理公司设计组件这一块,所以就想总结分享一下
设计师都会使用弹窗,但对于弹窗背后的分类及运用可能还不是特别了解,在写这篇文章之前,我查看了很多应用及资料,所以下面会有大量的案例,相信大家看完可以对弹窗的认识更明确,做设计规范的时候也能有自己的想法。
现在的弹窗分为两种,一种是模态弹窗(重提示),一种是非模态弹窗(轻提示)。
常见的模态弹窗:Dialog/Alert、Actionbar、Popover/Popup
常见的非模态弹窗:Toast/Hud、Tips、Snackbar、
Dialog/Alert 对话框
对话框是我们常用的弹窗,安卓开发语言是Dialog,iOS开发语言Alert,它通常出现在页面的中间,对话框/警示框的类别非常多,对用户的干扰比较大。前面之所以说模态弹窗是一种重提示,是因为它需要用户主动触发选择才可以继续当前的操作。
① 信息-选择确定
特点:这类弹窗通常是一些系统功能的授权、版本更新、消息通知、重要提示等,通常只有1~3个主按钮,只需要用户进行简单的选择。
下图举例分析:
iOS询问是否删除APP,就属于重要提示弹窗,它一般会用在像删除、确认提交...一些比较重要的功能操作中。
小红书的这个是否允许使用网络弹窗,大家一定在许多APP中都见过,这属于一个系统自带的授权弹窗。
马蜂窝与天猫的消息提醒弹窗,一个属于初次使用APP时,系统自带的弹窗,一个属于使用后期APP为了推送消息,主动提示你开启消息通知。
有钱花和爱奇艺的版本升级弹窗,都属于偏运营类的弹窗,这一类的弹窗通常会弱化暂不升级的按钮,突出升级主按钮。
② 信息-输入勾选
特点:这类弹窗通常是输入一些比较少的信息或者勾选信息,常用于备注输入、规格选择、分组选择等,通常只有确定和取消两个按钮。
下图举例分析:
微博对于已关注人的分组及备注,都属于信息输入及勾选类弹窗,操作通常都比较简单。
③ 信息-传达展示
特点:这类弹窗通常是一些广告、红包优惠、节日活动等一些运营类弹窗,主要是吸引用户点击及参加活动,这类运营弹窗通常会设计的比较吸引人,造型各异,会突出领取、查看等大按钮,弱化关闭按钮。
下图举例分析:
拼多多和饿了么这类的红包优惠弹窗,就不多说了,大家都懂,它们最主要的目的就是吸引用户点击,提升购买率。
美团的变黄送好礼弹窗,属于一次比较大的品牌升级,它主要目的是让用户更好的了解并接受品牌色升级。整体的元素及动效设计都非常清晰,视觉感很强。
支付宝的这个猜世界杯赢蚂蚁积分的弹窗,属于活动弹窗,它的整体设计非常贴合主题。
Actionbar操作栏
Actionbar主要分为Action Views和Action Sheets。它们通常是由底部弹出,它的操作及信息会比对话框类型的弹窗更多更复杂。这种当前页面的下拉弹窗好处就是,可以让用户清楚的感知当前的操作,比跳转到新页面更加有安全感。还有一个特殊的抽屉式弹窗也顺便说一下。
① Action Views操作视图
特点:这类视图弹窗通常占屏比较多,以文字、图标等形式展示各种功能,也可以说这类的弹窗是一个小型的页面。它一般从底部弹出,不太强调归属,大多出现在购买、支付、分享等场景。
下图举例分析:
百度网盘的这个+号扩展弹窗比较特殊,它也可以说是浮层,占满整个屏幕,它最吸引人的还是它的小动效。
京东购买时的弹窗和支付宝付款时的弹窗,都是比较典型的,在各种电商产品及付款页面用的非常多。
转转这个的键盘与输入为一体的弹窗,设计的非常人性化,让用户一次就可以输入多个价格。大大提高了用户的操作效率。
网易云音乐的分享弹窗就是典型的以文字与图标来展示功能的。
微信读书的底部阅读设置弹窗,比较特殊,为了使用户沉浸阅读,它是比较隐藏的,而且非常轻量化。
② Action Sheets 操作列表
特点:操作列表相对于操作视图,它更单一。主要是以文字展示功能按钮,重要敏感的功能操作一般会用主题颜色或红色显示,主要运用在一些日常控件、功能选择、删除、保存等场景。
下图举例分析:
Keep的选择日期,属于iOS原生控件,非常常见。
淘宝的选择地址弹窗,整个展示的非常清晰全面,而且用户每选择一项,就会有相应的显示。
支付宝和天猫超市的两种列表弹窗,就不多说了,简单的功能选择都会采用这种。
③ 抽屉式弹窗
特点:这种抽屉式弹窗一般从左右两边弹出,经常运用在一些导航扩展和目录展示中,它能承载比较多的信息,基本上都是用来放一些不太常用的功能。
下图举例分析:
微信读书及一些其他阅读类产品,由于目录很长,而且一般是从上到下浏览的,所以基本都采用了这种抽屉式弹窗。
小红书的这个抽屉式弹窗,以图标和文字的形式展示了一些不是很常用的功能,为我的页面节约了不少空间。
Popover/Popup 浮层
Popover是ios的开发语言,popup是安卓的开发语言,浮层是指,用户点击某个功能后浮出一个临时气泡对其作出补充,它通常会伴随着半透明的遮罩或者投影衬底,用户需要点击功能区域操作,或者点击空白处取消,才能进入下一步操作。它与上面操作栏的最大区别就在于,它更强调归属,可以出现在页面的任何地方,而操作栏一般只出现在底部,不强调归属。
① 指向浮层
特点:这类的浮层一般伴随有小三角指向,强调归属。气泡里面的功能通常以单一的文字或文字与图标结合的形式来展示,主要运用在顶部加号补充、复制、分享转发等场景。
下图举例分析:
支付宝和美团的顶部加号补充浮层,展示形式是差不多的,只是UI样式不一样,一个是白色气泡黑色半透明遮罩,一个是深灰色气泡。
微信读书和微信的选择文字气泡,在文字复制中很常见,通常会与其他转发收藏小功能一起出现。
② 导航筛选浮层
特点:所谓导航筛选,自然是与导航分不开的,再加上浮层是比较强调归属的,所以它通常会与导航连在一起,一般出现在顶部。
下图举例分析:
美团的导航筛选,因为选项及开关很多,所以它的底部会有两个主按钮,一个完成,一个重置。
饿了么的这个只有一个功能选项,所以它一般是直接选择就收起浮层了。
③ 引导浮层
特点:引导浮层的作用就是引导用户更好的使用产品及交互,降低用户的学习成本。它通常会出现在用户首次进入APP的时候,一般只会出现一次,点击空白位置或我知道了浮层就会消失。
下图举例分析:
QQ音乐与微医的引导浮层都是用户首次进入应用时,给出的功能搬家提醒浮层。
Toast/Hud 提示框
Hud是ios的控件名词,Toast是安卓的控件名词,它们都属于一种轻提示,给予用户及时反馈,让用户知道自己当前所处的状态。
Hud一般只出现在屏幕的中央,以毛玻璃的样式表现,内容展示比较富丰富。
Toast可以出现在屏幕任意位置,通常以黑色半透明的小框来表现,内容一般是纯文字提示或者文字与图标结合提示。
① 状态提示
特点:状态提示的Toast,它们一般都是反馈用户当前操作的状态,只出现1到2秒就会自动消失,场景一般是关注成功、密码错误、音量提示、静音、清除缓存等。
下图举例分析:
移动的属于操作遇阻提示。
京东的属于操作成功反馈。
iOS的音量控制属于毛玻璃Hud。
微信的清除缓存属于正在操作状态。
② 按键提示
特点:按键Toast提示与状态提示不同,它们一般自动出现或者点击触发才会出现,用于对功能点的补充说明,让用户对功能有更深的了解。
下图举例分析:
蚂蚁森林里点击树木就会出现相关信息,当然它也会自动出现,点击其他区域也会自动消失。
知乎的消息标签不仅有小红点提示,还会在上方自动出现数字提示。
Snackbar
Snackbar是Android中的一个控件。它一般会在超时自动关闭或者在屏幕上滑动关闭,它没有Toast那么轻量,设置出现的时间会比Toast长,而且可以点击按钮进行交互。
下图举例分析:
UC浏览器的Snackbar,是在提示用户上滑,来查看更多内容,它需要滑动或者超时才能关闭。
京东的Snackbar,是在为用户推荐商品,提示用户点击箭头来查看喜欢的商品,它比UC浏览器多了一个关闭的按钮。
Tips提示
Tips与Snackbar最主要的区别就是:Tips它是内嵌在页面上的,而Snackbar则是浮在页面上的。Tips一般要让用户主动触发关闭按钮或点击进入下级页面才会消失,一般用于需要用户感知到的通知信息,或者植入广告。
下图举例分析:
百度网盘在下载视频时,就会出现一个Tips的提示,让用户观看广告来得到加速下载。这种提示虽说是广告,但它抓住了用户的场景及心理,观看广告的几率大大提升。
爱奇艺的Tips提示就属于重要通知提示了,提示用户VIP即将到期,续费可优惠,它们都有一个主按钮及关闭按钮,需要用户主动触发提示才会消失。
规范总结
目前的弹窗样式非常多,你能想到的,你想不到的基本都可以技术实现。但这同时也带来一个问题,那就是“不规范”。以上提到的弹窗种类,你只需要选择符合你产品要求的几个类型,最好不要在一个产品中运用多个同种类型的弹窗,否则后期会很难规范及组件化,当然运营广告类弹窗可以另当别论。
转自:站酷
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务。
一、搭建cli
1.事先安装好cnpm(淘宝镜像)
npm install -g cnpm --registry=https://registry.npm.taobao.org
1
2.cnpm install -g vue-cli
全局安装vue脚手架工具。(下载一次就好)
3.vue init webpack your_project_name
创建一个脚手架项目(每次创建需要)
eg:这时在命令行中有需要你填的信息{
你的项目名;
你的项目描述;
还有你想是否下载的插件(y/n);
}
4.使用 npm run dev来运行项目
就这样,一个简单的vue开发项目模板就这样下载完成了。
eg:
i 是install 的简写。
全局安装依赖:
cnpm i 依赖名
1
局部安装依赖:
cnpm i -D 依赖名
1
二、vue-router
一般事先安装模板时,已经安装上了。
可以查看package.json中。
如果没有安装
cnpm i -D vue-router
1
安装好之后,在src目录中会生成一个router目录,里面放着index.js,
一般有两种配置
第一种:
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
export default new Router({
routes: [
// 一进入就显示页面
{
path: '/',
redirect: '/index'
},
{
path: '/',
component: pather => require(['../components/common/bodys.vue'], pather),
meta: { title: '主体' },
children:[
{
path: '/index',
component: pather => require(['../components/page/index.vue'], pather),
meta: { title: '系统首页' }
},
{
path: '/biaoge',
component: pather => require(['../components/page/biaoge.vue'], pather),
meta: { title: '基础表格' }
},
{
path: '/Tab',
component: pather => require(['../components/page/Tab.vue'], pather),
meta: { title: 'tab选项卡' }
},
{
path: '/jibenbiaodan',
component: pather => require(['../components/page/jibenbiaodan.vue'], pather),
meta: { title: '基本表单' }
},
{
path: '/fuwenben',
component: pather => require(['../components/page/fuwenben.vue'], pather),
meta: { title: '富文本编辑器' }
},
{
path: '/bianjiqi',
component: pather => require(['../components/page/bianjiqi.vue'], pather),
meta: { title: 'markdown编辑器' }
},
{
path: '/shangchuan',
component: pather => require(['../components/page/shangchuan.vue'], pather),
meta: { title: '文件上传' }
},
{
path: '/scharts',
component: pather => require(['../components/page/scharts.vue'], pather),
meta: { title: 'schart图表' }
},
{
path: '/tuozhuai',
component: pather => require(['../components/page/tuozhuai.vue'], pather),
meta: { title: '拖拽列表' }
},
{
path: '/quanxianceshi',
component: pather => require(['../components/page/quanxianceshi.vue'], pather),
meta: { title: '权限测试', permission: true }
}
]
},
{
path: '/login',
component: pather => require(['../components/page/login.vue'], pather)
},
{
path: '/cuowu404',
component: pather => require(['../components/page/cuowu404.vue'], pather)
},
{
path: '/cuowu403',
component: pather => require(['../components/page/cuowu403.vue'], pather)
},
{
path: '*',
redirect: '/404'
}
],
// 去掉#号
mode:"history"
})
第二种:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
})
三、axios
先安装
cnpm i -D axios
1
然后在main.js写入
import axios from 'axios'
Vue.prototype.$axios = axios
1
2
3
这样就可以在组件中使用axios 获取数据了
loadData(){
this.$axios.get(['https://free-api.heweather.com/v5/weather?city=qingdao&key=1b47b16e4aa545eaa55a66f859ac0089'])
.then((response) => {
// success
console.log(response.data);
})
.catch((error) => {
//error
console.log(error);
})
},
四、vuex
1、安装
cnpm i -D vuex
1
2、然后需要手动创建一个文件夹store在src目录当中,
接着在store文件夹中创建store.js
例:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment: state => state.count++,
decrement: state => state.count--,
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
3、然后在main.js引入注册
import Vuex from 'vuex'
import store from './store/store'
Vue.use(Vuex)
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
比如在headers.vue使用vuex
<template>
<div class="headers">
<p>{{count}}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'headers',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods: {
increment(){
this.$store.commit('increment')
},
decrement(){
this.$store.commit('decrement')
}
},
computed:{
count(){
return this.$store.state.count
},
}
}
</script>
<style scoped lang="scss" >
</style>
五、sass
1、需要安装sass
(1)安装node-sass
(2)安装sass-loader
(3)安装style-loader 有些人安装的是 vue-style-loader 其实是一样的!
cnpm install node-sass --save-dev
cnpm install sass-loader --save-dev
cnpm install style-loader --save-dev
1
2
3
2、接着需要更改build文件夹下面的webpack.base.config.js
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(dirname, '..', dir)
}
module.exports = {
context: path.resolve(dirname, '../'),
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /.(png|jpe?g|gif|svg)(\?.)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
},
{ //从这一段上面是默认的!不用改!下面是没有的需要你手动添加,相当于是编译识别sass!
test: /.scss$/,
loaders: ["style", "css", "sass"]
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
3、在你需要使用sass的地方写入即可
<style lang="scss" scoped="" type="text/css">
$primary-color: #333;
body {
color: $primary-color;
}
</style>
六、vue UI库
这里已著名的Element组件库为例
https://element.eleme.cn/#/zh-CN/component/carousel
1、安装
npm i element-ui -S
1
2、使用
在main.js写入
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
1
2
3
4
3、然后在组件使用就可以了
例:轮播图
<template>
<el-carousel indicator-position="outside">
<el-carousel-item v-for="item in 4" :key="item">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</template>
<style>
.el-carouselitem h3 {
color: #475669;
font-size: 18px;
opacity: 0.75;
line-height: 300px;
margin: 0;
}
.el-carouselitem:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
</style>
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务。
设计概要(Design briefs),也可以理解为设计简报、设计说明文档。设计概要负责说明设计的目标、设计的方向风格、不同阶段及对应的里程碑(指标)。
简而言之,设计概要是对本次设计项目的简要概括,可能是一份文档,或者一组文件内容,其中包括设计的几个关键概念如项目描述、项目范围、项目目标,目标受众、风格外观、预算时间安排。那么我们所整理的设计概要是提给谁看的呢?按照原作者观点是增进设计师和需求方的理解及信任。作者的观点是建立在服务甲方的基础上提出的,因为作者所属领域为平面设计领域,偏向创意性设计活动,因此通过建立共同目标,统一想法更容易创造出高满意度的方案。
但事实上设计概要不止于此,它不应该被局限在平面设计领域,虽然作者是以平面设计师的身份来普及这个观念(倾向提点平面广告类设计工作者,而不是UI/UX领域),但事实上其中很多角度都是从设计本质及设计工作的协作本质上提出的,它也可以被我们移植到UI/UX领域。当我读完这篇文章,我发现了设计概要一个更加重要的功能,那就是帮助UX设计团队梳理关键工作,建立共同目标,提高设计工作的效率,促进团队成员的协作与信任。(从设计团队角度)
当然如果从甲方角度考虑,设计简报依然可以用于UIUX领域,比如向leader提案,以及在项目初期向外包方展示设计说明,增进沟通交流,以保证设计师对需求的理解,同时更展示了设计人员的专业性。
总之设计概要适合在设计流程的前期被组织,并分享至团队和需求方,增进团队的凝聚力,促进创意的发生,展示团队专业性及增加需求方与设计人员的理解与信任。设计概要与最终提案实际上是一次完整的设计活动的首与尾,两者应当相互对应,设计结果应当围绕最初定义的目标进行,设计概要更像是设计思维的理解和定义阶段,把我们面临的问题,假设的目标呈现出来,以便在接下来的设计过程中精准打击,去解决设计概要中提到的问题或者目标。
下面开始正文。这里是帅气的分割线
在过去18年的广告设计工作中,我逐渐意识到这个行业里最好的事情就是与你合作的人——作家,艺术总监,用户体验和用户界面设计师,拥有出色的有创意的大脑,卓越的才能,不同的心态。
当他们有清晰的指导和足够的自由与时间时,他们往往能迸发出好的想法,提出创意性的解决方案。但只要是缺乏指导,各种相互矛盾的指示,混乱的目标及紧迫的时间,将导致设计师无法产出优秀的方案。
我多年来一直在观察这个现象,但我不知道该如何解决。一开始,我很难将客户需求好创意输出完美的结合,随着时间流逝,我逐渐明白,这一切都因为我们没有一个清晰地设计概要。从客户的需求文档开始,我们从中收集信息建立我们的总的设计概要,然后以此总概要来进一步细分为具体的概要,如视觉设计概要、体验设计概要、布局排版设计概要等。
没有任何东西可以取代一份准确详细的设计概要。没有任何电子邮件或者个人会议可以取代创意概要。如果缺少基本信息,你无法开始任何工作,无法估算资源,无法保证最后期限。
如果认真对待,设计概要就是任何创造性工作的关键。主要问题是客户和设计师在某些情况下都被低估了。设计行业变得如此庞大且不断扩张,任何人都可以称自己为设计师,任何人都可以收取任何费用。因此,需要特定流程的真正的设计被置于次要地位,完全以价格来评判。虽然我支持竞争并且完全理解并非每个公司或个人都能获得同样的预算,但它仍然对整个行业不利。
设计概要是一个很关键的部分,应当在正式设计开始前就组织好,但在一般设计流程中,它经常会缺失,通常我们认为我们一切都准备好了,认为我们的方案没有问题可以直接开始设计了,但事实往往相反。
什么是概要(brief)?
“概要”一词来源于军事术语,在军事术语中,简报被定义为“事先给出具体指示或信息的行为”。“它有一个具体的结构,简短扼要,包括所有必要的资信息,但不多,并包括一项既定的任务和要完成的结果,但有足够的自由来适应局势(任务摘要)。
当指示部队接管敌方阵地时,将军可能会给出如何执行以及考虑哪些因素的指示,但不会说把右脚放在左脚前面,重复这个动作100米(前进一百米),然后右转,等等。军事简报只给出一项任务,留给个人决定的空间。同样,creative briefing也不是一个描述创意过程的详细用户手册。它也不是对预期结果的描述。创意概要是一个框架,它可以通过提供足够的指导来推动创意过程,使创意保持在正确的轨道上,并为创意提供足够的自由。(译者注:核心是指导列表,且保证足够的自由,只提供框架,不干扰创意执行)
为什么我们在创作过程中需要概要?
如果我们有一个需要别人解决的问题,我们需要创意简报和创意简报用作说明,就是这么简单。当我们要进行创意活动时我们会写创意概要,列出关键的点,这意味着我们此时已经清楚存在的既定问题,我们列出问题然后才知道去解决什么。当然,也只有在别人要执行设计活动时,我们才需要去写一份概要,以供说明。 (简单理解,从某种角度,设计概是要写给需要执行设计的人员看的,我们需要别人去解决问题,而概要负责说明这些问题。)
什么是设计概要?
设计概要是描述设计项目的目标和里程碑的书面文档。它是设计过程中至关重要的一部分,因为它有助于在客户和设计师之间建立信任和理解。它和合同一样重要,是双方的重要参照点。它确保重要的设计问题在设计师开始工作之前就被考虑和讨论。
根据不同工作范围和不同产品领域,设计概要可以由许多元素组成,每个元素都详细描述某个范围的特定部分。
但为了保持简洁,以下五个要素不容忽视:
1.项目描述
简单描述一下我们需要做什么:我们对任务了解多少?期望是什么?一个新的设计?一个新的想法?现有的网站重新设计?我们需要用它来解决什么问题?这最多只能是一句话。
译者注:项目描述是对你所进行的项目的最简洁的概括,比如"我们在做一个共享打车的产品"。当然可以在这基础上丰富一点如:“我们在做一个服务白领人群、针对夜间打车场景的共享打车产品”,后面这个描述增加了用户和场景,但整个描述仍然是清晰易懂的。项目描述一般由战略层相关人员来定义,如公司老大,产品经理等。当然对于redesign项目,则需要设计师自己明确项目目标,然后去定义一个简洁的项目描述。
2.项目范围
根据项目的大小,这里需要提供更多的细节。什么是预期目标,有多少页多少内容量,它将具有什么功能和特性。你需要了解更多的细节来服务一个新的企业品牌项目,而不是一个简单的网站。报价将主要依据这一环节。尽可能具体是至关重要的。
此外,在互联网世界中,客户相信设计师能够解决所有问题,从UI到UX,最终开发一个完整的网站并解决SEO排名(seo即搜索引擎优化的意思),非常重要的是,尽早说明哪些内容在范围内,哪些不包括在范围内。
译者注:项目范围即范围层中的内容规格。我们在产品设计的五个层面中第二层中可以了解这部分内容,内容规格是对产品目标的拆解,细化为具体的内容和功能,例如我们设计一款打车应用,它可能会包含,顺风车(对应顺路接送服务)、普通快车(对应出租车服务)、高端用车(对应企业服务高端出行领域)这三种规格。
3.目标
通常情况下,你的客户并不知道他们的目标,也不知道设计工作会如何影响他们。但概括下来有以下三种不同类型的目标。
业务目标:客户给出的一个可衡量的目标,例如增加销售、市场份额、渗透率、减少X%的客户流失率等KPI。
营销目标:帮助客户实现商业目标中一切与营销相关的事情。帮助客户提升客户参与度的活动:意识-考虑-偏好-试用-购买-忠诚-宣传。(对标用户生命周期模型:获客、留存、激活、变现、传播 )
沟通目标:我们需要行动的目标!预期的结果是什么,消费者的行为或预期从我们设计的产品中获得什么?它必须以具体有形的形式表达出来,例如1500人注册,5000个额外的点赞,优惠券下载,产品试用,撰写评论,应用程序的使用,潜在客户,分享。
虽然了解业务和营销目标很重要,但是让我们的客户了解UI和UX有其局限性,并且它们并不会对糟糕的商业策略产生影响,这一点非常重要。这可能很关键(撇清责任俗称帅锅哈哈)。
4. 目标受众
这个产品是给谁的?谁将使用它,在什么时候什么场景下,为什么使用?描述用户受众必须尽可能具体,因为设计师通常会考虑到角色,特别是在UX方面,产品使用流程主要由用户角色及其在客户旅程中的特定阶段决定。
6.预算和时间
有些人可能会争论是否应该在一个简短的报告中加入预算,不一定是准确的预算,但我们至少要确定一个大致范围。清晰的预算可能意味着设计师或代理机构甚至不会接受该项目,或者如果客户无法支付他们的服务费用,他们会考虑另一种成本更低的解决方案。但若没有沟通清楚,在设计进行期间更容易产生分歧和问题。
定义总的时间和预期的各时间节点则是为了避免那些清晰沟通可以避免的冲突点。时间还会影响预算;在任何紧急情况下,获得额外资源都是可能的(比如若时间紧急可会提高价格)。
根据我的经验,真正重要的问题都是双重的。
1.客户的教育程度不足以提供可以推动项目正常运行的必要信息
2.设计师在没有正确理解客户的需求的情况下就心急直接开始设计。
总结
如果您是客户,一个好的设计概要将节省您在无意义的电子邮件,电话和会议上花费的时间。它还可以帮助您获得来自不同设计师和代理商的更和可比的报价。
如果你是一名设计师,如果你坚持从一个设计概要文件开始你的设计工作,你会从客户那里获得简洁的愿景和期望,这可以让你保持动力。你的时间和努力是昂贵的,从潜在客户那里获取的某种信息可能毫无意义。明智的做法是优先考虑那些已经有一些远见、愿意承担自己那部分工作的客户。(即优先考虑那些清晰的分析了产品的各类目标、预算等关键内容规格的客户)
一个好的简介应该是简洁、清晰和全面的。如果目标足够清晰,应当不超过两页。
为了使最终的结果尽可能的好,我们需要鼓励和教育客户和设计师去做更好的设计概要(说明文件),让我们的工作更容易,并把重点放在更重要的事情上。
文章来源:UI中国
在java的学习中,当接触到类这一章的时候,就会避免不了的接触到this关键字。
首先,this关键字指向的是当前对象的引用
作用:
this.属性名称
指的是访问类中的成员变量,用来区分成员变量和局部变量(重名问题)
class Test_08{
public static void main(String [] args){
//调用无参构造函数,
Person p1 = new Person();
p1.setAge(20);
p1.setName("张三");
p1.setGender("男");
System.out.println(""+p1.getName()+" 今年"+p1.getAge()+"岁 性别为:"+p1.getGender());
}
}
class Person{
private String name;
private int age;
private String gender;
Person(){}
Person(String name,int age,String gender){
this.name = name;
this.age = age;
this.gender = gender;
}
public void setName(String name){
name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
age = age;
}
public int getAge(){
return age;
}
public void setGender(String gender){
gender = gender;
}
public String getGender(){
return gender;
}
}
对Test_08运行后发现,调用的set方法并没有对 对象中的变量进行赋值,是因为,传入的参数变量名与类中属性变量名重复,因此我们在set方法和有参构造方法中加上了this.类属性名称,这样就可以完成对 对象变量的赋值。如下图:
this.方法名称
用来访问本类的成员方法
this();
访问本类的构造方法
()中可以有参数的 如果有参数 就是调用指定的有参构造
注意事项:
1.this() 不能使用在普通方法中 只能写在构造方法中
2.必须是构造方法中的第一条语句
例如,当我们把this()放在有参构造函数的末尾时,例如用this("哈哈");我们先不管语法是否有错误,试着按照程序的运行来判断一下结果,我们可以看出,当在创建对象时,假定调用含有this(“哈哈”)的构造函数,则刚开始存放的值,会被this(“哈哈”)调用的只含有一个参数的构造函数覆盖,也就是说,最后的name会变成“哈哈”,这是与我们的初衷相违背的,而且运行结果也是报错,
当我们换到构造方法的第一句时,则不会有这种错误,因为它并不会影响到后面name的赋值。
我们接下来把this语句放在构造函数的第一句位置,
就不会有报错
————————————————
版权声明:本文为CSDN博主「BetterShon」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42386014/article/details/81138684
实现导航的左右滑动类似于腾讯新闻,网易等导航,一下贴上代码:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<style>
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,form,input,p,th,td,table,textarea,select{margin:0;padding:0;}
h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}
th,em{font-style:normal;font-weight:normal;}
ol,ul{list-style:none;}
table{border-collapse:collapse;border-spacing:0;}
img,a img{border:0;}
body{font:12px 'Microsoft YaHei',Arial;color:#666;background-color:#eee;}
.nav{width:100%;overflow:hidden;margin:0 auto;height:35px;position:relative; line-height:35px;background-color:#000;}
.nav ul{position:absolute;left:0;top:0;width:640px;z-index:1;}
.nav ul li{width:80px; float:left; overflow:hidden;}
.nav a{color:#fff;width:100%; display:block; text-decoration:none; text-align:center;}
</style>
<body>
<div class="nav" id="nav">
<ul>
<li><a href="#">菜单1</a></li>
<li><a href="#">菜单2</a></li>
<li><a href="#">菜单3</a></li>
<li><a href="#">菜单4</a></li>
<li><a href="#">菜单5</a></li>
<li><a href="#">菜单6</a></li>
<li><a href="#">菜单7</a></li>
<li><a href="#">菜单8</a></li>
<li><a href="#">菜单9</a></li>
<li><a href="#">菜单10</a></li>
</ul>
</div>
<script>
window.Swipe = function(b, a) {
if (!b) {
return null
}
this.options = a || {};
this.index = this.options.startSlide || 0;//开始的导航页的第几屏
this.speed = this.options.speed || 300;//速度
this.lwidth = this.options.width || 80;//导航li宽度
this.delay = this.options.auto || 0;//自动滚动菜单速度0为不自动滚动
this.container = b;//在那个容器内
this.element = this.container.children[0];//
this.setup();
if (this.delay != 0) {
this.begin();
}
if (this.element.addEventListener) {
this.element.addEventListener("touchstart", this, false);
this.element.addEventListener("touchmove", this, false);
this.element.addEventListener("touchend", this, false);
this.element.addEventListener("touchcancel", this, false);
this.element.addEventListener("webkitTransitionEnd", this, false);
this.element.addEventListener("msTransitionEnd", this, false);
this.element.addEventListener("oTransitionEnd", this, false);
this.element.addEventListener("transitionend", this, false);//监听过度动画是否结束
window.addEventListener("resize", this, false)
}
};
Swipe.prototype = {
//设置其基本样式
setup: function() {
this.slides = this.element.children;
this.width = Math.ceil(("getBoundingClientRect" in this.container) ? this.container.getBoundingClientRect().width: this.container.offsetWidth);
if (!this.width||this.slides.length < 1) {//没有子节点,获取不到屏幕宽度均返回
return null
}
this.element.style.width = Math.ceil(this.slides.length this.lwidth) + "px";
var a = this.slides.length;
while (a--) {
var b = this.slides[a];
b.style.width = this.lwidth + "px";
}
this.slide(this.index, 0);
},
slide: function(a, c) {
var b = this.element.style;
if (c == undefined) {
c = this.speed
}
//过度效果需要花费时间
b.webkitTransitionDuration = b.MozTransitionDuration = b.msTransitionDuration = b.OTransitionDuration = b.transitionDuration = c + "ms";
this.index = a
//console.log(a this.width,Math.ceil((this.slides.lengththis.lwidth)/this.width));
if(a this.width>(Math.ceil((this.slides.lengththis.lwidth)/this.width)-1)this.width){
// b.MozTransform = b.webkitTransform = "translate3d(" + -((Math.ceil((this.slides.lengththis.lwidth)/this.width)-1) this.width) + "px,0,0)";
// b.msTransform = b.OTransform = "translateX(" + -((Math.ceil((this.slides.lengththis.lwidth)/this.width)-1) this.width) + "px)";
return false;
}
else{
b.MozTransform = b.webkitTransform = "translate3d(" + -(a this.width) + "px,0,0)";
b.msTransform = b.OTransform = "translateX(" + -(a this.width) + "px)";
}
},
getPos: function() {
return this.index
},
//前一个,
prev: function(a) {
this.delay = a || 0;
clearTimeout(this.interval);
// console.log(this.index);
if (this.index) {
this.slide(this.index - 1, this.speed)
//console.log( this.index);
} else {
this.slide(this.length - 1, this.speed)
}
},
//后一个
next: function(a) {
this.delay = a || 0;
clearTimeout(this.interval);
if (this.index < this.length - 1) {
this.slide(this.index + 1, this.speed)
} else {
this.slide(0, this.speed)
}
},
begin: function() {
var a = this;
console.log(a);
this.interval = (this.delay) ? setTimeout(function() {
a.next(a.delay)
},
this.delay) : 0
},
stop: function() {
this.delay = 0;
clearTimeout(this.interval)
},
resume: function() {
this.delay = this.options.auto || 0;
this.begin()
},
handleEvent: function(a) {
switch (a.type) {
case "touchstart":
this.onTouchStart(a);
break;
case "touchmove":
this.onTouchMove(a);
break;
case "touchcancel":
case "touchend":
this.onTouchEnd(a);
break;
case "webkitTransitionEnd":
case "msTransitionEnd":
case "oTransitionEnd":
case "transitionend":
this.transitionEnd(a);
break;
case "resize":
this.setup();
break
}
},
transitionEnd: function(a) {
if (this.delay) {
this.begin()
}
},
onTouchStart: function(a) {
this.start = {
pageX: a.touches[0].pageX,
pageY: a.touches[0].pageY,
time: Number(new Date())
};
// console.log(this.start)
this.isScrolling = undefined;
this.deltaX = 0;
this.element.style.MozTransitionDuration = this.element.style.webkitTransitionDuration = 0;
a.stopPropagation()
},
onTouchMove: function(a) {
if (a.touches.length > 1 || a.scale && a.scale !== 1) {
return
}
this.deltaX = a.touches[0].pageX - this.start.pageX;
if (typeof this.isScrolling == "undefined") {
//判断是横向还是树向滑动
this.isScrolling = !!(this.isScrolling || Math.abs(this.deltaX) < Math.abs(a.touches[0].pageY - this.start.pageY))
}
if (!this.isScrolling) {
a.preventDefault();
clearTimeout(this.interval);
this.deltaX = this.deltaX / ((!this.index && this.deltaX > 0 || this.index == this.length - 1 && this.deltaX < 0) ? (Math.abs(this.deltaX) / this.width + 1) : 1);
this.element.style.MozTransform = this.element.style.webkitTransform = "translate3d(" + (this.deltaX - this.index * this.width) + "px,0,0)";
a.stopPropagation()
}
},
onTouchEnd: function(c) {
var b = Number(new Date()) - this.start.time < 250 && Math.abs(this.deltaX) > 20 || Math.abs(this.deltaX) > this.width / 2,
a = !this.index && this.deltaX > 0 || this.index == this.length - 1 && this.deltaX < 0;
if (!this.isScrolling) {
this.slide(this.index + (b && !a ? (this.deltaX < 0 ? 1: -1) : 0), this.speed)
}
c.stopPropagation()
}
};
//开始调用插件
var slider=new Swipe(document.getElementById('nav'),{speed:500,auto:0,width:100,col:4,});
</script>
</body>
</html>
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务。
app.vue
<template>
<div id="app">
<transition :name="transitionName">
<keep-alive >
<router-view v-if="$route.meta.keepAlive" class="Router"></router-view>
</keep-alive>
</transition >
<transition :name="transitionName">
<router-view v-if="!$route.meta.keepAlive" class="Router"></router-view>
</transition >
<Play></Play>
</div>
</template>
<script>import Play from './components/play'
export default {
name: 'App',
data () {
return {
transitionName: 'slide-left'
}
},
watch: {
'$route' (to, from) {
// 切换动画
let isBack = this.$router.isBack // 监听路由变化时的状态为前进还是后退
if (isBack === true) {
this.transitionName = 'slide-right'
// from.meta.keepAlive = false
// to.meta.keepAlive = true
} else {
// from.meta.keepAlive = true
// to.meta.keepAlive = false
// this.transitionName = 'slide-left'
if (this.$route.path.split('/').length < 3) {
this.transitionName = 'slide-fade'
} else {
this.transitionName = 'slide-left'
}
}
this.$router.isBack = false
}
},
components: {
Play
}
}
</script>
<style>
.Router {
font-family: Roboto, Lato, sans-serif;
position: absolute;
width: 100%;
height: 100%;
padding-bottom: 60px;
transition: all .377s ease;
box-sizing: border-box;
overflow: auto;
}
.slide-left-enter,
.slide-right-leave-active {
opacity: 0;
-webkit-transform: translate(100%, 0);
transform: translate(100%, 0);
}
.slide-left-leave-active,
.slide-right-enter {
opacity: 0;
-webkit-transform: translate(-100%, 0);
transform: translate(-100% 0);
}
.ovf {
overflow: hidden;
}
.center {
width: 95%;
margin: 0 auto;
overflow-y: hidden;
}
li {
list-style: none;
}
</style>
路由配置
{
path: '/playListDetail/:id',
name: 'playListDetail',
component: pather => require(['../components/playListDetail.vue'], pather),
meta: {
title: '歌单详情',
keepAlive: true,
isBack: false
}
},
返回事件
back () {
this.$router.go(-1)
this.$router.isBack = true
}
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务。
蓝蓝设计的小编 http://www.lanlanwork.com