2017春节小结

目标

又是一年春节假期,而这个春节我制定了几个目标:

  • 完成100公里的跑步计划
  • 完成一个基于微信的活动平台
  • 完成WorkStation一期计划的80%

春节中的事情还是比较琐碎的,过节的常规事情,时不时还要处理下公司服务器的报警问题等。所以能完成以上几个事情是极好的。

总结

很快,假期到了尾声,也是对照目标做总结的时候了。

  • 目标一:「完成100公里的跑步计划」

这是我优先级最高的目标,长期的坐着不运动让人非常不舒服,长时间下来代码都不能愉快的写了。之前都是断断续续的跑着,最高纪录,也就是连续7天10公里,这次也算是个小挑战。锻炼这种东西,不能三天打渔两天晒网,否则根本没用。身体为先,我做到了每天坚持跑,即便是在只有1℃刮着4级风的日子。

2017后面的日子,就是要尽量做到一周至少五次,没理由不坚持!

查看全文

使用PHP-Imagick快速实现漂亮的复古效果

先来看下效果图

复古效果展示

要实现以上效果,我们先用Photoshop用以下步骤实现。

  • 打开原图
  • 新建图层,使用颜色#C0FFFF填充后,不透明度设为44%,图层混合模式为柔光
  • 新建图层,使用颜色#000699填充后,不透明设置为48%,图层混合模式为排除
  • 合并图层

用PHP代码,也就只需要按照以上步骤实现即可,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//打开图片
$im = new Imagick('./hebe.jpg');
//新建图层,使用颜色`#C0FFFF`填充后,不透明度设为`44%`
$layer = new Imagick();
$layer->newImage($im->getImageWidth(), $im->getImageHeight(), '#C0FFFF');
$layer->setImageOpacity (0.44);
//叠加到原图上,图层混合模式为`柔光`
$im->compositeImage($layer, Imagick::COMPOSITE_SOFTLIGHT, 0, 0);
//新建图层,使用颜色`#000699`填充后,不透明设置为`48%`
$layer = new Imagick();
$layer->newImage($im->getImageWidth(), $im->getImageHeight(), '#000699');
$layer->setImageOpacity (0.48);
//叠加到原图上,图层混合模式为`排除`
$im->compositeImage($layer, Imagick::COMPOSITE_EXCLUSION, 0, 0);
//完成!
$im->writeImage('./vintage.jpg');

查看全文

ES2015入门系列11-模块 Modules

看一下官方介绍:

Language-level support for modules for component definition.

JS在ES2015开始原生支持模块化开发,我们之前也曾借助于诸如:

  • AMD
  • CommonJS

等的模块加载器进行过模块化开发,我想说的是那些都没有今天要讲的简单好用。

⚠️ 警告,正式版中的ES2015中没有模块加载器,所以我们依然需要之前的模块加载器帮助我们。

先来介绍下语法(官方示例代码):

1
2
3
4
5
6
7
8
9
10
//lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
//app.js
import * as math from 'lib/math';
import {sum, pi} from 'lib/math';
console.log("2π = " + math.sum(math.pi, math.pi));
  • 模块中对象暴露

只需要 export xx 即可,可以是任何类型的对象。

查看全文

ES2015入门系列10-类 classes

OK, 我们继续,这次来聊聊类。

内有 Jon Snow大战异鬼, 😄

熟悉后端的朋友们对类肯定都不陌生,如下面一段PHP的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Human
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
public function introduce()
{
echo '你好,我叫 ' . $this->name . PHP_EOL;
}
}
$jack = new Human('Jack');
$jack->introduce();

上面的代码,我们创建了一个叫Human的类,初始化的时候传入名字,还有一个自我介绍的方法。

同样的功能到了JS的世界呢? 且看下面的代码(ES5):

1
2
3
4
5
6
7
8
9
10
var Human = function(name) {
this.name = name;
};
Human.prototype.introduce = function() {
console.log('你好,我叫 ' + this.name);
};
var jack = new Human('Jack');
jack.introduce();

对了,你没有看错,在JS的世界中,我们就是这么来实现类的开发的, 总感觉哪里不舒服对吧?

到了ES2015(ES6), 事情就变得美好了,一起来看看下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Human {
constructor(name) {
this.name = name;
}
introduce() {
console.log(`你好,我是 ${this.name}`);
}
}
let jack = new Human('Jack');
jack.introduce();

查看全文

Hexo插件之自动摘要生成器(hexo-excerpt)

Hexo 默认没有对列表页面进行摘要处理,即列表页面会把整个文章内容抛出,很吓人对不对?

除非手动在内容中增加:

1
<!-- more -->

本插件通过注册generator对所有文章在生成的时候进行处理,如果文章内容含有10个一级html标签,那么取这10个做为列表页面摘要,否则全部显示。

更新 v1.1.0

  • 支持传统的分割模式

用到了htmlparser2模块。

核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let nodes = [];
let parser = new htmlparser.Parser(new htmlparser.DomHandler((err, dom) => {
if (!err) {
nodes = dom;
}
}), {
decodeEntities: false
});
parser.write(post.content);
parser.done();
if (nodes.length > 10) {
let stopIndex = 0;
for (let i = 0; i < nodes.length; i++) {
if (nodes[i].type === 'tag') {
if (++stopIndex > 9) {
break;
}
}
}
nodes = nodes.slice(0, stopIndex);
post.excerpt = (nodes.map(node => domutils.getOuterHTML(node))).join('');
}

Github仓库:

查看全文

ES2015入门系列9-Babel和Rollup

