初始化
This commit is contained in:
commit
5efd5b9c40
129 files changed
+16739
No files matched your search
@@ -0,0 +1,7 @@
|
|||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
db.json
|
||||||
|
*.log
|
||||||
|
node_modules/
|
||||||
|
public/
|
||||||
|
.deploy*/
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
# Hexo Configuration
|
||||||
|
## Docs: https://hexo.io/docs/configuration.html
|
||||||
|
## Source: https://github.com/hexojs/hexo/
|
||||||
|
|
||||||
|
# Site
|
||||||
|
title: 程序猿的世界
|
||||||
|
subtitle: ''
|
||||||
|
description: ''
|
||||||
|
keywords:
|
||||||
|
author: 卑鄙的好人
|
||||||
|
language: zh-CN
|
||||||
|
timezone: ''
|
||||||
|
|
||||||
|
# URL
|
||||||
|
## If your site is put in a subdirectory, set url as 'http://example.com/child' and root as '/child/'
|
||||||
|
url: http://example.com
|
||||||
|
root: /
|
||||||
|
permalink: :year/:month/:day/:title/
|
||||||
|
permalink_defaults:
|
||||||
|
pretty_urls:
|
||||||
|
trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
|
||||||
|
trailing_html: true # Set to false to remove trailing '.html' from permalinks
|
||||||
|
|
||||||
|
# Directory
|
||||||
|
source_dir: source
|
||||||
|
public_dir: public
|
||||||
|
tag_dir: tags
|
||||||
|
archive_dir: archives
|
||||||
|
category_dir: categories
|
||||||
|
code_dir: downloads/code
|
||||||
|
i18n_dir: :lang
|
||||||
|
skip_render:
|
||||||
|
|
||||||
|
# Writing
|
||||||
|
new_post_name: :title.md # File name of new posts
|
||||||
|
default_layout: post
|
||||||
|
titlecase: false # Transform title into titlecase
|
||||||
|
external_link:
|
||||||
|
enable: true # Open external links in new tab
|
||||||
|
field: site # Apply to the whole site
|
||||||
|
exclude: ''
|
||||||
|
filename_case: 0
|
||||||
|
render_drafts: false
|
||||||
|
post_asset_folder: false
|
||||||
|
relative_link: false
|
||||||
|
future: true
|
||||||
|
highlight:
|
||||||
|
enable: true
|
||||||
|
line_number: true
|
||||||
|
auto_detect: false
|
||||||
|
tab_replace: ''
|
||||||
|
wrap: true
|
||||||
|
hljs: false
|
||||||
|
prismjs:
|
||||||
|
enable: false
|
||||||
|
preprocess: true
|
||||||
|
line_number: true
|
||||||
|
tab_replace: ''
|
||||||
|
|
||||||
|
# Home page setting
|
||||||
|
# path: Root path for your blogs index page. (default = '')
|
||||||
|
# per_page: Posts displayed per page. (0 = disable pagination)
|
||||||
|
# order_by: Posts order. (Order by date descending by default)
|
||||||
|
index_generator:
|
||||||
|
path: ''
|
||||||
|
per_page: 10
|
||||||
|
order_by: -date
|
||||||
|
|
||||||
|
# Category & Tag
|
||||||
|
default_category: uncategorized
|
||||||
|
category_map:
|
||||||
|
tag_map:
|
||||||
|
|
||||||
|
# Metadata elements
|
||||||
|
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
|
||||||
|
meta_generator: true
|
||||||
|
|
||||||
|
# Date / Time format
|
||||||
|
## Hexo uses Moment.js to parse and display date
|
||||||
|
## You can customize the date format as defined in
|
||||||
|
## http://momentjs.com/docs/#/displaying/format/
|
||||||
|
date_format: YYYY-MM-DD
|
||||||
|
time_format: HH:mm:ss
|
||||||
|
## updated_option supports 'mtime', 'date', 'empty'
|
||||||
|
updated_option: 'mtime'
|
||||||
|
|
||||||
|
# Pagination
|
||||||
|
## Set per_page to 0 to disable pagination
|
||||||
|
per_page: 10
|
||||||
|
pagination_dir: page
|
||||||
|
|
||||||
|
# Include / Exclude file(s)
|
||||||
|
## include:/exclude: options only apply to the 'source/' folder
|
||||||
|
include:
|
||||||
|
exclude:
|
||||||
|
ignore:
|
||||||
|
|
||||||
|
# Extensions
|
||||||
|
## Plugins: https://hexo.io/plugins/
|
||||||
|
## Themes: https://hexo.io/themes/
|
||||||
|
theme: butterfly
|
||||||
|
|
||||||
|
# Deployment
|
||||||
|
## Docs: https://hexo.io/docs/one-command-deployment
|
||||||
|
deploy:
|
||||||
|
type: ''
|
||||||
Generated
+2811
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "hexo-blog",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "hexo generate",
|
||||||
|
"clean": "hexo clean",
|
||||||
|
"deploy": "hexo deploy",
|
||||||
|
"server": "hexo server"
|
||||||
|
},
|
||||||
|
"hexo": {
|
||||||
|
"version": "5.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"hexo": "^5.0.0",
|
||||||
|
"hexo-generator-archive": "^1.0.0",
|
||||||
|
"hexo-generator-category": "^1.0.0",
|
||||||
|
"hexo-generator-index": "^2.0.0",
|
||||||
|
"hexo-generator-tag": "^1.0.0",
|
||||||
|
"hexo-migrator-wordpress": "^2.1.2",
|
||||||
|
"hexo-renderer-ejs": "^1.0.0",
|
||||||
|
"hexo-renderer-marked": "^3.0.0",
|
||||||
|
"hexo-renderer-pug": "^1.0.0",
|
||||||
|
"hexo-renderer-stylus": "^2.0.1",
|
||||||
|
"hexo-server": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: {{ title }}
|
||||||
|
tags:
|
||||||
|
---
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: {{ title }}
|
||||||
|
date: {{ date }}
|
||||||
|
---
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
title: {{ title }}
|
||||||
|
date: {{ date }}
|
||||||
|
tags:
|
||||||
|
---
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
---
|
||||||
|
title: Angular CLI 之初体验
|
||||||
|
tags: []
|
||||||
|
id: '143'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-09-20 17:13:04
|
||||||
|
---
|
||||||
|
|
||||||
|
[**Angular CLI**](https://cli.angular.io/)是一个**命令行界面**工具,它可以创建项目、添加文件以及执行一大堆开发任务,比如测试、打包和发布。 比起需要自己去搭建工作流,**[Angular CLI](https://cli.angular.io/)** 可以为你省去这些繁琐的工作,直接进行项目的开发。
|
||||||
|
|
||||||
|
## 配置开发环境
|
||||||
|
|
||||||
|
1. 安装最新版本的node,angular官方要求**node `6.9.x` 和 npm `3.x.x` 以上的版本。** 具体安装请参考 [node官网](http://nodejs.cn/) ,安装过程不再赘述。
|
||||||
|
2. 全局安装 [**Angular CLI**](https://cli.angular.io/)
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install -g @angular/cli
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 创建新项目
|
||||||
|
|
||||||
|
1. 打开终端窗口 运行下列命令来生成一个新项目以及应用的骨架代码:
|
||||||
|
|
||||||
|
```
|
||||||
|
ng new myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 进入项目目录,并启动服务器。
|
||||||
|
|
||||||
|
```
|
||||||
|
cd myapp
|
||||||
|
ng serve --open
|
||||||
|
```
|
||||||
|
|
||||||
|
ng serve命令会启动开发服务器,监听文件变化,并在修改这些文件时重新构建此应用。 使用--open(或-o)参数可以自动打开浏览器并访问http://localhost:4200/。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## 设置代理
|
||||||
|
|
||||||
|
1. 我们开发的时候,有时需要对接口做代理,**[Angular CLI](https://cli.angular.io/)**同样给我们提供了设置代理的方式
|
||||||
|
|
||||||
|
首先在项目的根目录下创建一个**proxy.conf.json** 文件
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"/data": {
|
||||||
|
"target": "http://xxx.xxx.xxx.xxx:8080",
|
||||||
|
"secure": false,
|
||||||
|
"changeOrigin": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
"/data"是接口所包含的字符,target则是代理的ip和端口号
|
||||||
|
|
||||||
|
2. 然后在项目的根目录打开终端,运行下面的指令:
|
||||||
|
|
||||||
|
```
|
||||||
|
ng serve --proxy-config proxy.conf.json
|
||||||
|
```
|
||||||
|
|
||||||
|
这样代理的设置就完成了。
|
||||||
|
|
||||||
|
|
||||||
|
## 样式编译
|
||||||
|
|
||||||
|
**[Angular CLI](https://cli.angular.io/)** 支持sass、less、stylus等方式编译样式
|
||||||
|
|
||||||
|
1. 在创建项目时可以设置编译方式:
|
||||||
|
|
||||||
|
```
|
||||||
|
ng new myapp --style=sass
|
||||||
|
ng new myapp --style=less
|
||||||
|
ng new myapp --style=stylus
|
||||||
|
```
|
||||||
|
|
||||||
|
上面分别是创建项目时设定的样式编译方式:sass、less、stylus
|
||||||
|
|
||||||
|
2. 当然,你也可以在手动修改,在项目根目录下找到 **.angular-cli.json**
|
||||||
|
|
||||||
|
```
|
||||||
|
"defaults": {
|
||||||
|
"styleExt": "styl",
|
||||||
|
"component": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
defaults下面的styleExt就是你要设定的编译方式,这里采用了stylus,stylus的后缀为styl,其他的方式设置对应的后缀名。
|
||||||
|
|
||||||
|
然后继续在该文件中找到
|
||||||
|
|
||||||
|
```
|
||||||
|
"styles": [
|
||||||
|
"styles.styl"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
全改完了之后,不要忘了把项目**根目录**里的css文件和**src/app**里的css文件也改成相应的后缀
|
||||||
|
|
||||||
|
|
||||||
|
## 打包编译后资源引入根目录
|
||||||
|
|
||||||
|
**[Angular CLI](https://cli.angular.io/)** 打包编译后,引入的资源都是"/"根目录引入,但有时候我们的项目可能并不是存放在域名的根目录,所以这种情况就需要我们设置一下引入资源的根目录了
|
||||||
|
|
||||||
|
1. 打开src目录下面的**index.html**文件,在<head>标签里面有个base标签
|
||||||
|
|
||||||
|
```
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>myapp</title>
|
||||||
|
<base href="/">
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<app-root></app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
base标签默认是"/"根目录
|
||||||
|
|
||||||
|
2. 然后我们回到整项目的根目录下面找到**package.json**文件,打开文件,找到"scripts",修改"build"的值
|
||||||
|
|
||||||
|
```
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve --proxy-config proxy.conf.json",
|
||||||
|
"build": "ng build --prod --bh /pages/myapp/",
|
||||||
|
"test": "ng test",
|
||||||
|
"lint": "ng lint",
|
||||||
|
"e2e": "ng e2e"
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
然后在命令行中输入
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
等待编译完成后,在dist目录下的**index.html**文件中的base标签的值就变成你之前设置的目录了,引入的资源放到正式环境也可以正常访问。
|
||||||
|
|
||||||
|
当然,你也可以不设置**package.json**文件,直接在命令行输入
|
||||||
|
|
||||||
|
```
|
||||||
|
ng build --prod --bh /pages/myapp/
|
||||||
|
或者
|
||||||
|
ng build --prod --base-href /pages/myapp/
|
||||||
|
```
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
title: browser-sync代理接口在IE8下返回406问题
|
||||||
|
tags: []
|
||||||
|
id: '64'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2016-06-28 10:15:34
|
||||||
|
---
|
||||||
|
|
||||||
|
正常情况下,代理返回的头信息为: HTTP/1.1 200 OK server?? ?Apache-Coyote/1.1 content-type?? ?application/json;charset=UTF-8 transfer-encoding?? ?chunked date?? ?Tue, 28 Jun 2016 02:07:39 GMT connection?? ?close 然而在IE8下面却返回了下面的头信息: HTTP/1.1 406 Not Acceptable server: Apache-Coyote/1.1 set-cookie: JSESSIONID=7F367B9EB53FDC8306D807E0A7BD4201; Path=/; HttpOnly content-type: text/html;charset=utf-8 date: Tue, 28 Jun 2016 02:01:31 GMT connection: close Transfer-Encoding: chunked 通过对比头信息,在代理设置里做了一下判断,在低版本IE浏览器重新设置一下头信息。
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
var browserSync = require('browser-sync');
|
||||||
|
|
||||||
|
var proxyMiddleware = require('http-proxy-middleware');
|
||||||
|
|
||||||
|
var proxy_context = ['/service/web'];
|
||||||
|
var proxy_option = {
|
||||||
|
target: 'http://' + proxyConfig.host + ':' + proxyConfig.port,
|
||||||
|
//增加一个错误处理在window 7 ie7,8
|
||||||
|
onProxyReq: function(proxyReq, req, res){
|
||||||
|
var is4dot0 = false;
|
||||||
|
var acceptValue = "";
|
||||||
|
var acceptEncodeing = "";
|
||||||
|
var rawHeaders = req.rawHeaders;
|
||||||
|
|
||||||
|
rawHeaders.forEach(function(value, index){
|
||||||
|
if(value === "Accept"){
|
||||||
|
acceptValue = rawHeaders[index+1];
|
||||||
|
}
|
||||||
|
if(value === "Accept-Encoding"){
|
||||||
|
acceptEncodeing = rawHeaders[index+1];
|
||||||
|
}
|
||||||
|
if(value.indexOf("Mozilla/4.0") === 0){
|
||||||
|
is4dot0 = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(is4dot0){
|
||||||
|
proxyReq.setHeader("Accept", acceptValue);
|
||||||
|
proxyReq.setHeader("Accept-Encoding", acceptEncodeing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var proxy = proxyMiddleware(proxy_context, proxy_option);
|
||||||
|
|
||||||
|
browserSync({
|
||||||
|
host: 'local.xxx.com',
|
||||||
|
port: 3000,
|
||||||
|
open: 'external',
|
||||||
|
browser: 'google chrome',
|
||||||
|
ghostMode: false, // 每个页面的镜像独立,不相互影响
|
||||||
|
server: {
|
||||||
|
baseDir: "build",
|
||||||
|
middleware: [proxy]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
---
|
||||||
|
title: egret 练手 《围住神经猫》
|
||||||
|
tags: []
|
||||||
|
id: '115'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-09-04 11:42:10
|
||||||
|
---
|
||||||
|
|
||||||
|
Egret引擎是一个开源免费的游戏框架,用于构建二维游戏、演示程序和其他图形界面交互应用等。Egret使用TypeScript脚本语言开发。当游戏完成最终的打包后,可以将程序转换为HTML5游戏。实现跨平台特性。 Egret不仅仅是一个基于HTML5技术的游戏引擎,我们的产品线中除了Egret引擎还提供了很多辅助游戏开发的工具。准确的来说,Egret是一套游戏开发的解决方案。你可以使用Egret引擎来帮助你开发HTML5游戏,并运行在手机和PC端的浏览器中,同时也你可以使用Egret提供的相关工具搭建你自己的游戏开发工作流。 Egret的语法与ActionScript 3.0 一致,如果对as3.0熟悉的童鞋能很快上手。 果然有兴趣的童鞋可以直接去Egret的官网,有详细的文档资料 [白鹭引擎官网](https://www.egret.com/) 最近学习Egret,看了一些文档后,决定找个简单的项目自己练一下手,《围住神经猫》应该是个很好的选择。 先贴上完成的作品 [Demo](https://demo.dengtongyu.com/pages/nervcat/) **1.新建项目** 打开EgretWing --> 文件 --> 新建项目 --> Egret游戏项目 完成后打开 src 下的 Main.ts,改文件就是整个项目的入口文件,里面还有一些已经写好的方法,方便你后面调用。 具体请参考 [传送门](http://edn.egret.com/cn/article/index/id/579) 里面介绍得很详细 **2.加载进度条** 新建游戏项目后,默认的加载进度比较简陋,我们需要美化一下。 打开 src\\LoadingUI.ts 文件,这个就是加载进度条的类。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
class LoadingUI extends egret.Sprite {
|
||||||
|
|
||||||
|
public constructor() {
|
||||||
|
super();
|
||||||
|
this.createView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private textField:egret.TextField;
|
||||||
|
|
||||||
|
private createView():void {
|
||||||
|
this.textField = new egret.TextField();
|
||||||
|
this.addChild(this.textField);
|
||||||
|
this.textField.y = 300;
|
||||||
|
this.textField.width = 480;
|
||||||
|
this.textField.height = 100;
|
||||||
|
this.textField.textAlign = "center";
|
||||||
|
}
|
||||||
|
|
||||||
|
public setProgress(current:number, total:number):void {
|
||||||
|
this.textField.text = `Loading...${current}/${total}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
从代码可以看出,进度条仅仅是用文字展示了加载进度,我们来加个进度条UI美化一下。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
class LoadingUI extends egret.Sprite {
|
||||||
|
|
||||||
|
public constructor() {
|
||||||
|
super();
|
||||||
|
this.createView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private textField:egret.TextField;
|
||||||
|
private pBarBg:egret.Shape;
|
||||||
|
private pBarMove:egret.Shape;
|
||||||
|
|
||||||
|
private createView():void {
|
||||||
|
this.pBarBg = new egret.Shape();
|
||||||
|
this.pBarBg.graphics.beginFill( 0x989898, 1);
|
||||||
|
this.pBarBg.graphics.drawRect( 0, 0, this.width, this.height );
|
||||||
|
this.pBarBg.graphics.endFill();
|
||||||
|
this.addChild(this.pBarBg);
|
||||||
|
|
||||||
|
this.pBarMove = new egret.Shape();
|
||||||
|
this.addChild(this.pBarMove);
|
||||||
|
|
||||||
|
this.textField = new egret.TextField();
|
||||||
|
this.textField.width = this.width;
|
||||||
|
this.textField.textAlign = "center";
|
||||||
|
this.textField.y = 15;
|
||||||
|
this.addChild(this.textField);
|
||||||
|
}
|
||||||
|
|
||||||
|
private moveProgressBar(percent:number):void{
|
||||||
|
this.pBarMove.graphics.beginFill( 0x518cdd, 1);
|
||||||
|
this.pBarMove.graphics.drawRect( 0, 0, this.width*percent, this.height);
|
||||||
|
this.pBarMove.graphics.endFill();
|
||||||
|
}
|
||||||
|
|
||||||
|
public setProgress(current:number, total:number):void {
|
||||||
|
var num = Math.floor(current / total * 100);
|
||||||
|
this.textField.text = 'Loading... ' + num.toString() + " %";
|
||||||
|
this.moveProgressBar(current/total);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
效果如图:  **3.开始画面** 进度条弄好之后,我们开始做游戏开始的画面。如图:  可以看出,开始画面由背景、网格地图和开始按钮的图片组成,这个实现起来很简单。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
private mapGroup:eui.Group;//地图容器
|
||||||
|
private circleArray:Array<object>;//圆圈网格的数组
|
||||||
|
|
||||||
|
private bg:egret.Bitmap;//开始Bitmap
|
||||||
|
private popGroup:eui.Group;//开始画面容器
|
||||||
|
private btnStart:eui.Button;//开始按钮
|
||||||
|
private btnStartPng:egret.Bitmap;//开始Bitmap
|
||||||
|
|
||||||
|
private init():void{
|
||||||
|
//利用白鹭预设的创建bitmap方法创建背景图片
|
||||||
|
this.bg = this.createBitmapByName("bg_jpg");
|
||||||
|
this.stage.addChild(this.bg);
|
||||||
|
|
||||||
|
//地图容器
|
||||||
|
this.mapGroup = new eui.Group();
|
||||||
|
this.mapGroup.width = 560;
|
||||||
|
this.mapGroup.height = 560;
|
||||||
|
this.mapGroup.x = 40;
|
||||||
|
this.mapGroup.y = 400;
|
||||||
|
this.stage.addChild(this.mapGroup);
|
||||||
|
|
||||||
|
//开始画面容器
|
||||||
|
this.popGroup = new eui.Group();
|
||||||
|
this.popGroup.width = this.SW;
|
||||||
|
this.popGroup.height = this.SH;
|
||||||
|
this.popGroup.layout = new eui.BasicLayout();
|
||||||
|
this.stage.addChild(this.popGroup);
|
||||||
|
|
||||||
|
//开始Bitmap
|
||||||
|
this.btnStartPng = this.createBitmapByName("btn_start_png");
|
||||||
|
this.btnStartPng.scaleX = this.btnStartPng.scaleY = 1.2;
|
||||||
|
|
||||||
|
//开始按钮
|
||||||
|
this.btnStart = new eui.Button();
|
||||||
|
this.btnStart.width = this.btnStartPng.width;
|
||||||
|
this.btnStart.height = this.btnStartPng.height;
|
||||||
|
this.btnStart.horizontalCenter = 0;
|
||||||
|
this.btnStart.verticalCenter = 0;
|
||||||
|
this.popGroup.addChild(this.btnStart);
|
||||||
|
this.btnStart.addChild(this.btnStartPng);
|
||||||
|
this.btnStart.addEventListener(egret.TouchEvent.TOUCH_TAP,this.touchHandler,this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private touchHandler(event:TouchEvent) {
|
||||||
|
this.popGroup.visible = this.btnStartPng.visible = false;
|
||||||
|
this.btnStart.removeEventListener(egret.TouchEvent.TOUCH_TAP,this.touchHandler,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
然后在createGameScene方法里面执行this.init()就可以了。
|
||||||
|
|
||||||
|
但是我们还要绘制围住神经猫的9X9的网格地图。
|
||||||
|
我们在 src 下面创建一个自定义布局类,命名为 Map.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
module uilayout {
|
||||||
|
|
||||||
|
var UIComponentClass = "eui.UIComponent";
|
||||||
|
|
||||||
|
/**自定义的布局类*/
|
||||||
|
export class CatMap extends eui.LayoutBase{
|
||||||
|
public constructor(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 计算target的尺寸
|
||||||
|
* 如果您的自定义布局需要根据内部子项计算尺寸,请重写这个方法
|
||||||
|
**/
|
||||||
|
public measure():void{
|
||||||
|
super.measure();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 重写显示列表更新
|
||||||
|
*/
|
||||||
|
public updateDisplayList(unscaledWidth:number, unscaledHeight:number):void{
|
||||||
|
super.updateDisplayList(unscaledWidth, unscaledHeight);
|
||||||
|
if (this.target==null)
|
||||||
|
return;
|
||||||
|
let sunElement:eui.UIComponent;
|
||||||
|
//子元素个数
|
||||||
|
let count:number = this.target.numElements;
|
||||||
|
//元素x轴方向间隔
|
||||||
|
let gapX:number = 0;
|
||||||
|
//元素y轴方向间隔
|
||||||
|
let gapY:number = 0;
|
||||||
|
//元素所在列数
|
||||||
|
let column:number = 0;
|
||||||
|
//元素所在行数
|
||||||
|
let row:number = 0;
|
||||||
|
//奇偶行数错位距离
|
||||||
|
let parityWidth:number = 0;
|
||||||
|
if(count > 0) {
|
||||||
|
sunElement = <eui.uicomponent> this.target.getElementAt(0);
|
||||||
|
gapX = (unscaledWidth - sunElement.width * 9 - sunElement.width / 2)/8;
|
||||||
|
gapY = (unscaledHeight - sunElement.height * 9 - sunElement.height / 2)/8;
|
||||||
|
//console.log(unscaledWidth,unscaledHeight,sunElement.width,sunElement.height);
|
||||||
|
}
|
||||||
|
for (let i:number = 0; i < count; i++){
|
||||||
|
|
||||||
|
let layoutElement:eui.UIComponent = <eui.uicomponent> ( this.target.getElementAt(i) );
|
||||||
|
if ( !egret.is(layoutElement,UIComponentClass) !layoutElement.includeInLayout ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
row = Math.floor(i / 9);
|
||||||
|
column = i % 9;
|
||||||
|
if(row % 2 == 0) {
|
||||||
|
parityWidth = 0;
|
||||||
|
}else{
|
||||||
|
parityWidth = layoutElement.width / 2;
|
||||||
|
}
|
||||||
|
let childX:number = column * (layoutElement.width + gapX) + parityWidth;
|
||||||
|
let childY:number = row * (layoutElement.height + gapY);
|
||||||
|
layoutElement.setLayoutBoundsPosition(childX, childY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这样一个自定义布局类就写好了,如果对自定义布局不太了解的,可以去Egret的官网查看文档 [传送门](http://edn.egret.com/cn/article/index/id/525) 然后,我们在Main.ts入口文件里绘制9X9的圆圈网格。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
/**创建网格**/
|
||||||
|
private creatMap() {
|
||||||
|
this.circleArray = new Array();
|
||||||
|
for(let i = 0;i<81;i++){ let circleData = new Object(); circleData['ui'] = new eui.Group(); circleData['ui'].name = i; circleData['img1'] = this.createBitmapByName('pot1_png'); circleData['img2'] = this.createBitmapByName('pot2_png'); if(i == 40) { circleData['img1'].visible = true; circleData['img2'].visible = false; circleData['val'] = 0; }else{ if(Math.random()*10 > 8) {
|
||||||
|
circleData['img1'].visible = false;
|
||||||
|
circleData['img2'].visible = true;
|
||||||
|
circleData['val'] = 1;
|
||||||
|
}else{
|
||||||
|
circleData['img1'].visible = true;
|
||||||
|
circleData['img2'].visible = false;
|
||||||
|
circleData['val'] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.circleArray.push(circleData);
|
||||||
|
circleData['img1'].scaleX = circleData['img1'].scaleY = 1.2;
|
||||||
|
circleData['img2'].scaleX = circleData['img2'].scaleY = 1.2;
|
||||||
|
circleData['ui'].width = circleData['img1'].width;
|
||||||
|
circleData['ui'].height = circleData['img1'].height;
|
||||||
|
//circleData['ui'].layout = new eui.BasicLayout();
|
||||||
|
circleData['ui'].addChild(circleData['img1']);
|
||||||
|
circleData['ui'].addChild(circleData['img2']);
|
||||||
|
if(i == 40) {//中间神经猫的位置
|
||||||
|
this.insertRunCat(circleData['ui']);
|
||||||
|
this.cat.visible = false;
|
||||||
|
this.catPos = 40;
|
||||||
|
}
|
||||||
|
if(circleData['val'] == 0) {
|
||||||
|
circleData['img1'].touchEnabled = true;
|
||||||
|
circleData['img1'].addEventListener(egret.TouchEvent.TOUCH_TAP,this.touchCircle,this);
|
||||||
|
}
|
||||||
|
this.mapGroup.addChild(circleData['ui']);
|
||||||
|
}
|
||||||
|
//引用自定义布局
|
||||||
|
this.mapGroup.layout = new uilayout.CatMap();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
然后在init方法里面执行this.creatMap()就可以完成绘制了  后面的操作逻辑就不赘述了,有机会再跟大家分享。
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
title: egret 获取设备陀螺仪信息以及运动状态信息
|
||||||
|
tags: []
|
||||||
|
id: '217'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-11-22 15:55:55
|
||||||
|
---
|
||||||
|
|
||||||
|
在最新版本的egret(5.0.12)中,已经支持了移动设备陀螺仪和运动状态的相关API。 **egret.DeviceOrientation** 可以监听设备方向的变化。 **egret.Motion**从用户设备读取运动状态信息并派发 CHANGE 事件。当设备移动时,传感器会检测到此移动并返回设备加速度,重力和旋转数据。 废话不多说,直接上代码:
|
||||||
|
|
||||||
|
```
|
||||||
|
class Main extends egret.DisplayObjectContainer {
|
||||||
|
|
||||||
|
private orientationLabel: egret.TextField;
|
||||||
|
|
||||||
|
private motionLabel: egret.TextField;
|
||||||
|
|
||||||
|
public constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.orientationLabel = new egret.TextField();
|
||||||
|
this.orientationLabel.width = 640;
|
||||||
|
this.orientationLabel.textAlign = egret.HorizontalAlign.CENTER;
|
||||||
|
this.addChild(this.orientationLabel);
|
||||||
|
|
||||||
|
this.motionLabel = new egret.TextField();
|
||||||
|
this.motionLabel.width = 640;
|
||||||
|
this.motionLabel.y = 300;
|
||||||
|
this.motionLabel.textAlign = egret.HorizontalAlign.CENTER;
|
||||||
|
this.addChild(this.motionLabel);
|
||||||
|
|
||||||
|
//创建 DeviceOrientation 类
|
||||||
|
var orientation = new egret.DeviceOrientation();
|
||||||
|
//添加事件监听器
|
||||||
|
orientation.addEventListener(egret.Event.CHANGE,this.onOrientation,this);
|
||||||
|
//开始监听设备方向变化
|
||||||
|
orientation.start();
|
||||||
|
|
||||||
|
//创建 Motion 类
|
||||||
|
var motion = new egret.Motion();
|
||||||
|
//添加事件监听器
|
||||||
|
motion.addEventListener(egret.Event.CHANGE,this.onMotion,this);
|
||||||
|
//开始监听设备方向变化
|
||||||
|
motion.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onOrientation(e:egret.OrientationEvent){
|
||||||
|
this.orientationLabel.textFlow = >[
|
||||||
|
{text: "绕 Z 轴的角度:\n"}
|
||||||
|
, {text: e.alpha, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\n绕 X 轴的角度:\n"}
|
||||||
|
, {text: e.beta, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\n绕 Y 轴的角度:\n"}
|
||||||
|
, {text: e.gamma, style: {"textColor": 0xff0000}}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private onMotion(e:egret.MotionEvent){
|
||||||
|
this.motionLabel.textFlow = >[
|
||||||
|
{text: "X 轴方向的加速度\n"}
|
||||||
|
, {text: e.acceleration.x, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\nY 轴方向的加速度:\n"}
|
||||||
|
, {text: e.acceleration.y, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\nZ 轴方向的加速度:\n"}
|
||||||
|
, {text: e.acceleration.z, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\nX 轴加速度(考虑重力加速度)\n"}
|
||||||
|
, {text: e.accelerationIncludingGravity.x, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\nZ 轴方向的加速度:\n"}
|
||||||
|
, {text: e.accelerationIncludingGravity.y, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\nZ 轴方向的加速度:\n"}
|
||||||
|
, {text: e.accelerationIncludingGravity.z, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\n左右旋转速度(alpha轴向的角速度)\n"}
|
||||||
|
, {text: e.rotationRate.alpha, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\n前后旋转速度(beta轴向的角速度)\n"}
|
||||||
|
, {text: e.rotationRate.beta, style: {"textColor": 0xff0000}}
|
||||||
|
, {text: "\n\n扭转速度(gamma轴向的角速度)\n"}
|
||||||
|
, {text: e.rotationRate.gamma, style: {"textColor": 0xff0000}}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
首先创建了DeviceOrientation的实例orientation。并给他添加了一个事件侦听器,监听它的CHANGE事件。然后调用了他的start()方法来开始监听设备方向的变化。 当系统监听到了方向的变化后,将回调函数 onOrientation。然后通过egret.OrientationEvent事件的三个属性来获取设备的方向变化信息。 OrientationEvent的三个属性:alpha,beta和gamma。 alpha表示设备绕 Z 轴的角度,单位是 角度 beta 表示设备绕 X 轴的角度,单位是 角度 gamma 表示设备绕 Y 轴的角度,单位是 角度 同样,创建了Motion的实例motion。并给他添加了一个事件侦听器,监听它的CHANGE事件。然后调用了他的start()方法来开始监听设备方向的变化。 当系统监听到了方向的变化后,将回调函数 onMotion。然后通过egret.MotionEvent事件的三个属性来获取设备运动的具体信息。 acceleration 表示设备在 X Y Z 轴方将的加速度信息,单位是 m/s2,不包含重力。 acceleration 表示设备在 X Y Z 轴方将的加速度信息,单位是 m/s2,包含重力。 rotationRate 表示设备在 alpha、 beta 和 gamma 三个轴向的角速度信息,单位是 角度每秒。 最终的效果demo->[传送门](https://demo.dengtongyu.com/pages/orientation/) 或者手机扫一扫: 
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
title: egret3d 用视频video做纹理贴图
|
||||||
|
tags: []
|
||||||
|
id: '267'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2018-01-29 17:50:02
|
||||||
|
---
|
||||||
|
|
||||||
|
前段时间学习了一下egret3d,然后有些奇妙的想法,如果用视频video来做纹理贴图可不可以呢?于是就尝试了一下,效果还不错。
|
||||||
|
|
||||||
|
思路也很简单,创建一个立方体,然后把立方的纹理设置成一个视频video,主要代码如下
|
||||||
|
|
||||||
|
```
|
||||||
|
public createGameScene() {
|
||||||
|
|
||||||
|
this.createVideoTexture();
|
||||||
|
|
||||||
|
this.loaderSkyBox();
|
||||||
|
}
|
||||||
|
//创建视频纹理
|
||||||
|
private createVideoTexture() {
|
||||||
|
this.video = new egret3d.VideoTexture(640,264);
|
||||||
|
this.video.source = "resource/oceans-clip.mp4";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载资源
|
||||||
|
private loaderSkyBox() {
|
||||||
|
this.queueLoader = new egret3d.QueueLoader();
|
||||||
|
this.queueLoader.load("resource/background.jpg");
|
||||||
|
this.queueLoader.addEventListener(egret3d.LoaderEvent3D.LOADER_COMPLETE, this.onSkyBoxTexture, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 资源加载完成 创建立方体
|
||||||
|
private onSkyBoxTexture(e: egret3d.LoaderEvent3D) {
|
||||||
|
// 设置背景
|
||||||
|
let panelIamge: egret3d.ITexture = this.queueLoader.getAsset("resource/background.jpg");
|
||||||
|
this.view.backImage = panelIamge;
|
||||||
|
|
||||||
|
// 创建立方体和cube贴图
|
||||||
|
this.ge = new egret3d.CubeGeometry(200, 200, 200);
|
||||||
|
this.mat = new egret3d.TextureMaterial(panelIamge);
|
||||||
|
this.mat.diffuseTexture = this.video;
|
||||||
|
|
||||||
|
this.mesh = new egret3d.Mesh(this.ge,this.mat);
|
||||||
|
this.view.addChild3D(this.mesh);
|
||||||
|
|
||||||
|
// 更新摄像机信息
|
||||||
|
this.cameraCtl.distance = 1000;
|
||||||
|
this.cameraCtl.rotationX = 45;
|
||||||
|
this.cameraCtl.rotationY = 45;
|
||||||
|
|
||||||
|
this.cameraCtl.update();
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
效果->[传送门](https://demo.dengtongyu.com/pages/videocude/)
|
||||||
|
|
||||||
|

|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
title: egret天空盒子浅尝
|
||||||
|
tags: []
|
||||||
|
id: '238'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-11-22 18:35:36
|
||||||
|
---
|
||||||
|
|
||||||
|
现在移动端越来越多类VR的推广H5页面需求,egret恰好也有相关的API可以方便我们使用,这就是egret的天空盒子-**egret3d.Sky** 在 Egret 3D 所创建的空间中最外层是由天空盒子来包裹起来的。我们通常使用天空盒子来展现风景,地平线,天空,星空等等空间的“大背景”。天空盒子由一组无缝的贴图包裹起来的盒状空间。当我们的 3D 场景中包含有物体时,天空盒子总是充当其背景。  环境:egret 5.0.12 IDE:egret wing 3
|
||||||
|
|
||||||
|
# 加载天空盒子素材资源
|
||||||
|
|
||||||
|
通过**egret3d.QueueLoader**加载器加载资源,然后监听资源加载完成事件**egret3d.LoaderEvent3D.LOADER\_COMPLETE**。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载器
|
||||||
|
*/
|
||||||
|
private queueLoader: egret3d.QueueLoader;
|
||||||
|
// 加载天空盒资源
|
||||||
|
private loaderSkyBox() {
|
||||||
|
this.queueLoader = new egret3d.QueueLoader();
|
||||||
|
this.queueLoader.load("resource/front.png");
|
||||||
|
this.queueLoader.load("resource/back.png");
|
||||||
|
this.queueLoader.load("resource/left.png");
|
||||||
|
this.queueLoader.load("resource/right.png");
|
||||||
|
this.queueLoader.load("resource/up.png");
|
||||||
|
this.queueLoader.load("resource/down.png");
|
||||||
|
this.queueLoader.addEventListener(egret3d.LoaderEvent3D.LOADER_COMPLETE, this.onSkyBoxTexture, this);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 创建天空盒子
|
||||||
|
|
||||||
|
资源加载完成后,用**egret3d.Sky**创建天空盒子,**egret3d.Sky**方法有三个参数, Sky(geometry:egret3d.Geometry, material:egret3d.MaterialBase, camera:egret3d.Camera3D), 分别是3D几何形状,纹理贴图,摄像机。然后把天空盒子添加到3D显示类里。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
// 天空盒资源加载完成 创建天空盒
|
||||||
|
private onSkyBoxTexture(e: egret3d.LoaderEvent3D) {
|
||||||
|
var loader: egret3d.QueueLoader = e.target;
|
||||||
|
|
||||||
|
var fr: egret3d.ITexture = loader.getAsset("resource/front.png");
|
||||||
|
var bk: egret3d.ITexture = loader.getAsset("resource/back.png");
|
||||||
|
var lf: egret3d.ITexture = loader.getAsset("resource/left.png");
|
||||||
|
var rt: egret3d.ITexture = loader.getAsset("resource/right.png");
|
||||||
|
var up: egret3d.ITexture = loader.getAsset("resource/up.png");
|
||||||
|
var dn: egret3d.ITexture = loader.getAsset("resource/down.png");
|
||||||
|
|
||||||
|
// 创建cube贴图
|
||||||
|
var cubeTexture: egret3d.CubeTexture = egret3d.CubeTexture.createCubeTextureByImageTexture(bk, fr, lf, rt, up, dn);
|
||||||
|
|
||||||
|
// 创建cube geometry 和 cube 材质
|
||||||
|
var sky: egret3d.Sky = new egret3d.Sky(new egret3d.CubeGeometry(500, 500, 500), new egret3d.CubeTextureMaterial(cubeTexture), this.view.camera3D);
|
||||||
|
// 设置天空盒 渲染模式为背面渲染
|
||||||
|
sky.material.cullMode = egret3d.ContextConfig.FRONT;
|
||||||
|
this.view.addChild3D(sky);
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# 获取陀螺仪信息
|
||||||
|
|
||||||
|
我们需要通过获取陀螺仪信息来根据手机的旋转,让天空盒子视角旋转对应的角度。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
// 获取设备旋转角度
|
||||||
|
private setOrientation() {
|
||||||
|
//创建 DeviceOrientation 类
|
||||||
|
var orientation = new egret.DeviceOrientation();
|
||||||
|
//添加事件监听器
|
||||||
|
orientation.addEventListener(egret.Event.CHANGE,this.onOrientation,this);
|
||||||
|
//开始监听设备方向变化
|
||||||
|
orientation.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onOrientation(e:egret.OrientationEvent){
|
||||||
|
this._alpha = e.alpha;
|
||||||
|
this._beta = e.beta;
|
||||||
|
this._gamma = e.gamma;
|
||||||
|
|
||||||
|
this.cameraCtl.rotationY = (this._alpha % 360) * (-1);
|
||||||
|
this.cameraCtl.rotationX = (this._beta - 90) % 360 * (-1);
|
||||||
|
this.cameraCtl.rotationZ = 0;
|
||||||
|
|
||||||
|
//console.log(e.rotationRate)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
最终效果->[传送门](https://demo.dengtongyu.com/pages/boxsky/) 手机扫一扫 
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
---
|
||||||
|
title: egret引用Animate CC发布的HTML5 Canvas
|
||||||
|
tags: []
|
||||||
|
id: '252'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-12-15 18:04:34
|
||||||
|
---
|
||||||
|
|
||||||
|
在flash时代,我们可以在Adobe Flash中导出swf,然后在ActionScript 3.0项目里面引用。让设计人员可以直接提供素材给开发人员,这大大提高了开发效率。
|
||||||
|
|
||||||
|
但在egret里,虽然官方也提供了很丰富的工具,但是不得不承认,目前并没有足够的设计人员参与进来,导致开发人员拿到素材后还要“二次加工”,开发效率自然上不去。
|
||||||
|
|
||||||
|
所以,在Adobe Animate CC已经普及的今天,我们能不能让Animate CC导出的HTML5 Canvas直接用到我们的项目里呢?
|
||||||
|
|
||||||
|
在我尝试了一翻后,确实能达到不错的效果。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 1.建立引用路径
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
在egret项目里建立一个存放Animate CC导出的HTML文件目录,这里我引用了/html/man的实例。里面的index.html和index.js是用Animate CC发布导出的
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 2.动画采集器
|
||||||
|
|
||||||
|
通过外部引用html,然后获取页面的canvas的bitmap,然后添加到egret的舞台上。
|
||||||
|
|
||||||
|
新创建一个类,命名为CollectAnimation.ts
|
||||||
|
|
||||||
|
```
|
||||||
|
class CollectAnimation extends egret.DisplayObjectContainer {
|
||||||
|
|
||||||
|
private _iframe:any;
|
||||||
|
|
||||||
|
private _canvas:any;
|
||||||
|
|
||||||
|
private _canvasBitmapData:any;
|
||||||
|
|
||||||
|
private _canvasTexture:egret.Texture;
|
||||||
|
|
||||||
|
private _canvasBitmap:egret.Bitmap;
|
||||||
|
|
||||||
|
private _oldCanvasBitmap:egret.Bitmap;
|
||||||
|
|
||||||
|
private _timer:egret.Timer;
|
||||||
|
|
||||||
|
public constructor(url:string) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this._iframe = document.createElement('iframe');
|
||||||
|
this._iframe.style.height = 0;
|
||||||
|
this._iframe.style.border = 'none';
|
||||||
|
this._iframe.style.display = 'none';
|
||||||
|
this._iframe.src = url;
|
||||||
|
document.querySelector('body').appendChild(this._iframe);
|
||||||
|
this._iframe.onload = () => {
|
||||||
|
this._canvas = this._iframe.contentWindow.canvas;
|
||||||
|
|
||||||
|
//console.log(this._canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._timer = new egret.Timer(50);
|
||||||
|
this._timer.addEventListener(egret.TimerEvent.TIMER,this.timerFunc,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get getCanvasBitmap() {
|
||||||
|
if(this._canvas) {
|
||||||
|
this._canvasBitmapData = new egret.BitmapData(this._canvas);
|
||||||
|
this._canvasTexture = new egret.Texture();
|
||||||
|
this._canvasTexture.bitmapData = this._canvasBitmapData;
|
||||||
|
this._canvasBitmap = new egret.Bitmap(this._canvasTexture);
|
||||||
|
return this._canvasBitmap;
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private timerFunc() {
|
||||||
|
if(this._canvas) {
|
||||||
|
|
||||||
|
this._canvasBitmapData = new egret.BitmapData(this._canvas);
|
||||||
|
this._canvasTexture = new egret.Texture();
|
||||||
|
this._canvasTexture.bitmapData = this._canvasBitmapData;
|
||||||
|
if(this._canvasBitmap) {
|
||||||
|
this._oldCanvasBitmap = this._canvasBitmap;
|
||||||
|
}
|
||||||
|
this._canvasBitmap = new egret.Bitmap(this._canvasTexture);
|
||||||
|
if(this._oldCanvasBitmap && this._oldCanvasBitmap.parent) {
|
||||||
|
this.removeChild(this._oldCanvasBitmap);
|
||||||
|
}
|
||||||
|
this.addChild(this._canvasBitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public start() {
|
||||||
|
this._timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public stop() {
|
||||||
|
this._timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public depose() {
|
||||||
|
if(this._iframe) {
|
||||||
|
this._iframe = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._canvas) {
|
||||||
|
this._canvas = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._canvasBitmapData) {
|
||||||
|
this._canvasBitmapData = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._canvasTexture) {
|
||||||
|
this._canvasTexture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._canvasBitmap) {
|
||||||
|
this._canvasBitmap = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._oldCanvasBitmap) {
|
||||||
|
this._oldCanvasBitmap = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this._timer) {
|
||||||
|
this._timer.stop();
|
||||||
|
this._timer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.parent) {
|
||||||
|
this.parent.removeChild(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 3.在egret中使用
|
||||||
|
|
||||||
|
在Main.ts中使用我们刚刚创建的类
|
||||||
|
|
||||||
|
```
|
||||||
|
class Main extends egret.DisplayObjectContainer {
|
||||||
|
|
||||||
|
public constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private onAddToStage(event: egret.Event) {
|
||||||
|
|
||||||
|
let man = new CollectAnimation('html/man/index.html');
|
||||||
|
this.addChild(man);
|
||||||
|
man.start();
|
||||||
|
|
||||||
|
// setTimeout(() =>{
|
||||||
|
// man.stop();
|
||||||
|
// man.depose();
|
||||||
|
// man = null;
|
||||||
|
// },3000)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
通过start和stop方法开始播放和停止,depose方法删除
|
||||||
|
|
||||||
|
以上就是在egret中引用HTML5 Canvas的一些尝试,还有别的东西可能要等我慢慢挖掘了。
|
||||||
|
|
||||||
|
效果->[传送门](https://demo.dengtongyu.com/pages/walkman/)
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
title: egret粒子系统官方文档的那些坑
|
||||||
|
tags: []
|
||||||
|
id: '200'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-10-20 16:33:15
|
||||||
|
---
|
||||||
|
|
||||||
|
最近体验了一下[egret粒子系统](http://edn.egret.com/cn/article/index/id/178),看了官方文档后,照着文档写,发现各种报错,不知道是原来文档就是错误的,还是egret版本多次迭代后,文档没有及时更新,而且在[egret开发者中心](http://developer.egret.com/)提供的QQ群加了也没有回应,或许是egret官方太忙了,但是不管怎样,这种错误的官方文档对新手很不友好。
|
||||||
|
|
||||||
|
下面我来说说我在体验[egret粒子系统](http://edn.egret.com/cn/article/index/id/178)踩的一些坑
|
||||||
|
|
||||||
|
说到egret的粒子系统,egret官方提供了一个制作粒子素材的工具——[Egret Feather](http://developer.egret.com/cn/github/egret-docs/tools/Feather/manual/index.html)
|
||||||
|
|
||||||
|
有兴趣的可以移步到相关的官方文档查看,因为我使用[Egret Feather](http://developer.egret.com/cn/github/egret-docs/tools/Feather/manual/index.html)的时候没有遇到什么问题,所以这里就不做赘述了,大家看官方文档就好了
|
||||||
|
|
||||||
|
### egret粒子系统官方文档的错误?
|
||||||
|
|
||||||
|
在egret的粒子系统文档中([传送门](http://edn.egret.com/cn/article/index/id/178)),在创建粒子示例的地方是这样的
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
按照示例的代码在egret 4.0.3版本中,编译就会报错
|
||||||
|
|
||||||
|
```
|
||||||
|
error TS2339: Property 'system' does not exist on type 'Main'.
|
||||||
|
```
|
||||||
|
|
||||||
|
'system'这个属性不属于'Main',新人们在这里会懵逼一会儿,但是代码是死的,人是活的,我直接用个变量来保存particle对象嘛。我把代码改一下
|
||||||
|
|
||||||
|
```
|
||||||
|
let texture = RES.getRes("funny");
|
||||||
|
let config = RES.getRes("funny_json");
|
||||||
|
let funny = new particle.GravityParticleSystem(texture, config);
|
||||||
|
funny.start();
|
||||||
|
this.addChild(funny);
|
||||||
|
```
|
||||||
|
|
||||||
|
我用个变量funny来保存particle对象,然后我再编译一下,没有报错,但是刷新浏览器的时候报错了
|
||||||
|
|
||||||
|
```
|
||||||
|
Uncaught TypeError: Cannot read property 'textureWidth' of null
|
||||||
|
```
|
||||||
|
|
||||||
|
无法读取纹理的宽度,其值为null。出现这种报错一般就是纹理加载不成功,所以要看看加载素材的地方
|
||||||
|
|
||||||
|
```
|
||||||
|
let texture = RES.getRes("funny");
|
||||||
|
let config = RES.getRes("funny_json");
|
||||||
|
```
|
||||||
|
|
||||||
|
上面的纹理加载很明显与egret的素材加载方式有点不一样,不知道官方文档为什么会这样写,所以我改了一下,把纹理的后缀加上
|
||||||
|
|
||||||
|
```
|
||||||
|
let texture = RES.getRes("funny_png");
|
||||||
|
let config = RES.getRes("funny_json");
|
||||||
|
```
|
||||||
|
|
||||||
|
编译没有报错,刷新浏览器,粒子效果完美呈现。[demo传送门](https://demo.dengtongyu.com/pages/featherfunuy/)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### egret粒子系统库的引入,另一个坑?
|
||||||
|
|
||||||
|
egret粒子系统库的引入也是一个小坑,我从[egret第三方库的GitHub](https://github.com/egret-labs/egret-game-library)上下载了particle粒子库,然后放到项目里引入,结果编译时间很久,而且会各种报错,经过一系列的Google 百度后,结果是:
|
||||||
|
|
||||||
|
**第三方库必须放到项目外面!**
|
||||||
|
|
||||||
|
**第三方库必须放到项目外面!**
|
||||||
|
|
||||||
|
**第三方库必须放到项目外面!**
|
||||||
|
|
||||||
|
重要的事情说三遍
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
title: ES6 下定义变量,let大法好!
|
||||||
|
tags: []
|
||||||
|
id: '52'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2016-06-16 22:37:51
|
||||||
|
---
|
||||||
|
|
||||||
|
var _声明的变量作用域不是块级的,会扩大变量的作用域,可能造成变量污染。_ let _声明的变量作用域就更精确,离开作用域变量就销毁。_ const _顾名思义就是常量了。_ **变量作用域更加精准** 不用担心变量作用域自动提升,造成上一级或全局变量值被覆盖。 举个栗子:
|
||||||
|
|
||||||
|
```js
|
||||||
|
let a = 1;
|
||||||
|
var b = 1;
|
||||||
|
if (true) {
|
||||||
|
let a = 2;
|
||||||
|
var b = 2;
|
||||||
|
}
|
||||||
|
console.log(a) // 输出 1
|
||||||
|
console.log(b) // 输出 2
|
||||||
|
```
|
||||||
|
|
||||||
|
**变量作用域可控性更好** let 的作用域是根据代码块(enclosing block)来判定的,而 var 的作用域是根据函数块(function block)来判定的。这样的话,如果我们的变量都使用 let/const 来声明,那么以前的立即执行函数就不需要了,我们只要加一个代码块就好了。 举个栗子:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
let a = 1;
|
||||||
|
}
|
||||||
|
console.log(a) // 输出 a is not defined
|
||||||
|
```
|
||||||
|
|
||||||
|
**Runtime自动检查重复声明的函数并报错** 在同一个作用域内不允许重复声明变量。 举个栗子:
|
||||||
|
|
||||||
|
```js
|
||||||
|
if (true) {
|
||||||
|
let a = 1;
|
||||||
|
let a = 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Runtime会报错:Uncaught SyntaxError: Identifier 'a' has already been declared 有了更加清晰的作用域,我们的代码就能够更好被预测,也更好维护。 有了更容易控制的作用域可以让我们减少很多立即执行的函数。 Runtime的自动检查可以避免不必要,甚至是错误的代码声明。
|
||||||
@@ -0,0 +1,246 @@
|
|||||||
|
---
|
||||||
|
title: https实践,Let's Encrypt 免费泛域名 SSL 证书申请
|
||||||
|
tags: []
|
||||||
|
id: '304'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2018-07-12 11:26:42
|
||||||
|
---
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
2018 年 3 月 14 日,Let’s Encrypt 对外宣布 ACME v2 已正式支持泛域名证书。这就意外味着用户可以在 Let’s Encrypt 上免费申请支持泛域名的 SSL 证书。
|
||||||
|
|
||||||
|
### 什么是 Let’s Encrypt
|
||||||
|
|
||||||
|
部署 HTTPS 网站的时候需要证书,证书由 CA 机构签发,大部分传统 CA 机构签发证书是需要收费的,这不利于推动 HTTPS 协议的使用。
|
||||||
|
|
||||||
|
[Let’s Encrypt](https://letsencrypt.org/) 也是一个 CA 机构,但这个 CA 机构是免费的!也就是说签发证书不需要任何费用。
|
||||||
|
|
||||||
|
[Let’s Encrypt](https://letsencrypt.org/) 是国外一个公共的免费 SSL 项目,由 Linux 基金会托管。由 Mozilla、思科、Akamai、IdenTrust 和 EFF 等组织发起,目的就是向网站自动签发和管理免费证书。以便加速互联网由 HTTP 过渡到 HTTPS,目前 Facebook 等大公司开始加入赞助行列。
|
||||||
|
|
||||||
|
Let’s Encrypt 已经得了 IdenTrust 的交叉签名,这意味着其证书现在已经可以被 Mozilla、Google、Microsoft 和 Apple 等主流的浏览器所信任。用户只需要在 Web 服务器证书链中配置交叉签名,浏览器客户端会自动处理好其它的一切,Let’s Encrypt 安装简单,使用非常方便。
|
||||||
|
|
||||||
|
### 什么是泛域名证书
|
||||||
|
|
||||||
|
泛域名证书类似 DNS 解析的泛域名概念,泛域名证书就是证书中可以包含一个通配符。主域名签发的泛域名证书可以在所有子域名中使用,比如 demo.domain.com、bbs.domain.com。这样就一张证书可以用于更多的主机了
|
||||||
|
|
||||||
|
### 如何申请 Let’s Encrypt 泛域名证书
|
||||||
|
|
||||||
|
Let’s Encrypt 上的证书申请是通过 ACME 协议来完成的。ACME 协议规范化了证书申请、更新、撤销等流程,实现了 Let’s Encrypt CA 自动化操作。解决了传统的 CA 机构是人工手动处理证书申请、证书更新、证书撤销的效率和成本问题。
|
||||||
|
|
||||||
|
ACME v2 是 ACME 协议的更新版本,泛域名证书只能通过 ACME v2 获得。要使用 ACME v2 协议申请泛域名证书,只需一个支持该协议的客户端就可以了,官方推荐的客户端是 Certbot。
|
||||||
|
|
||||||
|
#### 安装Certbot
|
||||||
|
|
||||||
|
如果没有下载安装过Certbot,先下载Certbot客户端
|
||||||
|
|
||||||
|
```
|
||||||
|
wget https://dl.eff.org/certbot-auto
|
||||||
|
```
|
||||||
|
|
||||||
|
然后把certbot-auto设为可执行权限
|
||||||
|
|
||||||
|
```
|
||||||
|
chmod a+x certbot-auto
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 升级Certbot
|
||||||
|
|
||||||
|
如果已经安装了Certbot,查看下自己的Certbot客户端是不是支持 ACME v2 版本,官方介绍 Certbot 0.22.0 版本支持新的协议版本
|
||||||
|
|
||||||
|
```
|
||||||
|
./certbot-auto --version
|
||||||
|
Upgrading certbot-auto 0.21.1 to 0.25.1...
|
||||||
|
Replacing certbot-auto...
|
||||||
|
|
||||||
|
./certbot-auto --version
|
||||||
|
certbot 0.22.0
|
||||||
|
```
|
||||||
|
|
||||||
|
客户在申请 Let’s Encrypt 证书的时候,需要校验域名的所有权,证明操作者有权利为该域名申请证书,目前支持三种验证方式:
|
||||||
|
|
||||||
|
1. dns-01:给域名添加一个 DNS TXT 记录。
|
||||||
|
2. http-01:在域名对应的 Web 服务器下放置一个 HTTP well-known URL 资源文件。
|
||||||
|
3. tls-sni-01:在域名对应的 Web 服务器下放置一个 HTTPS well-known URL 资源文件。
|
||||||
|
|
||||||
|
#### 申请泛域名证书
|
||||||
|
|
||||||
|
申请泛域名证书,只能使用 dns-01 的方式
|
||||||
|
|
||||||
|
使用 Certbot 客户端申请证书方法比较的简单,输入以下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
./certbot-auto certonly -d domain.com -d *.domain.com --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
```
|
||||||
|
|
||||||
|
_1、把domain换成你自己的域名。_
|
||||||
|
|
||||||
|
_2、\*.domain.com可作用于所有子域名,但好像不能作用于domain.com,所以加上domain.com这样的裸域名。_
|
||||||
|
|
||||||
|
#### 相关参数说明
|
||||||
|
|
||||||
|
1. certonly,表示安装模式,Certbot 有安装模式和验证模式两种类型的插件。
|
||||||
|
2. \--manual 表示手动安装插件,Certbot 有很多插件,不同的插件都可以申请证书,用户可以根据需要自行选择
|
||||||
|
3. \-d 为那些主机申请证书,如果是通配符,输入 \*.domain.com(可以替换为你自己的域名)
|
||||||
|
4. \--preferred-challenges dns,使用 DNS 方式校验域名所有权
|
||||||
|
5. \--server,Let's Encrypt ACME v2 版本使用的服务器不同于 v1 版本,需要显示指定。
|
||||||
|
|
||||||
|
执行完这一步之后,就是命令行的输出,请根据提示输入相应内容:
|
||||||
|
|
||||||
|
```
|
||||||
|
Saving debug log to /var/log/letsencrypt/letsencrypt.log
|
||||||
|
Plugins selected: Authenticator manual, Installer None
|
||||||
|
Cert is due for renewal, auto-renewing...
|
||||||
|
Renewing an existing certificate
|
||||||
|
Performing the following challenges:
|
||||||
|
dns-01 challenge for xxxxx.com
|
||||||
|
dns-01 challenge for xxxxx.com
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
NOTE: The IP of this machine will be publicly logged as having requested this
|
||||||
|
certificate. If you're running certbot in manual mode on a machine that is not
|
||||||
|
your server, please ensure you're okay with that.
|
||||||
|
|
||||||
|
Are you OK with your IP being logged?
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
(Y)es/(N)o: y
|
||||||
|
```
|
||||||
|
|
||||||
|
上述有两个交互式的提示:
|
||||||
|
|
||||||
|
1. 是否同意 Let's Encrypt 协议要求
|
||||||
|
2. 询问是否对域名和机器(IP)进行绑定
|
||||||
|
|
||||||
|
确认同意才能继续。
|
||||||
|
|
||||||
|
继续查看命令行的输出,非常关键:
|
||||||
|
|
||||||
|
```
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Please deploy a DNS TXT record under the name
|
||||||
|
_acme-challenge.xxxxx.com with the following value:
|
||||||
|
|
||||||
|
XQOqY8npyso******ovtudA3zMd_C1dh9bjMEkbkKHM
|
||||||
|
|
||||||
|
Before continuing, verify the record is deployed.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Press Enter to Continue
|
||||||
|
```
|
||||||
|
|
||||||
|
执行到上图最后一步时,先暂时不要回车。要求配置 DNS TXT 记录,从而校验域名所有权,也就是判断证书申请者是否有域名的所有权。接下来需要按照提示在域名后台添加对应的 DNS TXT 记录。
|
||||||
|
|
||||||
|
上面输出要求给 \_acme-challenge.XXXXX.com 配置一条 TXT 记录,在没有确认 TXT 记录生效之前不要回车执行。
|
||||||
|
|
||||||
|
我使用的是阿里云的域名服务器,登录控制台操作如下图:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
如上图所示,有两条DNS TXT,因为我们申请的时候就有两个域名,domain.com 和 \*.domain.com,所以我们在阿里云的后台添加一条DNS TXT后,我们回到命令行,按回车继续,然后会输出第二条DNS TXT
|
||||||
|
|
||||||
|
```
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Please deploy a DNS TXT record under the name
|
||||||
|
_acme-challenge.xxxxx.com with the following value:
|
||||||
|
|
||||||
|
XQOqY8npyso******ovtudA3zMd_C1dh9bjMEkbkKHM
|
||||||
|
|
||||||
|
Before continuing, verify the record is deployed.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Press Enter to Continue
|
||||||
|
```
|
||||||
|
|
||||||
|
同样,按照上面的步骤在阿里云的后台多加一条DNS TXT解析就好。加完稍等几分钟后,回到命令行,按回车
|
||||||
|
|
||||||
|
```
|
||||||
|
Waiting for verification...
|
||||||
|
Cleaning up challenges
|
||||||
|
|
||||||
|
IMPORTANT NOTES:
|
||||||
|
- Congratulations! Your certificate and chain have been saved at:
|
||||||
|
/etc/letsencrypt/live/dengtongyu.com/fullchain.pem
|
||||||
|
Your key file has been saved at:
|
||||||
|
/etc/letsencrypt/live/dengtongyu.com/privkey.pem
|
||||||
|
Your cert will expire on 2018-XX-XX. To obtain a new or tweaked
|
||||||
|
version of this certificate in the future, simply run certbot-auto
|
||||||
|
again. To non-interactively renew *all* of your certificates, run
|
||||||
|
"certbot-auto renew"
|
||||||
|
- If you like Certbot, please consider supporting our work by:
|
||||||
|
|
||||||
|
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
|
||||||
|
Donating to EFF: https://eff.org/donate-le
|
||||||
|
Press Enter to Continue
|
||||||
|
```
|
||||||
|
|
||||||
|
看到上面的输出,说明已经生效。
|
||||||
|
|
||||||
|
你也可以输入以下命令确认 TXT 记录是否生效:
|
||||||
|
|
||||||
|
```
|
||||||
|
dig -t txt _acme-challenge.XXXXXX.com @8.8.8.8
|
||||||
|
|
||||||
|
; <<>> DiG 9.10.6 <<>> -t txt _acme-challenge.XXXXXX.com @8.8.8.8
|
||||||
|
;; global options: +cmd
|
||||||
|
;; Got answer:
|
||||||
|
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55138
|
||||||
|
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
|
||||||
|
|
||||||
|
;; OPT PSEUDOSECTION:
|
||||||
|
; EDNS: version: 0, flags:; udp: 512
|
||||||
|
;; QUESTION SECTION:
|
||||||
|
;_acme-challenge.XXXXXX.com.INTXT
|
||||||
|
|
||||||
|
;; ANSWER SECTION:
|
||||||
|
_acme-challenge.XXXXXX.com.599 INTXT"bQzqaEADZbE******KvPiltbucW130jaj9PNTkAH3mU"
|
||||||
|
_acme-challenge.dengtongyu.com.599 INTXT"XQOqY8npyso******ovtudA3zMd_C1dh9bjMEkbkKHM"
|
||||||
|
|
||||||
|
;; Query time: 175 msec
|
||||||
|
;; SERVER: 8.8.8.8#53(8.8.8.8)
|
||||||
|
;; WHEN: Thu Jul 12 10:59:20 CST 2018
|
||||||
|
;; MSG SIZE rcvd: 171
|
||||||
|
```
|
||||||
|
|
||||||
|
到了这一步后,恭喜您,证书申请成功。 证书和密钥保存在下列目录:
|
||||||
|
|
||||||
|
```
|
||||||
|
/etc/letsencrypt/live/xxx.com/
|
||||||
|
|
||||||
|
├── cert.pem
|
||||||
|
├── chain.pem
|
||||||
|
├── fullchain.pem
|
||||||
|
└── privkey.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
然后校验证书信息,输入如下命令:
|
||||||
|
|
||||||
|
```
|
||||||
|
openssl x509 -in /etc/letsencrypt/live/xxx.com/cert.pem -noout -text
|
||||||
|
...
|
||||||
|
Authority Information Access:
|
||||||
|
OCSP - URI:http://ocsp.int-x3.letsencrypt.org
|
||||||
|
CA Issuers - URI:http://cert.int-x3.letsencrypt.org/
|
||||||
|
|
||||||
|
X509v3 Subject Alternative Name:
|
||||||
|
DNS:*.xxx.com
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
可以看到证书包含了 SAN 扩展,该扩展的值就是 \*.xxx.com
|
||||||
|
|
||||||
|
### 在 Nginx 中 配置 Let’s Encrypt 证书
|
||||||
|
|
||||||
|
Nginx 配置文件片断:
|
||||||
|
|
||||||
|
```
|
||||||
|
server {
|
||||||
|
server_name xxx.com;
|
||||||
|
listen 443 http2 ssl;
|
||||||
|
ssl on;
|
||||||
|
ssl_certificate /etc/letsencrypt/live/XXXXXX.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/XXXXXX.com/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
title: navigator.mediaDevices.getUserMedia调用本地摄像头
|
||||||
|
tags: []
|
||||||
|
id: '94'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-04-28 15:20:27
|
||||||
|
---
|
||||||
|
|
||||||
|
MediaDevices.getUserMedia()方法提示用户允许使用一个视频和/或一个音频输入设备,例如相机或屏幕共享和/或麦克风。 如果用户给予许可,就返回一个Promise 对象,MediaStream对象作为此Promise对象的Resolved[成功]状态的回调函数参数,相应的,如果用户拒绝了许可,或者没有媒体可用的情况下,PermissionDeniedError 或者NotFoundError作为此Promise的Rejected[失败]状态的回调函数参数。 _注意,由于用户不会被要求必须作出允许或者拒绝的选择,所以返回的Promise对象可能既不会触发resolve 也不会触发 reject。_ 首先在页面中放置一个video标签,用来播放本地摄像头采集到的视频流
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<video id="video" width="200" height="150" autoplay=""></video>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
然后在js部分如下
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
//获取video标签
|
||||||
|
var vedio = document.querySelector('#video');
|
||||||
|
|
||||||
|
//constraints 参数是一个包含了video 和 audio两个成员的MediaStreamConstraints
|
||||||
|
//对象,用于说明请求的媒体类型。必须至少一个类型或者两个同时可以被指定。
|
||||||
|
var constraints = {
|
||||||
|
audio: true,
|
||||||
|
video: {
|
||||||
|
//帧率
|
||||||
|
frameRate: { ideal: 10,max: 15,min: 8 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取设备(摄像头或者麦克风)
|
||||||
|
navigator.mediaDevices.getUserMedia({ audio: false, video: true })
|
||||||
|
.then(function(mediaStream){
|
||||||
|
console.log(mediaStream);
|
||||||
|
video.src = window.URL.createObjectURL(mediaStream);
|
||||||
|
video.onloadedmetadata = function(e) {
|
||||||
|
video.play();
|
||||||
|
console.log(e);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch(function(error){
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
_注意:调取本地视频或音频设备的接口,出于安全的考虑,只能在localhost或者https下使用!_
|
||||||
|
|
||||||
|
[demo 传送门](https://demo.dengtongyu.com/pages/20170522j7/)
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
title: react native for ios 下的一个小坑
|
||||||
|
tags: []
|
||||||
|
id: '84'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2016-12-09 18:07:07
|
||||||
|
---
|
||||||
|
|
||||||
|
最近在尝试学习一下react native,然后就按照官网的教程一步步配置环境,一切都很顺利,但是在xcode下run的时候就报错了。
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
Error: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
|
||||||
|
reason: 'bundleURL must be non-nil when not implementing loadSourceForBridge'
|
||||||
|
```
|
||||||
|
|
||||||
|
谷歌百度一系列之后,仍然无法解决,然后加了react native中文的官方群提问,有人说是开启了VPN导致,然而我的Mac并没有配置VPN,一切又回到原点。 然而受到这个启发,把之前写web dom时配置的 127.0.0.1 localhost 还原。神奇的事情发生了,Xcode里的项目跑起来了!喜大普奔,然而我也没搞懂这是为什么。
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
#host文件一定要有这个
|
||||||
|
127.0.0.1 localhost
|
||||||
|
```
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
title: vue CLI 代理设置以及打包引入配置
|
||||||
|
tags: []
|
||||||
|
id: '173'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-10-17 15:25:49
|
||||||
|
---
|
||||||
|
|
||||||
|
## 代理设置
|
||||||
|
|
||||||
|
在用 [vue CLI](https://www.npmjs.com/package/vue-cli) 做开发的时候,很多时候我们需要用到代理请求获取数据,[vue CLI](https://www.npmjs.com/package/vue-cli) 也很方便的为我们提供配置代理的API,打开[vue CLI](https://www.npmjs.com/package/vue-cli)项目的 _/config/index.js_ 文件,找到dev里的proxyTable
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
//代理设置
|
||||||
|
dev: {
|
||||||
|
env: require('./dev.env'),
|
||||||
|
port: 8080,
|
||||||
|
autoOpenBrowser: true,
|
||||||
|
assetsSubDirectory: 'static',
|
||||||
|
assetsPublicPath: '/',
|
||||||
|
proxyTable: {
|
||||||
|
'/data': {
|
||||||
|
target: 'http://dengtongyu.com', //代理目标地址
|
||||||
|
secure: false,
|
||||||
|
changeOrigin: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cssSourceMap: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 打包引入配置
|
||||||
|
|
||||||
|
我们用[vue CLI](https://www.npmjs.com/package/vue-cli)打包项目的时候默认引入的资源是"/"根目录,如果我们的项目在非根目录下就要重新配置一下了,同样的,打开[vue CLI](https://www.npmjs.com/package/vue-cli)项目的 _/config/index.js_ 文件,找到build里的assetsPublicPath
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
build: {
|
||||||
|
env: require('./prod.env'),
|
||||||
|
index: path.resolve(__dirname, '../dist/index.html'),
|
||||||
|
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||||
|
assetsSubDirectory: 'static',
|
||||||
|
assetsPublicPath: '/pages/myproject/', //配置引入资源的根目录
|
||||||
|
productionSourceMap: true,
|
||||||
|
productionGzip: false,
|
||||||
|
productionGzipExtensions: ['js', 'css'],
|
||||||
|
bundleAnalyzerReport: process.env.npm_config_report
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
title: vue-resource http请求在ios浏览器下的一个小坑
|
||||||
|
tags: []
|
||||||
|
id: '69'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2016-07-05 18:41:00
|
||||||
|
---
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: 'body',
|
||||||
|
ready:function(){
|
||||||
|
this.$http.get('url',{
|
||||||
|
|
||||||
|
}).then(function(json){
|
||||||
|
console.log( typeof json.data ) //谷歌返回的是string,ios返回的是object
|
||||||
|
},function(json){
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
以上代码,在谷歌返回的是string,ios浏览器返回的是object, 所以通过JSON.parse()格式化json.data的时候,在ios浏览器下就报错了 通过使用vue-resource提供的json()方法解决 具体代码如下
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: 'body',
|
||||||
|
ready:function(){
|
||||||
|
this.$http.get('url',{
|
||||||
|
|
||||||
|
}).then(function(json){
|
||||||
|
console.log( typeof json.json())
|
||||||
|
},function(json){
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 一个星期一早晨感慨
|
||||||
|
tags: []
|
||||||
|
id: '22'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-05-30 09:59:06
|
||||||
|
---
|
||||||
|
|
||||||
|
你看那天,看那墙,看那秋海棠,今天还是星期一。 ——加西亚马尔克斯《百年孤独》 为什么星期五离星期一这么近,星期一离星期五却这么远!这不科学!
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 人应该要学会生活
|
||||||
|
tags: []
|
||||||
|
id: '20'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-05-26 23:27:30
|
||||||
|
---
|
||||||
|
|
||||||
|
卖力,不卖命,卖艺,不卖身。 熬通宵这种玩意儿,最最摧残身体健康,有碍养生,过了青春期,万万不可行。 在这狗一般的生涯里,唯一的指望,就是太阳落山。 噫,又是一天,快快乐乐,躺下约会周公,几乎有种释放解脱涅槃的感觉。 ——亦舒《此一时也彼一时也》
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
---
|
||||||
|
title: 你也可以成为鉴黄师,nsfwjs鉴黄库初探
|
||||||
|
tags: []
|
||||||
|
id: '361'
|
||||||
|
categories:
|
||||||
|
|
||||||
|
+ - 分享
|
||||||
|
|
||||||
|
date: 2020-06-20 12:11:46
|
||||||
|
---
|
||||||
|
|
||||||
|
近日,我偶然在Github发现了一个鉴定不雅内容的 js 库 NSFW JS,出于好奇,于是就研究了一下,并且写了一个demo。下面就跟大家分享一下。
|
||||||
|
|
||||||
|
首先,NSFW JS 给一张图片鉴定的结果可能会得到如下 5 个分类结果。
|
||||||
|
|
||||||
|
1. 绘画(Drawing)——无害的艺术,或艺术绘画;
|
||||||
|
2. 变态(Hentai)——色情艺术,不适合大多数工作环境;
|
||||||
|
3. 中立(Neutral)——一般,无害的内容;
|
||||||
|
4. 色情(Porn)——不雅的内容和行为,通常涉及生殖器;
|
||||||
|
5. 性感(Sexy)——不合时宜的挑衅内容。
|
||||||
|
|
||||||
|
最终结果输出一个数组,每个分类都会输出一个概率,按概率从高到低排,所有分类的概率总和是1
|
||||||
|
|
||||||
|
```
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"className": "Sexy",
|
||||||
|
"probability": 0.35769057273864746
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"className": "Neutral",
|
||||||
|
"probability": 0.3514401912689209
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"className": "Porn",
|
||||||
|
"probability": 0.2888406813144684
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"className": "Hentai",
|
||||||
|
"probability": 0.0012577027082443237
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"className": "Drawing",
|
||||||
|
"probability": 0.0007708172197453678
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 安装
|
||||||
|
|
||||||
|
NSFW JS是由TensorFlow.js作为对等依赖项提供支持。 所以我们要先安装TensorFlow.js。
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn add @tensorflow/tfjs
|
||||||
|
yarn add nsfwjs
|
||||||
|
// or
|
||||||
|
npm i @tensorflow/tfjs
|
||||||
|
npm i nsfwjs
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 加载模型
|
||||||
|
|
||||||
|
然后我们需要加载模型。这个“模型”是用来评估图像的函数。可以在[nsfw\_model](https://github.com/gantman/nsfw_model)下载它们。这些文件是 4MB 大小的分片,便于在客户端进行缓存。因为我在vue项目中使用,所以把它们放在 /public/model/ 文件夹中。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 使用
|
||||||
|
|
||||||
|
```
|
||||||
|
// 导入模块
|
||||||
|
import * as nsfwjs from "nsfwjs";
|
||||||
|
// 图片dom节点
|
||||||
|
const img = document.getElementById('img')
|
||||||
|
// 载入模型
|
||||||
|
nsfwjs.load().then(model => {
|
||||||
|
// 鉴定图片
|
||||||
|
model.classify(img).then(predictions => {
|
||||||
|
console.log("Predictions: ", predictions);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
在demo中测试的结果很惊喜,特意选取了一些干扰性的图片,也能正确识别
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
 最后,这里附上我写的demo,[传送门](https://demo.dengtongyu.com/pages/nsfwtool/)
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
---
|
||||||
|
title: 使用acme.sh 申请 Let's Encrypt 泛域名SSL证书
|
||||||
|
tags: []
|
||||||
|
id: '333'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2018-07-23 18:25:45
|
||||||
|
---
|
||||||
|
|
||||||
|
之前用ertbot方式获取Let's Encrypt泛域名证书,必须手动在添加DNS TXT 记录,也不能自动续签,使用起来颇为不便。
|
||||||
|
|
||||||
|
今天发现了github上的一个开源工具[acme.sh](https://github.com/Neilpang/acme.sh),是一个开源的Let’s Encrypt SSL申请工具,操作和流程比官方的申请方式简化很多,使用起来非常方便,推荐大家使用。欢迎大家给该工具打星。
|
||||||
|
|
||||||
|
### 安装acme.sh
|
||||||
|
|
||||||
|
```
|
||||||
|
curl https://get.acme.sh sh
|
||||||
|
```
|
||||||
|
|
||||||
|
执行完代码后,acme.sh会被自动安装到~/.acme.sh/中
|
||||||
|
|
||||||
|
### 设置DNS API
|
||||||
|
|
||||||
|
目前泛域名证书仅支持DNS验证,acme.sh通过DNS提供商的API自动完成操作,因此需要先设置DNS API,以阿里云为例。
|
||||||
|
|
||||||
|
先前往阿里云后台获取App\_Key跟App\_Secret,在【用户信息管理】-【安全信息管理】创建SecretKey [传送门](https://ak-console.aliyun.com/#/accesskey),然后执行以下脚本
|
||||||
|
|
||||||
|
```
|
||||||
|
# 替换成从阿里云后台获取的密钥
|
||||||
|
export Ali_Key="LTA*********uV6"
|
||||||
|
export Ali_Secret="QKmsZgo*************8Htr6"
|
||||||
|
```
|
||||||
|
|
||||||
|
这个临时环境变量只需配置这一次,当成功申请证书后,API 信息会被自动保存在~/.acme.sh/account.conf,下次你使用acme.sh的时候会被自动使用
|
||||||
|
|
||||||
|
### 获取证书
|
||||||
|
|
||||||
|
```
|
||||||
|
# 换成自己的域名
|
||||||
|
acme.sh --issue --dns dns_ali -d dengtongyu.com -d *.dengtongyu.com
|
||||||
|
```
|
||||||
|
|
||||||
|
如果acme.sh,提示命令没找到,那就请再执行以下指令:
|
||||||
|
|
||||||
|
```
|
||||||
|
source ~/.bashrc
|
||||||
|
acme.sh --issue --dns dns_ali -d dengtongyu.com -d *.dengtongyu.com
|
||||||
|
```
|
||||||
|
|
||||||
|
或者先cd到acme.sh目录下,再执行文件
|
||||||
|
|
||||||
|
```
|
||||||
|
cd ~/.acme.sh
|
||||||
|
./acme.sh --issue --dns dns_ali -d dengtongyu.com -d *.dengtongyu.com
|
||||||
|
```
|
||||||
|
|
||||||
|
\--dns dns\_ali参数表示使用 阿里云 的 API,如果是其他解析商,请[点这里](https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md)查看对应的参数
|
||||||
|
|
||||||
|
执行完代码后,会有120秒等待DNS生效,所以至少需要等待两分钟,等倒数结束后看到Cert success就是成功了
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 拷贝证书
|
||||||
|
|
||||||
|
前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.
|
||||||
|
|
||||||
|
注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.
|
||||||
|
|
||||||
|
正确的使用方法是使用 --installcert 命令,并指定目标位置, 然后证书文件会被copy到相应的位置:
|
||||||
|
|
||||||
|
```
|
||||||
|
acme.sh --installcert -d dengtongyu.com \
|
||||||
|
--key-file /etc/nginx/ssl/dengtongyu.key \
|
||||||
|
--fullchain-file /etc/nginx/ssl/fullchain.cer \
|
||||||
|
--reloadcmd "service nginx force-reload"
|
||||||
|
```
|
||||||
|
|
||||||
|
(一个小提醒, 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload)
|
||||||
|
|
||||||
|
### 在 Nginx 中 配置 Let’s Encrypt 证书
|
||||||
|
|
||||||
|
Nginx 配置文件片断:
|
||||||
|
|
||||||
|
```
|
||||||
|
server {
|
||||||
|
server_name xxx.com;
|
||||||
|
listen 443 http2 ssl;
|
||||||
|
ssl on;
|
||||||
|
ssl_certificate /etc/nginx/ssl/fullchain.cer;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/dengtongyu.key;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 证书续期
|
||||||
|
|
||||||
|
Let's Encrypt 证书的有效期为三个月,acme.sh会每隔60天自动帮你续期,你无需任何操作
|
||||||
|
|
||||||
|
最后,更详细等内容请看[官方说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 吾日三省吾身
|
||||||
|
tags: []
|
||||||
|
id: '61'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-06-23 23:13:16
|
||||||
|
---
|
||||||
|
|
||||||
|
当你的才华还撑不起你的野心时,那你就应该静下心来学习。 当你的能力还驾驭不了你的目标时,那你就应该沉下心来历练。 我绝对算不上好人,也决非坏到无药可救, 我把在这个时期自我调整的过程,称为人生, 我把自我调整过程中的感受,称为命运。
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 咸鱼需要冷藏
|
||||||
|
tags: []
|
||||||
|
id: '29'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-06-02 21:22:10
|
||||||
|
---
|
||||||
|
|
||||||
|
6月,广州! 白天大地在蒸腾,只需在太阳底下10秒,就能感受到阳光满满的恶意。 夜晚空气弥漫着热浪,连呼吸都能灼伤你五脏六腑。 这种闷热的环境,让我忘了自己几乎就是条咸鱼。 咸鱼就应该待在咸鱼该待的地方,于是我开了空调……
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 奇妙能力歌
|
||||||
|
tags: []
|
||||||
|
id: '8'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-05-24 22:59:20
|
||||||
|
---
|
||||||
|
|
||||||
|
\[audio mp3="https://image.dengtongyu.com/blog/2016/05/奇妙能力歌.mp3"\]\[/audio\] 我想要更好更圆的月亮 想要未知的疯狂 想要声色的张扬 我想要你
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 如果有来生
|
||||||
|
tags: []
|
||||||
|
id: '24'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-06-01 09:31:05
|
||||||
|
---
|
||||||
|
|
||||||
|
 如果有来生,我要当条被子,不是躺在床上就是在晒太阳! ——野原新之助
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
title: 字符html创建DOM节点
|
||||||
|
tags: []
|
||||||
|
id: '76'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2016-08-25 09:58:05
|
||||||
|
---
|
||||||
|
|
||||||
|
jQuery的创建节点的方式非常方便,$('<div></div>') 只要这样就可以创建一个div的节点。 我们也可以通过JavaScript简单实现一下这种方式。
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
function createDom(html) {
|
||||||
|
var tempDom = document.createElement('div');
|
||||||
|
tempDom.innerHTML = html;
|
||||||
|
return tempDom.childNodes;
|
||||||
|
};
|
||||||
|
var div = createDom('<div>新创建的div</div>')[0];
|
||||||
|
document.getElementsByTagName('body').appendChild(div);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
不过值得注意的是,childNodes返回的是一个DOM节点的列表,记得处理一下
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 小悟
|
||||||
|
tags: []
|
||||||
|
id: '110'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2017-08-01 09:12:01
|
||||||
|
---
|
||||||
|
|
||||||
|
人生除了生和死,其他都是小事。 世界上没有无缘无故的爱,也没有无缘无故的恨, 一切的偶然其实都是必然, 一切的必然看起来可以躲过,其实都避免不了, 把握好当下的每一次偶然, 你才有机会改变未来的每一次必然,珍惜眼前!
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 忙碌的工作日,潮流的朋友圈
|
||||||
|
tags: []
|
||||||
|
id: '14'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-05-25 23:17:50
|
||||||
|
---
|
||||||
|
|
||||||
|
最近很忙,穷忙、瞎忙··· 朋友圈一如既往的热闹,今天是2016年5月25日,杨绛女士逝世。 朋友圈迎来了一场悼念杨绛女士的潮流。我相信那些人跟我一样不曾读过她的作品或者了解过她事迹,但不妨碍那些人加入这场悼念的盛会,纷纷在朋友圈表达了自己的悲痛和惋惜之情。 托朋友圈的福,我在今天终于认识了杨绛女士。惭愧,对于贡献如此之多的人,我现在才知道她。所以我辈有什么资格评价杨绛女士,多读点杨女士书吧。 至于朋友圈的蜡烛还是你们点吧,我继续生活的苟且···
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 我脑中的橡皮擦
|
||||||
|
tags: []
|
||||||
|
id: '34'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-06-12 21:52:59
|
||||||
|
---
|
||||||
|
|
||||||
|
 最近感觉自己容易忘记一些东西,重要的、琐碎的、又或者无关紧要的。 它犹如一块橡皮擦,偷偷的抹掉你一个字,一个词,甚至一句话,而你却浑然不觉。 待你回顾这些篇章的时候,你才发现记忆的空白。 于是你努力回想,企图找回只字片语,但看到的只是一片模糊的掠影。
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
title: 条件注释判断浏览器
|
||||||
|
tags: []
|
||||||
|
id: '38'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2016-06-14 10:03:23
|
||||||
|
---
|
||||||
|
|
||||||
|
项目
|
||||||
|
|
||||||
|
范例
|
||||||
|
|
||||||
|
说明
|
||||||
|
|
||||||
|
!
|
||||||
|
|
||||||
|
\[if !IE\]
|
||||||
|
|
||||||
|
_The NOT operator. This is placed immediately in front of the?feature,?operator, or?subexpression?to reverse the Boolean meaning of the expression._ **NOT运算符。这是摆立即在前面的_功能_,_操作员_,或_子表达式_扭转布尔表达式的意义。**
|
||||||
|
|
||||||
|
lt
|
||||||
|
|
||||||
|
\[if lt IE 5.5\]
|
||||||
|
|
||||||
|
_The less-than operator. Returns true if the first argument is less than the second argument._ **小于运算符。如果第一个参数小于第二个参数,则返回true。**
|
||||||
|
|
||||||
|
lte
|
||||||
|
|
||||||
|
\[if lte IE 6\]
|
||||||
|
|
||||||
|
_The less-than or equal operator. Returns true if the first argument is less than or equal to the second argument._ **小于或等于运算。如果第一个参数是小于或等于第二个参数,则返回true。**
|
||||||
|
|
||||||
|
gt
|
||||||
|
|
||||||
|
\[if gt IE 5\]
|
||||||
|
|
||||||
|
_The greater-than operator. Returns true if the first argument is greater than the second argument._ **大于运算符。如果第一个参数大于第二个参数,则返回true。**
|
||||||
|
|
||||||
|
gte
|
||||||
|
|
||||||
|
\[if gte IE 7\]
|
||||||
|
|
||||||
|
_The greater-than or equal operator. Returns true if the first argument is greater than or equal to the second argument._ **大于或等于运算。如果第一个参数是大于或等于第二个参数,则返回true。**
|
||||||
|
|
||||||
|
( )
|
||||||
|
|
||||||
|
\[if !(IE 7)\]
|
||||||
|
|
||||||
|
_Subexpression operators. Used in conjunction with boolean operators to create more complex expressions._ **子表达式运营商。在与布尔运算符用于创建更复杂的表达式。**
|
||||||
|
|
||||||
|
&
|
||||||
|
|
||||||
|
\[if (gt IE 5)&(lt IE 7)\]
|
||||||
|
|
||||||
|
_The AND operator. Returns true if all subexpressions evaluate to true_ **AND运算符。如果所有的子表达式计算结果为true,返回true**
|
||||||
|
|
||||||
|
\[if (IE 6)(IE 7)\]
|
||||||
|
|
||||||
|
_The OR operator. Returns true if any of the subexpressions evaluates to true._ **OR运算符。返回true,如果子表达式计算结果为true。**
|
||||||
|
|
||||||
|
举个栗子
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- [if IE 7]> 仅IE7可识别 <![endif]-->
|
||||||
|
<!--[if lte IE 7]> IE7以及IE7以下版本可识别 <![endif]-->
|
||||||
|
<!--[if gte IE 7]> IE7以及IE7以上版本可识别 <![endif]-->
|
||||||
|
```
|
||||||
@@ -0,0 +1,242 @@
|
|||||||
|
---
|
||||||
|
title: 浅尝 HTML 5 input 新属性
|
||||||
|
tags: []
|
||||||
|
id: '276'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2018-02-07 18:16:11
|
||||||
|
---
|
||||||
|
|
||||||
|
在HTML 5中,input增加了许多新的特性,本篇文章整理了一些新增的,并且谷歌浏览器也已经支持的属性。 这些新增的属性,很大程度的丰富了表单控件,很多原来需要js去验证的表单,现在只要一个属性就可以了,大大提高了生产效率。 #color::-webkit-input-placeholder { /\* WebKit, Blink, Edge \*/ color:#f00; } #color::-moz-placeholder { /\* Mozilla Firefox 19+ \*/ color:#f00; } #color:-ms-input-placeholder { /\* Internet Explorer 10-11 \*/ color:#f00; } dl input { border: 1px solid #ccc; }
|
||||||
|
|
||||||
|
## required 属性
|
||||||
|
|
||||||
|
required属性规定必需在提交表单之前填写输入字段。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 此输入框为必填-->
|
||||||
|
<input type="text" required>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## list 属性
|
||||||
|
|
||||||
|
属性引用 datalist 元素,其中包含 input 元素的预定义选项。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<input list="city">
|
||||||
|
<datalist id="city">
|
||||||
|
<option value="北京">
|
||||||
|
<option value="上海">
|
||||||
|
<option value="广州">
|
||||||
|
<option value="深圳">
|
||||||
|
<option value="杭州">
|
||||||
|
</datalist>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## maxlength 属性
|
||||||
|
|
||||||
|
属性规定 input 元素中允许的最大字符数。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 只允许输入3个字符 -->
|
||||||
|
<input type="text" name="usrname" maxlength="3">
|
||||||
|
```
|
||||||
|
|
||||||
|
## max min 属性
|
||||||
|
|
||||||
|
属性规定 input 元素的最大和最小值。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 最大值为10 -->
|
||||||
|
<input type="number" max="10" required>
|
||||||
|
<!-- 最小值为10 -->
|
||||||
|
<input type="number" min="10" required>
|
||||||
|
<!-- 1到10之间的数字 -->
|
||||||
|
<input type="number" min="1" max="10" required>
|
||||||
|
```
|
||||||
|
|
||||||
|
## multiple 属性
|
||||||
|
|
||||||
|
可接受多个值的文件上传字段
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 按住Ctrl,可选择上传多个文件 -->
|
||||||
|
<input type="file" multiple required>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## pattern 属性
|
||||||
|
|
||||||
|
pattern 属性规定用于验证 input 元素的值的正则表达式。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 用pattern属性限制只能输入字母 -->
|
||||||
|
<input type="text" pattern="^[a-zA-Z]+$" title="只能输入字母" required>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## step 属性
|
||||||
|
|
||||||
|
step 属性规定 input 元素的合法数字间隔。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 只能输入能被5整除的数字 -->
|
||||||
|
<input type="number" step="5" required>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## src alt 属性规定
|
||||||
|
|
||||||
|
input按钮用图片展示
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- src的值可以是图片链接或者base64 -->
|
||||||
|
<input type="image" src="data:image/png;base64">
|
||||||
|
```
|
||||||
|
|
||||||
|
## placeholder 属性
|
||||||
|
|
||||||
|
placeholder 属性规定可描述输入 input 字段预期值的简短的提示信息 。
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 带有 placeholder 文本的输入字段 -->
|
||||||
|
<input type="text" placeholder="请输入你的文本">
|
||||||
|
|
||||||
|
<!-- placeholder 文本也可以指定颜色 -->
|
||||||
|
<style type="text/css">
|
||||||
|
#color::-webkit-input-placeholder { /* WebKit, Blink, Edge */
|
||||||
|
color:#f00;
|
||||||
|
}
|
||||||
|
#color::-moz-placeholder { /* Mozilla Firefox 19+ */
|
||||||
|
color:#f00;
|
||||||
|
}
|
||||||
|
#color:-ms-input-placeholder { /* Internet Explorer 10-11 */
|
||||||
|
color:#f00;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<input id="color" type="text" placeholder="请输入你的文本">
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## type 属性
|
||||||
|
|
||||||
|
在HTML5中,type有了更多丰富的控件类型让我们使用
|
||||||
|
|
||||||
|
### color 拾色器
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 拾色器 -->
|
||||||
|
<input type="color">
|
||||||
|
```
|
||||||
|
|
||||||
|
### date 日期控件
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 日期控件 -->
|
||||||
|
<input type="date">
|
||||||
|
```
|
||||||
|
|
||||||
|
### month 年月控件
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 定义 month 和 year 控件(不带时区) -->
|
||||||
|
<input type="month">
|
||||||
|
```
|
||||||
|
|
||||||
|
### time 时间控件
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 定义用于输入时间的控件(不带时区) -->
|
||||||
|
<input type="time">
|
||||||
|
```
|
||||||
|
|
||||||
|
### week 周控件
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 定义 week 和 year 控件(不带时区) -->
|
||||||
|
<input type="week">
|
||||||
|
```
|
||||||
|
|
||||||
|
### datetime-local 带时间的日期控件
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- date 和 time 控件(不带时区) -->
|
||||||
|
<input type="datetime-local">
|
||||||
|
```
|
||||||
|
|
||||||
|
### email 定义用于 e-mail 地址的字段(当提交表单时会自动对 email 字段的值进行验证)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 输入的必须是邮箱格式 -->
|
||||||
|
<input type="email" required>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### number 数字
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 输入的必须是数字 -->
|
||||||
|
<input type="number">
|
||||||
|
```
|
||||||
|
|
||||||
|
### password 密码
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 输入密码控件 -->
|
||||||
|
<input type="password">
|
||||||
|
```
|
||||||
|
|
||||||
|
### range 范围取值
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 选择1到10的范围 -->
|
||||||
|
<input type="range" min="1" max="10">
|
||||||
|
```
|
||||||
|
|
||||||
|
### tel 电话
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 输入的值必须是电话号码 -->
|
||||||
|
<input type="tel">
|
||||||
|
```
|
||||||
|
|
||||||
|
### url 链接
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- 输入的值必须是链接 -->
|
||||||
|
<input type="url" required>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [页面demo](https://demo.dengtongyu.com/pages/input/)
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
---
|
||||||
|
title: 演唱会随机选座解题思路
|
||||||
|
tags: []
|
||||||
|
id: '346'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2018-12-16 14:07:46
|
||||||
|
---
|
||||||
|
|
||||||
|
最近遇到一个演唱会随机选座的问题,这个问题细想起来确实有趣,正好周末有空,所以我想花点时间分享一下我的解题思路。
|
||||||
|
|
||||||
|
演唱会会场分A、B、C、D四个区域,每个区域第一排50个座位,向后每排递增2个座位,最后一排100个座位。一个人可以买1~5张票,系统要随机分配座位,但必须连号,问要怎么分配?
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
因为买票的张数不确定性,如果直接随机分配,则有可能出现很多单个位置空出的情况,降低了座位的有效利用率。如果直接顺序出票,那就出现人群扎堆的情况。所以我们要在均衡分布与高利用率之间取一个平衡点。
|
||||||
|
|
||||||
|
首先定义座位信息
|
||||||
|
|
||||||
|
```
|
||||||
|
let item = {
|
||||||
|
index: 0, //下标(索引)
|
||||||
|
group: 0, //分组
|
||||||
|
groupName: 'A', //分组名称
|
||||||
|
number: 3, //座位编号
|
||||||
|
row: 9, //第几排
|
||||||
|
disable:false //该座位是否可选
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
把座位和排数用数组保存起来
|
||||||
|
|
||||||
|
```
|
||||||
|
let front = 2; //前排座位数
|
||||||
|
let back = 10; //后排座位数
|
||||||
|
let .gap = 2; //每行座位数差
|
||||||
|
let group = 4; //分组数
|
||||||
|
let lines = (this.back - this.front) / this.gap; //每个分组有多少排
|
||||||
|
|
||||||
|
let index = 0; //下标(索引)
|
||||||
|
for (let g = 0; g < this.group; g++) {
|
||||||
|
for (let line = this.lines; line >= 0; line--) {
|
||||||
|
let rowArray = [];
|
||||||
|
for (let seat = 0; seat < (this.back - this.gap * (this.lines - line)); seat++) {
|
||||||
|
let item = {
|
||||||
|
index:index++,
|
||||||
|
group: g,
|
||||||
|
groupName: this.groupName(g), //分组名称
|
||||||
|
number: seat,
|
||||||
|
row: line,
|
||||||
|
disable:false
|
||||||
|
};
|
||||||
|
rowArray.push(item);
|
||||||
|
seats.push(item);
|
||||||
|
//console.log(item)
|
||||||
|
}
|
||||||
|
rows.push(rowArray);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
把符合条件的座位排数筛选出来(即有足够连号的空位的排数)
|
||||||
|
|
||||||
|
```
|
||||||
|
suitableRows(length) {//length为买票的张数
|
||||||
|
let haveSeatRows = [];
|
||||||
|
this.rows.forEach((list) => {
|
||||||
|
//可选的座位数组
|
||||||
|
let haveSeatList = list.filter((item) => {
|
||||||
|
return !item.disable;
|
||||||
|
});
|
||||||
|
if(haveSeatList.length <= 0) return false;
|
||||||
|
|
||||||
|
//有N张连号的排数
|
||||||
|
if(this.selectPlace(haveSeatList,length).length > 0) {
|
||||||
|
haveSeatRows.push(haveSeatList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(haveSeatRows.length > 0) {
|
||||||
|
return haveSeatRows;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
最后把从筛选出来的排数中选出座位
|
||||||
|
|
||||||
|
```
|
||||||
|
let index = Math.floor(Math.random() * haveSeats.length);
|
||||||
|
let places = this.selectPlace(haveSeats[index], length);
|
||||||
|
selectPlace(list, length) {
|
||||||
|
let places = [];
|
||||||
|
|
||||||
|
for(let i = 0;i < list.length - 1;i++) {
|
||||||
|
let end = i + length;
|
||||||
|
if(end > list.length) break;
|
||||||
|
|
||||||
|
let selects = list.slice(i, end);
|
||||||
|
let flag = false;
|
||||||
|
selects.forEach((val, k) => {
|
||||||
|
if(k + 1 <= selects.length - 1) {
|
||||||
|
if(val.number + 1 == selects[k + 1].number) {
|
||||||
|
flag = true;
|
||||||
|
}else{
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(flag) {
|
||||||
|
places = selects;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return places;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
总结起来,基本思路就是把符合条件的行数收集起来,再从所有行数中随机选出一行,顺序出票,从而在均衡分布与高利用率之间取一个平衡点。
|
||||||
|
|
||||||
|
[demon实例,点击查看!](https://demo.dengtongyu.com/pages/20181112o4/)
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
title: 用Node+express搭建本地https服务
|
||||||
|
tags: []
|
||||||
|
id: '90'
|
||||||
|
categories:
|
||||||
|
- - 分享
|
||||||
|
date: 2017-01-24 15:21:05
|
||||||
|
---
|
||||||
|
|
||||||
|
1.安装node环境(自行谷歌百度,不赘述) 2.安装express(自行谷歌百度,不赘述) 3.打开命令行,利用openssl生成证书文件
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
//生成私钥key文件
|
||||||
|
openssl genrsa 1024 > /keys/private.pem
|
||||||
|
|
||||||
|
//通过私钥文件生成CSR证书签名
|
||||||
|
openssl req -new -key /keys/private.pem -out /keys/csr.pem
|
||||||
|
|
||||||
|
//通过私钥文件和CSR证书签名生成证书文件
|
||||||
|
openssl x509 -req -days 365 -in /keys/csr.pem -signkey /keys/private.pem -out /keys/file.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
4.编写server文件
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
var app = require('express')();
|
||||||
|
var fs = require('fs');
|
||||||
|
var http = require('http');
|
||||||
|
var https = require('https');
|
||||||
|
|
||||||
|
//引入私钥、证书
|
||||||
|
var privateKey = fs.readFileSync('./keys/private.pem', 'utf8');
|
||||||
|
var certificate = fs.readFileSync('./keys/file.crt', 'utf8');
|
||||||
|
var credentials = {key: privateKey, cert: certificate};
|
||||||
|
|
||||||
|
//创建服务,设置端口号
|
||||||
|
var httpServer = http.createServer(app);
|
||||||
|
var httpsServer = https.createServer(credentials, app);
|
||||||
|
var PORT = 18080;
|
||||||
|
var SSLPORT = 18081;
|
||||||
|
|
||||||
|
//监听端口号
|
||||||
|
httpServer.listen(PORT, function() {
|
||||||
|
console.log('HTTP Server is running on: http://localhost:%s', PORT);
|
||||||
|
});
|
||||||
|
httpsServer.listen(SSLPORT, function() {
|
||||||
|
console.log('HTTPS Server is running on: https://localhost:%s', SSLPORT);
|
||||||
|
});
|
||||||
|
|
||||||
|
//路由
|
||||||
|
app.get('/', function(req, res) {
|
||||||
|
if(req.protocol === 'https') {
|
||||||
|
res.status(200).send('这是一个经过加密的https请求!');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res.status(200).send('这是一个普通的http请求!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
5.启动服务
|
||||||
|
|
||||||
|
```js
|
||||||
|
|
||||||
|
node server.js
|
||||||
|
```
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: 第一条写些什么呢?
|
||||||
|
tags: []
|
||||||
|
id: '4'
|
||||||
|
categories:
|
||||||
|
- - 生活
|
||||||
|
date: 2016-05-24 18:30:10
|
||||||
|
---
|
||||||
|
|
||||||
|
 以后的生活会更精彩吧···嗯嗯···
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: 首页
|
||||||
|
tags: []
|
||||||
|
id: '18'
|
||||||
|
categories:
|
||||||
|
- - uncategorized
|
||||||
|
comments: false
|
||||||
|
date: 2016-05-26 16:57:35
|
||||||
|
---
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 140 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
Submodule
+1
Submodule themes/butterfly added at 6a1330de84.
@@ -0,0 +1,3 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
tmp
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
module.exports = function(grunt){
|
||||||
|
grunt.initConfig({
|
||||||
|
gitclone: {
|
||||||
|
fontawesome: {
|
||||||
|
options: {
|
||||||
|
repository: 'https://github.com/FortAwesome/Font-Awesome.git',
|
||||||
|
directory: 'tmp/fontawesome'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fancybox: {
|
||||||
|
options: {
|
||||||
|
repository: 'https://github.com/fancyapps/fancyBox.git',
|
||||||
|
directory: 'tmp/fancybox'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
copy: {
|
||||||
|
fontawesome: {
|
||||||
|
expand: true,
|
||||||
|
cwd: 'tmp/fontawesome/fonts/',
|
||||||
|
src: ['**'],
|
||||||
|
dest: 'source/css/fonts/'
|
||||||
|
},
|
||||||
|
fancybox: {
|
||||||
|
expand: true,
|
||||||
|
cwd: 'tmp/fancybox/source/',
|
||||||
|
src: ['**'],
|
||||||
|
dest: 'source/fancybox/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_clean: {
|
||||||
|
tmp: ['tmp'],
|
||||||
|
fontawesome: ['source/css/fonts'],
|
||||||
|
fancybox: ['source/fancybox']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
require('load-grunt-tasks')(grunt);
|
||||||
|
|
||||||
|
grunt.renameTask('clean', '_clean');
|
||||||
|
|
||||||
|
grunt.registerTask('fontawesome', ['gitclone:fontawesome', 'copy:fontawesome', '_clean:tmp']);
|
||||||
|
grunt.registerTask('fancybox', ['gitclone:fancybox', 'copy:fancybox', '_clean:tmp']);
|
||||||
|
grunt.registerTask('default', ['gitclone', 'copy', '_clean:tmp']);
|
||||||
|
grunt.registerTask('clean', ['_clean']);
|
||||||
|
};
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Copyright (c) 2013 Tommy Chen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
# Landscape
|
||||||
|
|
||||||
|
A brand new default theme for [Hexo].
|
||||||
|
|
||||||
|
- [Preview](http://hexo.io/hexo-theme-landscape/)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Install
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
$ git clone https://github.com/hexojs/hexo-theme-landscape.git themes/landscape
|
||||||
|
```
|
||||||
|
|
||||||
|
**Landscape requires Hexo 2.4 and above.** If you would like to enable the RSS, the [hexo-generate-feed] plugin is also required.
|
||||||
|
|
||||||
|
### Enable
|
||||||
|
|
||||||
|
Modify `theme` setting in `_config.yml` to `landscape`.
|
||||||
|
|
||||||
|
### Update
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
cd themes/landscape
|
||||||
|
git pull
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
``` yml
|
||||||
|
# Header
|
||||||
|
menu:
|
||||||
|
Home: /
|
||||||
|
Archives: /archives
|
||||||
|
rss: /atom.xml
|
||||||
|
|
||||||
|
# Content
|
||||||
|
excerpt_link: Read More
|
||||||
|
fancybox: true
|
||||||
|
|
||||||
|
# Sidebar
|
||||||
|
sidebar: right
|
||||||
|
widgets:
|
||||||
|
- category
|
||||||
|
- tag
|
||||||
|
- tagcloud
|
||||||
|
- archives
|
||||||
|
- recent_posts
|
||||||
|
|
||||||
|
# Miscellaneous
|
||||||
|
google_analytics:
|
||||||
|
favicon: /favicon.png
|
||||||
|
twitter:
|
||||||
|
google_plus:
|
||||||
|
```
|
||||||
|
|
||||||
|
- **menu** - Navigation menu
|
||||||
|
- **rss** - RSS link
|
||||||
|
- **excerpt_link** - "Read More" link at the bottom of excerpted articles. `false` to hide the link.
|
||||||
|
- **fancybox** - Enable [Fancybox]
|
||||||
|
- **sidebar** - Sidebar style. You can choose `left`, `right`, `bottom` or `false`.
|
||||||
|
- **widgets** - Widgets displaying in sidebar
|
||||||
|
- **google_analytics** - Google Analytics ID
|
||||||
|
- **favicon** - Favicon path
|
||||||
|
- **twitter** - Twiiter ID
|
||||||
|
- **google_plus** - Google+ ID
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Fancybox
|
||||||
|
|
||||||
|
Landscape uses [Fancybox] to showcase your photos. You can use Markdown syntax or fancybox tag plugin to add your photos.
|
||||||
|
|
||||||
|
```
|
||||||
|

|
||||||
|
|
||||||
|
{% fancybox img_url [img_thumbnail] [img_caption] %}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sidebar
|
||||||
|
|
||||||
|
You can put your sidebar in left side, right side or bottom of your site by editing `sidebar` setting.
|
||||||
|
|
||||||
|
Landscape provides 5 built-in widgets:
|
||||||
|
|
||||||
|
- category
|
||||||
|
- tag
|
||||||
|
- tagcloud
|
||||||
|
- archives
|
||||||
|
- recent_posts
|
||||||
|
|
||||||
|
All of them are enabled by default. You can edit them in `widget` setting.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
- [Grunt] 0.4+
|
||||||
|
- Hexo 2.4+
|
||||||
|
|
||||||
|
### Grunt tasks
|
||||||
|
|
||||||
|
- **default** - Download [Fancybox] and [Font Awesome].
|
||||||
|
- **fontawesome** - Only download [Font Awesome].
|
||||||
|
- **fancybox** - Only download [Fancybox].
|
||||||
|
- **clean** - Clean temporarily files and downloaded files.
|
||||||
|
|
||||||
|
[Hexo]: https://hexo.io/
|
||||||
|
[Fancybox]: http://fancyapps.com/fancybox/
|
||||||
|
[Font Awesome]: http://fontawesome.io/
|
||||||
|
[Grunt]: http://gruntjs.com/
|
||||||
|
[hexo-generate-feed]: https://github.com/hexojs/hexo-generator-feed
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# Header
|
||||||
|
menu:
|
||||||
|
Home: /
|
||||||
|
Archives: /archives
|
||||||
|
rss: /atom.xml
|
||||||
|
|
||||||
|
# Content
|
||||||
|
excerpt_link: Read More
|
||||||
|
fancybox: true
|
||||||
|
|
||||||
|
# Sidebar
|
||||||
|
sidebar: right
|
||||||
|
widgets:
|
||||||
|
- category
|
||||||
|
- tag
|
||||||
|
- tagcloud
|
||||||
|
- archive
|
||||||
|
- recent_posts
|
||||||
|
|
||||||
|
# display widgets at the bottom of index pages (pagination == 2)
|
||||||
|
index_widgets:
|
||||||
|
# - category
|
||||||
|
# - tagcloud
|
||||||
|
# - archive
|
||||||
|
|
||||||
|
# widget behavior
|
||||||
|
archive_type: 'monthly'
|
||||||
|
show_count: false
|
||||||
|
|
||||||
|
# Miscellaneous
|
||||||
|
google_analytics:
|
||||||
|
gauges_analytics:
|
||||||
|
favicon: /favicon.png
|
||||||
|
twitter:
|
||||||
|
google_plus:
|
||||||
|
fb_admins:
|
||||||
|
fb_app_id:
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: Kategorien
|
||||||
|
search: Suche
|
||||||
|
tags: Tags
|
||||||
|
tagcloud: Tag Cloud
|
||||||
|
tweets: Tweets
|
||||||
|
prev: zurück
|
||||||
|
next: weiter
|
||||||
|
comment: Kommentare
|
||||||
|
archive_a: Archiv
|
||||||
|
archive_b: "Archive: %s"
|
||||||
|
page: Seite %d
|
||||||
|
recent_posts: letzter Beitrag
|
||||||
|
newer: Neuer
|
||||||
|
older: Älter
|
||||||
|
share: Teilen
|
||||||
|
powered_by: Powered by
|
||||||
|
rss_feed: RSS Feed
|
||||||
|
category: Kategorie
|
||||||
|
tag: Tag
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: Categories
|
||||||
|
search: Search
|
||||||
|
tags: Tags
|
||||||
|
tagcloud: Tag Cloud
|
||||||
|
tweets: Tweets
|
||||||
|
prev: Prev
|
||||||
|
next: Next
|
||||||
|
comment: Comments
|
||||||
|
archive_a: Archives
|
||||||
|
archive_b: "Archives: %s"
|
||||||
|
page: Page %d
|
||||||
|
recent_posts: Recent Posts
|
||||||
|
newer: Newer
|
||||||
|
older: Older
|
||||||
|
share: Share
|
||||||
|
powered_by: Powered by
|
||||||
|
rss_feed: RSS Feed
|
||||||
|
category: Category
|
||||||
|
tag: Tag
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: Categorías
|
||||||
|
search: Buscar
|
||||||
|
tags: Tags
|
||||||
|
tagcloud: Nube de Tags
|
||||||
|
tweets: Tweets
|
||||||
|
prev: Previo
|
||||||
|
next: Siguiente
|
||||||
|
comment: Comentarios
|
||||||
|
archive_a: Archivos
|
||||||
|
archive_b: "Archivos: %s"
|
||||||
|
page: Página %d
|
||||||
|
recent_posts: Posts recientes
|
||||||
|
newer: Nuevo
|
||||||
|
older: Viejo
|
||||||
|
share: Compartir
|
||||||
|
powered_by: Construido por
|
||||||
|
rss_feed: RSS
|
||||||
|
category: Categoría
|
||||||
|
tag: Tag
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: Catégories
|
||||||
|
search: Rechercher
|
||||||
|
tags: Mot-clés
|
||||||
|
tagcloud: Nuage de mot-clés
|
||||||
|
tweets: Tweets
|
||||||
|
prev: Précédent
|
||||||
|
next: Suivant
|
||||||
|
comment: Commentaires
|
||||||
|
archive_a: Archives
|
||||||
|
archive_b: "Archives: %s"
|
||||||
|
page: Page %d
|
||||||
|
recent_posts: Articles récents
|
||||||
|
newer: Récent
|
||||||
|
older: Ancien
|
||||||
|
share: Partager
|
||||||
|
powered_by: Propulsé par
|
||||||
|
rss_feed: Flux RSS
|
||||||
|
category: Catégorie
|
||||||
|
tag: Mot-clé
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: カテゴリ
|
||||||
|
search: 検索
|
||||||
|
tags: タグ
|
||||||
|
tagcloud: タグクラウド
|
||||||
|
tweets: ツイート
|
||||||
|
prev: 戻る
|
||||||
|
next: 次へ
|
||||||
|
comment: コメント
|
||||||
|
archive_a: アーカイブ
|
||||||
|
archive_b: "アーカイブ: %s"
|
||||||
|
page: ページ %d
|
||||||
|
recent_posts: 最近の投稿
|
||||||
|
newer: 次の記事
|
||||||
|
older: 前の記事
|
||||||
|
share: 共有
|
||||||
|
powered_by: Powered by
|
||||||
|
rss_feed: RSSフィード
|
||||||
|
category: カテゴリ
|
||||||
|
tag: タグ
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: 카테고리
|
||||||
|
search: 검색
|
||||||
|
tags: 태그
|
||||||
|
tagcloud: 태그 클라우드
|
||||||
|
tweets: 트윗
|
||||||
|
prev: 이전
|
||||||
|
next: 다음
|
||||||
|
comment: 댓글
|
||||||
|
archive_a: 아카이브
|
||||||
|
archive_b: "아카이브: %s"
|
||||||
|
page: 페이지 %d
|
||||||
|
recent_posts: 최근 포스트
|
||||||
|
newer: 최신
|
||||||
|
older: 이전
|
||||||
|
share: 공유
|
||||||
|
powered_by: Powered by
|
||||||
|
rss_feed: RSS Feed
|
||||||
|
category: 카테고리
|
||||||
|
tag: 태그
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
categories: Categorieën
|
||||||
|
search: Zoeken
|
||||||
|
tags: Labels
|
||||||
|
tagcloud: Tag Cloud
|
||||||
|
tweets: Tweets
|
||||||
|
prev: Vorige
|
||||||
|
next: Volgende
|
||||||
|
comment: Commentaren
|
||||||
|
archive_a: Archieven
|
||||||
|
archive_b: "Archieven: %s"
|
||||||
|
page: Pagina %d
|
||||||
|
recent_posts: Recente berichten
|
||||||
|
newer: Nieuwer
|
||||||
|
older: Ouder
|
||||||
|
share: Delen
|
||||||
|
powered_by: Powered by
|
||||||
|
rss_feed: RSS Feed
|
||||||
|
category: Categorie
|
||||||
|
tag: Label
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: Kategorier
|
||||||
|
search: Søk
|
||||||
|
tags: Tags
|
||||||
|
tagcloud: Tag Cloud
|
||||||
|
tweets: Tweets
|
||||||
|
prev: Forrige
|
||||||
|
next: Neste
|
||||||
|
comment: Kommentarer
|
||||||
|
archive_a: Arkiv
|
||||||
|
archive_b: "Arkiv: %s"
|
||||||
|
page: Side %d
|
||||||
|
recent_posts: Siste innlegg
|
||||||
|
newer: Newer
|
||||||
|
older: Older
|
||||||
|
share: Share
|
||||||
|
powered_by: Powered by
|
||||||
|
rss_feed: RSS Feed
|
||||||
|
category: Category
|
||||||
|
tag: Tag
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: Categorias
|
||||||
|
search: Buscar
|
||||||
|
tags: Tags
|
||||||
|
tagcloud: Nuvem de Tags
|
||||||
|
tweets: Tweets
|
||||||
|
prev: Anterior
|
||||||
|
next: Próximo
|
||||||
|
comment: Comentários
|
||||||
|
archive_a: Arquivos
|
||||||
|
archive_b: "Arquivos: %s"
|
||||||
|
page: Página %d
|
||||||
|
recent_posts: Postagens Recentes
|
||||||
|
newer: Mais Recente
|
||||||
|
older: Mais Antigo
|
||||||
|
share: Compartilhar
|
||||||
|
powered_by: Desenvolvido por
|
||||||
|
rss_feed: Feed RSS
|
||||||
|
category: Categoria
|
||||||
|
tag: Tag
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: Категории
|
||||||
|
search: Поиск
|
||||||
|
tags: Метки
|
||||||
|
tagcloud: Облако меток
|
||||||
|
tweets: Твиты
|
||||||
|
prev: Назад
|
||||||
|
next: Вперед
|
||||||
|
comment: Комментарии
|
||||||
|
archive_a: Архив
|
||||||
|
archive_b: "Архив: %s"
|
||||||
|
page: Страница %d
|
||||||
|
recent_posts: Недавние записи
|
||||||
|
newer: Следующий
|
||||||
|
older: Предыдущий
|
||||||
|
share: Поделиться
|
||||||
|
powered_by: Создано с помощью
|
||||||
|
rss_feed: RSS-каналы
|
||||||
|
category: Категория
|
||||||
|
tag: Метка
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: 分类
|
||||||
|
search: 搜索
|
||||||
|
tags: 标签
|
||||||
|
tagcloud: 标签云
|
||||||
|
tweets: 推文
|
||||||
|
prev: 上一页
|
||||||
|
next: 下一页
|
||||||
|
comment: 留言
|
||||||
|
archive_a: 归档
|
||||||
|
archive_b: 归档:%s
|
||||||
|
page: 第 %d 页
|
||||||
|
recent_posts: 最新文章
|
||||||
|
newer: Newer
|
||||||
|
older: Older
|
||||||
|
share: Share
|
||||||
|
powered_by: Powered by
|
||||||
|
rss_feed: RSS Feed
|
||||||
|
category: Category
|
||||||
|
tag: Tag
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
categories: 分類
|
||||||
|
search: 搜尋
|
||||||
|
tags: 標籤
|
||||||
|
tagcloud: 標籤雲
|
||||||
|
tweets: 推文
|
||||||
|
prev: 上一頁
|
||||||
|
next: 下一頁
|
||||||
|
comment: 留言
|
||||||
|
archive_a: 彙整
|
||||||
|
archive_b: 彙整:%s
|
||||||
|
page: 第 %d 頁
|
||||||
|
recent_posts: 最新文章
|
||||||
|
newer: Newer
|
||||||
|
older: Older
|
||||||
|
share: Share
|
||||||
|
powered_by: Powered by
|
||||||
|
rss_feed: RSS Feed
|
||||||
|
category: Category
|
||||||
|
tag: Tag
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<% if (config.disqus_shortname){ %>
|
||||||
|
<script>
|
||||||
|
var disqus_shortname = '<%= config.disqus_shortname %>';
|
||||||
|
<% if (page.permalink){ %>
|
||||||
|
var disqus_url = '<%= page.permalink %>';
|
||||||
|
<% } %>
|
||||||
|
(function(){
|
||||||
|
var dsq = document.createElement('script');
|
||||||
|
dsq.type = 'text/javascript';
|
||||||
|
dsq.async = true;
|
||||||
|
dsq.src = '//' + disqus_shortname + '.disqus.com/<% if (page.comments) { %>embed.js<% } else { %>count.js<% } %>';
|
||||||
|
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<% if (theme.fancybox){ %>
|
||||||
|
<%- css('fancybox/jquery.fancybox') %>
|
||||||
|
<%- js('fancybox/jquery.fancybox.pack') %>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<%- js('js/script') %>
|
||||||
|
<%- partial('gauges-analytics') %>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<article class="archive-article archive-type-<%= post.layout %>">
|
||||||
|
<div class="archive-article-inner">
|
||||||
|
<header class="archive-article-header">
|
||||||
|
<%- partial('post/date', {class_name: 'archive-article-date', date_format: 'MMM D'}) %>
|
||||||
|
<%- partial('post/title', {class_name: 'archive-article-title'}) %>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<% if (pagination == 2){ %>
|
||||||
|
<% page.posts.each(function(post){ %>
|
||||||
|
<%- partial('article', {post: post, index: true}) %>
|
||||||
|
<% }) %>
|
||||||
|
<% } else { %>
|
||||||
|
<% var last; %>
|
||||||
|
<% page.posts.each(function(post, i){ %>
|
||||||
|
<% var year = post.date.year(); %>
|
||||||
|
<% if (last != year){ %>
|
||||||
|
<% if (last != null){ %>
|
||||||
|
</div></section>
|
||||||
|
<% } %>
|
||||||
|
<% last = year; %>
|
||||||
|
<section class="archives-wrap">
|
||||||
|
<div class="archive-year-wrap">
|
||||||
|
<a href="<%- url_for(config.archive_dir + '/' + year) %>" class="archive-year"><%= year %></a>
|
||||||
|
</div>
|
||||||
|
<div class="archives">
|
||||||
|
<% } %>
|
||||||
|
<%- partial('archive-post', {post: post, even: i % 2 == 0}) %>
|
||||||
|
<% }) %>
|
||||||
|
<% if (page.posts.length){ %>
|
||||||
|
</div></section>
|
||||||
|
<% } %>
|
||||||
|
<% } %>
|
||||||
|
<% if (page.total > 1){ %>
|
||||||
|
<nav id="page-nav">
|
||||||
|
<% var prev_text = "« " + __('prev');var next_text = __('next') + " »"%>
|
||||||
|
<%- paginator({
|
||||||
|
prev_text: prev_text,
|
||||||
|
next_text: next_text
|
||||||
|
}) %>
|
||||||
|
</nav>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<article id="<%= post.layout %>-<%= post.slug %>" class="article article-type-<%= post.layout %>" itemscope itemprop="blogPost">
|
||||||
|
<div class="article-meta">
|
||||||
|
<%- partial('post/date', {class_name: 'article-date', date_format: null}) %>
|
||||||
|
<%- partial('post/category') %>
|
||||||
|
</div>
|
||||||
|
<div class="article-inner">
|
||||||
|
<%- partial('post/gallery') %>
|
||||||
|
<% if (post.link || post.title){ %>
|
||||||
|
<header class="article-header">
|
||||||
|
<%- partial('post/title', {class_name: 'article-title'}) %>
|
||||||
|
</header>
|
||||||
|
<% } %>
|
||||||
|
<div class="article-entry" itemprop="articleBody">
|
||||||
|
<% if (post.excerpt && index){ %>
|
||||||
|
<%- post.excerpt %>
|
||||||
|
<% if (theme.excerpt_link){ %>
|
||||||
|
<p class="article-more-link">
|
||||||
|
<a href="<%- url_for(post.path) %>#more"><%= theme.excerpt_link %></a>
|
||||||
|
</p>
|
||||||
|
<% } %>
|
||||||
|
<% } else { %>
|
||||||
|
<%- post.content %>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
<footer class="article-footer">
|
||||||
|
<a data-url="<%- post.permalink %>" data-id="<%= post._id %>" class="article-share-link"><%= __('share') %></a>
|
||||||
|
<% if (post.comments && config.disqus_shortname){ %>
|
||||||
|
<a href="<%- post.permalink %>#disqus_thread" class="article-comment-link"><%= __('comment') %></a>
|
||||||
|
<% } %>
|
||||||
|
<%- partial('post/tag') %>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
<% if (!index){ %>
|
||||||
|
<%- partial('post/nav') %>
|
||||||
|
<% } %>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<% if (!index && post.comments && config.disqus_shortname){ %>
|
||||||
|
<section id="comments">
|
||||||
|
<div id="disqus_thread">
|
||||||
|
<noscript>Please enable JavaScript to view the <a href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<footer id="footer">
|
||||||
|
<% if (theme.sidebar === 'bottom'){ %>
|
||||||
|
<%- partial('_partial/sidebar') %>
|
||||||
|
<% } %>
|
||||||
|
<div class="outer">
|
||||||
|
<div id="footer-info" class="inner">
|
||||||
|
© <%= date(new Date(), 'YYYY') %> <%= config.author || config.title %><br>
|
||||||
|
<%= __('powered_by') %> <a href="http://hexo.io/" target="_blank">Hexo</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<% if (theme.gauges_analytics){ %>
|
||||||
|
<!-- Gaug.es Analytics -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
var _gauges = _gauges || [];
|
||||||
|
(function() {
|
||||||
|
var t = document.createElement('script');
|
||||||
|
t.type = 'text/javascript';
|
||||||
|
t.async = true;
|
||||||
|
t.id = 'gauges-tracker';
|
||||||
|
t.setAttribute('data-site-id', '<%= theme.gauges_analytics %>');
|
||||||
|
t.setAttribute('data-track-path', 'https://track.gaug.es/track.gif');
|
||||||
|
t.src = 'https://d36ee2fcip1434.cloudfront.net/track.js';
|
||||||
|
var s = document.getElementsByTagName('script')[0];
|
||||||
|
s.parentNode.insertBefore(t, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- End Gaug.es Analytics -->
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<% if (theme.google_analytics){ %>
|
||||||
|
<!-- Google Analytics -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||||
|
|
||||||
|
ga('create', '<%= theme.google_analytics %>', 'auto');
|
||||||
|
ga('send', 'pageview');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<!-- End Google Analytics -->
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<%- partial('google-analytics') %>
|
||||||
|
<%
|
||||||
|
var title = page.title;
|
||||||
|
|
||||||
|
if (is_archive()){
|
||||||
|
title = __('archive_a');
|
||||||
|
|
||||||
|
if (is_month()){
|
||||||
|
title += ': ' + page.year + '/' + page.month;
|
||||||
|
} else if (is_year()){
|
||||||
|
title += ': ' + page.year;
|
||||||
|
}
|
||||||
|
} else if (is_category()){
|
||||||
|
title = __('category') + ': ' + page.category;
|
||||||
|
} else if (is_tag()){
|
||||||
|
title = __('tag') + ': ' + page.tag;
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
<title><% if (title){ %><%= title %> | <% } %><%= config.title %></title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
|
<%- open_graph({twitter_id: theme.twitter, google_plus: theme.google_plus, fb_admins: theme.fb_admins, fb_app_id: theme.fb_app_id}) %>
|
||||||
|
<% if (theme.rss){ %>
|
||||||
|
<link rel="alternate" href="<%= url_for(theme.rss) %>" title="<%= config.title %>" type="application/atom+xml">
|
||||||
|
<% } %>
|
||||||
|
<% if (theme.favicon){ %>
|
||||||
|
<link rel="icon" href="<%- theme.favicon %>">
|
||||||
|
<% } %>
|
||||||
|
<% if (config.highlight.enable){ %>
|
||||||
|
<link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
|
||||||
|
<% } %>
|
||||||
|
<%- css('css/style') %>
|
||||||
|
</head>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<header id="header">
|
||||||
|
<div id="banner"></div>
|
||||||
|
<div id="header-outer" class="outer">
|
||||||
|
<div id="header-title" class="inner">
|
||||||
|
<h1 id="logo-wrap">
|
||||||
|
<a href="<%- url_for() %>" id="logo"><%= config.title %></a>
|
||||||
|
</h1>
|
||||||
|
<% if (theme.subtitle){ %>
|
||||||
|
<h2 id="subtitle-wrap">
|
||||||
|
<a href="<%- url_for() %>" id="subtitle"><%= theme.subtitle %></a>
|
||||||
|
</h2>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
<div id="header-inner" class="inner">
|
||||||
|
<nav id="main-nav">
|
||||||
|
<a id="main-nav-toggle" class="nav-icon"></a>
|
||||||
|
<% for (var i in theme.menu){ %>
|
||||||
|
<a class="main-nav-link" href="<%- url_for(theme.menu[i]) %>"><%= i %></a>
|
||||||
|
<% } %>
|
||||||
|
</nav>
|
||||||
|
<nav id="sub-nav">
|
||||||
|
<% if (theme.rss){ %>
|
||||||
|
<a id="nav-rss-link" class="nav-icon" href="<%- url_for(theme.rss) %>" title="<%= __('rss_feed') %>"></a>
|
||||||
|
<% } %>
|
||||||
|
<a id="nav-search-btn" class="nav-icon" title="<%= __('search') %>"></a>
|
||||||
|
</nav>
|
||||||
|
<div id="search-form-wrap">
|
||||||
|
<%- search_form({button: ''}) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<nav id="mobile-nav">
|
||||||
|
<% for (var i in theme.menu){ %>
|
||||||
|
<a href="<%- url_for(theme.menu[i]) %>" class="mobile-nav-link"><%= i %></a>
|
||||||
|
<% } %>
|
||||||
|
</nav>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<% if (post.categories && post.categories.length){ %>
|
||||||
|
<div class="article-category">
|
||||||
|
<%- list_categories(post.categories, {
|
||||||
|
show_count: false,
|
||||||
|
class: 'article-category',
|
||||||
|
style: 'none',
|
||||||
|
separator: '►'
|
||||||
|
}) %>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<a href="<%- url_for(post.path) %>" class="<%= class_name %>">
|
||||||
|
<time datetime="<%= date_xml(post.date) %>" itemprop="datePublished"><%= date(post.date, date_format) %></time>
|
||||||
|
</a>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<% if (post.photos && post.photos.length){ %>
|
||||||
|
<div class="article-gallery">
|
||||||
|
<div class="article-gallery-photos">
|
||||||
|
<% post.photos.forEach(function(photo, i){ %>
|
||||||
|
<a class="article-gallery-img fancybox" href="<%- url_for(photo) %>" rel="gallery_<%= post._id %>">
|
||||||
|
<img src="<%- url_for(photo) %>" itemprop="image">
|
||||||
|
</a>
|
||||||
|
<% }) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<% if (post.prev || post.next){ %>
|
||||||
|
<nav id="article-nav">
|
||||||
|
<% if (post.prev){ %>
|
||||||
|
<a href="<%- url_for(post.prev.path) %>" id="article-nav-newer" class="article-nav-link-wrap">
|
||||||
|
<strong class="article-nav-caption"><%= __('newer') %></strong>
|
||||||
|
<div class="article-nav-title">
|
||||||
|
<% if (post.prev.title){ %>
|
||||||
|
<%= post.prev.title %>
|
||||||
|
<% } else { %>
|
||||||
|
(no title)
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
<% if (post.next){ %>
|
||||||
|
<a href="<%- url_for(post.next.path) %>" id="article-nav-older" class="article-nav-link-wrap">
|
||||||
|
<strong class="article-nav-caption"><%= __('older') %></strong>
|
||||||
|
<div class="article-nav-title"><%= post.next.title %></div>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
</nav>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<% if (post.tags && post.tags.length){ %>
|
||||||
|
<%- list_tags(post.tags, {
|
||||||
|
show_count: false,
|
||||||
|
class: 'article-tag'
|
||||||
|
}) %>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<% if (post.link){ %>
|
||||||
|
<h1 itemprop="name">
|
||||||
|
<a class="<%= class_name %>" href="<%- url_for(post.link) %>" target="_blank" itemprop="url"><%= post.title %></a>
|
||||||
|
</h1>
|
||||||
|
<% } else if (post.title){ %>
|
||||||
|
<% if (index){ %>
|
||||||
|
<h1 itemprop="name">
|
||||||
|
<a class="<%= class_name %>" href="<%- url_for(post.path) %>"><%= post.title %></a>
|
||||||
|
</h1>
|
||||||
|
<% } else { %>
|
||||||
|
<h1 class="<%= class_name %>" itemprop="name">
|
||||||
|
<%= post.title %>
|
||||||
|
</h1>
|
||||||
|
<% } %>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<aside id="sidebar"<% if (theme.sidebar === 'bottom'){ %> class="outer"<% } %>>
|
||||||
|
<% theme.widgets.forEach(function(widget){ %>
|
||||||
|
<%- partial('_widget/' + widget) %>
|
||||||
|
<% }) %>
|
||||||
|
</aside>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<% if (site.posts.length){ %>
|
||||||
|
<div class="widget-wrap">
|
||||||
|
<h3 class="widget-title"><%= __('archive_a') %></h3>
|
||||||
|
<div class="widget">
|
||||||
|
<%- list_archives({show_count: theme.show_count, type: theme.archive_type}) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<% if (site.categories.length){ %>
|
||||||
|
<div class="widget-wrap">
|
||||||
|
<h3 class="widget-title"><%= __('categories') %></h3>
|
||||||
|
<div class="widget">
|
||||||
|
<%- list_categories({show_count: theme.show_count}) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<% if (site.posts.length){ %>
|
||||||
|
<div class="widget-wrap">
|
||||||
|
<h3 class="widget-title"><%= __('recent_posts') %></h3>
|
||||||
|
<div class="widget">
|
||||||
|
<ul>
|
||||||
|
<% site.posts.sort('date', -1).limit(5).each(function(post){ %>
|
||||||
|
<li>
|
||||||
|
<a href="<%- url_for(post.path) %>"><%= post.title || '(no title)' %></a>
|
||||||
|
</li>
|
||||||
|
<% }) %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<% if (site.tags.length){ %>
|
||||||
|
<div class="widget-wrap">
|
||||||
|
<h3 class="widget-title"><%= __('tags') %></h3>
|
||||||
|
<div class="widget">
|
||||||
|
<%- list_tags({show_count: theme.show_count}) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<% if (site.tags.length){ %>
|
||||||
|
<div class="widget-wrap">
|
||||||
|
<h3 class="widget-title"><%= __('tagcloud') %></h3>
|
||||||
|
<div class="widget tagcloud">
|
||||||
|
<%- tagcloud() %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<%- partial('_partial/archive', {pagination: config.archive, index: true}) %>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<%- partial('_partial/archive', {pagination: config.category, index: true}) %>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<%- partial('_partial/archive', {pagination: 2, index: true}) %>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<%- partial('_partial/head') %>
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<div id="wrap">
|
||||||
|
<%- partial('_partial/header', null, {cache: !config.relative_link}) %>
|
||||||
|
<div class="outer">
|
||||||
|
<section id="main"><%- body %></section>
|
||||||
|
<% if (theme.sidebar && theme.sidebar !== 'bottom'){ %>
|
||||||
|
<%- partial('_partial/sidebar', null, {cache: !config.relative_link}) %>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
<%- partial('_partial/footer', null, {cache: !config.relative_link}) %>
|
||||||
|
</div>
|
||||||
|
<%- partial('_partial/mobile-nav', null, {cache: !config.relative_link}) %>
|
||||||
|
<%- partial('_partial/after-footer') %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<%- partial('_partial/article', {post: page, index: false}) %>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<%- partial('_partial/article', {post: page, index: false}) %>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<%- partial('_partial/archive', {pagination: config.tag, index: true}) %>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "hexo-theme-landscape",
|
||||||
|
"version": "0.0.2",
|
||||||
|
"private": true,
|
||||||
|
"devDependencies": {
|
||||||
|
"grunt": "~0.4.2",
|
||||||
|
"load-grunt-tasks": "~0.2.0",
|
||||||
|
"grunt-git": "~0.2.2",
|
||||||
|
"grunt-contrib-clean": "~0.5.0",
|
||||||
|
"grunt-contrib-copy": "~0.4.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
var rUrl = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[.\!\/\\w]*))?)/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fancybox tag
|
||||||
|
*
|
||||||
|
* Syntax:
|
||||||
|
* {% fancybox /path/to/image [/path/to/thumbnail] [title] %}
|
||||||
|
*/
|
||||||
|
|
||||||
|
hexo.extend.tag.register('fancybox', function(args){
|
||||||
|
var original = args.shift(),
|
||||||
|
thumbnail = '';
|
||||||
|
|
||||||
|
if (args.length && rUrl.test(args[0])){
|
||||||
|
thumbnail = args.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
var title = args.join(' ');
|
||||||
|
|
||||||
|
return '<a class="fancybox" href="' + original + '" title="' + title + '">' +
|
||||||
|
'<img src="' + (thumbnail || original) + '" alt="' + title + '">'
|
||||||
|
'</a>' +
|
||||||
|
(title ? '<span class="caption">' + title + '</span>' : '');
|
||||||
|
});
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
$block-caption
|
||||||
|
text-decoration: none
|
||||||
|
text-transform: uppercase
|
||||||
|
letter-spacing: 2px
|
||||||
|
color: color-grey
|
||||||
|
margin-bottom: 1em
|
||||||
|
margin-left: 5px
|
||||||
|
line-height: 1em
|
||||||
|
text-shadow: 0 1px #fff
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
|
$block
|
||||||
|
background: #fff
|
||||||
|
box-shadow: 1px 2px 3px #ddd
|
||||||
|
border: 1px solid color-border
|
||||||
|
border-radius: 3px
|
||||||
|
|
||||||
|
$base-style
|
||||||
|
h1
|
||||||
|
font-size: 2em
|
||||||
|
h2
|
||||||
|
font-size: 1.5em
|
||||||
|
h3
|
||||||
|
font-size: 1.3em
|
||||||
|
h4
|
||||||
|
font-size: 1.2em
|
||||||
|
h5
|
||||||
|
font-size: 1em
|
||||||
|
h6
|
||||||
|
font-size: 1em
|
||||||
|
color: color-grey
|
||||||
|
hr
|
||||||
|
border: 1px dashed color-border
|
||||||
|
strong
|
||||||
|
font-weight: bold
|
||||||
|
em, cite
|
||||||
|
font-style: italic
|
||||||
|
sup, sub
|
||||||
|
font-size: 0.75em
|
||||||
|
line-height: 0
|
||||||
|
position: relative
|
||||||
|
vertical-align: baseline
|
||||||
|
sup
|
||||||
|
top: -0.5em
|
||||||
|
sub
|
||||||
|
bottom: -0.2em
|
||||||
|
small
|
||||||
|
font-size: 0.85em
|
||||||
|
acronym, abbr
|
||||||
|
border-bottom: 1px dotted
|
||||||
|
ul, ol, dl
|
||||||
|
margin: 0 20px
|
||||||
|
line-height: line-height
|
||||||
|
ul, ol
|
||||||
|
ul, ol
|
||||||
|
margin-top: 0
|
||||||
|
margin-bottom: 0
|
||||||
|
ul
|
||||||
|
list-style: disc
|
||||||
|
ol
|
||||||
|
list-style: decimal
|
||||||
|
dt
|
||||||
|
font-weight: bold
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
.archives-wrap
|
||||||
|
margin: block-margin 0
|
||||||
|
|
||||||
|
.archives
|
||||||
|
clearfix()
|
||||||
|
|
||||||
|
.archive-year-wrap
|
||||||
|
margin-bottom: 1em
|
||||||
|
|
||||||
|
.archive-year
|
||||||
|
@extend $block-caption
|
||||||
|
|
||||||
|
.archives
|
||||||
|
column-gap: 10px
|
||||||
|
@media mq-tablet
|
||||||
|
column-count: 2
|
||||||
|
@media mq-normal
|
||||||
|
column-count: 3
|
||||||
|
|
||||||
|
.archive-article
|
||||||
|
avoid-column-break()
|
||||||
|
|
||||||
|
.archive-article-inner
|
||||||
|
@extend $block
|
||||||
|
padding: 10px
|
||||||
|
margin-bottom: 15px
|
||||||
|
|
||||||
|
.archive-article-title
|
||||||
|
text-decoration: none
|
||||||
|
font-weight: bold
|
||||||
|
color: color-default
|
||||||
|
transition: color 0.2s
|
||||||
|
line-height: line-height
|
||||||
|
&:hover
|
||||||
|
color: color-link
|
||||||
|
|
||||||
|
.archive-article-footer
|
||||||
|
margin-top: 1em
|
||||||
|
|
||||||
|
.archive-article-date
|
||||||
|
color: color-grey
|
||||||
|
text-decoration: none
|
||||||
|
font-size: 0.85em
|
||||||
|
line-height: 1em
|
||||||
|
margin-bottom: 0.5em
|
||||||
|
display: block
|
||||||
|
|
||||||
|
#page-nav
|
||||||
|
clearfix()
|
||||||
|
margin: block-margin auto
|
||||||
|
background: #fff
|
||||||
|
box-shadow: 1px 2px 3px #ddd
|
||||||
|
border: 1px solid color-border
|
||||||
|
border-radius: 3px
|
||||||
|
text-align: center
|
||||||
|
color: color-grey
|
||||||
|
overflow: hidden
|
||||||
|
a, span
|
||||||
|
padding: 10px 20px
|
||||||
|
line-height: 1
|
||||||
|
height: 2ex
|
||||||
|
a
|
||||||
|
color: color-grey
|
||||||
|
text-decoration: none
|
||||||
|
&:hover
|
||||||
|
background: color-grey
|
||||||
|
color: #fff
|
||||||
|
.prev
|
||||||
|
float: left
|
||||||
|
.next
|
||||||
|
float: right
|
||||||
|
.page-number
|
||||||
|
display: inline-block
|
||||||
|
@media mq-mobile
|
||||||
|
display: none
|
||||||
|
.current
|
||||||
|
color: color-default
|
||||||
|
font-weight: bold
|
||||||
|
.space
|
||||||
|
color: color-border
|
||||||
@@ -0,0 +1,357 @@
|
|||||||
|
.article
|
||||||
|
margin: block-margin 0
|
||||||
|
|
||||||
|
.article-inner
|
||||||
|
@extend $block
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
.article-meta
|
||||||
|
clearfix()
|
||||||
|
|
||||||
|
.article-date
|
||||||
|
@extend $block-caption
|
||||||
|
float: left
|
||||||
|
|
||||||
|
.article-category
|
||||||
|
float: left
|
||||||
|
line-height: 1em
|
||||||
|
color: #ccc
|
||||||
|
text-shadow: 0 1px #fff
|
||||||
|
margin-left: 8px
|
||||||
|
&:before
|
||||||
|
content: "\2022"
|
||||||
|
|
||||||
|
.article-category-link
|
||||||
|
@extend $block-caption
|
||||||
|
margin: 0 12px 1em
|
||||||
|
|
||||||
|
.article-header
|
||||||
|
padding: article-padding article-padding 0
|
||||||
|
|
||||||
|
.article-title
|
||||||
|
text-decoration: none
|
||||||
|
font-size: 2em
|
||||||
|
font-weight: bold
|
||||||
|
color: color-default
|
||||||
|
line-height: line-height-title
|
||||||
|
transition: color 0.2s
|
||||||
|
a&:hover
|
||||||
|
color: color-link
|
||||||
|
|
||||||
|
.article-entry
|
||||||
|
@extend $base-style
|
||||||
|
clearfix()
|
||||||
|
color: color-default
|
||||||
|
padding: 0 article-padding
|
||||||
|
p, table
|
||||||
|
line-height: line-height
|
||||||
|
margin: line-height 0
|
||||||
|
h1, h2, h3, h4, h5, h6
|
||||||
|
font-weight: bold
|
||||||
|
h1, h2, h3, h4, h5, h6
|
||||||
|
line-height: line-height-title
|
||||||
|
margin: line-height-title 0
|
||||||
|
a
|
||||||
|
color: color-link
|
||||||
|
text-decoration: none
|
||||||
|
&:hover
|
||||||
|
text-decoration: underline
|
||||||
|
ul, ol, dl
|
||||||
|
margin-top: line-height
|
||||||
|
margin-bottom: line-height
|
||||||
|
img, video
|
||||||
|
max-width: 100%
|
||||||
|
height: auto
|
||||||
|
display: block
|
||||||
|
margin: auto
|
||||||
|
iframe
|
||||||
|
border: none
|
||||||
|
table
|
||||||
|
width: 100%
|
||||||
|
border-collapse: collapse
|
||||||
|
border-spacing: 0
|
||||||
|
th
|
||||||
|
font-weight: bold
|
||||||
|
border-bottom: 3px solid color-border
|
||||||
|
padding-bottom: 0.5em
|
||||||
|
td
|
||||||
|
border-bottom: 1px solid color-border
|
||||||
|
padding: 10px 0
|
||||||
|
blockquote
|
||||||
|
font-family: font-serif
|
||||||
|
font-size: 1.4em
|
||||||
|
margin: line-height 20px
|
||||||
|
text-align: center
|
||||||
|
footer
|
||||||
|
font-size: font-size
|
||||||
|
margin: line-height 0
|
||||||
|
font-family: font-sans
|
||||||
|
cite
|
||||||
|
&:before
|
||||||
|
content: "—"
|
||||||
|
padding: 0 0.5em
|
||||||
|
.pullquote
|
||||||
|
text-align: left
|
||||||
|
width: 45%
|
||||||
|
margin: 0
|
||||||
|
&.left
|
||||||
|
margin-left: 0.5em
|
||||||
|
margin-right: 1em
|
||||||
|
&.right
|
||||||
|
margin-right: 0.5em
|
||||||
|
margin-left: 1em
|
||||||
|
.caption
|
||||||
|
color: color-grey
|
||||||
|
display: block
|
||||||
|
font-size: 0.9em
|
||||||
|
margin-top: 0.5em
|
||||||
|
position: relative
|
||||||
|
text-align: center
|
||||||
|
// http://webdesignerwall.com/tutorials/css-elastic-videos
|
||||||
|
.video-container
|
||||||
|
position: relative
|
||||||
|
padding-top: (9 / 16 * 100)% // 16:9 ratio
|
||||||
|
height: 0
|
||||||
|
overflow: hidden
|
||||||
|
iframe, object, embed
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
margin-top: 0
|
||||||
|
|
||||||
|
.article-more-link a
|
||||||
|
display: inline-block
|
||||||
|
line-height: 1em
|
||||||
|
padding: 6px 15px
|
||||||
|
border-radius: 15px
|
||||||
|
background: color-background
|
||||||
|
color: color-grey
|
||||||
|
text-shadow: 0 1px #fff
|
||||||
|
text-decoration: none
|
||||||
|
&:hover
|
||||||
|
background: color-link
|
||||||
|
color: #fff
|
||||||
|
text-decoration: none
|
||||||
|
text-shadow: 0 1px darken(color-link, 20%)
|
||||||
|
|
||||||
|
.article-footer
|
||||||
|
clearfix()
|
||||||
|
font-size: 0.85em
|
||||||
|
line-height: line-height
|
||||||
|
border-top: 1px solid color-border
|
||||||
|
padding-top: line-height
|
||||||
|
margin: 0 article-padding article-padding
|
||||||
|
a
|
||||||
|
color: color-grey
|
||||||
|
text-decoration: none
|
||||||
|
&:hover
|
||||||
|
color: color-default
|
||||||
|
|
||||||
|
.article-tag-list-item
|
||||||
|
float: left
|
||||||
|
margin-right: 10px
|
||||||
|
|
||||||
|
.article-tag-list-link
|
||||||
|
&:before
|
||||||
|
content: "#"
|
||||||
|
|
||||||
|
.article-comment-link
|
||||||
|
float: right
|
||||||
|
&:before
|
||||||
|
content: "\f075"
|
||||||
|
font-family: font-icon
|
||||||
|
padding-right: 8px
|
||||||
|
|
||||||
|
.article-share-link
|
||||||
|
cursor: pointer
|
||||||
|
float: right
|
||||||
|
margin-left: 20px
|
||||||
|
&:before
|
||||||
|
content: "\f064"
|
||||||
|
font-family: font-icon
|
||||||
|
padding-right: 6px
|
||||||
|
|
||||||
|
#article-nav
|
||||||
|
clearfix()
|
||||||
|
position: relative
|
||||||
|
@media mq-normal
|
||||||
|
margin: block-margin 0
|
||||||
|
&:before
|
||||||
|
absolute-center(8px)
|
||||||
|
content: ""
|
||||||
|
border-radius: 50%
|
||||||
|
background: color-border
|
||||||
|
box-shadow: 0 1px 2px #fff
|
||||||
|
|
||||||
|
.article-nav-link-wrap
|
||||||
|
text-decoration: none
|
||||||
|
text-shadow: 0 1px #fff
|
||||||
|
color: color-grey
|
||||||
|
box-sizing: border-box
|
||||||
|
margin-top: block-margin
|
||||||
|
text-align: center
|
||||||
|
display: block
|
||||||
|
&:hover
|
||||||
|
color: color-default
|
||||||
|
@media mq-normal
|
||||||
|
width: 50%
|
||||||
|
margin-top: 0
|
||||||
|
|
||||||
|
#article-nav-newer
|
||||||
|
@media mq-normal
|
||||||
|
float: left
|
||||||
|
text-align: right
|
||||||
|
padding-right: 20px
|
||||||
|
|
||||||
|
#article-nav-older
|
||||||
|
@media mq-normal
|
||||||
|
float: right
|
||||||
|
text-align: left
|
||||||
|
padding-left: 20px
|
||||||
|
|
||||||
|
.article-nav-caption
|
||||||
|
text-transform: uppercase
|
||||||
|
letter-spacing: 2px
|
||||||
|
color: color-border
|
||||||
|
line-height: 1em
|
||||||
|
font-weight: bold
|
||||||
|
#article-nav-newer &
|
||||||
|
margin-right: -2px
|
||||||
|
|
||||||
|
.article-nav-title
|
||||||
|
font-size: 0.85em
|
||||||
|
line-height: line-height
|
||||||
|
margin-top: 0.5em
|
||||||
|
|
||||||
|
.article-share-box
|
||||||
|
position: absolute
|
||||||
|
display: none
|
||||||
|
background: #fff
|
||||||
|
box-shadow: 1px 2px 10px rgba(0, 0, 0, 0.2)
|
||||||
|
border-radius: 3px
|
||||||
|
margin-left: -145px
|
||||||
|
overflow: hidden
|
||||||
|
z-index: 1
|
||||||
|
&.on
|
||||||
|
display: block
|
||||||
|
|
||||||
|
.article-share-input
|
||||||
|
width: 100%
|
||||||
|
background: none
|
||||||
|
box-sizing: border-box
|
||||||
|
font: 14px font-sans
|
||||||
|
padding: 0 15px
|
||||||
|
color: color-default
|
||||||
|
outline: none
|
||||||
|
border: 1px solid color-border
|
||||||
|
border-radius: 3px 3px 0 0
|
||||||
|
height: 36px
|
||||||
|
line-height: 36px
|
||||||
|
|
||||||
|
.article-share-links
|
||||||
|
clearfix()
|
||||||
|
background: color-background
|
||||||
|
|
||||||
|
$article-share-link
|
||||||
|
width: 50px
|
||||||
|
height: 36px
|
||||||
|
display: block
|
||||||
|
float: left
|
||||||
|
position: relative
|
||||||
|
color: #999
|
||||||
|
text-shadow: 0 1px #fff
|
||||||
|
&:before
|
||||||
|
font-size: 20px
|
||||||
|
font-family: font-icon
|
||||||
|
absolute-center(@font-size)
|
||||||
|
text-align: center
|
||||||
|
&:hover
|
||||||
|
color: #fff
|
||||||
|
|
||||||
|
.article-share-twitter
|
||||||
|
@extend $article-share-link
|
||||||
|
&:before
|
||||||
|
content: "\f099"
|
||||||
|
&:hover
|
||||||
|
background: color-twitter
|
||||||
|
text-shadow: 0 1px darken(color-twitter, 20%)
|
||||||
|
|
||||||
|
.article-share-facebook
|
||||||
|
@extend $article-share-link
|
||||||
|
&:before
|
||||||
|
content: "\f09a"
|
||||||
|
&:hover
|
||||||
|
background: color-facebook
|
||||||
|
text-shadow: 0 1px darken(color-facebook, 20%)
|
||||||
|
|
||||||
|
.article-share-pinterest
|
||||||
|
@extend $article-share-link
|
||||||
|
&:before
|
||||||
|
content: "\f0d2"
|
||||||
|
&:hover
|
||||||
|
background: color-pinterest
|
||||||
|
text-shadow: 0 1px darken(color-pinterest, 20%)
|
||||||
|
|
||||||
|
.article-share-google
|
||||||
|
@extend $article-share-link
|
||||||
|
&:before
|
||||||
|
content: "\f0d5"
|
||||||
|
&:hover
|
||||||
|
background: color-google
|
||||||
|
text-shadow: 0 1px darken(color-google, 20%)
|
||||||
|
|
||||||
|
.article-gallery
|
||||||
|
background: #000
|
||||||
|
position: relative
|
||||||
|
|
||||||
|
.article-gallery-photos
|
||||||
|
position: relative
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
.article-gallery-img
|
||||||
|
display: none
|
||||||
|
max-width: 100%
|
||||||
|
&:first-child
|
||||||
|
display: block
|
||||||
|
&.loaded
|
||||||
|
position: absolute
|
||||||
|
display: block
|
||||||
|
img
|
||||||
|
display: block
|
||||||
|
max-width: 100%
|
||||||
|
margin: 0 auto
|
||||||
|
/*
|
||||||
|
$article-gallery-ctrl
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
height: 100%
|
||||||
|
width: 60px
|
||||||
|
color: #fff
|
||||||
|
text-shadow: 0 0 3px rgba(0, 0, 0, 0.3)
|
||||||
|
opacity: 0.3
|
||||||
|
transition: opacity 0.2s
|
||||||
|
cursor: pointer
|
||||||
|
&:hover
|
||||||
|
opacity: 0.8
|
||||||
|
&:before
|
||||||
|
font-size: 30px
|
||||||
|
font-family: font-icon
|
||||||
|
position: absolute
|
||||||
|
top: 50%
|
||||||
|
margin-top: @font-size * -0.5
|
||||||
|
|
||||||
|
.article-gallery-prev
|
||||||
|
@extend $article-gallery-ctrl
|
||||||
|
left: 0
|
||||||
|
&:before
|
||||||
|
content: "\f053"
|
||||||
|
left: 15px
|
||||||
|
|
||||||
|
.article-gallery-next
|
||||||
|
@extend $article-gallery-ctrl
|
||||||
|
right: 0
|
||||||
|
&:before
|
||||||
|
content: "\f054"
|
||||||
|
right: 15px*/
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#comments
|
||||||
|
background: #fff
|
||||||
|
box-shadow: 1px 2px 3px #ddd
|
||||||
|
padding: article-padding
|
||||||
|
border: 1px solid color-border
|
||||||
|
border-radius: 3px
|
||||||
|
margin: block-margin 0
|
||||||
|
a
|
||||||
|
color: color-link
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#footer
|
||||||
|
background: color-footer-background
|
||||||
|
padding: 50px 0
|
||||||
|
border-top: 1px solid color-border
|
||||||
|
color: color-grey
|
||||||
|
a
|
||||||
|
color: color-link
|
||||||
|
text-decoration: none
|
||||||
|
&:hover
|
||||||
|
text-decoration: underline
|
||||||
|
|
||||||
|
#footer-info
|
||||||
|
line-height: line-height
|
||||||
|
font-size: 0.85em
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
#header
|
||||||
|
height: banner-height
|
||||||
|
position: relative
|
||||||
|
border-bottom: 1px solid color-border
|
||||||
|
&:before, &:after
|
||||||
|
content: ""
|
||||||
|
position: absolute
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
height: 40px
|
||||||
|
&:before
|
||||||
|
top: 0
|
||||||
|
background: linear-gradient(rgba(0, 0, 0, 0.2), transparent)
|
||||||
|
&:after
|
||||||
|
bottom: 0
|
||||||
|
background: linear-gradient(transparent, rgba(0, 0, 0, 0.2))
|
||||||
|
|
||||||
|
#header-outer
|
||||||
|
height: 100%
|
||||||
|
position: relative
|
||||||
|
|
||||||
|
#header-inner
|
||||||
|
position: relative
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
#banner
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
background: url(banner-url) center #000
|
||||||
|
background-size: cover
|
||||||
|
z-index: -1
|
||||||
|
|
||||||
|
#header-title
|
||||||
|
text-align: center
|
||||||
|
height: logo-size
|
||||||
|
position: absolute
|
||||||
|
top: 50%
|
||||||
|
left: 0
|
||||||
|
margin-top: logo-size * -0.5
|
||||||
|
|
||||||
|
$logo-text
|
||||||
|
text-decoration: none
|
||||||
|
color: #fff
|
||||||
|
font-weight: 300
|
||||||
|
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3)
|
||||||
|
|
||||||
|
#logo
|
||||||
|
@extend $logo-text
|
||||||
|
font-size: logo-size
|
||||||
|
line-height: logo-size
|
||||||
|
letter-spacing: 2px
|
||||||
|
|
||||||
|
#subtitle
|
||||||
|
@extend $logo-text
|
||||||
|
font-size: subtitle-size
|
||||||
|
line-height: subtitle-size
|
||||||
|
letter-spacing: 1px
|
||||||
|
|
||||||
|
#subtitle-wrap
|
||||||
|
margin-top: subtitle-size
|
||||||
|
|
||||||
|
#main-nav
|
||||||
|
float: left
|
||||||
|
margin-left: -15px
|
||||||
|
|
||||||
|
$nav-link
|
||||||
|
float: left
|
||||||
|
color: #fff
|
||||||
|
opacity: 0.6
|
||||||
|
text-decoration: none
|
||||||
|
text-shadow: 0 1px rgba(0, 0, 0, 0.2)
|
||||||
|
transition: opacity 0.2s
|
||||||
|
display: block
|
||||||
|
padding: 20px 15px
|
||||||
|
&:hover
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
|
.nav-icon
|
||||||
|
@extend $nav-link
|
||||||
|
font-family: font-icon
|
||||||
|
text-align: center
|
||||||
|
font-size: font-size
|
||||||
|
width: font-size
|
||||||
|
height: font-size
|
||||||
|
padding: 20px 15px
|
||||||
|
position: relative
|
||||||
|
cursor: pointer
|
||||||
|
|
||||||
|
.main-nav-link
|
||||||
|
@extend $nav-link
|
||||||
|
font-weight: 300
|
||||||
|
letter-spacing: 1px
|
||||||
|
@media mq-mobile
|
||||||
|
display: none
|
||||||
|
|
||||||
|
#main-nav-toggle
|
||||||
|
display: none
|
||||||
|
&:before
|
||||||
|
content: "\f0c9"
|
||||||
|
@media mq-mobile
|
||||||
|
display: block
|
||||||
|
|
||||||
|
#sub-nav
|
||||||
|
float: right
|
||||||
|
margin-right: -15px
|
||||||
|
|
||||||
|
#nav-rss-link
|
||||||
|
&:before
|
||||||
|
content: "\f09e"
|
||||||
|
|
||||||
|
#nav-search-btn
|
||||||
|
&:before
|
||||||
|
content: "\f002"
|
||||||
|
|
||||||
|
#search-form-wrap
|
||||||
|
position: absolute
|
||||||
|
top: 15px
|
||||||
|
width: 150px
|
||||||
|
height: 30px
|
||||||
|
right: -150px
|
||||||
|
opacity: 0
|
||||||
|
transition: 0.2s ease-out
|
||||||
|
&.on
|
||||||
|
opacity: 1
|
||||||
|
right: 0
|
||||||
|
@media mq-mobile
|
||||||
|
width: 100%
|
||||||
|
right: -100%
|
||||||
|
|
||||||
|
.search-form
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
background: #fff
|
||||||
|
padding: 5px 15px
|
||||||
|
border-radius: 15px
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3)
|
||||||
|
|
||||||
|
.search-form-input
|
||||||
|
border: none
|
||||||
|
background: none
|
||||||
|
color: color-default
|
||||||
|
width: 100%
|
||||||
|
font: 13px font-sans
|
||||||
|
outline: none
|
||||||
|
&::-webkit-search-results-decoration
|
||||||
|
&::-webkit-search-cancel-button
|
||||||
|
-webkit-appearance: none
|
||||||
|
|
||||||
|
.search-form-submit
|
||||||
|
position: absolute
|
||||||
|
top: 50%
|
||||||
|
right: 10px
|
||||||
|
margin-top: -7px
|
||||||
|
font: 13px font-icon
|
||||||
|
border: none
|
||||||
|
background: none
|
||||||
|
color: #bbb
|
||||||
|
cursor: pointer
|
||||||
|
&:hover, &:focus
|
||||||
|
color: #777
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
// https://github.com/chriskempson/tomorrow-theme
|
||||||
|
highlight-background = #2d2d2d
|
||||||
|
highlight-current-line = #393939
|
||||||
|
highlight-selection = #515151
|
||||||
|
highlight-foreground = #cccccc
|
||||||
|
highlight-comment = #999999
|
||||||
|
highlight-red = #f2777a
|
||||||
|
highlight-orange = #f99157
|
||||||
|
highlight-yellow = #ffcc66
|
||||||
|
highlight-green = #99cc99
|
||||||
|
highlight-aqua = #66cccc
|
||||||
|
highlight-blue = #6699cc
|
||||||
|
highlight-purple = #cc99cc
|
||||||
|
|
||||||
|
$code-block
|
||||||
|
background: highlight-background
|
||||||
|
margin: 0 article-padding * -1
|
||||||
|
padding: 15px article-padding
|
||||||
|
border-style: solid
|
||||||
|
border-color: color-border
|
||||||
|
border-width: 1px 0
|
||||||
|
overflow: auto
|
||||||
|
color: highlight-foreground
|
||||||
|
line-height: font-size * line-height
|
||||||
|
|
||||||
|
$line-numbers
|
||||||
|
color: #666
|
||||||
|
font-size: 0.85em
|
||||||
|
|
||||||
|
.article-entry
|
||||||
|
pre, code
|
||||||
|
font-family: font-mono
|
||||||
|
code
|
||||||
|
background: color-background
|
||||||
|
text-shadow: 0 1px #fff
|
||||||
|
padding: 0 0.3em
|
||||||
|
pre
|
||||||
|
@extend $code-block
|
||||||
|
code
|
||||||
|
background: none
|
||||||
|
text-shadow: none
|
||||||
|
padding: 0
|
||||||
|
.highlight
|
||||||
|
@extend $code-block
|
||||||
|
pre
|
||||||
|
border: none
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
table
|
||||||
|
margin: 0
|
||||||
|
width: auto
|
||||||
|
td
|
||||||
|
border: none
|
||||||
|
padding: 0
|
||||||
|
figcaption
|
||||||
|
clearfix()
|
||||||
|
font-size: 0.85em
|
||||||
|
color: highlight-comment
|
||||||
|
line-height: 1em
|
||||||
|
margin-bottom: 1em
|
||||||
|
a
|
||||||
|
float: right
|
||||||
|
.gutter pre
|
||||||
|
@extend $line-numbers
|
||||||
|
text-align: right
|
||||||
|
padding-right: 20px
|
||||||
|
.line
|
||||||
|
height: font-size * line-height
|
||||||
|
.line.marked
|
||||||
|
background: highlight-selection
|
||||||
|
.gist
|
||||||
|
margin: 0 article-padding * -1
|
||||||
|
border-style: solid
|
||||||
|
border-color: color-border
|
||||||
|
border-width: 1px 0
|
||||||
|
background: highlight-background
|
||||||
|
padding: 15px article-padding 15px 0
|
||||||
|
.gist-file
|
||||||
|
border: none
|
||||||
|
font-family: font-mono
|
||||||
|
margin: 0
|
||||||
|
.gist-data
|
||||||
|
background: none
|
||||||
|
border: none
|
||||||
|
.line-numbers
|
||||||
|
@extend $line-numbers
|
||||||
|
background: none
|
||||||
|
border: none
|
||||||
|
padding: 0 20px 0 0
|
||||||
|
.line-data
|
||||||
|
padding: 0 !important
|
||||||
|
.highlight
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
border: none
|
||||||
|
.gist-meta
|
||||||
|
background: highlight-background
|
||||||
|
color: highlight-comment
|
||||||
|
font: 0.85em font-sans
|
||||||
|
text-shadow: 0 0
|
||||||
|
padding: 0
|
||||||
|
margin-top: 1em
|
||||||
|
margin-left: article-padding
|
||||||
|
a
|
||||||
|
color: color-link
|
||||||
|
font-weight: normal
|
||||||
|
&:hover
|
||||||
|
text-decoration: underline
|
||||||
|
|
||||||
|
pre
|
||||||
|
.comment
|
||||||
|
.title
|
||||||
|
color: highlight-comment
|
||||||
|
.variable
|
||||||
|
.attribute
|
||||||
|
.tag
|
||||||
|
.regexp
|
||||||
|
.ruby .constant
|
||||||
|
.xml .tag .title
|
||||||
|
.xml .pi
|
||||||
|
.xml .doctype
|
||||||
|
.html .doctype
|
||||||
|
.css .id
|
||||||
|
.css .class
|
||||||
|
.css .pseudo
|
||||||
|
color: highlight-red
|
||||||
|
.number
|
||||||
|
.preprocessor
|
||||||
|
.built_in
|
||||||
|
.literal
|
||||||
|
.params
|
||||||
|
.constant
|
||||||
|
color: highlight-orange
|
||||||
|
.class
|
||||||
|
.ruby .class .title
|
||||||
|
.css .rules .attribute
|
||||||
|
color: highlight-green
|
||||||
|
.string
|
||||||
|
.value
|
||||||
|
.inheritance
|
||||||
|
.header
|
||||||
|
.ruby .symbol
|
||||||
|
.xml .cdata
|
||||||
|
color: highlight-green
|
||||||
|
.css .hexcolor
|
||||||
|
color: highlight-aqua
|
||||||
|
.function
|
||||||
|
.python .decorator
|
||||||
|
.python .title
|
||||||
|
.ruby .function .title
|
||||||
|
.ruby .title .keyword
|
||||||
|
.perl .sub
|
||||||
|
.javascript .title
|
||||||
|
.coffeescript .title
|
||||||
|
color: highlight-blue
|
||||||
|
.keyword
|
||||||
|
.javascript .function
|
||||||
|
color: highlight-purple
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
@media mq-mobile
|
||||||
|
#mobile-nav
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
width: mobile-nav-width
|
||||||
|
height: 100%
|
||||||
|
background: color-mobile-nav-background
|
||||||
|
border-right: 1px solid #fff
|
||||||
|
|
||||||
|
@media mq-mobile
|
||||||
|
.mobile-nav-link
|
||||||
|
display: block
|
||||||
|
color: color-grey
|
||||||
|
text-decoration: none
|
||||||
|
padding: 15px 20px
|
||||||
|
font-weight: bold
|
||||||
|
&:hover
|
||||||
|
color: #fff
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#sidebar
|
||||||
|
@media mq-normal
|
||||||
|
column(sidebar-column)
|
||||||
|
|
||||||
|
.widget-wrap
|
||||||
|
margin: block-margin 0
|
||||||
|
|
||||||
|
.widget-title
|
||||||
|
@extend $block-caption
|
||||||
|
|
||||||
|
.widget
|
||||||
|
color: color-sidebar-text
|
||||||
|
text-shadow: 0 1px #fff
|
||||||
|
background: color-widget-background
|
||||||
|
box-shadow: 0 -1px 4px color-widget-border inset
|
||||||
|
border: 1px solid color-widget-border
|
||||||
|
padding: 15px
|
||||||
|
border-radius: 3px
|
||||||
|
a
|
||||||
|
color: color-link
|
||||||
|
text-decoration: none
|
||||||
|
&:hover
|
||||||
|
text-decoration: underline
|
||||||
|
ul, ol, dl
|
||||||
|
ul, ol, dl
|
||||||
|
margin-left: 15px
|
||||||
|
list-style: disc
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
.widget-wrap
|
||||||
|
margin-bottom: block-margin !important
|
||||||
|
@media mq-normal
|
||||||
|
column(main-column)
|
||||||
|
|
||||||
|
.widget-title
|
||||||
|
color: #ccc
|
||||||
|
text-transform: uppercase
|
||||||
|
letter-spacing: 2px
|
||||||
|
margin-bottom: .5em
|
||||||
|
line-height: 1em
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
|
.widget
|
||||||
|
color: color-grey
|
||||||
|
ul, ol
|
||||||
|
li
|
||||||
|
display: inline-block
|
||||||
|
zoom:1
|
||||||
|
*display:inline
|
||||||
|
padding-right: .75em
|
||||||
|
/* Having problems getting balanced white space between items
|
||||||
|
li:before
|
||||||
|
content: " | "
|
||||||
|
li:first-child:before
|
||||||
|
content: none
|
||||||
|
*/
|
||||||
Loaded 100 of 129 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user