npminstallbabel-plugin-import--save-dev
//.babelrc
{
"plugins":[["import",{
"libraryName":"view-design",
"libraryDirectory":"src/components"
}]]
}
在main.js中引入
import"view-design/dist/styles/iview.css";
import{Button,Table}from"view-design";
constviewDesign={
Button:Button,
Table:Table
};
Object.keys(viewDesign).forEach(element=>{
Vue.component(element,viewDesign[element]);
});
先用google浏览器打开正常,以上操作猛如虎,IE浏览器打开250,好了不废话,下面是解决方案
解决方案
//vue.config.js中配置
chainWebpack:config=>{
//解决iview按需引入babel转换问题
config.module
.rule("view-design")//我目前用的是新版本的iview,旧版本的iview,用iview代替view-design
.test(/view-design.src.*js$/)
.use("babel")
.loader("babel-loader")
.end();
问题原因
为什么会有如上问题呢这个就和babel转换问题有关了,按需引入时,那些组件里js文件未进行babel转换或转换不彻底就被引入了,ie11对es6+的语法支持是很差的,所以以上方法就是让引入文件前就对view-design的src下的所有js文件进行babel转换,举一反三,当按需引入第三方框架时出现这个问题,都可用这方法解决了,只要把规则和正则中view-design进行替换。
延伸扩展
//全局引入
importViewUIfrom"view-design";
Vue.use(ViewUI);
tips:在全局引入时,一定要记住不要在.babelrc文件里配置按需导入,会导致冲突
我们先看组来优的2019年6的调研数据:70%的美国认为,与5年前相个信息变得更不安全。尤其是学历收群体。由此可户对个信息数据的隐私担忧以往更甚。
户隐私安全很重要,涉及的范围和度也很多。本次的分析从户体验度切,涉及如下三个:
我们看组数据:
这是来DuckDuckGo2019年9的调研(DuckDuckGo是美国的款不记录户为保护户隐私的搜索引擎)。样本来美国、英国、德国和澳利亚的成年户,共计3,411的调研得出。各国户对使搜索引擎的个隐私安全常在意(是否搜集个的数据和记录搜索为)。
2020年5DuckDuckGo均搜索次数为6200万。对看2019年11底均搜索次数4900万,2018年10是2900万。
最近年的持续活跃度幅增证明了不记录个隐私的搜素引擎越来越受到户的睐。
国内,头条、UC浏览器在搜索框输状态也提供了「痕浏览」。
不仅是搜索引擎领域,保护户隐私也成为Facebook最重要的战略向之。FacebookCEOMarkZuckerberg在2019年F8开发者会上喊出「THEFUTUREISPRIVATE」。2019年3MarkZuckerberg发,主题就是《聚焦于保护隐私的社交络》。
我们先看国外社交媒体Stories(故事)产品形态的流。
Stories由Snapchat创,由Facebook发扬光。早在2019年4,Facebook+MessengerStories,InstagramStories活户数就突破5亿。2020年2-3LinkedIn,Twitter也先后宣布将上线类似功能。
注重隐私提供仅好友可/仅可/仅作者可/等多重维度的隐私设定有助于户更安地参与互动。
我们主要看YouTube的频道会员案例:
为什么V红有意愿开通频道会员?
YouTube频道会员费可以从三种会费(按)区间选择,持多选:
以上综述,我们可以说:
1.匿名模式:
虽然匿名模式由来已久,但仍然是当前的基本户体验设计趋势,尤其是匿名模式的切换便捷性常重要。
2.减少永久性:
3.减少公开性:
从UE度,我们可以为频道会员提供专属身份设计例如专属徽章,专属表情等。
THEFUTUREISPRIVATE,注重户隐私的体验设计越来越重要!
百度MEUX
最近在项目中遇到这样一个问题
当页面加载完毕后由于选项卡的另外两张属于display:none;状态所以另外两张选项卡内echarts的宽高都会变成默认100*100
查阅了很多网上的案例,得出一下一些解决方案:
1:
原因很简单,在tab页中,图表的父容器div是隐藏的(display:none),图表在执行js初始化的时候找不到这个元素,所以自动将“100%”转成了“100”,最后计算出来的图表就成了100px
解决办法:
找一个在tab页的切换操作中不会隐藏的父容器,把它的宽度的具体值取出后在初始化图表之前直接赋给图表
1$("#chartMain").css('width',$("#TabContent").width());//获取父容器的宽度具体数值直接赋值给图表以达到宽度100%的效果2varChart=echarts.init(document.getElementById('chartMain'));34//指定图表的配置项和数据5option={...配置项和数据};67//使用刚指定的配置项和数据显示图表。8Chart.setOption(option);2:mychart.resize()重新渲染高度
3:后来我想到了问题所在,既然高度是因为display:none;导致的那大可不必设置这个属性,但是在页面渲染完毕后加上即可
所以取消了选项卡的display:none;但在页面加载完毕后window.οnlοad=function(){根基id在添加cssdisplay:none;}即可解决,分割线---------------------------------------------------------------------接下来解决一下ifram内外通讯互相通讯赋值iframsrc和高度问题
很多时候你需要获取到一段URL的某个组成部分。它们可能是hostname(例如dmitripavlutin.com),或者pathname(例如/parse-url-javascript)。
一个方便的用于获取URL组成部分的办法是通过URL()构造函数。
接着,我会告诉你如何使用URL()构造函数来轻松获取URL的组成部分,比如hostname,pathname,query或者hash。
1.URL结构
一图胜千言。不需要过多的文字描述,通过下面的图片你就可以理解一段URL的各个组成部分:
image
2.URL()构造函数
URL()构造函数允许我们用它来解析一段URL:
consturl=newURL(relativeOrAbsolute[,absoluteBase]);
参数relativeOrAbsolute既可以是绝对路径,也可以是相对路径。如果第一个参数是相对路径的话,那么第二个参数absoluteBase则必传,且必须为第一个参数的绝对路径。
举个例子,让我们用一个绝对路径的URL来初始化URL()函数:
或者我们可以使用相对路径和绝对路径:
在新建了URL()的实例以后,你可以用它来访问前文图片中的任意URL组成部分。作为参考,下面是URL()实例的接口列表:
interfaceURL{
protocol:USVString;
username:USVString;
password:USVString;
host:USVString;
hostname:USVString;
port:USVString;
pathname:USVString;
search:USVString;
hash:USVString;
readonlyorigin:USVString;
readonlysearchParams:URLSearchParams;
toJSON():USVString;
上述的USVString参数在JavaScript中会映射成字符串。
3.Query字符串
url.search可以获取到URL当中后面的query字符串:
consturl=newURL(
);
url.search;//=>'message=hello&who=world'
如果query参数不存在,url.search默认会返回一个空字符串'':
url1.search;//=>''
url2.search;//=>''
3.1解析query字符串
相比于获得原生的query字符串,更实用的场景是获取到具体的query参数。
获取具体query参数的一个简单的方法是利用url.searchParams属性。这个属性是URLSearchParams的实例。
URLSearchParams对象提供了许多用于获取query参数的方法,如get(param),has(param)等。
下面来看个例子:
url.searchParams.get('message');//=>'hello'
url.searchParams.get('missing');//=>null
url.searchParams.get('message')返回了message这个query参数的值——hello。
如果使用url.searchParams.get('missing')来获取一个不存在的参数,则得到一个null。
4.hostname
url.hostname属性返回一段URL的hostname部分:
url.hostname;//=>'example.com'
5.pathname
url.pathname属性返回一段URL的pathname部分:
url.pathname;//=>'/path/index.html'
如果这段URL不含path,则该属性返回一个斜杠/:
url.pathname;//=>'/'
6.hash
最后,我们可以通过url.hash属性来获取URL中的hash值:
url.hash;//=>'#bottom'
当URL中的hash不存在时,url.hash属性会返回一个空字符串'':
url.hash;//=>''
7.URL校验
当使用newURL()构造函数来新建实例的时候,作为一种副作用,它同时也会对URL进行校验。如果URL不合法,则会抛出一个TypeError。
让我们用这个非法URL来初始化URL()构造函数:
try{
}catch(error){
error;//=>TypeError,"FailedtoconstructURL:InvalidURL"
8.修改URL
除了获取URL的组成部分以外,像search,hostname,pathname和hash这些属性都是可写的——这也意味着你可以修改URL。
举个例子,让我们把一段URL从red.com修改成blue.io:
url.hostname='blue.io';
注意,在URL()实例中只有origin和searchParams属性是只读的,其他所有的属性都是可写的,并且会修改原来的URL。
9.总结
URL()构造函数是JavaScript中的一个能够很方便地用于解析(或者校验)URL的工具。
newURL(relativeOrAbsolute[,absoluteBase])中的第一个参数接收URL的绝对路径或者相对路径。当第一个参数是相对路径时,第二个参数必传且必须为第一个参数的基路径。
在新建URL()的实例以后,你就能很轻易地获得URL当中的大部分组成部分了,比如:
url.search获取原生的query字符串
url.searchParams通过URLSearchParams的实例去获取具体的query参数
url.hostname获取hostname
url.pathname获取pathname
url.hash获取hash值
那么你最爱用的解析URL的JavaScript工具又是什么呢?
随着车内屏幕越来越多,越来越大,驾驶者在开车过程中因操作屏幕而分心机率逐渐升高。众多汽车制造商均希望探索出一种降低或避免「驾驶员分心」的安全性技术。
手势,是指人手、手和手臂结合产生的动作,作为解决「驾驶者分神」这个痛点的解决方案之一,正在全世界的汽车制造商中掀起「热浪」。
△移动端常见交互手势
常见的手势如上图,分别为
为了满足手机屏幕外观改变,屏内显示内容越来越多元化的需求,设计师们也在探索屏内手势的新玩法。
△android底部导航栏按键从左至右分别为:返回上一级、返回主页、多任务
2017年iPhoneX的发布,正式开启了全面屏时代。为了替代Home键及android底部导航栏,各大手机厂商相继开始拥抱「全面屏手势交互」。
在车机系统中,部分汽车制造商也在积极迎接变化,比如理想one采用「三指下滑」的手势交互替代「返回主页」的图标按键。
△「三指下滑」表示返回主页
2019年的GoogleI/O大会上,新版本AndroidQ选择与IOS采用一样的手势操作逻辑,即在屏幕下方提供一个指示条,用户在左侧页面边缘右滑代表「返回上一级」、提示条区域上滑代表「返回主页」、提示条区域上滑并悬停代表「多任务」。
△android系统中的三种全面屏手势
随着全面屏手势在手机端的操作交互上达成一致,相信在不久的将来,也将越来越频繁的在车机端看到全面屏手势的「身影」。
当汽车与数字屏幕相遇,如何让屏幕与内饰结合的更加完美,又能突显品牌特性,似乎给内饰设计师带来了许多挑战与机遇,「一字屏」、「T字屏」、「7字屏」、「旋转屏」应运而生。
△拜腾M-Byte一字屏
△理想one的T字屏
△合创007的7字屏
△比亚迪王朝系列的旋转屏
与此同时,因为成本及技术的限制,汽车制造商的量产车型不得不在屏幕上做出妥协。理想one的妥协方案是利用3块屏幕组合,在视觉上形成「大长屏」的既视感。
要让3块屏幕「变」成一块屏幕,仅仅在视觉上做足功夫显然还不够,多屏联动手势交互也不能「缺席」。
理想one在停车模式下,用户长按并向左滑动,即可将副驾娱乐屏上的信息「甩动」至中控屏。
天际ME7不仅有3块屏幕组合而成的前排「一字屏」,还有2块后排乘客娱乐屏,5屏联动的手势交互,天际采用「手势+屏幕显示」来解决。
目前量产的汽车中,盲操手势主要是通过标准手势与声音反馈的组合来实现。
比如在理想one中,用户在空调屏上左右滑动可以调节风量,上下滑动调节温度,且系统通过声音反馈告知用户操作成功与否。
与盲操手势相比,隔空手势似乎科技感十足,备受汽车制造商的青睐,我们不仅可以在各种概念车上窥见它的踪影,在君马SEEK上,也可以实际操作一番。
君马SEEK提供8种隔空手势。
△左图:上一曲右图:下一曲
△左图:音量升高右图:音量降低
△左图:音乐播放/暂停右图:玫瑰花
与君马SEEK相同,宝马提供「向左」手势代表上一曲、「向右」手势代表下一曲,「yeah」手势代表播放或暂停。
但在许多其他操作上,宝马与君马的手势操作则各有特色。
在倒车影像中,手指向右挥动代表调整视角。
在手势交互上,拜腾也交出了自己的「成绩单」。
拜腾的手势识别共五种,手掌向下激活手势识别,手掌向上启动主页面,手指移动代表移动光标,ok手势代表确定,五指捏合可拖拽内容。
这些高大上的技术看起来令人兴奋,但在实际使用的过程中,依旧存在识别范围有限、识别精度不灵敏、识别后的响应速度慢等等问题,而各个厂家的手势识别没有形成统一的标准,且没有大规模在在用户中进行推广,必然会增加用户的学习成本。
参考文献:
汽车内手势的交互设计,是一个有趣又好玩的课题,但如何让这个课题在好玩但同时易用、好用,恐怕只有设计师不断思考,并不断采用一些用户测试的方法进行验证才能获得答案。
宋体字可以说是我们现在最常用的字体之一,一方面他与黑体一样,具有非常良好的可读性和易辨性,另一方面,他又比黑体更具有历史感和东方韵味,我们可以看到很多的教材、书籍内文或者官方文件,都是用的宋体字,甚至许多设计都会用一些比较有表现力的宋体字作为标题。所以可想而知,学习设计宋体字对我们的帮助有多大。正所谓欲知大道,必先知史。所以在讲如何设计宋体字之前,我们先来扒一扒宋体字的历史吧。
虽然说宋体字叫做宋体字,但是如果要追溯宋体字的起源,我们还得从唐朝说起。
唐朝时期,佛教在中国开始盛行开来,唐朝皇帝甚至派出唐僧师徒四人前往西天取经。
于是便出现了「抄经生」这种人肉印刷机。这篇经文便是当时唐朝的抄经生所抄写的,他们需要使用规整统一的楷体,文字的开头在同一水平线,而且每一列的字数统一规定为17或者19个字,方便字数的统计,像这一篇经文每一列就是17个字。
可是即便出现了大量的抄经生,依旧满足不了人们对经书的需求。于是聪明的中国人开始印刷经书,将经文刻在木板上,就可以实现大量的印刷了。
可是楷书刻起来是很不方便的。一方面,书法家写的楷书讲究起承转合、抑扬顿挫,不同的人写出来的字风格差异十分明显,例如颜真卿和赵孟頫他们所写的「宋」字就明显不同,即便用笔临摹都很难了,更别说雕刻出来了。
另一方面楷体由于是书写的字体,所以大多数笔画都是带有弧度的,而在木板上刻字,曲线是非常难刻的。
于是他们逐渐将曲线刻成直线,把笔画的弧形特征降低,也将楷体中相同的笔画进行规范了,这样的字体便是宋体字的前身。
我们可以看一下宋朝时期的刻本,这是南宋时期陈宅经籍铺所刊刻的《朱庆馀诗集》。这时,撇、捺等笔画的弯曲程度大大降低了,而竖笔和横笔也基本上变成笔直的直线了。不过宋朝时期刻本体的横画依旧是倾斜的,从中依然能很明显地看到楷体的痕迹。那么为什么宋体字会形成横细竖粗,横画后带三角形饰角的字形呢?
那是因为刻字的木板上是带有木纹的,如果垂直木头的纹理刻的话,笔画会比较容易断,需要加粗一些。而如果是顺着木纹刻的话,就没那么容易断,所以可以相对细一些。可是为什么是横画细,竖画粗呢?反过来不行吗。
那是因为在大多数的汉字中,横画都是比竖画多的。上海交大的郭曙纶教授对20902个汉字进行了统计,发现这些汉字的总笔画数量多达268479个,而其中横画有82682个,占30.8%,而竖画有51459个,占19.2%。可见,在汉字中横画是比竖画多的。所以如果将横画刻粗,竖画刻细的话,可能会使得字体过挤而不美观。
虽然说横画顺着木纹,比较不容易断,可是横画的两端还是会比较容易磨损的,所以工匠们一般会将横画的两端稍微刻大一些,形成饰角。
在明朝,宋体得到了进一步的简化,原本复杂精细的刀刻技法简化成了横、竖和斜三种,所以刻字工匠的门槛大大降低了,宋体字得到了真正的普及。我们同样来看一下明朝时期的刻本,这是明朝时期汲古阁刻印的《道德指归论》,这个时候的宋体横画已经基本变成水平了,虽然笔画依旧比较张扬,但是已经少了许多楷体的影子。所以从明朝时期开始的刻本体才能算作真正的宋体。
也是在明朝时期,宋体字传到了日本,所以现在日本将宋体字称为明朝体。
清朝是刻本最多的一个朝代,而宋体字在中国真正被确定统一称为「宋体字」也是发生在清朝。
了解了宋体字的历史后,我们可以发现宋体字的意义并非只是美观和易读而已,他是经过中华民族近千年传承、优化和改良的文化结晶,他的身上有着厚重的文化气息。也难怪中国、日本、韩国等受中华文化影响的国家会对宋体有独特的偏爱。接着我们就正式进入设计宋体字的教程部分,首先我们来了解一下宋体字的主要特征。
从楷体字转变为宋体,主要产生了三个特征,第一个是横平竖直,也就是说横画是水平的,竖画是垂直的。第二个特征是横画比较细,竖画比较粗。第三个特征是笔画上出现了三角形的装饰角。
可是仿宋体是不能够算是宋体字的。我们看仿宋体是不是觉得他和宋朝时期的刻本非常像呢?因为仿宋体是在民国时期,丁善之和丁辅之模仿宋刻本所设计出来的字体,所以仿宋体模仿的是宋朝刻本,而非宋体字,那么仿宋体当然也就不能算在宋体的行列里了。
接着我们来分析一下宋体字的气质。由于宋体诞生于明朝,具有非常悠长的历史,而黑体是在民国时期才产生的,所以宋体相对于黑体更能体现传统感、文化感的气质属性。
所以我们做现代风格的设计的时候,可以使用黑体。
而做比较具有传统风格的设计则可以用宋体。当然也并非说宋体就没办法做现代感的设计,通过对宋体体饰和中宫的设计,我们完全可以做出一款现代型的宋体。
先来说一下中宫,我们在之前的教程里说过,中宫越大,越显现代感,而中宫越小,则越有传统感。在宋体里也不例外。
我们再来看看这两个「東」字,很明显也是左边的「東」字更现代一些,而右边的「東」字传统一些。这两个字的区别在于体饰的不同。体饰越少越简洁,宋体就越显现代;体饰越多越复杂,就越显传统。
另外几何形的体饰也会给宋体带来现代感。
而传统宋体字的体饰则是具有手写感的,线条比较圆滑。
根据体饰和中宫的不同,我们可以大致地将宋体分为三大类。中宫小、体饰多且具有手写感的宋体归类为传统型宋体,中宫大、体饰少且为几何体饰的则归类为现代型宋体。而具有一定手写感的体饰,且中宫偏大的宋体,则归类为中间型的宋体。
除了中宫和体饰之外,我们还经常调整笔画粗细去适应宋体字不同的用途。首先我们先来讲讲正文的宋体。一般正文的字号都是比较小的,如果横画过细的话,会使得横画几乎看不见了,而如果横画过粗的话,笔画又会糊在一块了,所以为了让宋体字在小字号下也能清晰的显示,一般横画和竖画的粗细会控制在1:2到1:3左右,最大一般也不会超过1:4。
不过我们设计正文字体的机会还是比较少的,大多数时候我们都是需要设计比较具有张力的标题字。这个时候我们就可以尝试拉大横画和竖画的粗细差距。当横画和竖画的粗细差距非常大的时候,可以产生较强的视觉冲击力。画面中这三款标题宋体,都用了细横画搭配粗竖画。
有时候我们也可以反其道而行之,将横画加粗,让横画与竖画差不多的粗细。这样我们就可以获得一款非常醒目的宋体。这样的宋体有点像比较粗的黑体,既有醒目的特点,也保留了宋体优雅的属性。
当然,具有张力的标题宋体也并非一定要通过控制横竖笔画的粗细来塑造,通过设计一些有张力的体饰,同样可以让宋体字变得具有表现力。设计体饰是设计宋体字非常重要的一个环节,因为宋体字的大多数笔画是存在许多体饰的,我们除了要将体饰设计得好看之外,更重要的是让不同的体饰和谐共存。如果一个宋体字里存在的体饰都风格不一,那么这个宋体字看着就会不伦不类了。下面我就给大家介绍一个我比较常用的,设计宋体字体饰的方法。
在做字之前,我们要先确定我们想要做的字体的气质,是传统的,还是现代的?文艺的还是可爱的?又或者是其他的气质。因为我们前面也说到,体饰和中宫都会影响字体的气质,所以我们必须要确定了气质之后,才能动手去设计字体的中宫和体饰。
另外还要确定字体的用途,需要比较有张力的标题字体,还是需要具备阅读舒适性的正文字体,那我们也能确定文字的笔画粗细。
确定好了风格之后,我们就可以开始设计笔画了。那么我们先来回顾一下,汉字里的八个基本笔画,我们可以先把这八个笔画的体饰特征都设计好了,再去拼凑我们想要的字。
一般来说,我们设计宋体会先从横画开始设计。因为确定了横画之后,体饰的风格、体饰大小、笔画粗细等很多东西就都可以确定了。
我们前面已经介绍了这两种衬角分别具有现代感和传统感。
而这一个的衬角是一个比较圆润的圆形,他可以用来做比较可爱的宋体。
这一个衬角和刚刚的就正好相反,非常的非常尖锐,适合用来做比较恐怖的宋体。
还有一点要注意的是,如果竖画越粗的话,横画的衬角一般也要相应的变大一些。
因为宋体的横画本来就已经很细了,如果衬角还非常小的话,横画很容易就会被忽略掉了,横画末端的这个三角形起到了一定强调横线的作用。当然如果是故意要设计成小衬角或者无衬角的话就另当别论了。
横画做好之后,就可以开始设计竖画了。在书法中,竖画在起笔处会有一个顿笔,而收笔的地方会稍微往左侧偏一些,这样分别形成了宋体中竖画起笔和收笔的两处体饰。
那么我们应该怎么用横画推导出竖画呢?横画和竖画关联度最大的地方在横画三角形衬角和竖画上方衬角的这个地方。例如这一组都是直线加切角。
而这组都是曲线加圆角。
另外我们还能将这两个地方给联系起来,因为他们都是起笔的位置。如果横画的起笔是水平的话,那么竖画的起笔就应该是垂直的。
而如果横画的起笔是往外扩的话,那么竖画的起笔也可以往外扩张。
我一般还会将竖画的起笔和收笔的的地方关联起来,如果起笔是垂直的,那么收笔我也会设置成垂直的。
而如果起笔往外扩的话,那么收笔我也会往外扩形成书写曲线,这样整个竖画能看起来平衡一些。
接着来设计横折。书法中在这个转折的地方会有一个顿笔。所以在宋体的横折处也会形成一个装饰角。
其实横折这个笔画在设计好横画和竖画之后基本就已经出来了。只要将他们组合在一起,然后将横画的衬角往回缩小一些,横折就做好了。
讲完了横折我们顺便也讲一下这种口字的结构好了。口字结构由刚刚做好的横折加上一个竖线和一个去掉三角衬角的横线组成。然后我们需要做一些细微的调整。竖笔体饰的这个地方需要往上收一些,不要漏出来,这样的笔画看着能干净一些。
然后竖画入笔的地方也要往上提一些,让左右两边的体饰能够平衡。
最后加上横画,把衬角的部分裁去,注意两个竖线需要出头一些。这个口字就完成了。
然后来做撇和捺。书法里的撇起笔的地方有一个顿笔,所以宋体里,撇有一处体饰。
书法里捺则在起笔和收笔处各有一处转折。所以宋体里,捺则有两处体饰。
撇基本上可以从竖线轻易地推导出来,因为他们的起笔都是一样的,只要稍微调整一下起笔的角度就可以了。
而捺与撇是正好相反的,起笔细,收笔粗,所以捺的起笔需要缩小一些,但是需要保证这两个地方是相同的。而捺的收笔是一个比较独立的地方,只需要风格保持大致一致就好了。
接着来做提。在书法中,提的起笔一般是会有一个顿笔的,这一个顿笔与竖的起笔的顿笔是类似,所以在宋体中,提的起笔会有一个与竖类似的体饰。
提与竖起笔的体饰是差不多的,只是方向不同而已。
最后就只剩下点和钩两个基础笔画还没设计了。这两个笔画和别的笔画之间的联系不太大,同样也只需要保持整体笔画风格一致就好了。不过点和钩之间却存在着一定的联系的。最主要的是体现在这个地方,如果是尖角,那么点和钩最好都统一为尖角。
而如果点是圆滑过渡的,那么钩最好也是圆角。
另外还有如果点的这个位置是比较饱满的话,那么钩转折的位置也应该设计得饱满一些。
而如果是瘦瘦的点,钩转折的位置也要相应的瘦一些。
最后还有一个需要统一的地方,就是撇、点、钩等笔画的收笔必须要保持一致。可以是圆角、还是切角、尖角或者是其他特殊的角,收笔的大小也应该统一。
不过我们设计宋体字时,也并非一定要百分百遵循这一套设计方法,因为这一套设计理论是结合书法所推导出来的,而随着时代的发展,宋体字的形式和定义也不断被拓宽,例如一些比较新型的宋体,都会省略掉竖、撇、捺等笔画的体饰,让字体显得更简洁一些。所以如果大家想做一些比较创新的宋体字,而非传统严谨的字体的话,大可以放开手脚去设计,最终只要保证美观和和谐统一就好了。
我们在将所有笔画都设计完之后,就可以将笔画拼起来了,可是如果我们设计的笔画比较没有特点,最后拼凑出来的字体也就显得有些中规中矩,缺乏视觉张力。那么接下来我就给大家介绍几个让宋体字比较有张力的常用方法。
第一个是在宋体字的笔画之间加入连接线,模拟写字的连笔效果。
由于宋体字是用刀刻出来的字,基本上是不会有连笔的存在,而加入连笔线条就可以缓和宋体字刀刻的僵硬感,让文字显得更灵动。
第二个方式是将设计好的笔画松散的排列。
因为宋体具有文艺的气质,而将笔画松散地排列能够体现一种慵懒的文艺感,和宋体的气质是非常契合的。
不过这种方式最好能与词义吻合,例如团圆这个词应该是笔画凝结在一起更能符合团圆的词义,像这样做得松松垮垮的味道就有些不太对了。
第三个方式是省略横画。由于宋体字存在着三角衬角,所以即便省略掉了横线,依旧能够通过三角衬角判断横线的位置。
所以省略横画对宋体的识别度影响不大,并且能够增加宋体字的图形感。
第四个方式是断笔。
刚刚我们讲到了宋体存在着三角衬角,所以省略掉横画也不会过多的影响识别度。那么在断笔这里也是一样的道理,我们最好选择断开横画,因为这样对字体识别度的影响最小。
我们这节课的案例就是做韦礼安这首猫咪共和国的单曲封面。这是我从MV开头截的图。我们可以看到MV中猫咪共和国这五个字是手写的,给人一种可爱随意的感觉。那么我们这节课就尝试用宋体字来体现这种感觉。
那么我们对这款字体的定位就很明确了,是一款可爱的标题字体。
我们先在屏幕上打上猫咪共和国五个字作为字体骨骼的参考。这里我选择了思源宋体,因为思源宋体是一款现代型的字体,中宫比较大一些。太过紧凑的中宫不适合我们塑造可爱、随意的感觉。另外一个很重要的原因是,思源宋体虽然高贵,但是免费,如果我们改动的程度不大,也不会造成侵权。
为了让字体更憨一点,我们可以将文字压扁一点点,营造出一种老子一米五的感觉。然后就可以降低透明度,开始在这个参考骨架上秀一波操作了,接下来我们就一个笔画一个笔画地来设计。
首先因为是标题字体,所以我们希望做一个横画和竖画都差不多粗的宋体,这样会比较醒目一些。然后因为气质是可爱的,所以我把体饰设置成圆圆的,胖胖的。
我们用横画推导出竖画。体饰方面基本上就直接照搬了横画的体饰,因为横画的风格很明显了,竖画保持一致就可以了。
接着做横折。我们先将横画和竖画凑一起看看。这样会有两个比较大的问题,一个是竖线的体饰凸出来了一块,另一个是横画和竖画的衬角叠加在一块显得太大了。所以我们需要将衬角缩小一些。
接着做口字结构,我们将竖画放好之后,发现不用调整也挺平衡的,所以我们就直接用这一个口字。
然后撇和捺的起笔我们也可以直接用竖画的起笔推导出来。
值得注意的是,我们可以看一下这个撇,为了凸显这个笔画的可爱,所以我们笔画的粗细变化其实是很小的,为的是让收笔的地方比较钝一些,显得更人畜无害。
同样为了营造字体可爱的气质,我将捺的收笔也设计成圆弧收笔,而并非普通宋体的尖锐收笔。
接下来我们应该是要做提笔画的,可是我们发现这五个字里并没有提,所以我们就跳过他,直接做点和钩了。同样为了保证风格的一致,这个点的粗细变化也不大,而且头特别钝。
点和钩之间是有关联的,这三组地方分别互相对应。
①端点应该都比较大,比较钝一些;
②圆滑地过渡;
③屁股的地方比较饱满一些。
将做好的笔画放上去,接着还需要做一些调整,因为我们现在用的还是思源宋体的骨架,这个骨架和我们设计的笔画并不一定搭。我对字面大小,视错觉等进行了一定的修正,然后还将中宫稍微扩大了一些。这时候我们会发现,调整过后的这组字依然显得太过正经,还是摆脱不了思源宋体正文字的属性,而我们想做的字应该是可爱、慵懒的标题字。
不知道大家还记不记得我们刚刚讲的宋体字四种增加张力的套路。很明显松散笔画这种方式最适合随机慵懒的感觉,那么我们来试试看。
我们先将这五个字的字距拉开一些,方便我们调整笔画。然后将笔画松散地排列开。
接着我们还需要做一些调整,这样看起来太粗糙了。我们将点、撇、捺等笔画调短一些,让他们具有点的感觉。因为点的构成具有随机和活泼的气质。
然后将重心往下压,因为重心靠下的字体会显得比较憨一些,那么我们这一组字就完成了。
最后我们用这个字来做一个版面,先建立一个单曲封面125mm*125mm的画板,并设置5mm的页边距和7*7的网格。
然后我们放入一张猫的照片作为版面的主体,占据右下角的5.5栏。
接着我们将做好的字体放在左上角,和右下角的猫做对角线的呼应,可是这么摆放好像还是不够好玩。
所以我们加入英文和线条做成一个文字组合。
最后在版面的左下角加入其它信息,这个单曲封面就做好了。
效果还不错吧。
最后我们来总结一下这节课。首先我们给大家扒了一下宋体字的历史,知道了宋体字诞生于明朝,可是最早能够追溯到唐朝。接着分析了宋体字的特征和气质,宋体字相较黑体字具有传统、文化的属性,可是也能通过对体饰、中宫的控制,设计出具有现代感的宋体。然后我们教给了大家一套设计宋体字体饰的方法,最后是四个增加宋体字张力的常用手法。那么我们这节课就到这里,我是千树,我们下次再见。
为什么需要额外的类型检查?
TypeScript只在编译期执行静态类型检查!实际运行的是从TypeScript编译的JavaScript,这些生成的JavaScript对类型一无所知。编译期静态类型检查在代码库内部能发挥很大作用,但对不合规范的输入(比如,从API处接收的输入)无能为力。
运行时检查的严格性
至少需要和编译期检查一样严格,否则就失去了编译期检查提供的保证。
如有必要,可以比编译期检查更严格,例如,年龄需要大于等于0。
运行时类型检查策略
定制代码手动检查
灵活
可能比较枯燥,容易出错
容易和实际代码脱节
使用校验库手动检查
比如使用joi:
importJoifrom"@hapi/joi"constschema=Joi.object({firstName:Joi.string().required(),lastName:Joi.string().required(),age:Joi.number().integer().min(0).required()});
容易编写
手动创建JSONSchema
例如:
使用标准格式,有大量库可以校验。
JSON很容易存储和复用。
可能会很冗长,手写JSONSchema可能会很枯燥。
需要确保Schema和代码同步更新。
自动创建JSONSchema
基于TypeScript代码生成JSONSchema
--比如typescript-json-schema这个工具就可以做到这一点(同时支持作为命令行工具使用和通过代码调用)。
--需要确保Schema和代码同步更新。
基于JSON输入示例生成
--没有使用已经在TypeScript代码中定义的类型信息。
--如果提供的JSON输入示例和实际输入不一致,可能导致错误。
--仍然需要确保Schema和代码同步更新。
转译
例如使用ts-runtime。
这种方式会将代码转译成功能上等价但内置运行时类型检查的代码。
比如,下面的代码:
interfacePerson{firstName:string;lastName:string;age:number;}consttest:Person={firstName:"Foo",lastName:"Bar",age:55}
会被转译为:
importtfrom"ts-runtime/lib";constPerson=t.type("Person",t.object(t.property("firstName",t.string()),t.property("lastName",t.string()),t.property("age",t.number())));consttest=t.ref(Person).assert({firstName:"Foo",lastName:"Bar",age:55});
这一方式的缺陷是无法控制在何处进行运行时检查(我们只需在输入输出的边界处进行运行时类型检查)。
顺便提一下,这是一个实验性的库,不建议在生产环境使用。
运行时类型派生静态类型
比如使用io-ts这个库。
这一方式下,我们定义运行时类型,TypeScript会根据我们定义的运行时类型推断出静态类型。
运行时类型示例:
importtfrom"io-ts";constPersonType=t.type({firstName:t.string,lastName:t.string,age:t.refinement(t.number,n=>n>=0,'Positive')})
从中提取相应的静态类型:
interfacePersonextendst.TypeOf
以上类型等价于:
interfacePerson{firstName:string;lastName:string;age:number;}
类型总是同步的。
io-ts很强大,比如支持递归类型。
需要将类型定义为io-ts运行时类型,这在定义类时不适用:
--有一种变通的办法是使用io-ts定义一个接口,然后让类实现这个接口。然而,这意味着每次给类增加属性的时候都要更新io-ts类型。
不容易复用接口(比如前后端之间使用同一接口),因为这些接口是io-ts类型而不是普通的TypeScript类型。
基于装饰器的类校验
比如使用class-validator这个库。
基于类属性的装饰器。
和Java的JSR-380BeanValidation2.0(比如HibernateValidator就实现了这一标准)很像。
--此类JavaEE风格的库还有typeorm(ORM库,类似Java的JPA)和routing-controllers(用于定义API,类似Java的JAX-RS)。
代码示例:
import{plainToClass}from"class-transformer";import{validate,IsString,IsInt,Min}from"class-validator";classPerson{@IsString()firstName:string;@IsString()lastName:string;@IsInt()@Min(0)age:number;}constinput:any={firstName:"Foo",age:-1};constinputAsClassInstance=plainToClass(Person,inputasPerson);validate(inputAsClassInstance).then(errors=>{//错误处理代码});
需要对类进行检查时很有用。
可以用来检查接口(定义一个实现接口的类)。
注意:class-validator用于具体的类实例。在上面的代码中,我们使用它的姊妹库class-transformer将普通输入转换为Person实例。转换过程本身不进行任何类型检查。
为什么要做数据可视化?
在一个设计项目里,
到底要从哪一个角度切入,才能经得推敲?
每个数据可视化,
模拟美国1790-2016移民的时代树轮
作者从自然中的树轮提取灵感,把树的生长迁移到移民变化上,发现了美国通过类似的移民过程。
现居上海,在澎湃新闻担任数据可视化设计师。
自学编程两年多,最初是为了做更酷的数据可视化作品,误打误撞放置了十款设计小工具,变成了模仿的设计玩具制造玩家,希望用编程去解锁设计/数据可视化的更多可能性。
●
为理清垃圾分类规则,亚赛及团队从上海市垃圾分类查询平台上筛选了2055件物品的垃圾分类信息,看可视化教你如何分类垃圾。
项目封面,垃圾从屏幕上方掉落,通过鼠标可以进行交互。
世界杯落幕,一个月来32支球队打入了169粒进球。如果俯瞰足球场,将所有进球在一张图上绘出,有某种绝妙的,惊险的,乌龙的瞬间?
红色向上为相对积极,蓝色行下为相对消极,每根柱子的长度代表情绪的大小,通过3000多条微博看到她在微博内容背后自己的情绪斗争。
02
数据可视化
创作的7个步骤
景点事件:某种前几天的女排十一连胜,就可以提前找数据做一个梳理类的题。
1.获取数据,无所谓是来自文件,磁盘亦或者网络等;
2.分析数据结构,分类排序;
3.过滤,去掉所有不感兴趣的数据;
4.综合使用数学,统计,模式识别等方法来挖掘出一些特征数据;
5.选择某种树状图,列表,树等的可视化模型来替换数据;
6.精炼基本表示法,使数据插入的更清楚,预期视觉效果;
7.添加一些用于控制或操作数据的交互方法。
这是亚赛做过一个关于春节禁放烟花的选题,把某些城市的除夕中午12点到春节中午12点变成一朵24片花瓣(代表24小时)的烟花,对比2017年和2018年两年的数据。
通过环境质量数据来看烟花禁放政策下的效果,看到不同地区不同政策带来的影响。
03
如今,PageSpeed(页面速度)的意义非凡。
什么是PageSpeed
对于任何给定的用户来说,页面缓慢的原因可能有很多,你的用户可能正在火车上,通过信号弱的隧道,或者他们的互联网速度很慢。
通过遵循最佳实践,我们至少可以通过确保我们已经做了最好的工作来缓解问题。
现在你知道它是什么了,下面我就来教你如何提高页面速度。
注意:这些是按难度顺序列出的。在某个时候,你将需要开发人员来帮助优化你的网站。
1.使用CDN
一定要检查你的CDN配置是否正确——在你的CDN中缓存丢失意味着CDN必须向你的源服务器请求资源,这就违背了使用CDN的初衷!所以,你的CDN必须要有一个正确的配置。
2.启用GZIP压缩
在一些CDN上,GZIP压缩只是一个标有"启用压缩"的复选框。这大概会减少一半的文件大小,你的用户需要下载文件才能使用你的网站,你的用户会因此而喜欢你。
3.使用较小的图像
这意味着既要降低分辨率(例如,摄像头的输出从4000x3000像素减少到网络的1000x750),又要通过压缩文件来减小尺寸。
如果你的网站使用WordPress,则有一些插件会在你上传图片时自动为你执行此操作。
4.减少页面发出的请求数
目标是减少加载页面顶部部分所需的请求数量。
这里有两种思维方式,你可以:
通过删除花哨的动画或不能改善网站体验的图像,减少整个页面上的请求数量。
或者,你可以通过使用延迟加载来推迟优先级不高的加载内容。
5.尽可能避免重定向
重定向会大大降低网站速度。使用响应式CSS并从一个域为你的网站提供服务,而不是为移动用户提供特殊的子域。
有些重定向是不可避免的,比如www->根域或根域->www,但你的大部分流量不应该经历重定向来查看你的网站。
有两个部分:
7.减少并删除阻止渲染的JavaScript
外部脚本(特别是那些用于营销的外部脚本)往往会写得很差,会阻止你的页面加载,直到它运行完毕。
你可以通过将外部脚本标记为异步来减少这种影响:
你还可以延迟加载市场营销脚本,直到用户开始滚动为止:
window.addEventListener(
'scroll',
()=>
setTimeout(()=>{
//在此插入营销片段
},1000),
{once:true}
8.缩小CSS和JS
Minifying是指使用工具来删除空格、换行符和缩短变量名。通常情况下,这将作为构建过程的一部分自动完成。
要缩小JavaScript,请查看UglifyJS。
要缩小CSS,请查看cssnano。
9.删除未使用的CSS
自Chrome59(2017年4月发布)以来,在ChromeDevTools中可以看到未使用的JS和CSS。
要看这个,打开DevTools,显示控制台抽屉(就是点击Esc时出现的那个烦人的东西),点击左下角的三个小点,打开"Coverage",就可以看到。
点击带有重新加载图标的按钮将刷新页面,并审核CSS和JS的使用情况。
在GoogleChrome浏览器中审核初始页面时,外观如下所示:
10.定期跟踪网站速度
在你的网站速度变慢的瞬间,修复网站速度问题就会容易得多。除此之外,如果你把检查网站速度作为一种习惯,那么修复网站速度慢的问题就会变成一件小得多的事情。
有免费的工具可以监视你网站的速度,其中的两个是WebPageTest和GoogleLighthouse。这些工具的缺点是你需要记住在进行更改之前和之后都必须运行它们。
PerfBeacon是一项服务(由本文的作者创建),该服务定期运行GoogleLighthouse,并让你随时跟踪网站的速度。