-
Notifications
You must be signed in to change notification settings - Fork 22
/
atom.xml
587 lines (351 loc) · 194 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>喵</title>
<subtitle>欢迎光临喵~</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="https://neko.ayaka.moe/"/>
<updated>2020-08-31T14:44:03.000Z</updated>
<id>https://neko.ayaka.moe/</id>
<author>
<name>Ayaka Neko</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>Arweave 储存网站</title>
<link href="https://neko.ayaka.moe/2020/08/31/044/"/>
<id>https://neko.ayaka.moe/2020/08/31/044/</id>
<published>2020-08-31T14:44:03.000Z</published>
<updated>2020-08-31T14:44:03.000Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>初识 Arweave 是在看到这样的一条新闻:<a href="https://www.chainnews.com/news/107645751530.htm" target="_blank" rel="noopener">隐私社交工具 Maskbook 集成 Arweave 支持永久储存文件</a><br><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/OCEQIqVtfN39npG.png" alt="" title=""> </div> <div class="image-caption"></div> </figure></p><p>然后岛娘就问猫猫去做一下研究,看看能不能把 Matataki 的东西存储到 Arweave 上。<br>起初我只是抱着一个很简单的心态来看待这个问题,我觉得肯定很简单。于是我前往了 Arweave 的官网,获取了我的第一笔 AR 钱包和金额,虽然只有少量的 0.25 AR,但是看了看官方的文档,部署起来肯定不会需要太多的花费的。</p><a id="more"></a><h1 id="研究"><a href="#研究" class="headerlink" title="研究"></a>研究</h1><p>去到了 GitHub,创建了一个名为 <a href="https://github.com/AyakaLab/ArcLight" target="_blank" rel="noopener">ArcLight</a> 的项目,专门用来存储相关的项目内容,这个项目最早定义是一个储存 App,你可以储存你的文件到 Arweave 中,永久可用。<br>起初用的是 <a href="https://github.com/ArweaveTeam/arweave-js" target="_blank" rel="noopener">Arweave.js</a>,这个是官方的 HTTP API 的 Node.js wrapper,里面集成了很多基本的方法和使用接口所需要的东西。<br>我想着这个项目应该是一个类似后端的程序,我就拍拍脑袋开始写 app.js,然后添加 Koa 作为后端框架支持开始工作。但是一开始我就发现这个 API 不简单,很多时候的操作要 verify 很多,也需要测试很多才行。<br>然后开始去浏览他们的 <a href="https://mtfvznw2pwxykoicvxpoe7ao5rp4nhaueueux2bbe4klxankdhra.arweave.net/ZMtcttp9r4U5Aq3e4nwO7F_GnBQlCUvoIScUu4GqGeI/" target="_blank" rel="noopener">dApp 列表</a><br>看了一会儿之后点击 Publish App 的时候需要选择 App 类型,看到那么多的类型的时候我才反应过来,原来 Arweave 能做这么多事情。这个 Arweave 有点类似曾经的 ZeroNet,也像 IPFS 能做的事情,但是 Arweave 能做的就是能用普通的浏览器访问这些<strong>以哈希值存储的内容</strong>,并且运行优美的 Web App。<br>第一天就想着,我试着部署一个网站上去算了。</p><h2 id="部署一个纯粹的-HTML-文件"><a href="#部署一个纯粹的-HTML-文件" class="headerlink" title="部署一个纯粹的 HTML 文件"></a>部署一个纯粹的 HTML 文件</h2><p>最初我去 Codepen 上找了一个参考的背景 CSS 动画写法,然后在这个里面决定好我们的主题颜色:粉色,然后修改了一个标题和一些小动画出来制作出来了一个完全只有 HTML 和 CSS 构成的一个 <a href="https://github.com/AyakaLab/ArcLight/blob/b3154deaf10a764ade476c7d3e48e03aed428e9b/public/index.html" target="_blank" rel="noopener">index.html</a> 文件。<br>然后使用官方给的 <a href="https://github.com/ArweaveTeam/arweave-deploy" target="_blank" rel="noopener">Arweave Deploy</a> 命令行工具部署到了 Arweave 的去中心化网络上。<br>部署一个纯粹的 HTML 文件和 favicon 的文件夹看起来似乎如鱼得水,就按照官方的说明:</p><pre><code>arweave deploy-dir ./public --key-file secrets/ayaka.key.json</code></pre><p>用这个命令就能完成存储在 public 文件夹下面整个文件夹的部署工作,这个过程看起来很简单很简洁,ayaka.key.json 就是你从网站上免费获取的下载的那个文件。<br>对于 <strong><em>Arweave 区块纺</em> 而言,你的用户 ID 和你的认证凭据就是那个 JSON 文件</strong>,请一定小心保管。<br>部署的最早的版本看上去很简陋,什么都没有,<a href="https://hsaiqhvqmphybnatuq7ticoxu6j4nm6p5apjuktlf5xvun2chl5a.arweave.net/PICIHrBjz4C0E6Q_NAnXp5PGs8_oHpoqay9vWjdCOvo" target="_blank" rel="noopener">地址</a></p><h2 id="第二天的研究"><a href="#第二天的研究" class="headerlink" title="第二天的研究"></a>第二天的研究</h2><p>第二天我对 <a href="https://github.com/ArweaveTeam/arweave-js" target="_blank" rel="noopener">Arweave.js</a> 进行了很细致的研究,比如如何使用这个 Javascript 库完成文件上传和 对 Transactions 进行 sign 和 submit,然后就意识到我们需要的是一个独立的,去中心化,不需要后端的前端 App,这让我从那个 app.js 和 Koa 的梦中醒来,发现自己并不需要这样,我们只需要像往常一样构建一个普通的 Vue + Webpack 的网站就可以了,因为可以上传到 Arweave 的东西可以是一整个文件夹,只要我打包好就行。</p><p>于是我开始着手改造整个 ArcLight 项目,去掉了 public 文件夹,保留了存储 key 的 secrets 文件夹,然后为 Vue + Webpack 初始化使用</p><pre><code>vue init webpack .</code></pre><p>然后一个崭新的 Vue 项目就构建起来了。</p><h3 id="搬迁原有的东西"><a href="#搬迁原有的东西" class="headerlink" title="搬迁原有的东西"></a>搬迁原有的东西</h3><p>像往常一样,我在 src/router/index.js 中写下 / 的地址对应的是 Landing 页面,也就是原本部署到网络的页面写到 <a href="https://github.com/AyakaLab/ArcLight/blob/57b3ee139e6388484704aa12b8feb18238532296/src/pages/Landing.vue" target="_blank" rel="noopener">Landing.vue</a> 这个文件下。<br>因为岛娘的有一部分需求是要能够存储 Podcast 或者是图片或者是 PDF 之类的文件,完成去中心化的文件存储,于是我准备了 Flower Dance 这首音乐来作为测试对象,又添加了 DIYGod 写的 Aplayer 作为我们的播放器,这样可以避免使用原生的 <audio> 标签导致不同浏览器不同音乐播放器的效果,导致我们看到的结果不统一。</p><h3 id="构建一些新的东西"><a href="#构建一些新的东西" class="headerlink" title="构建一些新的东西"></a>构建一些新的东西</h3><p>因为有音乐播放器,有音乐,我们需要一个音乐目录和音乐菜单,还有播放音乐的页面。于是建立了 <a href="https://github.com/AyakaLab/ArcLight/blob/57b3ee139e6388484704aa12b8feb18238532296/src/pages/Music.vue" target="_blank" rel="noopener">Music.vue</a> 和 <a href="https://github.com/AyakaLab/ArcLight/blob/57b3ee139e6388484704aa12b8feb18238532296/src/pages/Music/_id.vue" target="_blank" rel="noopener">Music/_id.vue</a> 这两个文件。在这个时候,我们依然还没有一个具体的原型,为了构建的速度足够快,我选择让每一个页面的背景都是相同的,只有 title 也就是大标题不一致。比如 Music 选单里,标题就是 Music,播放页面的标题就是歌曲的 name 参数等等。</p><p>我们需要给 Music 页面写一个音乐列表,</p><pre><code><template> <div class="music-list"> <b-menu> <b-menu-list v-for="(audio, index) in audioList" :key="index" label="Music List"> <b-menu-item :label="audio.name" tag="router-link" target="_blank" :to="audio.path"></b-menu-item> </b-menu-list> </b-menu> </div></template><script>export default { data () { return { audioList: [ { name: 'Flower Dance', path: '/music/flowerdance' } ] } }}</script><style lang="less" scoped>.music-list { padding-top: 200px; text-align: center; margin-top: 20rem; width: 50%; border-radius: 20px; margin: 0 auto;}/deep/ .menu-list a { border-radius: 10px; color: white;}/deep/ .menu-list a:hover { background-color: #E56D9B;}/deep/ .menu-label { font-size: 1rem !important;}/deep/ span { font-size: 1.2rem !important;}</style></code></pre><p>注意这里使用的 /deep/ 是为了改变我使用的 Buefy 的 Menu 样式。</p><p>有了这些内容,我们写一个 Header 来帮助用户定位,</p><pre><code><template> <div class="header"> <div class="link-container"> <router-link :to="{ name: 'Landing' }" class="link"> <img src="../assets/logo.png" style="height: 3rem"> </router-link> <router-link :to="{ name: 'Landing' }" class="link text-link"> ArcLight </router-link> <router-link :to="{ name: 'MusicMenu' }" class="link text-link"> Music </router-link> </div> </div></template><style lang="less" scoped>.link-container { margin-top: 2rem; margin-left: 2rem; width: 100%; display: flex; align-items: center;}.link { margin-left: .75rem; font-size: 1.2rem;}.text-link { margin-bottom: 5px;}.text-link:hover { animation-name: colorChange; animation-duration: 0.25s; animation-timing-function: ease-in-out; color: #ff92bc;}@keyframes colorChange { 0% { color: white; } 100% { color: #ff92bc; }}/deep/ a { color: white;}</style></code></pre><p>好了,现在我们有了一个完整的页面来显示:<br><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/kUL1NxdHWl76Vmr.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><br><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/xUIg8n6LYaWDtmh.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><br><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/Jn9CSfgWIMUhDpu.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><br>大概就是长成这样。</p><p>我们尝试使用</p><pre><code>yarn build</code></pre><p>构建我们的页面 App,然后我们再来 deploy-dir,一定能成功。<br><code>yarn build</code> 不会花很久,然后我们继续运行同一个命令,这次我们把 目录改成 <code>yarn build</code> 之后生成的文件目录 <code>./dist</code></p><pre><code>arweave deploy-dir ./dist --key-file secrets/ayaka.key.json</code></pre><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/hrGdEzvaXL189Kn.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>整个过程都看起来没什么问题,我们的 Transaction 已经被提交并且能够被访问了,我们点击链接。</p><p><strong>???</strong><br><strong>为什么什么都没有?</strong></p><p>打开开发者工具查看 Console 发现所有资源全部都报错了,说明没有到服务器上,可是我们使用工具查阅 transaction:<a href="https://viewblock.io/arweave/tx/7wRXzBZqahTCGn1iZlCqpMuAToZplGtqxkNYM5ywztg" target="_blank" rel="noopener">https://viewblock.io/arweave/tx/7wRXzBZqahTCGn1iZlCqpMuAToZplGtqxkNYM5ywztg</a><br>发现的确已经部署上去了,问题出在哪里?</p><h3 id="部署失败了"><a href="#部署失败了" class="headerlink" title="部署失败了"></a>部署失败了</h3><p>我们尝试官方文档说的:</p><pre><code>arweave deploy ./dist/index.html --package --key-file secrets/ayaka.key.json</code></pre><p>我们再去尝试访问:<br><a href="https://7xr6o7ief7vrfrlm7ixvekkphritxtylffurzcmp67ckkfc6mvnq.arweave.net/_ePnfQQv6xLFbPovUilPPFE7zwspaRyJj_fEpRReZVs" target="_blank" rel="noopener">https://7xr6o7ief7vrfrlm7ixvekkphritxtylffurzcmp67ckkfc6mvnq.arweave.net/_ePnfQQv6xLFbPovUilPPFE7zwspaRyJj_fEpRReZVs</a><br>发现还是不行。为什么呢?<br>从理论上而言,我们使用 Webpack 打包文件的话,是需要一个 source map 和 js 文件来协同工作的,就像参照 ASCII 表格来分析二进制代码一样。可是我们查阅 transaction,文件 vendor 都是被打包上传好的。<br>我发现自己一个人是解决不了这个问题的,于是在 Discord 上提问:</p><p>他们建议我使用 status 命令看看状态,因为文件必须要被 mined 到一个 accepted block 之后才可以被访问:<br><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/nLyItOm1NZjMrpe.png" alt="" title=""> </div> <div class="image-caption"></div> </figure></p><p>但是结果显而易见,是成功的状态。</p><h2 id="第三天的挣扎"><a href="#第三天的挣扎" class="headerlink" title="第三天的挣扎"></a>第三天的挣扎</h2><h3 id="发现原因"><a href="#发现原因" class="headerlink" title="发现原因"></a>发现原因</h3><p>我提出了问题之后,在 Discord 上有一位十分热心的用户帮我看了问题,在第三天的时候给了回复:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/WLUfxFydgrZevtH.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>他说的确看起来一切都是被上传的,可是不知道为什么 proxy 系统没有正常工作提供路由地址。<br>也有人说是不是没有使用 –package 参数打包 index.html 文件导致的,可是我尝试了这个方法,也不能确保文件正常,比如被编码过后的网站图标变得不可用了,即便打开开发者工具栏依然可以看到是 base64 编码的 data/image</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/y1SK6asYUnqViPo.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>不久之后他提出了问题的关键所在,关键所在就是<strong>我不能对着每一个资源使用绝对路径,而是相对路径</strong>,这样就能访问到我们需要的东西了。</p><h3 id="解决问题"><a href="#解决问题" class="headerlink" title="解决问题"></a>解决问题</h3><p>想要解决这个问题也很简单,我们需要去 config/index.js 的配置文件中告诉 Webpack 我们的链接替换方式,<br>我们打开 <a href="https://github.com/AyakaLab/ArcLight/blob/5de0607a12bffe48d1646f5f640ad0e7aea73dcb/config/index.js" target="_blank" rel="noopener">config/index.js</a> 文件就能看到:</p><pre><code>build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/', /** * Source Maps */ productionSourceMap: true, // https://webpack.js.org/configuration/devtool/#production devtool: '#source-map', // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to `true`, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: false, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: // `npm run build --report` // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report }</code></pre><p>在 <code>assetsSubDirectory</code> 和 <code>assetsPublicPath</code> 的位置需要进行调整。<br>应该调整为下面的两个值,在每个值前面确保是 <strong>./</strong> 就可以了:</p><pre><code>build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: './static', assetsPublicPath: './', /** * Source Maps */ productionSourceMap: true, // https://webpack.js.org/configuration/devtool/#production devtool: '#source-map', // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to `true`, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: false, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: // `npm run build --report` // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report }</code></pre><p>于是现在我们再尝试</p><pre><code>yarn buildarweave deploy-dir ./dist --key-file secrets/ayaka.key.json</code></pre><p>点击新的链接: <a href="https://arweave.net/DdjCHM9GiWxQ7NnRQq_jJ7Ib4kOe8tlSchdu4nGbVWw" target="_blank" rel="noopener">https://arweave.net/DdjCHM9GiWxQ7NnRQq_jJ7Ib4kOe8tlSchdu4nGbVWw</a> ,就发现一切都可以用了。</p><h1 id="结论"><a href="#结论" class="headerlink" title="结论"></a>结论</h1><p>在 Arweave 的 Web App 上,你必须使用 <strong>相对路径</strong> 来填充你的资源(Assets),而不是默认配置的 <strong>绝对路径</strong>。<br>这个问题在其他前端框架上一样可能出现问题,因为都是基于 Webpack 给的打包文件和 Source Map,所以如果你也在给 Arweave 开发 Web App,就要小心这个问题了。</p><p>Webpack 的确可以在 Arweave 上使用,所有的外部资源都可以被调用,但是一定要注意:你必须使用 <strong>相对路径</strong> 来填充你的资源(Assets),而不是默认配置的 <strong>绝对路径</strong>。<br>另外就是,如果使用 vue-router 来进行路由的话,记得<strong>模式应该设置为 <code>Hash</code></strong>。如果你使用 React 或者其他前端框架,也应该考虑相应的问题。<br>以上就是我在 Arweave 踩到的坑啦。</p><h1 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h1><p>谢谢 Discord 帮我寻找问题的每一个人,谢谢 Arweave 团队能够做出这样惊喜的作品。<br>也谢谢其他 dApp 作者给的启发,没有你们就没有现在的 ArcLight。</p><p>现在 ArcLight 应邀 Arweave 团队在 GitCoin 的 Hackathon 邀请,现在作为一个可以上传和发布音乐作品的 Web App 存在着,在将来的一个月都会专注于开发这个部分的内容。</p><h1 id="链接"><a href="#链接" class="headerlink" title="链接"></a>链接</h1><p>隐私社交工具 Maskbook 集成 Arweave 支持永久储存文件: <a href="https://www.chainnews.com/news/107645751530.htm" target="_blank" rel="noopener">https://www.chainnews.com/news/107645751530.htm</a><br>ArcLight: <a href="https://github.com/AyakaLab/ArcLight" target="_blank" rel="noopener">https://github.com/AyakaLab/ArcLight</a><br>Arweave.js: <a href="https://github.com/ArweaveTeam/arweave-js" target="_blank" rel="noopener">https://github.com/ArweaveTeam/arweave-js</a><br>dApp 列表: <a href="https://mtfvznw2pwxykoicvxpoe7ao5rp4nhaueueux2bbe4klxankdhra.arweave.net/ZMtcttp9r4U5Aq3e4nwO7F_GnBQlCUvoIScUu4GqGeI/" target="_blank" rel="noopener">https://mtfvznw2pwxykoicvxpoe7ao5rp4nhaueueux2bbe4klxankdhra.arweave.net/ZMtcttp9r4U5Aq3e4nwO7F_GnBQlCUvoIScUu4GqGeI/</a><br>Arweave Deploy: <a href="https://github.com/ArweaveTeam/arweave-deploy" target="_blank" rel="noopener">https://github.com/ArweaveTeam/arweave-deploy</a><br>Arweave Viewer: <a href="https://viewblock.io/arweave" target="_blank" rel="noopener">https://viewblock.io/arweave</a></p>]]></content>
<summary type="html">
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>初识 Arweave 是在看到这样的一条新闻:<a href="https://www.chainnews.com/news/107645751530.htm" target="_blank" rel="noopener">隐私社交工具 Maskbook 集成 Arweave 支持永久储存文件</a><br><figure class="image-bubble">
<div class="img-lightbox">
<div class="overlay"></div>
<img src="https://i.loli.net/2020/08/31/OCEQIqVtfN39npG.png" alt="" title="">
</div>
<div class="image-caption"></div>
</figure></p>
<p>然后岛娘就问猫猫去做一下研究,看看能不能把 Matataki 的东西存储到 Arweave 上。<br>起初我只是抱着一个很简单的心态来看待这个问题,我觉得肯定很简单。于是我前往了 Arweave 的官网,获取了我的第一笔 AR 钱包和金额,虽然只有少量的 0.25 AR,但是看了看官方的文档,部署起来肯定不会需要太多的花费的。</p>
</summary>
<category term="Guide" scheme="https://neko.ayaka.moe/categories/Guide/"/>
<category term="Vue" scheme="https://neko.ayaka.moe/tags/Vue/"/>
<category term="Webpack" scheme="https://neko.ayaka.moe/tags/Webpack/"/>
<category term="区块链" scheme="https://neko.ayaka.moe/tags/%E5%8C%BA%E5%9D%97%E9%93%BE/"/>
<category term="P2P" scheme="https://neko.ayaka.moe/tags/P2P/"/>
<category term="区块纺" scheme="https://neko.ayaka.moe/tags/%E5%8C%BA%E5%9D%97%E7%BA%BA/"/>
<category term="Arweave" scheme="https://neko.ayaka.moe/tags/Arweave/"/>
</entry>
<entry>
<title>在基于 Three.js 的 3D 地球上放置图片</title>
<link href="https://neko.ayaka.moe/2020/08/28/043/"/>
<id>https://neko.ayaka.moe/2020/08/28/043/</id>
<published>2020-08-28T14:44:03.000Z</published>
<updated>2020-08-28T14:44:03.000Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>和之前的 Mapbox 的文章一样,这篇文章的由来也是在我接手开发 Crypto Meetup 的时候遇到的一个实现问题。这个问题的来源是因为我本身对 Three.js 的不熟悉导致的,但是大家都知道,Three.js 是 Node.js 中十分著名而且简单的 WebGL 的实现库,你可以绘制动态的 2D 或者 3D 的物件或者是场景,甚至是写就一个游戏也是没问题的。<br><a href="https://cryptomeetup.async.moe" target="_blank" rel="noopener">Crypto Meetup</a> 是我在入职仙女座星系之后接手的第一个 Dapp 项目,目的是让用户之间可以共享地理位置,可以在持有特定 Fan 票的情况下,解锁他人的地理位置分享。虽然说叫 Dapp,但其实最终产品在写就的时候就没有太多关于区块链和去中心化的技术,使用的依然是 Vue 前端 + Koa2 后端这样的一个模式来完成的开发,最终部署到你们看到的网站的时候,也是依赖于中心化服务器提供的数据,所以说不算是一个严谨的 Dapp 吧,但是作为 Matataki 的一个小应用,还是蛮不错的,我在其中也学到了 Vue 项目的基本结构和如何构建的知识。</p><a id="more"></a><h1 id="是什么问题呢?"><a href="#是什么问题呢?" class="headerlink" title="是什么问题呢?"></a>是什么问题呢?</h1><p>在 Crypto Meetup 中,我们有两个东西组成,一个是平面地图的展示,一个是 3D 地球的展示,我们在<a href="https://neko.ayaka.moe/2020/06/30/040/">上一篇相关的文章</a>里面写到了关于怎么实现 Mapbox 在地图上渲染用户头像,以及 Mapbox 实现鼠标划过变色的具体实现问题和解决方案。<br><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/py3iN7bmXKatZ2O.png" alt="" title=""> </div> <div class="image-caption"></div> </figure></p><p>现在我们要做的,就是把用户的头像放到地球上,然后让地球上进行 2D 到 3D 的坐标转换,也就是球面坐标转换,还有令一点就是,用户头像是扁平的图像,是圆形的一个 2D 物体,我们还要让这个物体永远对齐我们的摄像机对准的地方。</p><p>因为我一开始对于怎么实现这个地球是十分疑惑的,在之前的人写下的代码中,使用了渲染器的代码,看起来不免有些困难,但是这个不是重点。我去找了很多资料,真的是非常多非常多的资料。</p><h2 id="寻找参考资料"><a href="#寻找参考资料" class="headerlink" title="寻找参考资料"></a>寻找参考资料</h2><p>我先浏览的是 Three.js 提供的官方案例:<a href="https://threejs.org/examples/" target="_blank" rel="noopener">https://threejs.org/examples/</a><br>然后搜索了 geometry,发现没有什么比较类似的案例。于是我转向了搜索引擎,去寻找更多的案例。<br><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/GO6r7MTY2pxFWUm.png" alt="" title=""> </div> <div class="image-caption"></div> </figure></p><center>webgl geometry convex by <a href="https://threejs.org/examples/?q=geometry#webgl_geometry_convex" target="_blank" rel="noopener">Three.js</a></center><p>首先是这个问题: <a href="https://stackoverflow.com/questions/46017167/how-to-place-marker-with-lat-lon-on-3d-globe-three-js" target="_blank" rel="noopener">How To Place Marker with Lat/Lon On 3D Globe, Three.js?</a></p><p>后来找到了一个网站:<a href="http://stemkoski.github.io/Three.js/index.html" target="_blank" rel="noopener">http://stemkoski.github.io/Three.js/index.html</a><br>在这个网站里我找到了一个类似我们实现的内容的演示案例:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/rqKSbGW8pBjs6ck.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><center>Labeled Geometry by <a href="https://github.com/stemkoski" target="_blank" rel="noopener">Lee Stemkoski</a></center><p>接下来我看了源代码:</p><pre><code>var spriteMaterial = new THREE.SpriteMaterial( { map: texture, useScreenCoordinates: false, alignment: spriteAlignment } );</code></pre><h2 id="什么-Geometry-类型才适合?"><a href="#什么-Geometry-类型才适合?" class="headerlink" title="什么 Geometry 类型才适合?"></a>什么 Geometry 类型才适合?</h2><p>他使用的是 Sprite 这个 Object API 来完成的,但是 Sprite 在加载图像作为 SpirteMaterial 的时候会有渲染不到的困难。于是我开始搜寻怎么样转换 2D 到 3D 的方法可以让我转换图片为一个所谓的 Mesh 对象。<br>我们先回去看看 Mesh 是怎么介绍的:<a href="https://threejs.org/docs/#api/zh/objects/Mesh" target="_blank" rel="noopener">Mesh - Three.js Documentation</a>,在文档中,Mesh 是一个网格,是每一个 Geometry 结构的基础,是绘制图案的基本来源,我们定义 Mesh 之后,为我们的对象添加 Material 才能被渲染出来。接下来问题就来了,我应该用什么 Geometry?<br><strong>2D 转 3D?什么样的 Geometry 才适合我们?我们已经知道 Sprite 是行不通的,我们需要换一个方案,</strong><br>我找到了这个问题 <a href="https://stackoverflow.com/questions/19121349/converting-a-3d-scene-to-2d-image-using-raytracing-webgl-three-js" target="_blank" rel="noopener">Converting a 3D-Scene to 2D-image using raytracing (webgl, three.js)</a><br>但是似乎不是我们想要的答案,这里只是描述了 scene 的区别,和转换的理论方法。<br>我再找到了这个 <a href="https://stackoverflow.com/questions/31297567/how-do-you-build-a-custom-plane-geometry-in-three-js" target="_blank" rel="noopener">How do you build a custom plane geometry in three.js? - StackOverflow</a>,在这个问题的回答下面有很多方案,但是我看了另一个问题之后明确了我们需要的是什么:<br><a href="https://stackoverflow.com/questions/11325548/creating-a-plane-adding-a-texture-on-both-sides-and-rotating-the-object-on-its" target="_blank" rel="noopener">Creating a plane, adding a texture on both sides and rotating the object on its side - StackOverflow</a>,在这个回答下面,以及提问的代码中我们可以看到,使用了大量的 PlaneGeometry 来作为我们的图片承载对象。<br>那也就是说,<strong>我们 2D 物体都是基于 PlaneGeometry 完成的</strong>,那么怎么加载外部图像文件呢?<br>我找到了这个问题:<a href="https://stackoverflow.com/questions/16029103/three-js-using-2d-texture-sprite-for-animation-planegeometry" target="_blank" rel="noopener">Three.js Using 2D texture\sprite for animation (planeGeometry) - StackOverflow</a><br>我们发现,<code>THREE.ImageUtils.loadTexture()</code> 这个函数为我们加载了图像资源,后来又在下面看到,这个方法在后来的 Three.js 版本中废弃了,不得不换成 <code>THREE.TextureLoader().load()</code> 才能使用</p><h2 id="基本的代码"><a href="#基本的代码" class="headerlink" title="基本的代码"></a>基本的代码</h2><p>于是我开始写代码。</p><pre><code>const image = new THREE.TextureLoader().load(process.env.VUE_APP_CMUAPI + '/user/avatar?id=1332');const geometry = new THREE.PlaneGeometry(10, 10, 1, 1)const material = new THREE.MeshBasicMaterial({ map: image, transparent: true, side: THREE.DoubleSide })const result = new THREE.Mesh(geometry, material)</code></pre><p>我们先把这个物品放到 0,0,0 这个坐标上,然后注释掉渲染地球和其他物品的代码,我们刷新页面发现我们的图片被正确的加载了。也能正常的旋转,那么我们接下来要做的就是怎么去进行球面坐标的转换:</p><h2 id="直角坐标和球面坐标的转换"><a href="#直角坐标和球面坐标的转换" class="headerlink" title="直角坐标和球面坐标的转换"></a>直角坐标和球面坐标的转换</h2><p>按照<a href="https://zhuanlan.zhihu.com/p/34485962" target="_blank" rel="noopener">球坐标与直角坐标的转换 - 知乎</a> 和 <a href="https://zh.wikipedia.org/wiki/%E7%90%83%E5%BA%A7%E6%A8%99%E7%B3%BB" target="_blank" rel="noopener">球坐标系 - Wikipedia</a> 的介绍,我们知道了这个公式可以给我们进行几何坐标的转换。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/ewtTEZ72WYSXIUy.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><center>转换公式 by <a href="https://zh.wikipedia.org/wiki/%E7%90%83%E5%BA%A7%E6%A8%99%E7%B3%BB" target="_blank" rel="noopener">球坐标系 - Wikipedia</a></center><p>我们把这个写到代码里,</p><pre><code>const phi = (90 - lat) * Math.PI / 180 // lat 是 纬度const theta = (180 - lon) * Math.PI / 180 // lon 是 经度const x = (EARTH_RADIUS + 8) * Math.sin(phi) * Math.cos(theta)const y = (EARTH_RADIUS + 8) * Math.cos(phi)const z = (EARTH_RADIUS + 8) * Math.sin(phi) * Math.sin(theta)</code></pre><p>于是这样,我们就得到了我们的参数,x,y 和 z。<br>我们把之前渲染好的图片位置传入进去:</p><pre><code>result.position.x = xresult.position.y = yresult.position.z = zthis.scene.add(result)</code></pre><h2 id="摄影机的视角跟踪怎么做?"><a href="#摄影机的视角跟踪怎么做?" class="headerlink" title="摄影机的视角跟踪怎么做?"></a>摄影机的视角跟踪怎么做?</h2><p>好了,现在我们的头像可以紧紧的贴在我们的地球上,并且永远朝向一个方向,那么问题来了,我们怎么样才能使头像永远对齐我们的摄像机呢(也就是我们的视角)?<br>我查阅了 PlaneGeometry 的确有一个 <code>lookAt(camera.position)</code> 这样的使用方法,但是当我用到我们实际的代码的时候却没有什么反应。<br>我们在这个问题下找到了一些答案,<a href="https://stackoverflow.com/questions/12919638/textgeometry-to-always-face-user" target="_blank" rel="noopener">TextGeometry to always face user? - StackOverflow</a></p><pre><code>mesh.quaternion.copy(camera.quaternion)</code></pre><p>这个方法相当于给 mesh 复制了一份动态的 摄像机 位置,但是这个方法不是动态的。<br>但是这样是不够的,我在另一个帖子里找到了最终解决这个问题的方法,首先我们在 Class 内定义一个 AvatarResult 数组来存储这些渲染好的图像,</p><pre><code>this.AvatarResult.push(result)</code></pre><p>我们在 <code>this.scene.add(result)</code> 之后添加到这个数组里,之后我们到 animate(也就是你的 this.render 所在的地方) 这个全局函数的地方,使用 forEach 方法,为每一个 Avatar 对象添加这个动态变化的参数</p><pre><code>@autobindanimate() { if (!this.running) { return; } this.AvatarResult.forEach(e => e.rotation.setFromRotationMatrix(this.camera.matrix)) requestAnimationFrame(this.animate); this.render();}</code></pre><h2 id="最后的结果"><a href="#最后的结果" class="headerlink" title="最后的结果"></a>最后的结果</h2><p>最终我们获得了这样的结果:<br><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/l5uE8TjRoO1ZPfN.png" alt="" title=""> </div> <div class="image-caption"></div> </figure></p><h2 id="最终的代码"><a href="#最终的代码" class="headerlink" title="最终的代码"></a>最终的代码</h2><p>最后,我们全部的代码只有很少的几行:</p><pre><code>addNewPoint(lon, lat, magnitude, uid) { const phi = (90 - lat) * Math.PI / 180; const theta = (180 - lon) * Math.PI / 180; const x = (EARTH_RADIUS + 8) * Math.sin(phi) * Math.cos(theta); const y = (EARTH_RADIUS + 8) * Math.cos(phi); const z = (EARTH_RADIUS + 8) * Math.sin(phi) * Math.sin(theta); const image = new THREE.TextureLoader().load(process.env.VUE_APP_CMUAPI + '/user/avatar?id=' + uid); const geometry = new THREE.PlaneGeometry(10, 10, 1, 1) const material = new THREE.MeshBasicMaterial({ map: image, transparent: true, side: THREE.DoubleSide }) const result = new THREE.Mesh(geometry, material) result.position.x = x result.position.y = y result.position.z = z result.quaternion.copy(this.camera.quaternion) this.scene.add(result) this.AvatarResult.push(result)}@autobindanimate() { if (!this.running) { return; } this.AvatarResult.forEach(e => e.rotation.setFromRotationMatrix(this.camera.matrix)) requestAnimationFrame(this.animate); this.render();}</code></pre><p>这样我们就完成了我们要实现的内容了。</p><h1 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h1><p>谢谢你阅读到这里,感谢你对猫猫的支持,如果文中有什么地方写的不对和不够也希望大家能够指正。<br>因为国内 Three.js 的案例和解释还有文档实在不多,而且 Three.js 的官方文档查阅起来和搜索起来并不是很全面,在这里踩了很多很多的坑。<br>如果你也有类似的需求和需要,也感谢你阅读这些内容,也请放心,请自由的使用我在这篇文章中使用的任何代码</p><h1 id="链接和参考"><a href="#链接和参考" class="headerlink" title="链接和参考"></a>链接和参考</h1><p>Mesh - Three.js Documentation: <a href="https://threejs.org/docs/#api/zh/objects/Mesh" target="_blank" rel="noopener">https://threejs.org/docs/#api/zh/objects/Mesh</a></p><p>webgl geometry convex by <a href="https://threejs.org/examples/?q=geometry#webgl_geometry_convex" target="_blank" rel="noopener">Three.js</a><br>Labeled Geometry by <a href="https://github.com/stemkoski" target="_blank" rel="noopener">Lee Stemkoski</a><br><a href="https://stackoverflow.com/questions/31297567/how-do-you-build-a-custom-plane-geometry-in-three-js" target="_blank" rel="noopener">How do you build a custom plane geometry in three.js? - StackOverflow</a><br><a href="https://stackoverflow.com/questions/11325548/creating-a-plane-adding-a-texture-on-both-sides-and-rotating-the-object-on-its" target="_blank" rel="noopener">Creating a plane, adding a texture on both sides and rotating the object on its side - StackOverflow</a><br><a href="https://stackoverflow.com/questions/16029103/three-js-using-2d-texture-sprite-for-animation-planegeometry" target="_blank" rel="noopener">Three.js Using 2D texture\sprite for animation (planeGeometry) - StackOverflow</a><br><a href="https://zhuanlan.zhihu.com/p/34485962" target="_blank" rel="noopener">球坐标与直角坐标的转换 - 知乎</a><br><a href="https://zh.wikipedia.org/wiki/%E7%90%83%E5%BA%A7%E6%A8%99%E7%B3%BB" target="_blank" rel="noopener">球坐标系 - Wikipedia</a><br><a href="https://stackoverflow.com/questions/12919638/textgeometry-to-always-face-user" target="_blank" rel="noopener">TextGeometry to always face user? - StackOverflow</a></p><p>感谢以上所有提供资源的作者和提问者,如果没有他们,也就不会有我的结果和最终的产品。</p>]]></content>
<summary type="html">
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>和之前的 Mapbox 的文章一样,这篇文章的由来也是在我接手开发 Crypto Meetup 的时候遇到的一个实现问题。这个问题的来源是因为我本身对 Three.js 的不熟悉导致的,但是大家都知道,Three.js 是 Node.js 中十分著名而且简单的 WebGL 的实现库,你可以绘制动态的 2D 或者 3D 的物件或者是场景,甚至是写就一个游戏也是没问题的。<br><a href="https://cryptomeetup.async.moe" target="_blank" rel="noopener">Crypto Meetup</a> 是我在入职仙女座星系之后接手的第一个 Dapp 项目,目的是让用户之间可以共享地理位置,可以在持有特定 Fan 票的情况下,解锁他人的地理位置分享。虽然说叫 Dapp,但其实最终产品在写就的时候就没有太多关于区块链和去中心化的技术,使用的依然是 Vue 前端 + Koa2 后端这样的一个模式来完成的开发,最终部署到你们看到的网站的时候,也是依赖于中心化服务器提供的数据,所以说不算是一个严谨的 Dapp 吧,但是作为 Matataki 的一个小应用,还是蛮不错的,我在其中也学到了 Vue 项目的基本结构和如何构建的知识。</p>
</summary>
<category term="Guide" scheme="https://neko.ayaka.moe/categories/Guide/"/>
<category term="CryptoMeetup" scheme="https://neko.ayaka.moe/tags/CryptoMeetup/"/>
<category term="Three.js" scheme="https://neko.ayaka.moe/tags/Three-js/"/>
<category term="3D" scheme="https://neko.ayaka.moe/tags/3D/"/>
<category term="地球" scheme="https://neko.ayaka.moe/tags/%E5%9C%B0%E7%90%83/"/>
<category term="2D转3D" scheme="https://neko.ayaka.moe/tags/2D%E8%BD%AC3D/"/>
</entry>
<entry>
<title>Hexo 和 hexo-plugin-matataki 的使用和开发后记</title>
<link href="https://neko.ayaka.moe/2020/08/25/042/"/>
<id>https://neko.ayaka.moe/2020/08/25/042/</id>
<published>2020-08-25T06:05:03.000Z</published>
<updated>2020-08-25T06:05:03.000Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>有幸在加入仙女座星系之后能够给大家开发这么一个好用的站外工具和插件,当然这也少不了很多人的帮助和支持。</p><p>最先要提到的肯定是 <a href="https://github.com/MikeCoder/hexo-blog-encrypt" target="_blank" rel="noopener">hexo-blog-encrypt</a> 的作者 <a href="https://github.com/MikeCoder" target="_blank" rel="noopener">MikeCoder</a> 和其他所有对这个加密插件项目的贡献者(贡献者列表:<a href="https://github.com/MikeCoder/hexo-blog-encrypt/graphs/contributors" target="_blank" rel="noopener">https://github.com/MikeCoder/hexo-blog-encrypt/graphs/contributors</a> ,如果没有他们首先开发出这个插件,猫猫在这里也没有什么能做的,虽然在很多方面我学习了很多很多知识,借鉴了很多人很多事物的作品才到今天这一步,也才有了我们即将要介绍的 <a href="https://github.com/nekomeowww/hexo-plugin-matataki" target="_blank" rel="noopener">hexo-plugin-matataki</a> 和 <a href="https://github.com/nekomeowww/fanlocker" target="_blank" rel="noopener">FanLocker</a>,两个作为 Matataki 站外的交互插件和脚本。<br><a id="more"></a></p><p>在这里,再次感谢以下几个项目给我的灵感和源代码支持:</p><ol><li>Gitalk: <a href="https://github.com/gitalk/gitalk" target="_blank" rel="noopener">https://github.com/gitalk/gitalk</a></li><li>Disqus: <a href="https://disqus.com/" target="_blank" rel="noopener">https://disqus.com/</a></li><li>hexo-blog-encrypt: <a href="https://github.com/MikeCoder/hexo-blog-encrypt" target="_blank" rel="noopener">https://github.com/MikeCoder/hexo-blog-encrypt</a></li><li>Hexo: <a href="https://hexo.io/" target="_blank" rel="noopener">https://hexo.io/</a></li><li>utterances: <a href="https://github.com/utterance/utterances" target="_blank" rel="noopener">https://github.com/utterance/utterances</a></li></ol><p>如果没有以上项目的支持,不会有今天的 hexo-plugin-matataki 和 FanLocker</p><h1 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h1><p>上面说的东西不是很多,但是也不是很简单就能完成的,虽然的确是复制了别人好多的代码,但是,我们学习到了怎么去完成和实现才是最重要的不是吗?所以不阅读也没事,我们直接来描述怎么使用这个东西吧!</p><p>事不宜迟,不如先看看效果是什么样子的?看看<a href="https://neko.ayaka.moe/hexo-plugin-matataki-showcase/">演示博客</a>。</p><p>我在我的博客中也展示了如何使用这个插件,<a href="https://neko.ayaka.moe/2020/08/25/041/">试试看解锁这篇文章吧!</a></p><p>我搭建了一个很简单的模版博客,在这个里面你可以看到这个插件完成的具体工作,我也会相应的给出一个 Hexo 博客的配置方案给大家参照去完成魔改。</p><p>如果阅读本文不是很清楚的时候可以参考这个仓库的 Hexo 配置来搭建你的博客:<a href="https://github.com/nekomeowww/hexo-plugin-matataki-example" target="_blank" rel="noopener">基础模版</a></p><h2 id="从哪里开始呢?"><a href="#从哪里开始呢?" class="headerlink" title="从哪里开始呢?"></a>从哪里开始呢?</h2><p>我们最首先要知道的是,在 Hexo 中使用 hexo-plugin-matataki 是需要你在 Matataki 有注册账号,并且绑定过邮箱的,这样才能登录开发者中心,而 hexo-plugin-matataki 和 FanLocker 都是需要开发者中心才能完成他们的工作的。</p><p>首先前往<a href="https://developer.matataki.io" target="_blank" rel="noopener">Matataki 开发者中心</a>,登录之后就可以看到这样的列表:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/25/vIMygeKr38C7iYm.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>在这里就可以管理你的 App(我们称之为 App 是因为你可以使用我们的开发者中心提供的帮助和 API 接口以及 SDK 来完成许多 Matataki 外部应用的开发,当然如果只是写文章的你,不用在乎这些),以及你的团队,还有查阅开发文档。</p><h2 id="创建属于博客的-App"><a href="#创建属于博客的-App" class="headerlink" title="创建属于博客的 App"></a>创建属于博客的 App</h2><p>我们在这里点击新建就可以新建一个属于你的博客的 App:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/25/XC5mK3Q4AlybIUr.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>选择一个好看的图片,因为到时候会用到这个图片,大家会在使用 Matataki 账号登录到你的博客的时候看到这个图标,也可以看到你在这里填写的一切信息。</p><p>要注意这里填写的内容哦,这里填写的时候一定要注意回调链接这一栏,我们的服务器是不允许回调链接配置的时候超出域名范畴的,简单的来说,就是这里写上的域名,以及之后 FanLocker 帮你临时添加回调链接的时候必须是同一个域名,为什么会这样去限制呢?因为我们认为,FanLocker 把你的 client Id 和 client Secret 暴露在网页外部的时候,很可能会被外部的黑客利用,并且跳转到他们的网站,这样的话会给你的读者带来很多不安全的麻烦,所以我们限制了这个内容,只允许同域名的跳转。</p><p>当然,如果你是在本地尝试预览你的博客,<code>hexo server</code> 这个命令默认的端口号 4000,你可以在这里填写:</p><pre><code>localhost:4000</code></pre><p>这样本地测试链接回调的时候就会返回你本地的 localhost 了呢,但是要注意哦,当你部署到正式的域名下之后,要记得把回调链接改成你的博客域名地址,无论你的博客是否放在子域名或者子路径下,比如:xxx.com/blog 这才是你的博客的话,填写 xxx.com 也是没有问题的哦。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/25/W2vgCyaXA8MkpRl.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>点击立即创建就可以了哦,你会在 App 列表中看到你创建的 App。</p><p>其他的内容在用户登录的时候也会展示出来,你可以前往 Oauth2 这个页面去查看你的 App Oauth 登录地址,可以看到在登录界面下,你填写的所有内容都是可以被用户查阅的。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/26/mBogLpwXsv4Va7y.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>这就是授权登录的界面。</p><p>我们下一步要做什么呢?配置你的 Hexo。</p><h2 id="配置-Oauth"><a href="#配置-Oauth" class="headerlink" title="配置 Oauth"></a>配置 Oauth</h2><p>在 Oauth2 页面下获取到的这个链接,要在 Hexo 的根目录或者主题目录下创建一个键值,键值名称叫 fanlocker,填写的内容就是你的 Oauth 地址,粘贴进去就好了。</p><pre><code>fanlocker: https://developer.matataki.io/app/a0df0a921ffc94f3/oauth</code></pre><p>如果还是不清楚的话可以看这个链接:<a href="https://github.com/nekomeowww/hexo-plugin-matataki-example/blob/4622f004cafcd9edf452ff79cca8c774fe04dcb5/_config.yml#L112" target="_blank" rel="noopener">_config.yml:112</a></p><p>主题页面下到这里就结束了。</p><h2 id="安装-hexo-plugin-matataki"><a href="#安装-hexo-plugin-matataki" class="headerlink" title="安装 hexo-plugin-matataki"></a>安装 hexo-plugin-matataki</h2><p>我们现在在博客中添加我们的 hexo-plugin-matataki:</p><pre><code>yarn add hexo-plugin-matataki@latest</code></pre><p>如果你没有安装 yarn 只有 npm 的话也没问题哦,国内速度会稍为慢一些:</p><pre><code>npm install hexo-plugin-matataki@latest</code></pre><p>好啦,现在就大功告成了,Hexo 现在运行的时候就会去读取根目录下的 package.json 去加载这个插件。</p><p>我们现在在文章的 md 文件中只需要在开头的位置填写下面的内容就好了,</p><pre><code>matataki: token: 填写你的 token id,这个 id 在你的 Fan 票详情页面地址栏里尾部的数字就是 password: 你的加密密码,随机字符串就好 name: 你的加密密码名称,要记住这个,我们之后还要用到 amount: 需要多少数量才可以解密呢?填写数字就好了 mode: hold 这里是模式,填写 hold 就好,将来会有支付的选项,可以填写 pay,但是现在还不行,我们写 hold 就好了</code></pre><p>这里也有一些额外的参数可以选择和使用,比如</p><pre><code>matataki: abstract: 这篇文章使用了 Fan 票加密,持有特定 Fan 票来解锁文章 message: 持有 Fan 票来解锁文章 wrongPassMessage: 解锁失败了呢。如果你是博客作者遇到这个问题,看看保险箱的键值对是否设置正确呢 wrongHashMessage: 好像文章加密的时候的时候遗漏了几页呢,不过这些剩下的内容还是可以看看啦</code></pre><p>这些参数分别作用在:</p><ol><li>abstract:文章外部,文章列表的地方会读取到的内容</li><li>message:这个是文章内部的提示</li><li>wrongPassMessage:这是加密密码正确的提示,通常是因为配置 name 错误导致的</li><li>wrongHashMessage:这是加密全文丢失了部分内容导致的,通常是因为原文渲染不正确</li></ol><p>还有一个额外参数,比如你希望不同的页面使用不同的 Oauth 地址,也可以在这里声明:</p><pre><code>matataki: oauth: 你的 Oauth 地址</code></pre><p>那么我们最后的文章编辑器可以看到这样的结果:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/26/TcqiCjzVtmL1p7B.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>只要把这个内容放在 — 开头和 — 结尾的地方就好了呢。</p><p>现在我们要去魔改我们的主题,让我们的主题能够进行解锁。</p><p>如果你的文章内容涉及到了一些比如:ToC(目录,大纲),或者阅读时间,字数统计的话,你需要在字数统计的地方使用的</p><pre><code>page.content</code></pre><p>更换为</p><pre><code>page.origin</code></pre><p>就好了,这个地方使用的 origin 就是你的原文内容,如果你需要更多可以变更的选项,大都依赖这个值。</p><p>如果还有其他问题,请前往:<a href="https://github.com/nekomeowww/hexo-plugin-matataki/issues" target="_blank" rel="noopener">https://github.com/nekomeowww/hexo-plugin-matataki/issues</a> 提交你的问题和相应的原因。</p><h2 id="添加-FanLocker-脚本"><a href="#添加-FanLocker-脚本" class="headerlink" title="添加 FanLocker 脚本"></a>添加 FanLocker 脚本</h2><p>我们以 landscape 这个默认的主题来进行演示,如何进行修改。</p><p>我们定位到这个文件:</p><pre><code>themes/landscape/layout/post.ejs</code></pre><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/26/pdH2PC3oSlecAOM.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>通常点进去你只会发现一行代码的内容,这个文件在渲染的过程中完成了你的文章独立页面的渲染,我们要在你的每一个文章页面渲染下都添加这个小代码:</p><pre><code><script src="https://unpkg.com/fanlocker@latest/dist/fanlocker.js"></script><script> let fl = new FanLocker({ clientId: '<%- config.matataki.clientId %>', clientSecret: '<%- config.matataki.clientSecret %>' })</script></code></pre><p>这段代码要求浏览器去加载最新版本的 FanLocker 脚本,这是需要联网才能获取的,在这点上我表示很抱歉我们不能做成本地存储的,当然你也可以把源代码下载下来,放置到你的 js 目录中使用本地加载:<a href="https://github.com/nekomeowww/fanlocker/tree/master/dist" target="_blank" rel="noopener">FanLocker 静态文件</a></p><p>在上面这段代码中,我们还引入了两个参数:</p><pre><code>config.matataki.clientId</code></pre><p>和</p><pre><code>config.matataki.clientSecret</code></pre><p>这两个参数我们可以到根目录配置文件的位置填上:<a href="https://github.com/nekomeowww/hexo-plugin-matataki-example/blob/4622f004cafcd9edf452ff79cca8c774fe04dcb5/_config.yml#L113" target="_blank" rel="noopener">_config.yml:113</a></p><pre><code>matataki: clientId: 你在开发者中心获取的 Client ID clientSecret: 你在开发者中心获取的 ClientSecret</code></pre><p>这两个参数我们要前往 App 的基本信息页面去获取:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/25/TFGgx13rOV5EdzI.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>点击复制就可以了,然后对应着粘贴到你的根目录配置文件内。</p><p>这一步到这里就结束了,但是还有最后一步,我们需要一个安全的地方来存储我们的密码。</p><h2 id="设置密码键值对"><a href="#设置密码键值对" class="headerlink" title="设置密码键值对"></a>设置密码键值对</h2><p>再次前往开发者中心,我们去保险箱这个页面创建我们的密码和内容,点击右上角的「创建键值对」就可以创建了。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/25/9vwtiMkgTrAG17U.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>我们把我们之前在文件中填写的 name 参数和密码参数填写进来,名字和密码都不能错哦,不能有多余的字符,要不然之后就获取不到了。</p><p>点击立即创建就可以创建一个键值对。</p><p>在这里猫猫需要声明一下呢,如果你在文章页面不进行声明 name 的话,会默认使用你的文件名,也就是 Markdown 的文件名作为 name 参数进行获取,我们如果想要方便的管理密码和密码的对应名字,应该是设定一个固定的密码,这样可以重复使用的,当然,如果你在保险箱中心不创建任何东西,你的文章在加密的时候也不会和服务器进行任何连接和数据传输,所以就算你不想去指定一个 name,你也需要自己手动来完成这个创建的过程,因为这才是安全的办法。</p><p>创建之后就会返回保险箱主页,你可以看到你创建的键值对的名称,但是获取不到信息,在这里我们学习了 GitHub Secrets 的设计,我们不会在这里获取任何密钥信息,服务器只会返回你有的键值名称,如果你需要变更你的密码,点击更新就可以了。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/25/YpvmAQjPTlL5a7c.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>到这里就一切就绪了。</p><h2 id="要注意的内容"><a href="#要注意的内容" class="headerlink" title="要注意的内容"></a>要注意的内容</h2><p>这里猫猫在开发的过程中遇到了一点小问题,Hexo 会使用本地 db.json 文件进行存储和临时数据的管理,如果你发现你的页面没有更新,那么你应该删除本地的 db.json 文件,如果之前有运行过 <code>hexo g</code> 这个命令,那你也应该优先运行 <code>hexo clean</code> 来清除之前的生成。</p><p>如果本地没有 db.json 文件,也没有 public 文件夹,那么我们就可以运行这个命令来看到我们的内容了:</p><pre><code>hexo s --debug</code></pre><p>如果你在加密的参数中更新了什么信息的话,建议再次删除 db.json 再去运行上面的命令。</p><h2 id="发布"><a href="#发布" class="headerlink" title="发布"></a>发布</h2><p>如果你准备好了发布你的博客,运行</p><pre><code>hexo d</code></pre><p>就好了</p><h1 id="开发"><a href="#开发" class="headerlink" title="开发"></a>开发</h1><h2 id="怎么做呢?"><a href="#怎么做呢?" class="headerlink" title="怎么做呢?"></a>怎么做呢?</h2><p>其实在开发初期岛给我这个方向之后,我一开始思考的是怎么去做一个使用地址栏作为 query 的动态验证机制,因为在开始这两个项目之前我在开发的主要方向是 Matataki 的开发者中心:<a href="https://github.com/nekomeowww/DeveloperPortal-FE" target="_blank" rel="noopener">DeveloperPortal-FE</a>/<a href="https://github.com/nekomeowww/DeveloperPortal-BE" target="_blank" rel="noopener">BE</a>, 做的很多事情也是完成一个 Matataki 的第三方登录的机制,也就是众所周知的 Oauth2 授权,整个开发过程可以说是从基础模块去构建,去一步一步实现一整套完整的系统,到现在我们的 FanLocker 也就是完全基于开发者中心和 Matataki API 完成的所有工作。那么我是怎么解决这个问题的呢?</p><h2 id="评论模块的启发"><a href="#评论模块的启发" class="headerlink" title="评论模块的启发"></a>评论模块的启发</h2><p>Hexo 用户可能很熟悉怎么去折腾评论模块,而我之前有接触过的两个评论模块都是使用了第三方登录,或者说使用了 Oauth(Gitalk)或者跳转登录(Disqus)的方式去完成,那么我想,如果要让开发者中心的 API 返回一个夹带着授权 token 的链接并且跳转到指定的地点,就需要一个 Window 相关的方法来动态检测和完成。我一步一步去 debug 和 trace back 了 disqus,gitalk,utterance 的登录方式,最后得出的结论是这样的:</p><ol><li>Disqus 的实现可能会慢一些,但是效果最好</li><li>Gitalk 就是使用了 window 相关的 API 接口完成的(达成了我想要的结果)</li><li>utterance 是后来认识的,debug 起来很简单,也是依赖 GitHub API Oauth 的结果</li></ol><p>那么综上所述,我选择了去阅读 Gitalk 的源码,去一步一步了解过程的发生和结束,认证的开始和许可</p><h2 id="Gitalk-怎么完成的?"><a href="#Gitalk-怎么完成的?" class="headerlink" title="Gitalk 怎么完成的?"></a>Gitalk 怎么完成的?</h2><pre><code>const queryParse = (search = window.location.search) => { if (!search) return {} const queryString = search[0] === '?' ? search.substring(1) : search const query = {} queryString .split('&') .forEach(queryStr => { const [key, value] = queryStr.split('=') if (key) query[decodeURIComponent(key)] = decodeURIComponent(value) }) return query}</code></pre><p>在这里我把源码贴出来,也就是 window.location.search 这个关键的变量在起作用,当你的地址栏中有,存在 ? 这个 query string 的时候,就会把这个部分和后面的所有字符串当作是一个 search 变量,我们使用这个封装好的方法就可以得到一个地址栏 parser 的函数。</p><h2 id="我们怎么用?"><a href="#我们怎么用?" class="headerlink" title="我们怎么用?"></a>我们怎么用?</h2><p>当我们开发者中心返回了 &token=xxx 之后,我们在地址栏的尾部增加一个句段</p><pre><code>?callback=true</code></pre><p>当然我们还要发给 Oauth 服务器一个 redirect_uri 的请求,这样才能正常的返回我们的指定的文章页面,而不是死板的博客首页,基于这样的需求,我又去开发者中心后端添加了这个接口,能够动态变更和控制 redirect_uri。</p><p>于是我们先完成下面的请求:</p><pre><code>axios.post(`https://developer.matataki.io/api/app/oauth`, { clientId: clientId, clientSecret: clientSecret, redirect_uri: `${window.location.origin}${window.location.pathname}?callback=true` })</code></pre><p>这里的 window.location.origin 和 window.location.pathname 就是我们的博客页面和博客附属地址,以及我们需要的字段,这样服务器就会知道,在下一次即将完成的 Oauth 授权中,需要跳转到这个指定的位置。</p><p>当我们点击按钮,绑定的 click 事件就会触发这个解密的函数,去获取指定的密码来解锁文章。</p><p>每次进入文章独立的页面的时候就会加载这个脚本并且检查是否有可以获取的信息,当用户点击登录并且授权之后,返回 token 就可以被获取和加载了。这一部分的内容可以查阅开发者中心的<a href="https://developer.matataki.io/doc/userprofile" target="_blank" rel="noopener">用户信息获取</a>的文档。</p><h2 id="开发成两个分离的模块"><a href="#开发成两个分离的模块" class="headerlink" title="开发成两个分离的模块"></a>开发成两个分离的模块</h2><p>为什么是两个独立的项目呢,虽然加密解密的过程是需要同步和一致的,但是我们使用了外部第三方 API(也就是开发者中心提供的保险箱 API)来完成这个解密的过程,也是因为我借鉴的主要项目是 Gitalk,我认为两者运行的代码应该是可分离可拆解的,所以变成了两个项目,</p><p>我们使用 hexo-plugin-matataki 在本地进行加密和生成,我们到了线上之后,使用 FanLocker 脚本进行动态的信息获取和解密文本。</p><p>hexo-plugin-matataki 在本地按照用户的策略来加密和生成文章的加密后内容和信息,以及所有的信息存储方式按照模版注入进去,然后我们在本地添加一个动态加载 FanLocker 的脚本作为每个文章页面的详情页面的解锁方案。</p><p>FanLocker 在运行的时候还会获取用户的钱包信息和用户 id 等等的基础内容,在获取之后我们进行比对,获取我们需要的 Fan 票 Id 来进行第一步校验,查看用户是否拥有这个指定的 Fan 票和指定数量的 Fan 票,如果有的话,我们进行第二步内容,我们使用提供的 client Id 和 client secret 来获取用户指定的密码,获取保险箱内容,最后使用获取的保险箱内容进行解密。</p><p>到这里就完成了我们所有的内容整合,集成和运行。</p><h1 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h1><p>谢谢你阅读到这里,也感谢你选择和使用 Matataki 和开发者中心,以及我们提供的 hexo-plugin-matataki 提供的站外解锁的方案。</p><p>再一次我们不得不感谢以下几个项目给我的灵感和源代码支持:</p><ol><li>Gitalk: <a href="https://github.com/gitalk/gitalk" target="_blank" rel="noopener">https://github.com/gitalk/gitalk</a></li><li>Disqus: <a href="https://disqus.com/" target="_blank" rel="noopener">https://disqus.com/</a></li><li>hexo-blog-encrypt: <a href="https://github.com/MikeCoder/hexo-blog-encrypt" target="_blank" rel="noopener">https://github.com/MikeCoder/hexo-blog-encrypt</a></li><li>Hexo: <a href="https://hexo.io/" target="_blank" rel="noopener">https://hexo.io/</a></li><li>utterances: <a href="https://github.com/utterance/utterances" target="_blank" rel="noopener">https://github.com/utterance/utterances</a></li></ol><p>谢谢他们给我的源代码和灵感的实现。</p><h1 id="链接"><a href="#链接" class="headerlink" title="链接"></a>链接</h1><p>预览 hexo-plugin-matataki 的样式:<a href="https://neko.ayaka.moe/hexo-plugin-matataki-showcase/">https://neko.ayaka.moe/hexo-plugin-matataki-showcase/</a><br>搭建博客的参考配置:<a href="https://github.com/nekomeowww/hexo-plugin-matataki-example" target="_blank" rel="noopener">https://github.com/nekomeowww/hexo-plugin-matataki-example</a><br>hexo-plugin-matataki 源码:<a href="https://github.com/nekomeowww/hexo-plugin-matataki" target="_blank" rel="noopener">https://github.com/nekomeowww/hexo-plugin-matataki</a><br>FanLocker 源码:<a href="https://github.com/nekomeowww/fanlocker" target="_blank" rel="noopener">https://github.com/nekomeowww/fanlocker</a><br>Matataki 开发者中心:<a href="https://developer.matataki.io" target="_blank" rel="noopener">https://developer.matataki.io</a></p>]]></content>
<summary type="html">
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>有幸在加入仙女座星系之后能够给大家开发这么一个好用的站外工具和插件,当然这也少不了很多人的帮助和支持。</p>
<p>最先要提到的肯定是 <a href="https://github.com/MikeCoder/hexo-blog-encrypt" target="_blank" rel="noopener">hexo-blog-encrypt</a> 的作者 <a href="https://github.com/MikeCoder" target="_blank" rel="noopener">MikeCoder</a> 和其他所有对这个加密插件项目的贡献者(贡献者列表:<a href="https://github.com/MikeCoder/hexo-blog-encrypt/graphs/contributors" target="_blank" rel="noopener">https://github.com/MikeCoder/hexo-blog-encrypt/graphs/contributors</a> ,如果没有他们首先开发出这个插件,猫猫在这里也没有什么能做的,虽然在很多方面我学习了很多很多知识,借鉴了很多人很多事物的作品才到今天这一步,也才有了我们即将要介绍的 <a href="https://github.com/nekomeowww/hexo-plugin-matataki" target="_blank" rel="noopener">hexo-plugin-matataki</a> 和 <a href="https://github.com/nekomeowww/fanlocker" target="_blank" rel="noopener">FanLocker</a>,两个作为 Matataki 站外的交互插件和脚本。<br>
</summary>
<category term="Guide" scheme="https://neko.ayaka.moe/categories/Guide/"/>
<category term="指南" scheme="https://neko.ayaka.moe/tags/%E6%8C%87%E5%8D%97/"/>
<category term="Hexo" scheme="https://neko.ayaka.moe/tags/Hexo/"/>
<category term="GitHub Blog" scheme="https://neko.ayaka.moe/tags/GitHub-Blog/"/>
<category term="Matataki" scheme="https://neko.ayaka.moe/tags/Matataki/"/>
<category term="Fan票" scheme="https://neko.ayaka.moe/tags/Fan%E7%A5%A8/"/>
</entry>
<entry>
<title>试试看解锁这篇文章吧!</title>
<link href="https://neko.ayaka.moe/2020/08/25/041/"/>
<id>https://neko.ayaka.moe/2020/08/25/041/</id>
<published>2020-08-25T05:05:03.000Z</published>
<updated>2020-08-25T05:05:03.000Z</updated>
<content type="html"><![CDATA[<div id="hexo-plugin-matataki" data-wpm="解锁失败了呢。如果你是博客作者遇到这个问题,看看保险箱的键值对是否设置正确呢" data-whm="好像文章加密的时候的时候遗漏了几页呢,不过这些剩下的内容还是可以看看啦"> <div class="hpm-input-container"> <div class="symbol-line"> <img src="https://ssimg.frontenduse.top/image/2020/07/15/8eaf65e03fcd9d49a6a528909fc6e9c0.png" class="hpm-avatar" /> <div class="message">持有<span class="purple"> 1猫猫币 (ANC) </span>解锁文章</div> </div> <div style="display: flex;justify-content: flex-end;width: 100%;"> <a href="https://developer.matataki.io/app/98bf09484eeeb2a2/oauth"><div id="login-btn">解锁</div></a> <div id="unlock-btn">解锁</div> </div> </div> <script id="hpmToken" type="hpmToken">73</script> <script id="hpmAmount" type="hpmAmount">1</script> <script id="hpmName" type="hpmName">demo_password</script> <script id="hpmData" type="hpmData" data-hmacdigest="88cfc80430307d28e7b9a42be8cbada6521a791e25585fefdceb1ae9f234c2f6">711bc531e9db7e25159793b9a372b6b35075d73dbdd9291bb9d204d732f4261151baa02384937aa1dfa3265a306212296949bfc88c713f43fa102bff6632f5adc774fda675f4c4e32bc176e7f2d60dc1ed39f55fd4f870d0169e0dd8d1d97cf2be714de1b9220e634fc8920f0c4800db76e154a7cb3651e56fe14835db370f88db83565dcfc603d0bbe538a4d20f07fce444f584fdd754d859d4c85533af837b835bfffecb13e9f5312bab46383d20d18e5452dd31d1638627d6abc2e37d6eed10a79c9b2a67db20de3dfdd2ab99ecb5996cb503c5bc001e31b8f61950d1efaaefb3b1cfa9bd33b0e726c0c29a8a347591c1738de667b208582a2b0b702a815f4653754ac72866b61504eac249171fa3d590eebda34fe46c12b1dc34ace3abe389fd9065cefdae2dd3d3bb51aa836c7ca8331a7bbac55b5f248707e8181352dbdc575ccdfb79e41cb6b21583b392be40534bc568e299cd6347f009fc84518c5842569aa87866461c500b677b5ff344949a597ccb2496c9d7553bd8e01b1d4e6108445d057c5af33ae9404743adcf31183d4019d7e2a858a61aefa3632958964513914c24a327e0d3301d8f0ca2b09d6a</script></div></script><link href="/css/hpm.css" rel="stylesheet" type="text/css">]]></content>
<summary type="html">
这篇文章使用了 Fan 票加密,持有1猫猫币 (ANC) 来解锁文章
</summary>
<category term="Demo" scheme="https://neko.ayaka.moe/categories/Demo/"/>
<category term="指南" scheme="https://neko.ayaka.moe/tags/%E6%8C%87%E5%8D%97/"/>
<category term="Hexo" scheme="https://neko.ayaka.moe/tags/Hexo/"/>
<category term="GitHub Blog" scheme="https://neko.ayaka.moe/tags/GitHub-Blog/"/>
<category term="Matataki" scheme="https://neko.ayaka.moe/tags/Matataki/"/>
<category term="Fan票" scheme="https://neko.ayaka.moe/tags/Fan%E7%A5%A8/"/>
</entry>
<entry>
<title>Mapbox 和那些坑</title>
<link href="https://neko.ayaka.moe/2020/06/30/040/"/>
<id>https://neko.ayaka.moe/2020/06/30/040/</id>
<published>2020-06-30T12:11:44.000Z</published>
<updated>2020-06-30T12:11:44.000Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>这篇文章是我在接手 Crypto Meetup 这个项目之后在使用 Mapbox-gl 的时候遇到的一些问题的总结,以及相应的解决办法。因为国内关于 Mapbox-gl 的资料很少很少,所以查阅的时候大部分都是英文资料,我想,希望能够写下这篇文章,来帮助国内的一些开发者,能让你们也受众,这里也会给出一些很少人,很少论坛会引用到的,我查找到的一些资源,希望能够帮助到大家。</p><p><a href="https://cryptomeetup.async.moe" target="_blank" rel="noopener">Crypto Meetup</a> 是我在入职仙女座星系之后接手的第一个 Dapp 项目,目的是让用户之间可以共享地理位置,可以在持有特定 Fan 票的情况下,解锁他人的地理位置分享。虽然说叫 Dapp,但其实最终产品在写就的时候就没有太多关于区块链和去中心化的技术,使用的依然是 Vue 前端 + Koa2 后端这样的一个模式来完成的开发,最终部署到你们看到的网站的时候,也是依赖于中心化服务器提供的数据,所以说不算是一个严谨的 Dapp 吧,但是作为 Matataki 的一个小应用,还是蛮不错的,我在其中也学到了 Vue 项目的基本结构和如何构建的知识。<br><a id="more"></a></p><h1 id="实现功能,问题本身"><a href="#实现功能,问题本身" class="headerlink" title="实现功能,问题本身"></a>实现功能,问题本身</h1><p>其实要实现的内容很简单,在 <a href="https://cryptomeetup.async.moe/globe" target="_blank" rel="noopener">Crypto Meetup</a> 可以看到,地球模式下,鼠标滑过国家地区的时候,会有高亮边缘的一个动画特效,我希望这个功能也能够在地图模式下实现。因为使用的是 Mapbox-gl-js,自然文档就要去 Mapbox 官网去找:<a href="https://docs.mapbox.com/mapbox-gl-js/api/" target="_blank" rel="noopener">https://docs.mapbox.com/mapbox-gl-js/api/</a> ,在这里就能看到所有的文档,这个页面还有一个中文版,但是为了保证原生的文档内容,我们在这里就使用英文文档提供的资料就好。</p><p>我查阅了文档本身提供的 Examples(用例),找到了这个 <a href="https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/" target="_blank" rel="noopener">Create a hover effect(创建一个鼠标划过的特效)</a>:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/16/gkjDYbq4mNGT5Fo.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>也就是我想要的鼠标滑动相关的内容,这个实现呢,就是一个<strong>鼠标滑动经过这些地图的区块的时候,我们鼠标下方的区块可以发生我们所设定的图像样式的变化</strong>,这个也就是我在接手这个项目的时候 3D 地球里面使用的鼠标滑动高亮的类似实现。看到这个文档的时候我就想,就是这个了。我们可以看看大致的文档内容是如何描述的。</p><p>这里是代码:</p><pre><code class="javascript">var hoveredStateId = null;map.on('load', function() { map.addSource('states', { 'type': 'geojson', 'data': 'https://docs.mapbox.com/mapbox-gl-js/assets/us_states.geojson' }); // The feature-state dependent fill-opacity expression will render the hover effect // when a feature's hover state is set to true. map.addLayer({ 'id': 'state-fills', 'type': 'fill', 'source': 'states', 'layout': {}, 'paint': { 'fill-color': '#627BC1', 'fill-opacity': [ 'case', ['boolean', ['feature-state', 'hover'], false], 1, 0.5 ] } }); map.addLayer({ 'id': 'state-borders', 'type': 'line', 'source': 'states', 'layout': {}, 'paint': { 'line-color': '#627BC1', 'line-width': 2 } }); // When the user moves their mouse over the state-fill layer, we'll update the // feature state for the feature under the mouse. map.on('mousemove', 'state-fills', function(e) { if (e.features.length > 0) { if (hoveredStateId) { map.setFeatureState( { source: 'states', id: hoveredStateId }, { hover: false } ); } hoveredStateId = e.features[0].id; map.setFeatureState( { source: 'states', id: hoveredStateId }, { hover: true } ); } }); // When the mouse leaves the state-fill layer, update the feature state of the // previously hovered feature. map.on('mouseleave', 'state-fills', function() { if (hoveredStateId) { map.setFeatureState( { source: 'states', id: hoveredStateId }, { hover: false } ); } hoveredStateId = null; });});</code></pre><p>官方给出来的代码原本还有一些是用来初始化地图和 mapbox-gl-js 这个 JavaScript Library 的,这一部分我会在另一篇文章来介绍是怎么样使用 Vue + Webpack + Mapbox-GL 来加载地图(这个方案可以代替百度地图或者是高德地图的 API),这些代码我就省略了,因为在 Vue 的实际使用中有不同的方案和方法。</p><h2 id="代码分析"><a href="#代码分析" class="headerlink" title="代码分析"></a>代码分析</h2><p>我们来看官方给出的参考代码是怎么描述的,这段代码分成三个部分来描述。</p><p>首先是第一点,我们要加载 Geojson 的资源进来。</p><h3 id="加载-Geojson"><a href="#加载-Geojson" class="headerlink" title="加载 Geojson"></a>加载 Geojson</h3><pre><code>map.addSource('states', { 'type': 'geojson', 'data': 'https://docs.mapbox.com/mapbox-gl-js/assets/us_states.geojson'});</code></pre><p>这个地方使用的 Geojson 资源是 Mapbox 官方文档给的一个演示用 Geojson 文件。这里我们使用 map 对象的 addSource 方法加载了一个类型为 geojson 的数据,data 就是我们的 url (这里给出 URL 说明这个是一个可以自动生成一个 XMLHttpRequest 的,关于 XMLHttpRequest 的知识我们可以看:<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest" target="_blank" rel="noopener">XMLHttpRequest - MDN</a>)我们先略过这个部分,因为重要的实现不在这个地方。</p><h3 id="添加图层-Layer"><a href="#添加图层-Layer" class="headerlink" title="添加图层 Layer"></a>添加图层 Layer</h3><pre><code>map.addLayer({ 'id': 'state-fills', 'type': 'fill', 'source': 'states', 'layout': {}, 'paint': { 'fill-color': '#627BC1', 'fill-opacity': [ 'case', ['boolean', ['feature-state', 'hover'], false], 1, 0.5 ] }});map.addLayer({ 'id': 'state-borders', 'type': 'line', 'source': 'states', 'layout': {}, 'paint': { 'line-color': '#627BC1', 'line-width': 2 }});</code></pre><p>在这里我们可以看到我们使用之前加载进来的 source:<strong>states</strong> 来标记我们为哪一个资源添加图层,这里是 states。我们在这里添加了两个图层,一个是填充(state-fills),一个是边缘(state-borders),他们的类型分别是 <strong>fill</strong> 和 <strong>line</strong> ,在 paint 对象里面还定义了填充的方式,以及 Mapbox 特有的对象编辑表达式:<a href="https://www.mapbox.cn/mapbox-gl-js/style-spec/#expressions" target="_blank" rel="noopener">https://www.mapbox.cn/mapbox-gl-js/style-spec/#expressions</a></p><p>要了解这一点很重要,我一开始在开发的过程中看文档没有很清楚的描述表达式,在开发的过程中对这个 <code>fill-opacity</code> 对象就很疑惑,我们到底是怎么表达的。在这里我进行解释:</p><p>我们先把这个格式化好的代码变成一行:</p><pre><code>'fill-opacity': ['case', ['boolean', ['feature-state', 'hover'], false], 1, 0.5 ]</code></pre><p>这样方便我们去理解。</p><p>首先是第一个参数,<strong>case</strong>,在文档中被描述为:<strong>expression_name</strong>,表达式名称,也就是这个表达式运行的方式,是基于给定 case(状态)来判定后续代码的,接下来是第二个参数,是一个数组,这个数组又是另一个表达式,描述了 <strong>boolean</strong> 类型的工作方式(这部分可以参考 <a href="https://www.mapbox.cn/mapbox-gl-js/style-spec/#expression-reference" target="_blank" rel="noopener">Expression Reference - Mapbox-GL</a> ),我们可以看到这里定义了 <code>feature-state</code> 基于 <code>hover</code> 来变化,初始化值为 <code>false</code>,继续往下看,我们看到,<strong>当 boolean 返回 false 或者 true 的时候,就会运行后面的两个参数,并且赋值给 <code>fill-opacity</code></strong>。</p><p>这个就是表达式的基本解读,这点十分十分十分重要,在其他 Mapbox 的实现的时候能够使用表达式做很多计算和预处理和数据解析,能够省去很多东西,还能借助 Geojson 的资源进行对应的计算来反映到实际的地图实例上。</p><p>接下来就是最后一部分代码。</p><h3 id="绑定鼠标事件并且添加动态变量"><a href="#绑定鼠标事件并且添加动态变量" class="headerlink" title="绑定鼠标事件并且添加动态变量"></a>绑定鼠标事件并且添加动态变量</h3><pre><code>map.on('mousemove', 'state-fills', function(e) { if (e.features.length > 0) { if (hoveredStateId) { map.setFeatureState( { source: 'states', id: hoveredStateId }, { hover: false } ); } hoveredStateId = e.features[0].id; map.setFeatureState( { source: 'states', id: hoveredStateId }, { hover: true } ); }});// When the mouse leaves the state-fill layer, update the feature state of the// previously hovered feature.map.on('mouseleave', 'state-fills', function() { if (hoveredStateId) { map.setFeatureState( { source: 'states', id: hoveredStateId }, { hover: false } ); } hoveredStateId = null;});</code></pre><p>分两段来阅读,第一部分是添加鼠标的事件:<strong>mousemove</strong>,也就是在鼠标移动的时候会运行下面的代码,如果鼠标悬浮的位置下方有有效的 feature,那么就赋值 id 并且设置 hover 对象为 true。</p><p>注意看代码的这个部分:</p><pre><code>if (hoveredStateId) { map.setFeatureState( { source: 'states', id: hoveredStateId }, { hover: false } );}hoveredStateId = e.features[0].id;map.setFeatureState( { source: 'states', id: hoveredStateId }, { hover: true });</code></pre><p>这里说明了,我们改动变化的时候,改动的资源是 <strong>states</strong>,并且会把 hover 这个对象复制为两个不同的结果,也就是 true 和 false。</p><p>我们继续看下面的代码,</p><p>第二部分是绑定鼠标事件:<strong>mouseleave</strong> ,也就是鼠标离开某个对象的时候会运行下面的代码,这个代码把高亮起来的对象设置 hover 对象为 false,这样在之前的表达式中描述的地图效果就会应用到地图对象上。</p><h3 id="问题在哪里?"><a href="#问题在哪里?" class="headerlink" title="问题在哪里?"></a>问题在哪里?</h3><p>我们现在了解了代码的使用方法和 API 的相关用法。我们改动一下数值,我们先载入一个我们的 Geojson 对象,然后看看会不会有什么变化。</p><p>这里我选用了:<a href="https://github.com/simonepri/geo-maps/blob/master/info/countries-coastline.md" target="_blank" rel="noopener">@geo-maps 海岸线</a> 的 npm 包:<a href="https://www.npmjs.com/package/@geo-maps/countries-coastline-1m" target="_blank" rel="noopener">https://www.npmjs.com/package/@geo-maps/countries-coastline-1m</a> 提供的 json</p><p>我发现引入直接在 Vue 中引入这个 npm 包是无法正常解析的,于是我单独把文件拿出来,我们换个名字,叫:custom.geo.json</p><p>const geoData = require(‘custom.geo.json’)</p><p>接着继续引入。</p><p>我打开浏览器查看变化,发现什么都没有标记出来,为什么会这样?我查阅了很多资料都没有提到这个问题和相应的解决办法,甚至没有人提到这样的问题。我去翻阅文档的时候看到了一个十分重要的描述:<a href="https://docs.mapbox.com/mapbox-gl-js/api/map/#map#getfeaturestate" target="_blank" rel="noopener">getFeatureState()</a> 这个方法的描述中有个很重要的解释:<strong>Features are identified by their <code>feature.id</code> attribute, which can be any number or string.</strong> 什么意思呢?就是说 <strong>Feature 是基于 <code>feature.id</code> 来定位的,这个值可以是一个数字或者是字符串</strong>,于是我看了看我的 custom.geo.json,他们并没有在这个里面标注 id 这个对象,我打开了 Mapbox 提供的那个 states.json 文件,看到了 id 的定义,还有一个 state_id,但是那个并不重要。</p><p>也就是说我们的 Mapbox 即便读取到了 Geojson 的数据,但是也不能基于 feature.id 给出特定的指向。我换了几个 Geojson 的资源,发现都是犯了同样的错误所以我不能很好的去设置 feature-state 的状态。</p><h2 id="解决问题"><a href="#解决问题" class="headerlink" title="解决问题"></a>解决问题</h2><p>无奈之下,我写了一个小小的脚本来完成这个任务:</p><pre><code>const fs = require('fs')let geoData = require("./custom.geo.json")console.log(geoData.features.length)for(let i = 0; i < geoData.features.length; i++) { Object.defineProperty(geoData.features[i], "id", { value: i, writable: true, enumerable: true })}geoData.features.forEach(e => console.log("1: ", e.id))geoData.features.forEach(e => console.log(e.hasOwnProperty("id")))console.log(geoData.features[0])fs.writeFileSync("./customgeo.json", JSON.stringify(geoData))let geoDataEdited = require("./customgeo.json")geoDataEdited.features.forEach(e => console.log(e))</code></pre><p>我们用原始的 Node 就可以跑起来,这里的 custom.geo.json 就是你的国家资源,也可以是省份区划,但是一定是 Geojson 结构的,我们在这里给每一个 feature 添加一个 id,并且赋值上去。</p><p>现在我们使用新的这个 customgeo.json 引入之后发现,可以使用了!</p><p>原因就是在于 <code>feature.id</code> 没有被定义就无法被 Mapbox 识别和标记。</p><p>因为我还需要高亮国家边界线所以我把原来的代码也修缮了一下:</p><pre><code>map.addSource('countries', { type: 'geojson', data: geoData});// The feature-state dependent fill-opacity expression will render the hover effect// when a feature's hover state is set to true.map.addLayer({ id: 'state-fills', type: 'fill', source: 'countries', layout: {}, paint: { 'fill-color': '#000', 'fill-opacity': [ 'case', ['boolean', ['feature-state', 'hover'], false], 0, 0 ] }});map.addLayer({ id: 'state-borders', type: 'line', source: 'countries', layout: {}, paint: { 'line-color': '#FFD83F', 'line-width': 2, 'line-opacity': [ 'case', ['boolean', ['feature-state', 'hover'], false], 0.5, 0 ] }});// When the user moves their mouse over the state-fill layer, we'll update the// feature state for the feature under the mouse.let hoveredStateId = null;map.on('mousemove', 'state-fills', (e, i) => { if (e.features.length > 0) { if (hoveredStateId) { map.setFeatureState( { source: 'countries', id: hoveredStateId }, { hover: false } ); } hoveredStateId = e.features[0].id; map.setFeatureState( { source: 'countries', id: hoveredStateId }, { hover: true } ); }});map.on('mouseleave', 'state-fills', () => { if (hoveredStateId) { map.setFeatureState( { source: 'countries', id: hoveredStateId }, { hover: false } ); } hoveredStateId = null;});</code></pre><h1 id="添加用户头像到地图上"><a href="#添加用户头像到地图上" class="headerlink" title="添加用户头像到地图上"></a>添加用户头像到地图上</h1><p>我原本以为这个功能是十分容易理解的:</p><pre><code>map.addImage(avatar, image);map.addSource('user-avatar', { type: 'geojson', data: { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: position.data } } ] }});map.addLayer({ id: 0, type: 'symbol', source: 'user-avatar', layout: { 'icon-image': avatar, 'icon-size': 0.08 }});</code></pre><ol><li>我们创建一个新的 Geojson 对象,这个对象包含了一个 FeatureCollection</li><li>Feature 是一个点,点对应的是一个坐标</li><li>我们在这个对象里添加一个图层,这个图层是一个图标,是一个图像文件。</li></ol><p>可是我们需要做到的是显示多个用户的头像到这个地图上,我在开发的时候却怎么也做不到。<br>最后还是查阅文档发现了一个很重要的内容,<strong>我们添加的这个 source id 也是独立的,我们的 layer id 是独立的,我们的头像才可以多个显示出来</strong>,因为这样才有独立的 id 可以被 Mapbox 区分开来。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.loli.net/2020/08/31/py3iN7bmXKatZ2O.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>所以最后我们需要修改的部分就是添加图层的部分和添加 source 的时候的不同:</p><pre><code>const itemId = 'id' + element.userIdconst avatar = 'avatar' + element.userIdif (error) throw error;map.addImage(avatar, image);map.addSource(itemId, { type: 'geojson', data: { type: 'FeatureCollection', features: [ { type: 'Feature', geometry: { type: 'Point', coordinates: position.data } } ] }});map.addLayer({ id: itemId, type: 'symbol', source: itemId, layout: { 'icon-image': avatar, 'icon-size': 0.08 }});</code></pre><p>我不得不创建两个独立的 id 来针对 source 和 图层 进行标记才行。</p><h1 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h1><p>希望我的这篇文章能够给你提供帮助,因为国内外的资源都相当稀缺,很多弯路都是在这个不断的实验中得出的。希望我的这些代码分析和小脚本能够在你的项目当中给你提供足够的帮助。</p><p>再一次,感谢你一路阅读到这里,谢谢你的支持。</p><h1 id="引用,参考,和相关资源"><a href="#引用,参考,和相关资源" class="headerlink" title="引用,参考,和相关资源"></a>引用,参考,和相关资源</h1><h2 id="Vue-Mapbox-GL"><a href="#Vue-Mapbox-GL" class="headerlink" title="Vue-Mapbox-GL"></a>Vue-Mapbox-GL</h2><p><a href="https://github.com/phegman/vue-mapbox-gl" target="_blank" rel="noopener">https://github.com/phegman/vue-mapbox-gl</a></p><h2 id="介绍和使用-Geojson-相关的资料"><a href="#介绍和使用-Geojson-相关的资料" class="headerlink" title="介绍和使用 Geojson 相关的资料"></a>介绍和使用 Geojson 相关的资料</h2><p><a href="http://blog.infographics.tw/2016/01/draw-map-with-geojson-io/" target="_blank" rel="noopener">http://blog.infographics.tw/2016/01/draw-map-with-geojson-io/</a><br><a href="http://geojson.io/#map=2/20.1/0.0" target="_blank" rel="noopener">http://geojson.io/#map=2/20.1/0.0</a><br><a href="https://www.mapbox.cn/mapbox-gl-js/example/hover-styles/" target="_blank" rel="noopener">https://www.mapbox.cn/mapbox-gl-js/example/hover-styles/</a><br><a href="https://geojson-maps.ash.ms/" target="_blank" rel="noopener">https://geojson-maps.ash.ms/</a><br><a href="https://datahub.io/core/geo-countries" target="_blank" rel="noopener">https://datahub.io/core/geo-countries</a></p><h2 id="下载和使用开放的-Geojson-的网站"><a href="#下载和使用开放的-Geojson-的网站" class="headerlink" title="下载和使用开放的 Geojson 的网站"></a>下载和使用开放的 Geojson 的网站</h2><p><a href="https://www.naturalearthdata.com/" target="_blank" rel="noopener">https://www.naturalearthdata.com/</a></p><h2 id="Geojson-和-Mbtiles-绘制的软件和项目"><a href="#Geojson-和-Mbtiles-绘制的软件和项目" class="headerlink" title="Geojson 和 Mbtiles 绘制的软件和项目"></a>Geojson 和 Mbtiles 绘制的软件和项目</h2><p><a href="https://www.qgis.org/en/site/forusers/download.html" target="_blank" rel="noopener">https://www.qgis.org/en/site/forusers/download.html</a></p><p><a href="https://gdal.org/index.html" target="_blank" rel="noopener">https://gdal.org/index.html</a></p><h2 id="各个国家和世界地图的-Geojson-文件(GitHub)"><a href="#各个国家和世界地图的-Geojson-文件(GitHub)" class="headerlink" title="各个国家和世界地图的 Geojson 文件(GitHub)"></a>各个国家和世界地图的 Geojson 文件(GitHub)</h2><p><a href="https://github.com/mledoze/countries" target="_blank" rel="noopener">https://github.com/mledoze/countries</a><br><a href="https://github.com/johan/world.geo.json" target="_blank" rel="noopener">https://github.com/johan/world.geo.json</a><br><a href="https://github.com/simonepri/geo-maps" target="_blank" rel="noopener">https://github.com/simonepri/geo-maps</a></p>]]></content>
<summary type="html">
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>这篇文章是我在接手 Crypto Meetup 这个项目之后在使用 Mapbox-gl 的时候遇到的一些问题的总结,以及相应的解决办法。因为国内关于 Mapbox-gl 的资料很少很少,所以查阅的时候大部分都是英文资料,我想,希望能够写下这篇文章,来帮助国内的一些开发者,能让你们也受众,这里也会给出一些很少人,很少论坛会引用到的,我查找到的一些资源,希望能够帮助到大家。</p>
<p><a href="https://cryptomeetup.async.moe" target="_blank" rel="noopener">Crypto Meetup</a> 是我在入职仙女座星系之后接手的第一个 Dapp 项目,目的是让用户之间可以共享地理位置,可以在持有特定 Fan 票的情况下,解锁他人的地理位置分享。虽然说叫 Dapp,但其实最终产品在写就的时候就没有太多关于区块链和去中心化的技术,使用的依然是 Vue 前端 + Koa2 后端这样的一个模式来完成的开发,最终部署到你们看到的网站的时候,也是依赖于中心化服务器提供的数据,所以说不算是一个严谨的 Dapp 吧,但是作为 Matataki 的一个小应用,还是蛮不错的,我在其中也学到了 Vue 项目的基本结构和如何构建的知识。<br>
</summary>
<category term="Guide" scheme="https://neko.ayaka.moe/categories/Guide/"/>
<category term="Vue" scheme="https://neko.ayaka.moe/tags/Vue/"/>
<category term="CryptoMeetup" scheme="https://neko.ayaka.moe/tags/CryptoMeetup/"/>
<category term="Mapbox" scheme="https://neko.ayaka.moe/tags/Mapbox/"/>
<category term="mapbox-gl" scheme="https://neko.ayaka.moe/tags/mapbox-gl/"/>
</entry>
<entry>
<title>新的这一切</title>
<link href="https://neko.ayaka.moe/2020/06/12/039/"/>
<id>https://neko.ayaka.moe/2020/06/12/039/</id>
<published>2020-06-12T06:05:03.000Z</published>
<updated>2020-06-12T06:05:03.000Z</updated>
<content type="html"><![CDATA[<p>其实到现在,我也不知道对你是什么样的感情呢。</p><p>是和之前一样在寻找的那种情感吗?是我一直在追寻的和羽毛在一起的那种情感吗?我不知道呢。</p><h1 id="之前"><a href="#之前" class="headerlink" title="之前"></a>之前</h1><p>之前,从 9 月份回来之后,就一直想要找回那种和羽毛在一起的那种特殊的情感,那种,似乎是相依为命,似乎是两个人相互是对方的救命稻草一样的抓住的样子,分离不开的感觉。其实也有很多很细腻的东西在里面,比如羽毛也会玩一些很有趣的游戏,猫猫也会感兴趣,羽毛也会英语,可以和猫猫一起看 YouTube 上的很多东西,能懂很多 memes。但是,这种相似程度的概率的人,要喜欢在一起,是什么样的概率才会碰到一起呢?</p><a id="more"></a><h2 id="和朵朵的那段生活"><a href="#和朵朵的那段生活" class="headerlink" title="和朵朵的那段生活"></a>和朵朵的那段生活</h2><p>其实对朵朵,猫猫看到了很多羽毛的影子,但是始终没有能够抓住呢。我也不知道应不应该在博客里说这样的话,但是,始终是错过了一些东西呢,但是很感谢那 22 天的相伴,真的给了猫猫很多东西。是自从猫猫从好孩子处理之后带给猫猫的一些很特殊的情感和经历呢,虽然是悲剧收尾。但是,一直都会记住。</p><h2 id="和泉喵的那段生活"><a href="#和泉喵的那段生活" class="headerlink" title="和泉喵的那段生活"></a>和泉喵的那段生活</h2><p>其实从 9 月份回来就折腾了很久很久,很多东西都很混乱,到去泉喵那边住的时候,事情还有很多没有能够处理完,还多了很多没能处理的事情,也被父母找到了,还惹上了一些小麻烦。</p><p>中途因为那些麻烦又回去了云南一趟,虽然,其实不应该回去的吧,自己为什么要相信他回去呢?自己到现在都还记得那天晚上他要挟带着我和妈妈一起自杀的时候的场景,还记得说起来遗嘱分配的事情,猫猫都记得。也算是噩梦和害怕的一部分吧,自己很讨厌那段时间,原本打算第二天就回来的,但是因为惹上了一些麻烦,也有了一些限制,没能回去。</p><p>等到回去已经是十二月份的事情了,那时候回去很开心呢,能够见到大家,虽然那时候,和大家相处也没有太久吧,从十月份到十一月份中旬,也没有太多接触,至少,和你们在一起,至少相信自己是安全的。</p><p>自己的很多东西都是大家拼拼凑凑给的,电脑是名雪攒的,手机和手表是泉喵借给用的,安全的住所也是泉和她们提供的,自己很感谢呢。</p><p>但是自己始终不会喜欢泉吧,在博客里说这样的话,不知道会不会伤到你,但是,一定是永远的朋友呢,因为帮助过猫猫这么多,很感谢你。</p><h2 id="不得不提起的人"><a href="#不得不提起的人" class="headerlink" title="不得不提起的人"></a>不得不提起的人</h2><p>名雪是很感谢的人呢,从 9 月份开始就尽心尽力帮助猫猫的人,一直到现在,猫猫也不知道自己的情感到底应该是怎么样的,也不知道自己应该接受谁的关心和爱护。但是,真的很感谢你的照顾和帮忙,很重要,很感谢,很开心,在贵阳和长沙,也会保留那些短暂的记忆的。</p><h2 id="后来"><a href="#后来" class="headerlink" title="后来"></a>后来</h2><p>后来遇到的 Cocoa,和朵朵有相似的地方吧,但是始终不匹配呢,经常有争吵,因为一点点事情和误解就会争论很久,但其实都是语言上的分歧和不理解造成的,Cocoa 有更好的发展空间呢,应该去找更好的人,而不是停留在这个地方。</p><p>陪着你写出了 sobani, mamori, yawarakai 这样的项目,很开心了,也陪你玩了很多游戏,也一起花了很多时间讨论很多东西吧,很感谢你教会猫猫的很多知识,特别是 C 语言的指针呢,也有凛的帮助,才能理解。</p><h1 id="现在"><a href="#现在" class="headerlink" title="现在"></a>现在</h1><p>现在不知道对待小音是什么感情,不知道自己是在做什么,不知道自己心里的情感到底冲动在什么地方了?</p><p>毕竟,我们都是情感控制的动物啊,就算再理性的人,受到感情的影响,也会感性用事的,至少,心里会触动的。</p><p>很高兴那天晚上能够在南京东路地铁站的门口第一次见到你呢,一开始以为你是原生的女孩子,很羡慕呢。后来知道是 mtf 的时候就更羡慕了,自己毕竟缺了那 17 个月的药物维持呢,再怎么样也不会像你们一样了。</p><p>很喜欢就是了,还有琉璃。</p><p>说到这里,自己就像是 PUA 一样,感觉自己脚踏两条船,自己公开说明自己喜欢两个人,始终会被人唾弃的吧。</p><p>但是这是自己真实的情感呢,我愿意去面对。</p><h2 id="我"><a href="#我" class="headerlink" title="我"></a>我</h2><p>我,自己,迷茫着呢。</p><p>我,内心,痛苦着呢。</p><p>我,回忆,伤痛着呢。</p><p>我,希冀,未知着呢。</p><p>什么时候才会知道这些问题的答案呢?不知道。</p><p>不知道呢。</p>]]></content>
<summary type="html">
<p>其实到现在,我也不知道对你是什么样的感情呢。</p>
<p>是和之前一样在寻找的那种情感吗?是我一直在追寻的和羽毛在一起的那种情感吗?我不知道呢。</p>
<h1 id="之前"><a href="#之前" class="headerlink" title="之前"></a>之前</h1><p>之前,从 9 月份回来之后,就一直想要找回那种和羽毛在一起的那种特殊的情感,那种,似乎是相依为命,似乎是两个人相互是对方的救命稻草一样的抓住的样子,分离不开的感觉。其实也有很多很细腻的东西在里面,比如羽毛也会玩一些很有趣的游戏,猫猫也会感兴趣,羽毛也会英语,可以和猫猫一起看 YouTube 上的很多东西,能懂很多 memes。但是,这种相似程度的概率的人,要喜欢在一起,是什么样的概率才会碰到一起呢?</p>
</summary>
<category term="Thoughts" scheme="https://neko.ayaka.moe/categories/Thoughts/"/>
<category term="内心" scheme="https://neko.ayaka.moe/tags/%E5%86%85%E5%BF%83/"/>
</entry>
<entry>
<title>React to Webpack 手记</title>
<link href="https://neko.ayaka.moe/2020/06/02/038/"/>
<id>https://neko.ayaka.moe/2020/06/02/038/</id>
<published>2020-06-02T08:23:00.000Z</published>
<updated>2020-06-02T08:23:00.000Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>其实很早之前就想要好好学习一下搭建整个脚手架和前端,但是鉴于各种奇怪的原因,始终没能这么做。今天就来这里参考了好几个教程和文档来学习一下怎么从头开始搭建 React 和 Webpack 的前端开发。</p><h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><p><a href="https://segmentfault.com/a/1190000012921279" target="_blank" rel="noopener">React入门看这篇就够了</a></p><p><a href="https://wizardforcel.gitbooks.io/reactjs101/Ch02/webpack-dev-enviroment.html" target="_blank" rel="noopener">从零开始学 ReactJS(ReactJS 101)</a></p><a id="more"></a><h1 id="搭建"><a href="#搭建" class="headerlink" title="搭建"></a>搭建</h1><p>首先 React.js 还有 Webpack.js 的具体用途就不解释了呢,我们直接到搭建的部分。</p><h2 id="React-安装"><a href="#React-安装" class="headerlink" title="React 安装"></a>React 安装</h2><p>React 本身最基础的核心只有两个 <code>react</code> 和 <code>react-dom</code> 这两个包。</p><p>所以运行:</p><pre><code>yarn add react react-dom</code></pre><p>就可以安装这两个我们最需要的东西了。但是因为 React 是用了 JSX,所以我们还需要 Babel 来转译 JSX 为浏览器可以阅读的 Javascript 代码和 ReactDOM 能处理的 DOM 信息。</p><h2 id="Babel-安装"><a href="#Babel-安装" class="headerlink" title="Babel 安装"></a>Babel 安装</h2><p>所以我们还需要:<code>@babel/core</code>, <code>@babel/preset-env</code>, <code>@babel/preset-react</code>, <code>babel-eslint</code>, <code>babel-loader</code>, <code>babel-preset-es2015</code>,作为 Babel 的组件来安装进来,运行:</p><pre><code>yarn add @babel/core @babel/preset-env @babel/preset-react babel-eslint babel-loader babel-preset-es2015 -D</code></pre><p>记得添加后面的 <code>-D</code> 参数,将这些保存为我们作为开发环境的依赖包,而不是主要项目的依赖包。</p><p>然后接下来就是 Webpack 了。</p><h2 id="Webpack-安装"><a href="#Webpack-安装" class="headerlink" title="Webpack 安装"></a>Webpack 安装</h2><p>首先为了能够执行 webpack 我们要先全局安装一次 <code>webpack-cli</code> 才行,所以运行:</p><pre><code>yarn global add webpack-cli</code></pre><p>然后就是安装 webpack 的其他开发环境的依赖包,有这些:<code>html-webpack-plugin</code>, <code>webpack</code>, <code>webpack-cli</code>, <code>webpack-dev-server</code></p><p>那么我们接下来直接运行:</p><pre><code>yarn add html-webpack-plugin webpack webpack-cli webpack-dev-server -D</code></pre><p>就可以安装好我们必备的所有的东西了。</p><h1 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h1><p>配置分为两个部分,一个是 babel 的配置,一个是 webpack 的配置。</p><p>我们以下面这个模式为例:</p><pre><code>├─app ├─index.js ├─index.html├─node_modules├─.babelrc├─package.json├─webpack.config.js└─yarn.lock</code></pre><h2 id="配置-Babel"><a href="#配置-Babel" class="headerlink" title="配置 Babel"></a>配置 Babel</h2><p>我们先在根目录下新建一个文件,名叫 <code>.babelrc</code></p><pre><code class="json">{ "presets": [ "@babel/preset-env", "@babel/preset-react" ], "plugins": []}</code></pre><p>在里面填入这样的内容。其中,presets 第一个是引入了我们安装的 <code>@babel/preset-env</code>,第二个引入了我们 React 需要的 <code>@babel/preset-react</code>。</p><h2 id="配置-Webpack"><a href="#配置-Webpack" class="headerlink" title="配置 Webpack"></a>配置 Webpack</h2><p>我们在依然在根目录下新建文件,名字就是 <code>webpack.config.js</code></p><pre><code class="javascript">const HtmlWebpackPlugin = require("html-webpack-plugin")const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({ template: `${__dirname}/app/index.html`, filename: 'index.html', inject: 'body'})module.exports = { entry: [ './app/index.js' ], output: { path: `${__dirname}/dist`, filename: 'index_bundle.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } } ] }, devServer: { inline: true, // 这个端口自行选择自己喜欢的就好 port: 4200 }, plugins: [HTMLWebpackPluginConfig]}</code></pre><p>在里面填入这样的内容。</p><h1 id="前端服务渲染"><a href="#前端服务渲染" class="headerlink" title="前端服务渲染"></a>前端服务渲染</h1><p>webpack 的命令有很多参数,也有很多可以选择的内容:</p><blockquote><ul><li>webpack:会在开发模式下开始一次性的建置</li><li>webpack -p:会建置 production 的程式码</li><li>webpack --watch:会监听程式码的修改,当储存时有异动时会更新档案</li><li>webpack -d:加入 source maps 档案</li><li>webpack --progress --colors:加上处理进度与颜色</li></ul><p>参考自:<a href="https://wizardforcel.gitbooks.io/reactjs101/Ch02/webpack-dev-enviroment.html" target="_blank" rel="noopener">https://wizardforcel.gitbooks.io/reactjs101/Ch02/webpack-dev-enviroment.html</a></p></blockquote><p>我们可以在 <code>package.json</code> 文件中添加这样的参数:</p><pre><code class="javascript">"scripts": {"dev": "webpack-dev-server --devtool eval --progress --colors --content-base build"}</code></pre><p>这样的话,以后运行 <code>yarn dev</code> 或者是 <code>npm run dev</code> 就可以省去我们输入很多参数和命令了。</p><h1 id="React-文件"><a href="#React-文件" class="headerlink" title="React 文件"></a>React 文件</h1><p>我们在根目录新建目录<code>app</code>,然后放入两个文件 <code>index.html</code>, <code>index.js</code></p><p>在<code>index.html</code>文件中我们写入</p><pre><code class="html"><!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <title>React Setup</title> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> </head> <body> <!-- 这个 id 就是之后在 index.js 中会用到的东西 --> <div id="app"></div> </body></html></code></pre><p>在 <code>index.js</code> 文件中我们写入</p><pre><code class="javascript">import React from 'react'import ReactDOM from 'react-dom'class App extends React.Component { constructor(props) { super(props) this.state = { } } render() { return ( <div> <h1>Hello, React!</h1> </div> ) }}ReactDOM.render(<App />, document.getElementById('app'))</code></pre><h1 id="结尾"><a href="#结尾" class="headerlink" title="结尾"></a>结尾</h1><p>现在运行</p><pre><code>yarn dev</code></pre><p>打开测试界面就能看到你的内容啦~</p><h1 id="引用,参考,纠错"><a href="#引用,参考,纠错" class="headerlink" title="引用,参考,纠错"></a>引用,参考,纠错</h1><p><a href="https://webpack.docschina.org/guides/getting-started" target="_blank" rel="noopener">Doc - Webpack 起步</a></p><p><a href="https://webpack.js.org/concepts/loaders/#example" target="_blank" rel="noopener">Doc - Webpack Loaders</a></p><p><a href="https://babeljs.io/docs/en/options#presets" target="_blank" rel="noopener">Doc - Babel Preset Options List</a></p><p><a href="https://github.com/kdchang/reactjs101/issues/108" target="_blank" rel="noopener">GitHub Issue - Ch02 .1 webpack.config.js不全,npm run dev跑不起来</a></p><p><a href="https://github.com/babel/babel/issues/8599" target="_blank" rel="noopener">GitHub Issue - Module build failed (from ./node_modules/babel-loader/lib/index.js)</a></p><p><a href="https://github.com/babel/babel/issues/8707" target="_blank" rel="noopener">GitHub Issue - Plugin/Preset files are not allowed to export objects, only functions</a></p><p><a href="https://stackoverflow.com/questions/49182862/preset-files-are-not-allowed-to-export-objects" target="_blank" rel="noopener">StackOverflow - Preset files are not allowed to export objects</a></p>]]></content>
<summary type="html">
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>其实很早之前就想要好好学习一下搭建整个脚手架和前端,但是鉴于各种奇怪的原因,始终没能这么做。今天就来这里参考了好几个教程和文档来学习一下怎么从头开始搭建 React 和 Webpack 的前端开发。</p>
<h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><p><a href="https://segmentfault.com/a/1190000012921279" target="_blank" rel="noopener">React入门看这篇就够了</a></p>
<p><a href="https://wizardforcel.gitbooks.io/reactjs101/Ch02/webpack-dev-enviroment.html" target="_blank" rel="noopener">从零开始学 ReactJS(ReactJS 101)</a></p>
</summary>
<category term="Guide" scheme="https://neko.ayaka.moe/categories/Guide/"/>
<category term="前端" scheme="https://neko.ayaka.moe/tags/%E5%89%8D%E7%AB%AF/"/>
<category term="笔记" scheme="https://neko.ayaka.moe/tags/%E7%AC%94%E8%AE%B0/"/>
<category term="React" scheme="https://neko.ayaka.moe/tags/React/"/>
<category term="Webpack" scheme="https://neko.ayaka.moe/tags/Webpack/"/>
</entry>
<entry>
<title>对于填补内容</title>
<link href="https://neko.ayaka.moe/2019/12/09/037/"/>
<id>https://neko.ayaka.moe/2019/12/09/037/</id>
<published>2019-12-09T12:24:17.000Z</published>
<updated>2019-12-09T09:05:00.000Z</updated>
<content type="html"><![CDATA[<p>其实还写了很多很多的东西,但是丢失了好多,实际消耗的话,消耗了 6 本笔记本了呢,送去了 2 本,还有一本很重要的东西 9.1 的那天不见了呢,大概是有人喜欢那些创造出来的另一个世界的故事和传说吧,剩下的东西,就是一本随便写写画画的本子,一本记录上面那些东西的本子,一本记录看书的感受的呢。好多写出来的东西也在里面造成了不小的麻烦,这些就放到以后的故事再说吧,也有很多是比较隐私的东西呢,也就不发出来啦。</p><a id="more"></a><p>自己创造了好多东西来陪着自己,也感谢当时在身边的那些小伙伴,也不能忘记在外面的大家,你们都辛苦了呢。</p><p>上面的那些东西,是原文本输入进去的,没有改动,除去修改的部分。如果觉得阅读起来困难或者情感比较偏激的话,感觉也是比较正常的吧。</p><p>大家…谢谢呢。</p>]]></content>
<summary type="html">
<p>其实还写了很多很多的东西,但是丢失了好多,实际消耗的话,消耗了 6 本笔记本了呢,送去了 2 本,还有一本很重要的东西 9.1 的那天不见了呢,大概是有人喜欢那些创造出来的另一个世界的故事和传说吧,剩下的东西,就是一本随便写写画画的本子,一本记录上面那些东西的本子,一本记录看书的感受的呢。好多写出来的东西也在里面造成了不小的麻烦,这些就放到以后的故事再说吧,也有很多是比较隐私的东西呢,也就不发出来啦。</p>
</summary>
<category term="LaterAdded" scheme="https://neko.ayaka.moe/categories/LaterAdded/"/>
<category term="Thoughts" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/"/>
<category term="日记" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
<category term="悲伤的年份" scheme="https://neko.ayaka.moe/tags/%E6%82%B2%E4%BC%A4%E7%9A%84%E5%B9%B4%E4%BB%BD/"/>
<category term="在奇怪地方的记述" scheme="https://neko.ayaka.moe/tags/%E5%9C%A8%E5%A5%87%E6%80%AA%E5%9C%B0%E6%96%B9%E7%9A%84%E8%AE%B0%E8%BF%B0/"/>
</entry>
<entry>
<title>人生中第一幅心经完成啦【填补内容】</title>
<link href="https://neko.ayaka.moe/2018/11/21/036/"/>
<id>https://neko.ayaka.moe/2018/11/21/036/</id>
<published>2018-11-21T12:42:17.000Z</published>
<updated>2019-12-09T09:26:00.000Z</updated>
<content type="html"><![CDATA[<p>值得庆祝的一天呢!</p><p>今天是人生中第一幅书法写成的心经作品完成的日子~从开始写到今天,花了三个星期呢(可是一星期也就两个小时的时间写…)</p><p>虽然写的还不是很完美,但是据说要挂在学校里,也算是被认可了吧。</p><a id="more"></a>]]></content>
<summary type="html">
<p>值得庆祝的一天呢!</p>
<p>今天是人生中第一幅书法写成的心经作品完成的日子~从开始写到今天,花了三个星期呢(可是一星期也就两个小时的时间写…)</p>
<p>虽然写的还不是很完美,但是据说要挂在学校里,也算是被认可了吧。</p>
</summary>
<category term="LaterAdded" scheme="https://neko.ayaka.moe/categories/LaterAdded/"/>
<category term="Thoughts" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/"/>
<category term="日记" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
<category term="悲伤的年份" scheme="https://neko.ayaka.moe/tags/%E6%82%B2%E4%BC%A4%E7%9A%84%E5%B9%B4%E4%BB%BD/"/>
<category term="在奇怪地方的记述" scheme="https://neko.ayaka.moe/tags/%E5%9C%A8%E5%A5%87%E6%80%AA%E5%9C%B0%E6%96%B9%E7%9A%84%E8%AE%B0%E8%BF%B0/"/>
</entry>
<entry>
<title>没有 Tweet,没有 Keyboard【填补内容】</title>
<link href="https://neko.ayaka.moe/2018/11/14/035/"/>
<id>https://neko.ayaka.moe/2018/11/14/035/</id>
<published>2018-11-14T12:24:17.000Z</published>
<updated>2019-12-09T09:17:00.000Z</updated>
<content type="html"><![CDATA[<p>事实上,准确地讲,<br>毫不保留地讲,<br>嗯,恕我直言,<br>计算机改变我们生活太多了呢,在一个没有这些东西的环境,我深深感受到了这一点。(或者我过分依赖它们了呢)</p><a id="more"></a><p>星期二的时候,我和小伙伴聊了「瘾」这个概念,也论证了信息技术所带来的许多生活上的变革。得到的结果是,并没有什么所谓的「网瘾」一说,但不得不承认,的确有很多人,因为游戏,网络上的很多东西沉醉其中,可是换个方式想,和 Kurzgesagt 的一期视频, Addiction 一样,若不是这一部分人身边周围以及童年收到了影响,很多东西的欲望和意识弱化了,他周遭的人没有能够给他足够的感全感、爱,他为什么要去依赖这部分东西呢?若不是现实使他深感不适,为什么需要去依赖另一个世界的关爱呢?何况,一般情况下他们只会逐步恶化,进入一个恶性循环,身边的人也不会愿意多加鼓励,与之建立一个社交关系,久而久之,甚至有一部分人丧失了社交能力,这与毒品差别也不是太大。</p><p>嘛,不过,不管这么多,在以往的时间,还可以在 Twitter 上的树洞发泄和表达一下自己的东西,或者找柠檬酱吐槽一下,再不用社交网络,可是用笔写文,太…落后了吧。</p><p>总之好累的。</p><p>【后记】(这部分是 2019.12.09 添加的)</p><p>实际上当时写这个东西的时候,对里面很多那种思想状态很讨厌很愤慨,自己也做不了什么事情,上面说的这些也有一部分是不太准确的,后来也花时间去了解了毒品的情况,还有大麻,事实上也有一些差距。总之,现代社会造成的这种社交关系 疏离 是肯定存在的,而很多人感觉到孤独也肯定是有关的。</p>]]></content>
<summary type="html">
<p>事实上,准确地讲,<br>毫不保留地讲,<br>嗯,恕我直言,<br>计算机改变我们生活太多了呢,在一个没有这些东西的环境,我深深感受到了这一点。(或者我过分依赖它们了呢)</p>
</summary>
<category term="LaterAdded" scheme="https://neko.ayaka.moe/categories/LaterAdded/"/>
<category term="Thoughts" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/"/>
<category term="日记" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
<category term="悲伤的年份" scheme="https://neko.ayaka.moe/tags/%E6%82%B2%E4%BC%A4%E7%9A%84%E5%B9%B4%E4%BB%BD/"/>
<category term="在奇怪地方的记述" scheme="https://neko.ayaka.moe/tags/%E5%9C%A8%E5%A5%87%E6%80%AA%E5%9C%B0%E6%96%B9%E7%9A%84%E8%AE%B0%E8%BF%B0/"/>
</entry>
<entry>
<title>想飞上天【填补内容】</title>
<link href="https://neko.ayaka.moe/2018/11/02/034/"/>
<id>https://neko.ayaka.moe/2018/11/02/034/</id>
<published>2018-11-02T12:24:17.000Z</published>
<updated>2019-12-09T09:10:00.000Z</updated>
<content type="html"><![CDATA[<p>终于和信任的人说出了心里想说的话,可是她也帮不了我什么,变故太多了,最近也没有时间写下称得上篇幅的文章。</p><p>我想起来在电影《肖申克的救赎》中说的那句话,</p><blockquote><p>「你是永远关不住一只连每片羽毛都散发着自由光辉的鸟儿的」</p></blockquote><p>我现在的处境与其又有什么不同呢,想要飞上蓝天,去任何我想去的地方,想起九月份的时候,有小伙伴在留言的小黄纸上写下</p><blockquote><p>「勇踏前人未进之境」</p></blockquote><a id="more"></a><p>给我的感悟太多了呢。</p><p>想飞上天…</p><p>放了两部比较不错的电影,一部是《悲伤逆流成河》,一部是《我不是药神》,拍摄技巧都很值得去学习呢,只是剧情太突然了一些,应该把重心放在女主身上才是呢,但还是很棒,至少在这样的地方,足够了。后者嘛,我认为外界评价还是不错的吧,因为主题很明确,也是基于现实事实作出了许多保留创作的作品,从反面衬托出了别样的一种寓意,超喜欢。只是,想看许多电影呢,还想再看一次《银翼杀手》</p><p>想飞上天…</p><p>想要过自己想要的生活,并不想与之牵涉其他人的事情。况且,我的心愿怎么了嘛,我想要安全的生活,一个属于我自己的小世界,我想要许多许多的可爱的小物件,想养只猫,可是…</p><p>他们不让我飞呢。</p>]]></content>
<summary type="html">
<p>终于和信任的人说出了心里想说的话,可是她也帮不了我什么,变故太多了,最近也没有时间写下称得上篇幅的文章。</p>
<p>我想起来在电影《肖申克的救赎》中说的那句话,</p>
<blockquote>
<p>「你是永远关不住一只连每片羽毛都散发着自由光辉的鸟儿的」</p>
</blockquote>
<p>我现在的处境与其又有什么不同呢,想要飞上蓝天,去任何我想去的地方,想起九月份的时候,有小伙伴在留言的小黄纸上写下</p>
<blockquote>
<p>「勇踏前人未进之境」</p>
</blockquote>
</summary>
<category term="LaterAdded" scheme="https://neko.ayaka.moe/categories/LaterAdded/"/>
<category term="Thoughts" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/"/>
<category term="日记" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
<category term="悲伤的年份" scheme="https://neko.ayaka.moe/tags/%E6%82%B2%E4%BC%A4%E7%9A%84%E5%B9%B4%E4%BB%BD/"/>
<category term="在奇怪地方的记述" scheme="https://neko.ayaka.moe/tags/%E5%9C%A8%E5%A5%87%E6%80%AA%E5%9C%B0%E6%96%B9%E7%9A%84%E8%AE%B0%E8%BF%B0/"/>
</entry>
<entry>
<title>拿到了想要的东西【填补内容】</title>
<link href="https://neko.ayaka.moe/2018/10/15/032/"/>
<id>https://neko.ayaka.moe/2018/10/15/032/</id>
<published>2018-10-15T12:24:17.000Z</published>
<updated>2019-12-09T09:05:00.000Z</updated>
<content type="html"><![CDATA[<p>在这里看到了很好看的小说,是好朋友外出之后带回来的,在大约一个月前就看完了,解决好悲伤,但是也好鼓励自己呢。(看得泪流满面,虽然科幻的内槽点太多了啦w)是一整套小说呢,叫《散落星河的记忆》。半个月前找他去问问能不能留下来送给我,因为他要走惹,才刚刚问完就答应了呢。今天也拿到了全部的书呢w,可以准备看第二遍了。<br><a id="more"></a><br>今天早上叫音乐的老师带给我了「萧」,这个是上个月拉屎吹走过的乐器呢,感觉声音超好听,超有感觉。<br>反正,这两样东西都拿到了,会好好保管珍惜的。</p>]]></content>
<summary type="html">
<p>在这里看到了很好看的小说,是好朋友外出之后带回来的,在大约一个月前就看完了,解决好悲伤,但是也好鼓励自己呢。(看得泪流满面,虽然科幻的内槽点太多了啦w)是一整套小说呢,叫《散落星河的记忆》。半个月前找他去问问能不能留下来送给我,因为他要走惹,才刚刚问完就答应了呢。今天也拿到了全部的书呢w,可以准备看第二遍了。<br>
</summary>
<category term="LaterAdded" scheme="https://neko.ayaka.moe/categories/LaterAdded/"/>
<category term="Thoughts" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/"/>
<category term="日记" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
<category term="悲伤的年份" scheme="https://neko.ayaka.moe/tags/%E6%82%B2%E4%BC%A4%E7%9A%84%E5%B9%B4%E4%BB%BD/"/>
<category term="在奇怪地方的记述" scheme="https://neko.ayaka.moe/tags/%E5%9C%A8%E5%A5%87%E6%80%AA%E5%9C%B0%E6%96%B9%E7%9A%84%E8%AE%B0%E8%BF%B0/"/>
</entry>
<entry>
<title>对之前文章的概述【填补内容】</title>
<link href="https://neko.ayaka.moe/2018/10/04/031/"/>
<id>https://neko.ayaka.moe/2018/10/04/031/</id>
<published>2018-10-04T07:09:31.000Z</published>
<updated>2019-12-09T08:52:00.000Z</updated>
<content type="html"><![CDATA[<p>最近发生的变动太多了呢,我也在尽力去控制自己的情绪来稳定自己。昨天我得知羽毛出事的情况,几近崩溃,一度想要爆发出来,但是又因为搬迁到了新的班级,不得不尽量避免事故的发生,但是他们只是传回一个极其简单的一句话,所以我也尽量去相信你一切都安好。</p><a id="more"></a><p>之前的文章在 9 月 16 日的时候被处理掉了,自 2018 年 7 月 14 日开始,每两天就可以写一篇东西,分散的有五篇比较长的信件,四篇小日记,四篇 Thoughts(基于本博客的归类分类),还有部分乐谱。那五篇长信是写给自己,父母,还有朋友,这些是混杂在一起的,表达自己想说的话,四篇小日记是简述这里的生活,也包含一些回忆,不过相比长信中所写的内容的话,回忆少一些。剩下的四篇思考,提出了几个有趣的想法呢。</p><p>「人的一生,最重要的就是心愿」这就话就是来自于其中,和 Neko 比较亲近的人一定都知道这句话,这是极为重要的东西呢。其他的就是对我自己真正心愿的不断论述罢了。</p><p>早在 5 月指出,我开始尝试创作,从乐曲(虽然一开始只有葫芦丝),到绘画,平面设计,到小说的创作,都开始去试试,尽量寻找一些可以解决这种困境的方法来把自己的注意力转移开。在当时有一个稿题为「猫之梦」的故事开始讲述,相应的,也建立了我记忆中能回忆起来的银河系星图,也把这个东西用于去创造一个虚假的围绕太阳系 400 光年的想象星图(银河系星图是来源于 Elite: Dangerous 这个游戏呢)。这个过程在当时那种处境下,真的很有趣,可惜找不回来了。</p><p>以上就是对过往文章的解释啦。</p><p>「留存给以后的我,以免忘记了」</p>]]></content>
<summary type="html">
<p>最近发生的变动太多了呢,我也在尽力去控制自己的情绪来稳定自己。昨天我得知羽毛出事的情况,几近崩溃,一度想要爆发出来,但是又因为搬迁到了新的班级,不得不尽量避免事故的发生,但是他们只是传回一个极其简单的一句话,所以我也尽量去相信你一切都安好。</p>
</summary>
<category term="LaterAdded" scheme="https://neko.ayaka.moe/categories/LaterAdded/"/>
<category term="Thoughts" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/"/>
<category term="日记" scheme="https://neko.ayaka.moe/categories/LaterAdded/Thoughts/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
<category term="悲伤的年份" scheme="https://neko.ayaka.moe/tags/%E6%82%B2%E4%BC%A4%E7%9A%84%E5%B9%B4%E4%BB%BD/"/>
<category term="在奇怪地方的记述" scheme="https://neko.ayaka.moe/tags/%E5%9C%A8%E5%A5%87%E6%80%AA%E5%9C%B0%E6%96%B9%E7%9A%84%E8%AE%B0%E8%BF%B0/"/>
</entry>
<entry>
<title>一个 Neko 想要讲述的故事</title>
<link href="https://neko.ayaka.moe/2018/03/11/025/"/>
<id>https://neko.ayaka.moe/2018/03/11/025/</id>
<published>2018-03-11T13:00:00.000Z</published>
<updated>2018-03-11T14:00:00.000Z</updated>
<content type="html"><![CDATA[<h1 id="我,Neko"><a href="#我,Neko" class="headerlink" title="我,Neko"></a>我,Neko</h1><h2 id="第一个也是最后一个故事"><a href="#第一个也是最后一个故事" class="headerlink" title="第一个也是最后一个故事"></a>第一个也是最后一个故事</h2><p>从前有一个高高的海岸,在不远处的海面上有一个灯塔,每天晚上都会给周围的船只指南航向。<br>这是一个陆地很少海面占据几乎所有地方的世界,船只来来回回的运行着,最近的陆地是一个很高很高的海岸,紧接着是峡谷,<br>从哪个峡谷的最顶端可以看到灯塔和周围陆地的全貌,远处什么也没有,陆地上一半是枯萎的植物,一半是努力生枝发芽的树丛。<br><a id="more"></a></p><p>一半枯萎的树木曾经尝试去浇灌他们,但是做不到救活他们,他们记录了小时候的所有记忆,可能是太沉重了,都枯萎了。<br>一半努力生长的树丛,我小心地打理他们,每次从现实回到这个世界的时候都会细心关照它们。</p><p>时间过去了很久,灌木丛的花开了,冒出的是第一次看到的很漂亮的风景,花儿散发出无数的味道,无数的粒子飘散到天空。<br>这个世界属于我自己,这是我的心里世界,<br>曾经最美丽的时候我看到了五彩斑斓的情感变成了丝带,变成丝带之后又变成像是极光一样的东西流开,<br>那是五彩斑斓的时候,只见过 2 次呢。<br>一次是小时候,一次是那年。</p><p>这个故事从这里说起,<br>那天不知道为什么,天刮起了大风,原本多云的天空变成了漆黑漆黑的颜色。<br>我意识到这不对劲,开始往自己的避难所逃离,并且问询我的小伙伴请求天气控制,<br>可是失败了。</p><p>那次灾难,是风暴和地震所引起的洪水和海啸。</p><p>避难所被摧毁了,我泡在水里不知道应该做什么…<br>一直到现在…<br>被周围的水包围着,水似乎是洋红色的,水很安静,我就漂浮在水下不知道应该做什么</p><p>我憋不住了呢,那样的压抑感,所以这次决定离开这个世界了…</p><h3 id="我讨厌的这个世界"><a href="#我讨厌的这个世界" class="headerlink" title="我讨厌的这个世界"></a>我讨厌的这个世界</h3><p>我很喜欢我自己的小世界,即便现在我依然泡在水里,感受不到一丝我的世界的变化,也不知道水面上那个灯塔怎么样了。<br>或许已经过去几百年了吧。</p><p>我讨厌我所存在的现实世界,我喜欢逃避到自己的小世界里,因为现实世界里面有太多我讨厌的东西了呢,比如家里的“爸爸”,比如回家,比如那些不理解我的同学…<br>还记得呢,当初抑郁症的时候,在美国的最后一个月,大家都不相信我是抑郁症,大家都觉得我只是想要偷懒罢了,大家都觉得我只是想要休息,或者想要玩电脑之类的。<br>可是不是的呢,当初就已经很难受了,记得最亲近自己的人一句 「会长你也会得抑郁症啊,别骗我了哈哈啊哈」,蛮伤痛的,不过想想看也不知道应该怎么说吧,我在他们面前表现出来的样子就根本不像是一个抑郁症患者的样子,只是一个很安静的人。当时在学校我都算是一个很奇怪的怪胎了吧,<br>进入到课堂和任何一节可以用电脑的课都在鼓捣自己的东西,当然如果遇到有趣的课目提到有趣的话题我也会去参加,比如 LGBTQIA 呢,当时自己就是 Transgender 了呢,只是没有完全暴露出来,自己也不敢暴露出来,害怕被别人讨厌害怕被别人当成异端,但是大家唯一给我的快乐大概就是我做菜给他们吃,我照顾他们了吧,是奇怪的快乐获得来源呢。</p><p>这些都是在美国的那些记忆,国内的话,我很讨厌在昆明呢,因为家里总是冷冰冰的,自己总是被限制着一样的,所以有机会就会跑出家门和同学去逛街(虽然逛街的时候我依然很孤独就是啦,自己带着耳机,走在路上,听着他们淡淡的不知道在说什么的话题,跟着他们走,跟着他们到处走),至少这样的话,可以不用在家里见到“爸爸”,可以不用在家里接受那些东西。</p><p>我讨厌现实,我喜欢我自己的小世界。</p><p>我会把自己藏在音乐的世界里,就在自己的小氛围里,躲藏在那里。</p><h3 id="我讨厌的父母"><a href="#我讨厌的父母" class="headerlink" title="我讨厌的父母"></a>我讨厌的父母</h3><p>我讨厌父母呢,真的很讨厌呢,那种被抛弃的感觉是永远忘不掉的。就像之前在<a href="https://neko.ayaka.moe/2018/01/01/020/">日记</a>里面写的,那些被抛弃的感觉,一个人在异国他乡被抛弃的感觉,虽然在妈妈那边也会好很多,因为自己的房间很温馨,每天回到家关起房门躲在自己的小世界就很温暖了,妈妈一个人在外面做着她的事情,互相也不会有什么干扰呢。记得当时高三回国的时候,回到个旧,一个人每天躲在自己的小房间里,不知道做什么,每天浑浑噩噩,每次和爸爸打电话都会吵一架之类的。其实小时候当时离异的时候就开始有点讨厌爸爸了呢,是后来慢慢又积攒起这些坏的感情,否则换句话说,爸爸很努力的吧,可是不知道怎么表达爱什么的。不过可以不用在乎了呢,可以离开这个世界了。</p><h3 id="冰冷的家"><a href="#冰冷的家" class="headerlink" title="冰冷的家"></a>冰冷的家</h3><p>即便是在自己的小房间里,在昆明的家依然是那样的冰冷,因为见证过太多了吧。2008 年的各种家庭争吵、家庭暴力,我自己因为学业被打之类的事情,在昆明的家总是显得那么寒凉,总是以一种白色展现在眼前;即便是昆明的新家也是这样,因为那边主调色就是白色,很大很空旷,甚至一开始的几天都是我去居住着,一个人觉得很孤独呢。所以讨厌昆明的家,因为总是给人很冷的感觉,不像个旧的家那样温馨。个旧的家就是很聚集的样子,自己的房间也很温暖,所以更喜欢把自己关在个旧的家里呢。</p><blockquote><p>我会把自己藏在音乐的世界里,就在自己的小氛围里,躲藏在那里。</p></blockquote><p>一个人温暖的和电脑面对着,有吃的有喝的有风扇有电热毯,无论是什么季节都很舒服。高三退学回来之后就在个旧的家里住了好几个月。</p><h1 id="她,Neko"><a href="#她,Neko" class="headerlink" title="她,Neko"></a>她,Neko</h1><h2 id="他变成了她"><a href="#他变成了她" class="headerlink" title="他变成了她"></a>他变成了她</h2><p>因为自己的特殊性,早在幼儿园就有意识到自己和周围的小朋友是不一样的,到了小学知道了更多,到了初中知道了更多。开始扭正自己,尝试了很多方式,但是自己的伤痛加上自己的特殊性,还是会想要变成女孩子才会适合自己的呢,第一次尝试吃糖已经是两年前的事情,是 2016 年 6 月中旬的时候,当时为了不让家长和老师发现,自己只吃很少量很少量的激素药物,慢慢转变自己,所以高三才会因为对家庭的内疚抑郁到神经崩溃呢。然后就是之前<a href="https://neko.ayaka.moe/2018/01/01/020/">日记</a>里面有小小提到过的一部分故事,就是高三退学的故事呢。</p><h3 id="我想要变成女孩子"><a href="#我想要变成女孩子" class="headerlink" title="我想要变成女孩子"></a>我想要变成女孩子</h3><p>我想要变成女孩子。<br>是很奇怪的要求吧,作为一个男孩子说出这样的话,但是现在来看同类越来越多了呢,希望大家都会好,希望大家都会好好活着,而不是像我一样,选择离开这个世界。<br>大家…都要好好努力坚持着呢,我先走了呢。变成女孩子什么的这样的选择,</p><blockquote><p>「只要你的内心是善良的,对错都是他人的事。」<br> –《大鱼海棠》的台词</p></blockquote><p>所以只要觉得自己是正确的东西,只要是你自己觉得是正确的方向,就努力去取得吧。<br>记得那年,纠结了很久很多,也隐藏了自己的本性,在寄宿家庭的时候也更多时候的把自己关在自己的房间里,穿着漂亮的衣服抱着玩偶躺在床上,就这样我吃了近 300 天的药,度过了基本上大半个高三,在快毕业的时候选择了退学,那个时候停下来了(怕被家里人发现,当时回到昆明家里被审讯的时候也就是说我想变成女孩子然后家里就炸了锅),然后又在 2017 年 7 月 1 日开始吃糖(激素药物)因为自己断药的那段时间想清楚了,一定要吃药提前开始变成女孩子,一直到做手术的时候才会停下。</p><p>到了现在了呢,我以女装的身份活着,活着… 恢复吃糖已经过去了半年多几乎快一年…</p><p>还记得退学回来的那个假期当时 7 月份被邀请去游玩,结果和大家都格格不入呢,因为自己有很多地方都变了呀,于是那段记忆也不是很愉快很开心。<br>大概自己已经变得面目全非了吧,还记得当时被同学说“还是喜欢几年前的你”。</p><h2 id="写给你们"><a href="#写给你们" class="headerlink" title="写给你们"></a>写给你们</h2><h3 id="写给-羽毛(羽毛的博客:https-oao-moe-)"><a href="#写给-羽毛(羽毛的博客:https-oao-moe-)" class="headerlink" title="写给 羽毛(羽毛的博客:https://oao.moe/ )"></a>写给 羽毛(羽毛的博客:<a href="https://oao.moe/" target="_blank" rel="noopener">https://oao.moe/</a> )</h3><p>羽毛是我最重要的人了呢。羽毛是我最爱最在乎的人,虽然是一个很傲娇很喜欢在我面前撒娇闹小脾气的人呢,但是很可爱。当时第一次和所谓的 “网友见面” ,羽毛是第二个呢,当时到飞机场还是羽毛来接的 Neko,两个人在见面前就恩恩爱爱的了,见面的那天两个人的心跳速度都很快很快。<br>知道吗,你是第一个让我有勇气去相信并且坐飞机坐火车坐汽车去见面的人呢,32 是第一个坐飞机去见面的。但是勇气的来源很奇怪呢,我居然会相信你呢,相信一个莫名在网络上认识的一个很疲惫的人。你也是焦虑患者,你也有性别焦虑,更重要的是我们两个经历类似呢,所以能感受到对方很多很多东西,感受到对方的情感,感受到对方的很多需求甚至是心里所想的东西。爱你呢,我也一直只爱你,最喜欢你呢,自从和你接触之后我用社交网络都没有以前多了,只要你在家里的时候就会放下手机好好陪你或者躺在床上陪你(躺在床上是因为自己没有多少力气坐着或者站着呢,会觉得很累的),只想和你在一起啊,所以这次死亡,我想了一个晚上才给你答复说我会帮你推注的,其实是很困难的决定呢,因为说白了是在杀死你呢。对不起啦,但是这样可以解脱你的话,那就解脱好了呢… 我会立即去世界的另一端找你的。</p><h3 id="写给-琉璃(琉璃的博客:https-blog-chiyukiruri-moe-)"><a href="#写给-琉璃(琉璃的博客:https-blog-chiyukiruri-moe-)" class="headerlink" title="写给 琉璃(琉璃的博客:https://blog.chiyukiruri.moe/ )"></a>写给 琉璃(琉璃的博客:<a href="https://blog.chiyukiruri.moe/" target="_blank" rel="noopener">https://blog.chiyukiruri.moe/</a> )</h3><p>琉璃是我除了羽毛以外最在乎的人了呢。是后来才仔细认识互相见面的人,以前不会依赖那么多,也不说太多话,只是平时在社交网络上两个人互相沟通一下之类的。自从那次见面之后就不一样了呢,你带着我们去拿了易性病(性别焦虑)的证明(虽然没有拿完全啦,但是至少可以证明了呢),还去专门请你们的小区居委会给我开证明…好感谢的,在保定的那段时间也是你提供的住宿,一起过的除夕和春节,我们一起度过了好多,经历了好多。甚至还能想起来当时我们两个人在 Nintendo Switch 上玩 UNO 的场景呢。你好迷你好可爱,也很疲惫的吧,那样的生活。记得还一起做过菜,你的黄瓜炒蛋,我的豆瓣酱炒肉,喜欢吃你的咖喱饭什么的… 真的是好多记忆了。只有仔细认识后才会注意到那么多的东西呢。谢谢你,谢谢你的帮助,今天也谢谢你一起离开这个世界呢,辛苦你了,也很高兴能够认识你呢。</p><h3 id="写给-32"><a href="#写给-32" class="headerlink" title="写给 32"></a>写给 32</h3><p>32 是最希望帮助 Neko 的人了呢。32 是前男友的存在,相较于现在我和羽毛的百合关系,当时 32 有很多不珍惜感情的地方呢,32 专注游戏太多了啦。但是严肃起来还是可以严肃讨论问题的呢,你也是第一个说要和父母借 20 万让我在美国继续上大学的人呢。很感谢你,和你玩游戏的那些记忆也很开心,比如在 Elite Dangerous 里面去 Lost World 那颗行星的环上,我们一起拍照一起录像,记录了好多。还有那个黑洞,你死掉的那个黑洞那里我真的哭了呢,哭了好久,因为失去了你呀。还记得和你玩 Factorio 的时候,我们会吵架,会争执。可是只知道玩游戏不够呢,虽然还是培养了很多感情,现在你大概能理解我以前说的很多话了呢,你也应该有了更多的情感,愿意去感受了吧,只是有的时候表达方式还是有点缺陷呢,不过是可以改的。在说谢谢之前先和你说对不起呢,对不起那些争执,那些玩游戏的时候的争吵,对不起呢,当时我们还在一起的时候会有一些过度依赖你的小情绪,对不起呢,要离开了。谢谢你呢,谢谢你的父母的帮助呢,对不起呢,离开你了。也谢谢你一直愿意陪着我呢。</p><h3 id="写给-琦才"><a href="#写给-琦才" class="headerlink" title="写给 琦才"></a>写给 琦才</h3><p>原本,琦才是我最在乎的人呢。原本你才是我最爱的人呢,可是后来那么多变数,加上我对你的劝说你都不去尝试什么的…就分开了,虽然那个契约依然生效呢,就是。</p><blockquote><p>你永远都是我的主人,我永远都是你的小妹抖</p></blockquote><p>这个永远不会变呢。你和豆腐一样都有着一种奇怪的给人的独特感,虽然还没有见过面呢,但是是很羡慕的人,毕竟是学医的人呢,会的东西肯定比自己多出很多很多,事实也是这样,你在很多地方都很有天赋呢,只是你把它当做一种本能而已,其实别人没有呢,至于是什么,自己去探寻吧w(给一个小提醒呢,古典乐),对不起啦,我要先走一步了呢。我先去世界的另一端等你呢…如果你也会来的话。谢谢你陪我走过的路,谢谢你陪我走过的那几个月…对不起呢,没有能够陪你到最后…</p><h3 id="写给-豆腐"><a href="#写给-豆腐" class="headerlink" title="写给 豆腐"></a>写给 豆腐</h3><p>豆腐是我信任的人呢。为什么会写在这里是因为,你也是我见面见过一次的人呢,而且印象蛮深刻的,头发比我长,性格很有趣。信任你所以把邮件递送给了你,希望你帮我料理后面如果我真的离开了的很多事情。写给你什么呢?其实和你的记忆只有几小时呢,你来到我们房间,放下了行李,然后和 A2 去吃饭了,然后晚上很晚才回来,早上 6 点匆匆忙忙又离开了。只能说豆腐是很温柔的人呢,如果愿意进行 HRT 的话,尽管去吧,就像我说的呀,</p><blockquote><p>「只要你的内心是善良的,对错都是他人的事。」<br> –《大鱼海棠》的台词</p></blockquote><p>豆腐很会关心人呢,和我见到的男生都不太一样,有一种说不出来的独特感。这种独特感是无法用言语描述的,把你放在人群当中也可以轻易找出来的那种独特感,很喜欢。<br>谢谢你呢,谢谢你陪我聊天,谢谢你关心我在乎我…但是也对不起呢…要做出这样的决定。</p><h3 id="写给-Jelly"><a href="#写给-Jelly" class="headerlink" title="写给 Jelly"></a>写给 Jelly</h3><p>Jelly 是我信任而且愿意帮助我的人呢。很多时候缺钱了或者 Linux 有一些小问题了都会和你问询和讨论,是很羡慕的人,很羡慕很羡慕的人,无论是技术还是经验还是身材还是性格本身,可能是我心目中最完美的男友吧?如果要我评价的话,因为 INFJ 和 INT/FJ 都会互相理解的,因为对方都是很神秘的人呢。谢谢你一直帮我,谢谢你一直劝说我一直陪我,谢谢你一直借钱给我,谢谢你一直的存在,即便中间在游玩 ED 的时候有对你恨意的时候,但是谢谢你呢。还有就是对不起啦,把你叫到 Jelly Nebula 就跑掉了,开了 Factorio 的服务器几天都没有去理你,对不起呢,对不起呢,要离开了。</p><h1 id="它,Neko"><a href="#它,Neko" class="headerlink" title="它,Neko"></a>它,Neko</h1><p>我想要离开了。<br>因为我坚持不下去了,我喜欢的人也坚持不下去了呢。</p><p>或者是这个世界太残酷了吧,我们活的太累了,死掉对于我们来说会好很多,死掉对于我们来说是一种解脱吧。<br>不希望再痛苦了呢,所以选择了,这样的路。</p><p>要离开了呢,再见。<br>大家,我在世界的另一端等你呢…</p><h2 id="疲惫的生活"><a href="#疲惫的生活" class="headerlink" title="疲惫的生活"></a>疲惫的生活</h2><p>知道抑郁症患者的世界是什么样子吗?</p><blockquote><p>是灰色的</p></blockquote><p>是的呢,一切都看起来是灰色的。醒过来看到的东西都是灰色的,没有一点生气,没有一点颜色。只有手机上面的一些消息有着温度,极少数的消息会有那样的温暖,因为自己的朋友已经越来越少了呢,社交能力也远远不如以前,不如说我本来就不社交吧;因为我不说话的呀,因为我很少第一个人开口说话的呢。因为如此也断开了无数联系人的连接,现在也找不回来了,只能这样了呢,只有几个人会关心我了。</p><p>这样的生活甚是疲惫呢,又是想要变成女孩子,又是抑郁,又是对家里的恐惧,不知道去哪里,只能漂泊在这个世界的大回流里,现在来到了你的身边 —— 羽毛的身边。我把这里当做是我的家,因为它只属于我们,你会关心我会照顾我,这里像是一个温暖的地方。不过还记得吗,当时从云南回来的时候我们聊起来,你说我在云南的家表现的很拘束,不像是在这边上海的时候这样愉快自由。的确是这样呢,也的确吧,我真的依赖上这个地方了。每天休息的地方,每天情感表达的地方,每天头疼难受你不在的地方,可以和你一起的地方。</p><blockquote><p>是一个缺爱的孩子呢。</p></blockquote><p>有很多人这么评价过我,我也很依赖羽毛,见到琉璃习惯了之后也会依赖琉璃。</p><p>但是很疲惫呢,因为抑郁的原因,因为很多压力的原因。原本当时在 2017 年 8 月份我准备重新以一种态度来看待生活,重新开始一段生活,可是家里人对我的抛弃造成了现在这个样子了呢,在日记里面有说过,原本就很疲惫的我,被家里人抛弃了,回到了上海,然后又在上海被伤害一次,回到了云南个旧没有住在家里,住在了亲戚家里,我又开始准备以一种新的态度来,可是这次失效了呢,我一点一点破碎,我的世界变得越来越黑暗,风暴吹得越来越狂躁,不知道为什么,即便我用枕头把自己围起来还是感觉不到安全感,我总是很难入睡,总之睡到一半醒来,然后停下。</p><p>然后去医院诊断,已经是重度抑郁中度焦虑了呢。开了很多药,一开始吃好眩晕好难受呢。一直到现在才习惯那些精神药物。</p><p>好疲惫的生活啊,动不动就去精神卫生中心去看医生去开药,花掉了不少的钱呢。</p><!--more-->]]></content>
<summary type="html">
<h1 id="我,Neko"><a href="#我,Neko" class="headerlink" title="我,Neko"></a>我,Neko</h1><h2 id="第一个也是最后一个故事"><a href="#第一个也是最后一个故事" class="headerlink" title="第一个也是最后一个故事"></a>第一个也是最后一个故事</h2><p>从前有一个高高的海岸,在不远处的海面上有一个灯塔,每天晚上都会给周围的船只指南航向。<br>这是一个陆地很少海面占据几乎所有地方的世界,船只来来回回的运行着,最近的陆地是一个很高很高的海岸,紧接着是峡谷,<br>从哪个峡谷的最顶端可以看到灯塔和周围陆地的全貌,远处什么也没有,陆地上一半是枯萎的植物,一半是努力生枝发芽的树丛。<br>
</summary>
<category term="Letter" scheme="https://neko.ayaka.moe/categories/Letter/"/>
<category term="Farewell" scheme="https://neko.ayaka.moe/tags/Farewell/"/>
</entry>
<entry>
<title>对你的感情</title>
<link href="https://neko.ayaka.moe/2018/02/09/023/"/>
<id>https://neko.ayaka.moe/2018/02/09/023/</id>
<published>2018-02-09T07:31:02.000Z</published>
<updated>2018-02-09T07:31:02.000Z</updated>
<content type="html"><![CDATA[<p>你想知道为什么我会喜欢你嘛…<br>你想知道为什么我会告白的嘛…<br>你还想知道一些什么的东西呢…</p><p>不知不觉又让这些字符完全对齐了呢…</p><p>你想知道我的情感是什么嘛…</p><a id="more"></a><p>嘛,那就先从最开始的最开始开始说的呢,基本的来说…喜欢你是因为在乎你的呢…在乎你到了那种想要在你身边照顾你的程度。<br>喜欢你,大概是从我们开始互相展露内心的时候开始吧,就是 10 月份的那段时间呢…<br>后面也很感谢你呢…能陪着我度过那一天…<br>从那一天开始就觉得离不开你了的样子…<br>我也不知道为什么会有这样的感觉。</p><p>我喜欢照顾别人呢…<br>很喜欢照顾别人的我…<br>你那段时间经常会觉得很难受,经常会觉得孤独,经常会说很多的话在 Twitter 上,甚至是去看你的树洞,<br>我就想陪在你的身边,照顾你,给你那些你想要的东西。<br>现在做到了很大部分了呢…</p><p>为什么会告白呢…<br>为什么呢…<br>为什么那样的事情会发生呢…<br>还记得那次我们两个很激烈的吧…我就想着<br>用一次最强大的感情力量灌满你的内心,让你觉得我陪着你,<br>大概这样就会好了吧。<br>我只是这样想着。</p><p>即便是当时那样,我也还是不确定我自己的感情,但是现在回头去看那些聊天记录,<br>就像你说的,就像是两个在热恋中的人的样子呢…只是是百合一样的存在。</p><p>我也会迷茫呢,你说的这些,<br>我喜欢百合一样的情感,但是 Neko 也会觉得迷茫,到底自己是喜欢什么样的人…<br>可是我现在的感情意义是:我在乎的,我想照顾的,我想陪着的永远的,就是我喜欢的人,这个就是我现在的定义了呢。<br>所以就算是迷茫了也不要担心太多,因为我的意义就是陪着你呢,你接受的话去照顾你的呢。</p><p>真的确定自己的心情是在见到你的时候,<br>你在机场的时候,很漂亮的,见到你就冲过去紧紧抱住哭了起来,<br>记得你当时比我都还激动,周围的人都看着觉得好奇怪的样子。</p><p>你想知道 Neko 的内心对吧…<br>Neko 的内心很难理解呢…就算是我自己也不会知道怎么去理解这些…<br>我会尝试在 Twitter 和 Telegram 上尝试表达…<br>但是自己也是很难理解的呢…<br>很多东西都会尝试和你解释和表达的啦,在我的能力之内。</p><p>综合上面,<br>我爱你呢。</p>]]></content>
<summary type="html">
<p>你想知道为什么我会喜欢你嘛…<br>你想知道为什么我会告白的嘛…<br>你还想知道一些什么的东西呢…</p>
<p>不知不觉又让这些字符完全对齐了呢…</p>
<p>你想知道我的情感是什么嘛…</p>
</summary>
<category term="日记" scheme="https://neko.ayaka.moe/categories/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
</entry>
<entry>
<title>如果这是梦</title>
<link href="https://neko.ayaka.moe/2018/01/05/022/"/>
<id>https://neko.ayaka.moe/2018/01/05/022/</id>
<published>2018-01-05T08:44:22.000Z</published>
<updated>2018-01-05T08:44:22.000Z</updated>
<content type="html"><![CDATA[<p>是好奇怪的标题呢…<br>这两天脑子里都会不自觉的冒出这个想法…不知道为什么呢。<br>最近几天做梦也很累的样子,有梦见自己被蛇咬,有梦见你变小,可以放在手心,有梦见很多壮观的场景…<br>可是…此时此刻,如果是梦的话…会怎样呢?</p><a id="more"></a><p>那这个梦是最甜美的吧,是能哭出来的梦呢…<br>可是我不相信这是梦呢,哪有这样甜美的梦呢,即便这一切…都是第一次体验呢…</p><p>在这个梦里哭过好多次呢…孤独过好多次呢…但是有你陪着的那些部分,就真的是好开心的…<br>是天真的猫喔,有些许安全感和温暖就会觉得安心的猫呢…<br>在这个梦里不知道有没有照顾好你呢…<br>至少猫猫有尽力了吧,有一直在陪着你的。</p><p>如果这是一个梦的话,我不想醒来呢,因为醒来就可能回到以前的那些痛苦的时光去了呢…<br>我不要回去…我不要回去…我不要一个人…<br>超黏人的吧,你说你很喜欢的呢,我也很喜欢的呢。<br>这个梦真的真的好甜美。</p><p>记得刚才吃饭的时候和你说的嘛…猫猫大概是自己不会维持关系什么的吧…所以关心到自己的人真的没有呢…<br>除了你。<br>还有谁呢…还有谁可以这样对猫猫呢…<br>毕竟…最缺乏的就是安全感和爱啊…<br>就像猫猫说的…<br>自己 Twitter 一天没动态…要不是你说了,也不会有人主动找自己的…<br>不会的呢…<br>或者就像你说的,我在忽视吧…因为他们也无法理解自己的不是吗?我自己也无法理解自己的呢…一个 INFJ 怎么会理解自己到底是什么东西呢…所以把自己当做是一直猫就好了呢。</p><p>真的是孤单的猫呢…<br>如果这是梦的话…请让我永远睡下去呢…</p><p>我不要醒过来…<br>因为这里面,有我最依赖的东西呢…也有我最想要的东西呢…</p><p>好像…每次写日记都会哭呢…</p>]]></content>
<summary type="html">
<p>是好奇怪的标题呢…<br>这两天脑子里都会不自觉的冒出这个想法…不知道为什么呢。<br>最近几天做梦也很累的样子,有梦见自己被蛇咬,有梦见你变小,可以放在手心,有梦见很多壮观的场景…<br>可是…此时此刻,如果是梦的话…会怎样呢?</p>
</summary>
<category term="内心" scheme="https://neko.ayaka.moe/categories/%E5%86%85%E5%BF%83/"/>
<category term="内心" scheme="https://neko.ayaka.moe/tags/%E5%86%85%E5%BF%83/"/>
</entry>
<entry>
<title>是好难受的梦</title>
<link href="https://neko.ayaka.moe/2018/01/03/021/"/>
<id>https://neko.ayaka.moe/2018/01/03/021/</id>
<published>2018-01-03T14:29:04.000Z</published>
<updated>2018-01-04T16:29:04.000Z</updated>
<content type="html"><![CDATA[<p>最近做了好多梦好多梦…</p><p>早上醒来之前印象最深刻的梦境是<br>被蛇咬了一口。<br>然后因为怕毒性太大,自己吸了一口,发现吸出来的那些毒液都是绿色的…<br>就把自己吓坏了,和旁边的人(似乎是家里人)说了一下让他们打急救电话…<br>结果他们说…没事的,只是一些小问题…</p><a id="more"></a><p>然后猫猫就晕过去了呢</p><p>最近梦境都在现实和想象之间不停切换呢…</p><p>其实很害怕现实的梦境…因为会有分不清梦境和现实的情况…好多次呢…<br>自己也一直做不到在梦境里面意识到自己在做梦什么的…<br>这大概也算是猫猫不喜欢睡觉的原因吧…<br>虽然自己很多时候都好困困…</p><p>可是讨厌夜晚的呢,讨厌夜晚睡觉的呢。<br>不知道为什么现在变成了这样…可能是高中的时候生活习惯都很奇怪的缘故吧…<br>回家就去床上抱着枕头睡一觉,半夜起来找吃的,然后凌晨做作业玩游戏什么的…<br>不过在当时会觉得这样的生活方式蛮好的,不会困,而且还能和国内的小伙伴玩一会儿什么的…虽然只有 2 个呢…</p><p>说起这些脑子里想到的全是高三时候的生活,<br>就是每天陪着别人玩…然后自己颓废…最后裸考高考(ACT)</p><p>嘛,昨天那样的梦境什么的…好讨厌的不是吗…</p><p>说白了自己还是讨厌在学校什么的吧…自学什么的总是很有动力呢(可是自己都把自己逼出强迫状态了啦)。<br>还是多休息好一些呢…<br>虽然现在的精神和情绪状况…大概还行吧…<br>只是那些小波动什么的…自己仍然不能控制的呢…</p><p>以前有想过自己是不是喜欢这样的伤心…<br>可是自己告诉自己的是…其实很讨厌这样很情绪化呢…<br>因为基本上什么东西都会触发情绪…加上现在的状态,基本上就是过激的情绪化…<br>反正难受的时候就躺着好了呢…</p><p>希望自己会好起来的…<br>希望的呢…<br>噩梦什么的也不要出现了呢…</p>]]></content>
<summary type="html">
<p>最近做了好多梦好多梦…</p>
<p>早上醒来之前印象最深刻的梦境是<br>被蛇咬了一口。<br>然后因为怕毒性太大,自己吸了一口,发现吸出来的那些毒液都是绿色的…<br>就把自己吓坏了,和旁边的人(似乎是家里人)说了一下让他们打急救电话…<br>结果他们说…没事的,只是一些小问题…</p>
</summary>
<category term="日记" scheme="https://neko.ayaka.moe/categories/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
</entry>
<entry>
<title>那些噩梦...真的好讨厌呢</title>
<link href="https://neko.ayaka.moe/2018/01/01/020/"/>
<id>https://neko.ayaka.moe/2018/01/01/020/</id>
<published>2018-01-01T15:49:54.000Z</published>
<updated>2018-01-01T15:49:54.000Z</updated>
<content type="html"><![CDATA[<p>12 月 31 日的这天晚上做了一个梦呢…<br>又是和那个时候很相似的场景…</p><p>当时在美国好不容易有大学,之前暑假高三自我放弃了…退学早早的就回国,所以原本大学什么的已经是不可能的了<br>加上当时有断药…情绪基本上就是越陷越深越来越糟糕…<br><a id="more"></a><br>当时知道可以去大学…满脑子都是说不出来的感觉,就是很矛盾的自己,不知道自己还有没有力气,不知道自己能不能再回到那个讨厌的地方挣扎一下…<br>一开始去到的时候是想好了,要好好面对这样的新生活的呢…所以一开始也很努力,选了一直想要的日语课,上课的时候也比以前认真了许多…<br>可是结果是去了快一个月,只有去大学 5 天,最后那天还是去办理退学手续才去的呢…<br>为什么最后会回来了呢…<br>家里没有给猫猫钱了呢…和他们发消息也不会理睬,发多少消息都不会回复…<br>原本相信妈妈的呢,结果打电话给妈妈想要她和爸爸说一下什么的…可是他们就是不愿意呢<br>宿舍那边的东西都没买齐,也没有吃的,两天喝一碗汤…</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.imgur.com/MZWZMqj.jpg" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>月初要交宿舍费了,中介那边说宿舍这边会有麻烦,希望能和家里联系一下,要交下个月的宿舍费了…<br>可是就是联系不上呢…<br>原本是有工作的,结果工作的那边说猫猫还是一个学生,当天应聘之后说好的 700 美元一个月就没有了呢…<br>虽然猫猫还是很努力的有在努力,可是他们看不起学生呢…明明给了他们 GitHub 的链接,偏偏要说猫猫不给他们 Update Infomation…<br>依然记得那是接近周末…他们就不要猫猫了呢。唯一的希望也没有了呢…</p><p>当时都希望晚上坐着公交车离开,去到一个没有人会找到的地方,自己死掉,也不会有人会注意的不是吗,自己家人都不要自己了呢,学校里面也没有在乎自己的人呢…<br>死掉就好了吧…反正回国自己什么都做不了,没有高中学历,没有大学学历,自己什么都不会…<br>会饿死的,不如死掉…<br>当时已经想好了呢,毕竟被自己的亲人抛弃了呢,虽然小时候就不喜欢了…</p><p>过了周末…被小伙伴劝说了好多…自己决定要回国…<br>周二就一个人去和学校说退学,退了学费,退了宿舍,定了机票,自己一个人去到机场…</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.imgur.com/LrGdEUn.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>第二天就坐飞机离开了呢…</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.imgur.com/pjgBCEK.jpg" alt="" title=""> </div> <div class="image-caption"></div> </figure><p>原本这次打击就够大了呢…想着去上海之后要自己尝试活下去呢…<br>结果在上海的第 14 天,家里妈妈打了一个电话过来,说想知道现在猫猫的情况如何,<br>因为考虑到妈妈已经是一个人…如果太担心自己的话可能会出现自己并不希望的意外…加上当时还是信任妈妈的呢…<br>妈妈问到地址的时候就说了…<br>结果第二天爸爸也来了…<br>当然从这里开始猫猫就不会相信家里的任何人了呢。<br>“爸爸” 当时和猫猫说的就是,如果不跟着他们回去的话,就去收拾一顿猫猫的朋友(因为住所和工作都是朋友帮助的<br>因为还是不希望连累到别人呢,就只能忍痛…<br>回去的路上都在哭呢…都在哭呢…都在害怕着呢…<br>不再相信他们…<br>回去也是住在一个亲戚家里…<br>后来他说要回来看看猫猫…但是依然是那样呢…<br>记得他说过最伤人的话就是:</p><blockquote><p>你看看你都把你妈妈弄成什么样子了,你自己不会想想吗?你自己心里不会痛吗?</p></blockquote><p>拜托…猫猫就是因为想太多了才会这样啊…</p><p>就是这两个巨大的冲击呢…<br>像这样的剧情的梦境有梦见过好多好多…<br>每次在梦里都是超级绝望…超级难受的那种<br>梦里最尖锐最令人恐惧的也是所谓的 “爸爸” 呢…</p><p>可是这次梦境里让自己怀疑自己了呢…<br>自己放弃了学业,又一次,尽管是梦里…<br>他依然是恐怖的样子…<br>然后怀疑自己…<br>可能自己真的不适合待在学校里面吧…毕竟这么久以来,自己知道的东西都是自学的呀…<br>或许是这样的吧…</p><!-- more -->]]></content>
<summary type="html">
<p>12 月 31 日的这天晚上做了一个梦呢…<br>又是和那个时候很相似的场景…</p>
<p>当时在美国好不容易有大学,之前暑假高三自我放弃了…退学早早的就回国,所以原本大学什么的已经是不可能的了<br>加上当时有断药…情绪基本上就是越陷越深越来越糟糕…<br>
</summary>
<category term="内心" scheme="https://neko.ayaka.moe/categories/%E5%86%85%E5%BF%83/"/>
<category term="内心" scheme="https://neko.ayaka.moe/tags/%E5%86%85%E5%BF%83/"/>
</entry>
<entry>
<title>想要变成猫</title>
<link href="https://neko.ayaka.moe/2017/12/28/019/"/>
<id>https://neko.ayaka.moe/2017/12/28/019/</id>
<published>2017-12-28T10:58:05.000Z</published>
<updated>2017-12-28T19:58:05.000Z</updated>
<content type="html"><![CDATA[<p>今天一整天都是你的猫猫呢…</p><p>想要变成猫,<br>那样就可以被你完全抱住了呢,<br>那样的话就可以在你面前随意蹭蹭了呢,<br>那样的话就可以被你抱着去上学了呢,<br>那样的话就可以和你玩逗猫棒的游戏了呢…<br><a id="more"></a><br>可是猫猫只有 15 年的寿命…好短呢…想要陪你陪到时间的尽头<br>不过反过来想,如果 Neko 是猫的话,那就是用自己的一生去陪你了呢…<br>猫猫的一生都是你的世界呢,<br>陪在你身边,你哭的时候听着你哭,你冷的时候爬过去给你暖暖…<br>可以和你撒娇要挠挠肚子什么的…</p><p>写到这里就哭出来了呢…<br>真的想陪着你的呢…想要陪着你一直走下去的呢。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.imgur.com/RGHaV3W.png" alt="" title=""> </div> <div class="image-caption"></div> </figure><center><a href="https://www.pixiv.net/member_illust.php?mode=medium&illust_id=65293346" target="_blank" rel="noopener">「おやすみ邪ンヌ」</a> by <a href="https://www.pixiv.net/member.php?id=3079252" target="_blank" rel="noopener">「林けゐ」</a></center><!-- more --><p>感觉日记写的越来越短,不过自己也不知道应该说些什么呢。<br>想要讲故事,但是不知道说什么好。</p><p>早上起得好早…<br>然后中午陪你睡了好久…<br>然后又是日常的 21:00 睡着。<br>陪着你真的好开心…在你身边就好安心的呢…</p><p>当然今天哭着和你说的那些…也算是猫猫的故事了吧。<br>猫猫一个人去洗澡真的好难受的呢…<br>猫猫真的好害怕一个人…<br>猫猫真的好害怕被抛弃…<br>一个人就在里面哭…<br>洗一会儿哭一会儿…<br>不想要一个人的啊…真的不想…<br>好害怕…</p><p>一个人蹲在那里…被热水冲刷着…抱着腿哭了起来…<br>希望你可以进来和猫猫说一句话都好呢…<br>可是…<br>真的好害怕…<br>不要一个人…<br>不要…</p><p>不希望再见到以前那样的场景了呢…<br>一个人穿着喜欢的小裙子…玩累了就跑去床上抱着玩偶…旁边摆着等身抱枕假装有人陪着…<br>然后慢慢睡着…睡到深夜…一个人做吃的一个人玩……谁也不会管…谁也不会在乎…<br>真的不希望那样了呢…</p><p>猫猫变得好脆弱…<br>只想依偎在你的怀里呢…</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://i.imgur.com/Q0nttEL.jpg" alt="" title=""> </div> <div class="image-caption"></div> </figure><center><a href="https://www.pixiv.net/member_illust.php?mode=medium&illust_id=53457328" target="_blank" rel="noopener">「眠いにゃー」</a> by <a href="https://www.pixiv.net/member.php?id=395595" target="_blank" rel="noopener">「KD」</a></center><p><strong>不要抛弃猫猫好不好?</strong></p>]]></content>
<summary type="html">
<p>今天一整天都是你的猫猫呢…</p>
<p>想要变成猫,<br>那样就可以被你完全抱住了呢,<br>那样的话就可以在你面前随意蹭蹭了呢,<br>那样的话就可以被你抱着去上学了呢,<br>那样的话就可以和你玩逗猫棒的游戏了呢…<br>
</summary>
<category term="日记" scheme="https://neko.ayaka.moe/categories/%E6%97%A5%E8%AE%B0/"/>
<category term="日记" scheme="https://neko.ayaka.moe/tags/%E6%97%A5%E8%AE%B0/"/>
</entry>
<entry>
<title>网易云音乐 本地API指南</title>
<link href="https://neko.ayaka.moe/2017/10/02/024/"/>
<id>https://neko.ayaka.moe/2017/10/02/024/</id>
<published>2017-10-02T02:15:00.000Z</published>
<updated>2017-10-02T02:15:00.000Z</updated>
<content type="html"><![CDATA[<h1 id="网易云音乐-history-本地API指南"><a href="#网易云音乐-history-本地API指南" class="headerlink" title="网易云音乐 history 本地API指南"></a>网易云音乐 history 本地API指南</h1><p>这是一个在项目代码文件中的迷你文档,用于快速帮助开发者定位history文件的键值,详细的文档可以到GitHub的repo上查看www</p> <a id="more"></a><ul><li>fm 私人FM的fm判定值,true即为此项来自私人FM,不存在即不来自私人FM</li><li>data 不明数据,在不同模式下会有不同值,示例值:34799039,dailyrecommend</li><li>fid 不明数据,fid,在正常播放模式下会有值</li><li>id 私人FM的ID,在非私人FM模式下,此处有一个长ID,字符串</li><li><p>track track列,一个键值列表,其中包含曲目的详细数据</p><ul><li>name 曲目名字</li><li>id 曲目ID</li><li>position 曲目在专辑中的曲目号,同<code>track.no</code></li><li>alias 一个数组,曲目别名</li><li>status 不明数据</li><li>fee 费用,数字</li><li>copyrightId 不明数据,版权ID</li><li>disc 专辑碟号</li><li>no 曲目在专辑中的曲目号,同track.postion</li><li>artists artists数组,一个数组,其中包含了此曲目的作曲家<ul><li>name 艺术家名字</li><li>id 艺术家ID</li><li>picId 艺术家图片ID</li><li>img1v1Id 不明数据,数字,同picId</li><li>briefDesc 不明数据</li><li>picUrl 艺术家图片链接</li><li>img1v1Url 不明数据,链接,同picUrl</li><li>albumSize 不明数据,专辑大小</li><li>alias 不明数据,可作为别名列表</li><li>trans 不明数据</li><li>tns 不明数据</li><li>musicSize 不明数据</li><li>userId 用户ID,网易音乐人ID</li></ul></li><li><p>album album列,一个键值列表,其中包含专辑的信息</p><ul><li>id 专辑ID</li><li>name 专辑名字</li><li>picId 专辑图片ID</li><li>picUrl 专辑图片链接</li><li>alias 不明数据,可作为别名列表</li><li>transNames 别名</li><li>type 类型,一般值为 “专辑”</li><li>size 专辑曲目数量</li><li>blurPicUrl 模糊图片链接,一般值同picUrl</li><li>companyId 专辑发布公司ID</li><li>pic 图片,一个数字,同picId</li><li>publishTime 发布日期(此项值需要转换,示例值:1490716800000)</li><li>description 专辑简介,这个值在客户端无法获取</li><li>tags 标签</li><li>company 专辑发行公司</li><li>breifDesc 不明数据</li><li>artist 专辑艺术家<ul><li>name (初始化值)艺术家名字</li><li>id (初始化值)艺术家ID</li><li>picId (初始化值)艺术家图片ID</li><li>img1v1Id (初始化值)不明数据</li><li>briefDesc (初始化值)不明数据</li><li>picUrl 艺术家图片链接</li><li>img1v1Url 不明数据,一般值同picUrl</li><li>albumSize (初始化值)不明数据,专辑大小</li><li>alias (初始化值)不明数据,可作为别名列表</li><li>trans (初始化值)不明数据</li><li>tns (初始化值)不明数据</li><li>musicSize (初始化值)不明数据</li><li>songs 数组</li></ul></li><li>commentThreadId 评论区ID,字符串</li><li>mvid MV的ID,数字</li><li>cd 专辑碟号,该曲目所在的专辑单碟编号,数字</li><li>starred 喜欢的判定值,判定用户是否喜欢过该曲目</li><li>popularity 热度,数字</li><li>score 分数,数字</li><li>starredNum 不明数据,喜欢的数目</li><li>duration 曲目长度</li><li>playedNum 播放次数</li><li>ringtone 不明数据,客户端均衡器用</li><li>rtUrl 不明数据</li><li>rtUrls 不明数据,数组</li><li>pstatus 不明数据</li><li>fee 费用,数字</li><li>version 版本号,曲目信息版本</li><li>songType 曲目类型</li><li>mst 不明数据</li><li>ftype 不明数据</li><li>yunSong 不明数据</li><li>mp3Url MP3文件链接</li><li>reason 推荐原因,不同于recommendReason,这个仅在每日推荐列表播放下可见</li><li>bMusic 不明数据,一个键值列表,未知品质<ul><li>name 名字</li><li>id 品质ID</li><li>size 文件大小</li><li>extension 文件扩展名</li><li>sr 采样率</li><li>playTime 长度</li><li>dfsId_str 不明数据</li><li>bitrate 比特率,此品质未知</li><li>dfsId 不明数据,数字</li><li>size 文件大小,字节作为单位,byte,数字</li><li>volumeDelta 音量Delta值,浮点型</li></ul></li><li>hMusic 高品质音乐,一个键值列表<ul><li>name 名字</li><li>id 品质ID</li><li>size 文件大小</li><li>extension 文件扩展名</li><li>sr 采样率</li><li>playTime 长度</li><li>dfsId_str 不明数据</li><li>bitrate 比特率,高品质为320000</li><li>dfsId 不明数据,数字</li><li>size 文件大小,字节作为单位,byte,数字</li><li>volumeDelta 音量Delta值,浮点型</li></ul></li><li>mMusic 中品质音乐,一个键值列表<ul><li>name 名字</li><li>id 品质ID</li><li>size 文件大小</li><li>extension 文件扩展名</li><li>sr 采样率</li><li>playTime 长度</li><li>dfsId_str 不明数据</li><li>bitrate 比特率,中品质为160000</li><li>dfsId 不明数据,数字</li><li>size 文件大小,字节作为单位,byte,数字</li><li>volumeDelta 音量Delta值,浮点型</li></ul></li><li>lMusic 低品质音乐,一个键值列表<ul><li>name 名字</li><li>id 品质ID</li><li>size 文件大小</li><li>extension 文件扩展名</li><li>sr 采样率</li><li>playTime 长度</li><li>dfsId_str 不明数据</li><li>bitrate 比特率,低品质为96000</li><li>dfsId 不明数据,数字</li><li>size 文件大小,字节作为单位,byte,数字</li><li>volumeDelta 音量Delta值,浮点型</li></ul></li><li>privilege 权限<ul><li>id ID值,同曲目ID</li><li>version 版本号,测试时获得的值是:0-0-0-999-999-999-320-7-1-1-0</li><li>fee 费用,数字</li><li>payed 已支付次数,数字</li><li>status 不明数据</li><li>maxPlayBr 最大的可播放比特率</li><li>maxDownBr 最大的可下载比特率</li><li>maxSongBr 最大的曲目比特率</li><li>maxFreeBr 最大的免费比特率</li><li>sharePriv 分享权限,数字</li><li>commentPriv 评论权限,数字</li><li>subPriv 不明数据,子权限,数字</li><li>cloudSong 不明数据,云音乐,数字</li><li>toast 不明数据,此处测试时为false</li></ul></li><li>copyFrom 不明数据,字符串</li><li>audition 不明数据,空值</li><li>rtype 不明数据,数字</li><li>rurl 不明数据,空值</li><li>recommendReason 推荐原因,字符串</li><li>alg 不明数据</li><li>commentCount 评论数统计,数字</li><li>copyright 不明数据,版权,数字</li><li>lrcAbstractEnd 不明数据,歌词抽象结束</li><li>lrcAbstractStart 不明数据,歌词抽象开始</li><li>indexId 不明数据,索引ID,数字</li><li>haslyric 是否有歌词的判定值,判定是否有歌词 </li></ul><ul><li>tid 不明数据,同id</li><li>radio 电台,一个键值列表,不太详细的列表<ul><li>dj DJ的名字,此处为null</li><li>category 分类,字符串</li><li>buyed 购买的判定值,这里指的应该是订阅与否</li><li>price 价格,此处无效</li><li>originalPrice 原始价格,此处无效</li><li>discountPrice 打折价格,此处无效</li><li>purchaseCount 购买人数,数字</li><li>lastProgramName 最后更新的节目名字</li><li>videos 视频,此处空值</li><li>finished 不明数据,结束的判断值</li><li>underShelf 不明数据</li><li>picUrl 电台图片链接</li><li>picId 电台图片ID</li><li>categoryId 分类ID</li><li>lastProgramId 最后更新的节目ID</li><li>createTime 创建时间</li><li>feeScope 不明数据</li><li>programCount 项目统计数</li><li>subCount 订阅人数统计</li><li>desc 介绍,字符串</li><li>lastProgramCreateTime 最后更新的节目创建时间</li><li>radioFeeType 电台费用类型</li><li>name 电台名字</li><li>id 电台ID</li><li>subed 订阅的判定值</li></ul></li></ul></li><li>program 节目,一个键值列表,仅在电台条目下可用<ul><li>mainSong 不明数据,主要曲目,一个值,示例值:411421177</li><li>songs 曲目数,空值</li><li>dj DJ,一个键值列表,详细的电台主播信息<ul><li>defaultAvatar 默认头像的判定值</li><li>province 不明数据,省份</li><li>authStatus 认证状态,数字</li><li>followed 关注的判定值</li><li>avatarUrl 头像链接</li><li>accountStatus 账号状态,注销账号的值为30</li><li>gender 性别,女性为2</li><li>city 不明数据,城市,数字</li><li>birthday 出生日期,数字</li><li>userId 用户ID,数字</li><li>userType 用户类型,数字</li><li>nickname 用户名,字符串</li><li>signature 个性签名</li><li>description 自我介绍</li><li>detailDescription 详细的自我介绍</li><li>avatarImgId 头像图片ID,数字</li><li>backgroundImgId 背景图片ID,数字</li><li>backgroundUrl 背景图片链接</li><li>authority 不明数据,许可机构</li><li>mutual 不明数据,判定值</li><li>expertTags 用户徽章,比如音乐达人</li><li>experts 徽章</li><li>djStatus 主播状态</li><li>vipType VIP类型</li><li>remarkName 额外名字</li><li>avatarImgIdStr 头像图片ID,字符串</li><li>backgroundImgIdStr 背景图片ID,字符串</li><li>avatarImgId_str 头像图片ID,字符串</li><li>brand 不明数据</li></ul></li><li>blurCoverUrl 模糊的封面链接</li><li>radio 电台,一个键值列表,简要的信息<ul><li>dj DJ的名字,字符串<ul><li>defaultAvatar 默认头像的判定值</li><li>province 不明数据,省份</li><li>authStatus 认证状态,数字</li><li>followed 关注的判定值</li><li>avatarUrl 头像链接</li><li>accountStatus 账号状态,注销账号的值为30</li><li>gender 性别,女性为2</li><li>city 不明数据,城市,数字</li><li>birthday 出生日期,数字</li><li>userId 用户ID,数字</li><li>userType 用户类型,数字</li><li>nickname 用户名,字符串</li><li>signature 个性签名</li><li>description 自我介绍</li><li>detailDescription 详细的自我介绍</li><li>avatarImgId 头像图片ID,数字</li><li>backgroundImgId 背景图片ID,数字</li><li>backgroundUrl 背景图片链接</li><li>authority 不明数据,许可机构</li><li>mutual 不明数据,判定值</li><li>expertTags 用户徽章,比如音乐达人</li><li>experts 徽章</li><li>djStatus 主播状态</li><li>vipType VIP类型</li><li>remarkName 额外名字</li><li>avatarImgIdStr 头像图片ID,字符串</li><li>backgroundImgIdStr 背景图片ID,字符串</li><li>avatarImgId_str 头像图片ID,字符串</li><li>brand 不明数据</li><li>canReward 打赏的判定值</li><li>rewardCount 打赏数目统计</li></ul></li><li>category 分类,字符串</li><li>buyed 购买的判定值,这里指的应该是订阅与否</li><li>price 价格,此处无效</li><li>originalPrice 原始价格,此处无效</li><li>discountPrice 打折价格,此处无效</li><li>purchaseCount 购买人数,数字</li><li>lastProgramName 最后更新的节目名字</li><li>videos 视频,此处空值</li><li>finished 不明数据,结束的判断值</li><li>underShelf 不明数据</li><li>picUrl 电台图片链接</li><li>picId 电台图片ID</li><li>categoryId 分类ID</li><li>lastProgramId 最后更新的节目ID</li><li>createTime 创建时间</li><li>feeScope 不明数据</li><li>programCount 节目统计数</li><li>subCount 订阅人数统计</li><li>desc 介绍,字符串</li><li>lastProgramCreateTime 最后更新的节目创建时间</li><li>radioFeeType 电台费用类型</li><li>name 电台名字</li><li>id 电台ID</li><li>subed 订阅的判定值</li><li>rcmdtext 不明数据,空值,字符串</li><li>newProgramCount 新的节目数目统计</li><li>rcmdText 不明数据,空值,字符串</li><li>composeVideo 创作视频的判定值</li><li>shareCount 分享次数统计</li><li>likedCount 喜欢次数统计</li><li>commentDatas 评论数据,一个键值列表<ul><li>userProfile 用户资料,一个键值列表<ul><li>defaultAvatar 默认头像的判定值</li><li>province 不明数据,省份</li><li>authStatus 认证状态,数字</li><li>followed 关注的判定值</li><li>avatarUrl 头像链接</li><li>accountStatus 账号状态,注销账号的值为30</li><li>gender 性别,女性为2</li><li>city 不明数据,城市,数字</li><li>birthday 出生日期,数字</li><li>userId 用户ID,数字</li><li>userType 用户类型,数字</li><li>nickname 用户名,字符串</li><li>signature 个性签名</li><li>description 自我介绍</li><li>detailDescription 详细的自我介绍</li><li>avatarImgId 头像图片ID,数字</li><li>backgroundImgId 背景图片ID,数字</li><li>backgroundUrl 背景图片链接</li><li>authority 不明数据,许可机构</li><li>mutual 不明数据,判定值</li><li>expertTags 用户徽章,比如音乐达人</li><li>experts 徽章</li><li>djStatus 主播状态</li><li>vipType VIP类型</li><li>remarkName 额外名字</li><li>avatarImgIdStr 头像图片ID,字符串</li><li>backgroundImgIdStr 背景图片ID,字符串</li></ul></li><li>content 评论内容</li><li>programName 节目名称</li><li>programId 节目ID</li><li>commentId 评论ID</li></ul></li><li>commentCount 评论计数</li></ul></li></ul></li><li>radio 电台,一个键值列表,不太详细的列表<ul><li>dj DJ的名字,此处为null</li><li>category 分类,字符串</li><li>buyed 购买的判定值,这里指的应该是订阅与否</li><li>price 价格,此处无效</li><li>originalPrice 原始价格,此处无效</li><li>discountPrice 打折价格,此处无效</li><li>purchaseCount 购买人数,数字</li><li>lastProgramName 最后更新的节目名字</li><li>videos 视频,此处空值</li><li>finished 不明数据,结束的判断值</li><li>underShelf 不明数据</li><li>picUrl 电台图片链接</li><li>picId 电台图片ID</li><li>categoryId 分类ID</li><li>lastProgramId 最后更新的节目ID</li><li>createTime 创建时间</li><li>feeScope 不明数据</li><li>programCount 项目统计数</li><li>subCount 订阅人数统计</li><li>desc 介绍,字符串</li><li>lastProgramCreateTime 最后更新的节目创建时间</li><li>radioFeeType 电台费用类型</li><li>name 电台名字</li><li>id 电台ID</li><li>subed 订阅的判定值</li><li>href 来源链接,字符串,专辑链接;私人FM播放模式示例值:/m/fm/?fromSource=1</li></ul></li></ul></li><li>text 来源,多种可能性</li><li>nickName 来源作者,比如歌单作者</li><li>userId 作者ID</li><li>startlogtime 不明数据,数字</li><li>loaderr 加载错误的判定值</li><li>playedTime 播放次数,数字</li><li>playType 播放类型</li><li>playBrt 正在播放的比特率</li><li>playFile 本地文件所在位置</li><li>lrctype 歌词类型,online</li><li>lrcid 歌词ID</li><li>qid 不明数据,示例值:4937714_2_493807</li><li>time 时间,数字 </li></ul><h1 id="备注部分"><a href="#备注部分" class="headerlink" title="备注部分"></a>备注部分</h1><h3 id="href的值"><a href="#href的值" class="headerlink" title="href的值"></a>href的值</h3><p>在专辑播放模式下:<code>/m/album/?id=3428149&rid=R_AL_3_3428149&fromSource=1</code><br>在私人FM播放模式下:<code>/m/fm</code><br>在电台播放模式下:<code>/m/djradio/?id=828002&fromSource=1</code><br>在每日推荐模式下:<code>/m/dailysong/?fromSource=1</code><br>在搜索页下:<code>/m/search/?type=1&s=Kaine%20%2F%20Salvation&fromSource=1</code><br>歌单:<code>/m/playlist/?id=894355338&rid=A_PL_0_894355338&fromSource=1</code> </p>]]></content>
<summary type="html">
<h1 id="网易云音乐-history-本地API指南"><a href="#网易云音乐-history-本地API指南" class="headerlink" title="网易云音乐 history 本地API指南"></a>网易云音乐 history 本地API指南</h1><p>这是一个在项目代码文件中的迷你文档,用于快速帮助开发者定位history文件的键值,详细的文档可以到GitHub的repo上查看www</p>
</summary>
<category term="Guide" scheme="https://neko.ayaka.moe/categories/Guide/"/>
<category term="Neko" scheme="https://neko.ayaka.moe/tags/Neko/"/>
<category term="网易云音乐" scheme="https://neko.ayaka.moe/tags/%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90/"/>
<category term="网易云音乐API" scheme="https://neko.ayaka.moe/tags/%E7%BD%91%E6%98%93%E4%BA%91%E9%9F%B3%E4%B9%90API/"/>
<category term="API文档" scheme="https://neko.ayaka.moe/tags/API%E6%96%87%E6%A1%A3/"/>
</entry>
</feed>