Poetry-share」是基于「Modern-poetry」开发的「一言 - 中国现代诗」分享平台

网站介绍

Poetry-share 电脑版界面

Poetry-share 的总体设计风格较为简单,采用类似一言的一句话形式。只不过把一句话换成了 Modern-poetry 的现代诗内容。

网站功能主要由四部分组成:

  • 随机更换背景
  • 随机显示一句诗
  • 定时更换诗歌内容
  • 下载网站作为背景图

下文的内容主要讲如何实现这几个功能。

更换背景

网站的背景存储在网站 images 目录下,一共有十张图,命名从 1-10。所以生成一个 1 - 10 的随机数就可以获取到相应的图片。因为比较简单所以就直接贴代码了:

function setBackground(){
	var random = Math.ceil(Math.random()*10);
	document.body.style.background = "url('https://cdn.jsdelivr.net/gh/qyxtim/poetry-share@master/images/" + random + ".jfif') no-repeat"
}

setBackground();

请求 Modern-poetry 仓库内容

Modern-poetry 目录结构

下一步就是获取现代诗数据。我们可以看到 Modern Poetry 的仓库的目录是如上图所示。每个目录里面都有对应国家的诗。 Poetry-share 采用的主要是中国现代诗的数据内容,数据存放在 China-modern-poetry/contemporary 目录下,目录里的内容如下图所示:

中国现代诗内容

我们可以通过 Github 本身提供的 raw 链接来访问这些 Json 数据,但是因为国内网络缘故,网站采用了由 jsdelivr 提供的 CDN 服务进行 Json 数据的访问。如果你不清楚 jsdelivr 是什么,可以参考这篇文章👈

讲完了在仓库中的位置以及链接,接下来就是如何使用。Poetry-share 利用了 Ajax 请求 Json 数据,从而完成一言的显示,代码如下:

function getPoetry(){
	var list = new Array("0-49","50-99","100-149","150-199","200-249","250-299","300-349","400-449","450-499","500-518")
	var random = Math.ceil(Math.random() * list.length) - 1;
	return list[random];
}
function getJsonLength(jsonData){
    var jsonLength = 0;
    for(var item in jsonData){
       jsonLength++;
    }
    return jsonLength;
}
function loadPoem () {
	var url = "https://cdn.jsdelivr.net/gh/qyxtim/modern-poetry@1.0/China-modern-poetry/contemporary/" + getPoetry() + ".json";
	var xhr = new XMLHttpRequest();
	xhr.open("GET",url,true); //到这一步就已经获取到了 Json 数据了
	xhr.onload = function (){
		if(this.status == 200) {
			var poem = JSON.parse(this.responseText);
			var length = getJsonLength(poem);
			var random = Math.ceil(Math.random() * length);
			var outPut = '';
			outPut += `—— ${poem[random].author} 《${poem[random].title}》`; // 提取诗人名字以及诗标题
			document.getElementById("description").innerHTML = outPut;
			var para = poem[random].paragraphs;
			random = Math.ceil(Math.random() * para.length) - 1;
			text = para[random];
			if (text.charAt(text.length - 1) == ","){
				text = text.substring(0,text.length - 1);
			}
			outPut = `「${text}」`; //提取诗歌内容
			document.getElementById("poem").innerHTML = outPut;
		}
	}
	xhr.send();
}    

具体在请求后如何操作数据也已经写在代码里面了,Json 文件具体的数据结构如下:

[{
	"author":"author-name",
	"title":"poem-title",
	"paragraphs":[
	"sentence-1","sentence-2"
	],
	"id":""
}
]

定时更换诗歌内容

定时调用就需要把获取诗歌内容的函数封装起来,并且加入一个休眠函数。这里为了切换诗歌时的美观效果,我引入了 animate.css;如果你不希望加入动画,可以删掉 getAnimate 函数以及有关部分。

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
function getAnimate(){
	list = ['pulse','swing','tada','bounce'];
	var random = Math.ceil(Math.random() * 4) - 1;
	return list[random];
}
async function poem() {
  while(1){
	loadPoem();
	var disp = document.getElementById('intro');
	disp.classList.add('animated');
	anima = getAnimate();
	disp.classList.add(anima);
	await sleep(2000);
	disp.classList.remove(anima);
	await sleep(13000);
  }
}

下载网站作为背景图

下载网站作为背景图主要是如下思路:

  • 获取背景图,将它绘制到 canvas 中
  • 获取诗内容和作者,绘制到 canvas 中
  • 保存 canvas 为 png 图片
function saveFile(data, filename) {
    const save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
    save_link.href = data;
    save_link.download = filename;
    const event = document.createEvent('MouseEvents');
    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    save_link.dispatchEvent(event);
}
function getPicture(){
	var text = document.getElementById("poem").innerText;
	var summary = document.getElementById("description").innerText;
	
	var c = document.createElement("CANVAS");
	c.width = window.screen.width;
	c.height = window.screen.height;
	var context = c.getContext("2d");
	var bg = new Image();
	bg_src = document.body.style['background-image'];
	bg_src = bg_src.substring(bg_src.indexOf('http'), bg_src.length - 2);
	bg.setAttribute("crossOrigin",'Anonymous');
	bg.src = bg_src;
	bg.onload = function () {
		context.drawImage(bg,0,0);
		context.font = "58px bold";
		context.fillStyle = "#fff";
		context.textAlign = "center";
		context.textBaseline = "middle";
		context.fillText(text, 0.5*window.screen.width, 0.5 * window.screen.height - 10);
		context.font = "29px bold";
		context.fillText(summary, 0.5*window.screen.width, 0.5 * window.screen.height + 40);
		saveFile(c.toDataURL("image/png"), "background.png")			
	}
};

现存问题

手机上保存如果字过长会导致诗歌内容不全,正在想办法解决……

现已解决,手机上也可以下载下来作为壁纸咯!【但是会存在处理缓慢的问题,因为在绘制canvas】


完成以上这些,你也可以搭建自己的一言了!