通过前面章节的讲解,大家对ES2015的一些新语法有了初步的理解,之前我们的测试代码都可以直接放入 Chrome Console 中直接运行,为了更好的学习后面的面向对象和模块开发,我先用一章介绍一下 Babel 和 Rollup。

ES2015虽然够好用,奈何没有浏览器对其可以完全支持,本文书写时间,Chrome开发版号称已经支持99%的ES2015特性。

所以,我们需要借助一个可以帮助我们将ES6代码翻译为浏览器都100%支持的ES5代码的工具,这就是本文的主角之一:Babel

打开Babel官网, 可以看到大大的介绍:

Babel is a JavaScript complier. Use next generation JavaScript today.

Babel是Javascript编译器,可以让我们现在就可以使用新的语法写JavaScript,而不用担心浏览器兼容的问题。

开始安装:

本系列假定读者都有NodeJS使用经验,如果还没有,赶紧去这里了解并安装吧。

我们可以使用

1
npm install --global babel-cli

查看全文

ES2015入门系列8-新对象特性

继续以代码进行展开, 在ES5中,如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function makeDuckToy() {
var name = '鸭子';
var color = '黄色';
return {
name: name,
color: color,
quacks: function() {
console.log('嘎嘎嘎~~~');
}
}
}
var duck = makeDuckToy();
console.log(duck.name); // 鸭子
console.log(duck.color); // 黄色
duck.quacks(); //嘎嘎嘎~~~

ES2015为对象带来的新特性:

  • 属性简写

如果属性名称和变量名称一致,那么可以直接用省略变量名,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function makeDuckToy() {
let name = '鸭子';
let color = '黄色';
return {
name,
color,
quacks: function() {
console.log('嘎嘎嘎~~~');
}
}
}
let duck = makeDuckToy();
console.log(duck.name); // 鸭子
console.log(duck.color); // 黄色
duck.quacks(); //嘎嘎嘎~~~
  • 方法简写

方法可以省略冒号以及function关键字, 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function makeDuckToy() {
let name = '鸭子';
let color = '黄色';
return {
name,
color,
quacks() {
console.log('嘎嘎嘎~~~');
}
}
}
let duck = makeDuckToy();
console.log(duck.name); // 鸭子
console.log(duck.color); // 黄色
duck.quacks(); //嘎嘎嘎~~~
  • 解构赋值

查看全文

ES2015入门系列7-模版字符串

说到 模版字符串 (Template strings or Template literals), 我们先来看看在ES5中,我们遇到的问题:

假设我们需要拼接一段html字符串,常规的做法如下:

1
2
3
4
5
6
var text = 'ES5 sucks!';
var html = '\
<div> \
<p>' + text + '</p>\
</div>';
console.log(html);

或者:

1
2
3
4
5
6
7
var text = 'ES5 sucks!';
var html = [
'<div>',
'<p>' + text + '</p>',
'</div>'
].join('');
console.log(html);

写的很难受对不对?到了ES2015, 有了 模版字符串 后,事情就变得简单了。

模版字符串,就是用 `` 包裹起来的字符串, 如:

1
2
3
4
5
6
let html = `
<div>
<p>ES5 sucks!</p>
</div>
`;
console.log(html);

在其中,我们还可以使用 ${变量名}, 直接引用变量,而不用字符串拼接了,如:

1
2
3
4
5
6
7
let text = 'ES5 sucks!';
let html = `
<div>
<p>${text}</p>
</div>
`;
console.log(html);

查看全文

ES2015入门系列6-Rest和Spread

ES2015为我们带来了一个新的操作符: ,

  • 用于定义函数参数的地方,称之为 Rest
  • 用于调用函数的地方,称之为 Spread

我们一个个来分析:

  • Rest

写程序的时候或多或少都会有,传入不定参数给一个函数的需求,如,给一个班级加入学生名单,可以一次给一个,也可以一次给多个,以前的做法,可能是传入数组,或者定义2个方法,一个传入单个学生,一个传入学生数组,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class ClassRoom {
constructor(name) {
this.name = name;
this.students = [];
}
addStudent(name) {
this.students.push(name);
}
addStudents(names) {
this.students = this.students.concat(names);
}
listStudents() {
console.log(this.students);
}
}
const classRoom = new ClassRoom('三年二班');
classRoom.addStudent('张三');
classRoom.addStudents(['李四', '王五']);
classRoom.listStudents();

有了 Rest 我们的代码就简单了,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ClassRoom {
constructor(name) {
this.name = name;
this.students = [];
}
addStudents(...names) {
this.students = this.students.concat(names);
}
listStudents() {
console.log(this.students);
}
}
const classRoom = new ClassRoom('三年二班');
classRoom.addStudents('张三');
classRoom.addStudents('李四', '王五');
classRoom.listStudents();

代码中的…names, 意思就是: 从我开始不管后面有多少参数,请帮我把它们组成数组给我后面的参数。 如此一来,也可以这样,

1
2
3
4
5
function callFriends(via, ...friends) {
console.log('使用' + via + '通知: ' + friends.join(',') + '等' + friends.length + '个好友');
}
callFriends('QQ', '张三');
callFriends('电话', '张三', '李四', '王五');

查看全文

ES2015入门系列5-解构赋值

用过ReactNative的同学肯定见过类似下面的代码:

1
import { Text, View } from 'react-native';

这就是ES2015为JavaScript带来的另一个新的语法:解构赋值。

解构赋值(Destructuring assignment), 是用来让我们从数组或者对象中提取数据赋值给不同的变量。

语法如下:

  • 从数组中解构赋值
1
let [a, b] = [1, 2];
  • 从对象中解构赋值
1
let {a, b} = {a: 1, b: 2}

PHP开发者有没有觉得很眼熟? 对了,这不就是:

查看全文