有没有"fast"方法可以获取有关可变 Google 字体的信息?



我正在构建一个UI作为产品的一部分,使其易于选择,选择和样式谷歌字体。我受到可变字体的挑战,因为我找不到一个好的方法来获取这些信息。开发者API通过一个大的JSON字符串为所有Google字体提供元数据。然而,它似乎不包含任何数据,使开发人员能够辨别哪些字体是可变的。它们看起来都是标准字体。

是否有一种快速的方法来获得这样的数据?通过快速,我说的是类似于谷歌字体的开发者API,但有各种可变字体的数据,包括:

  • 哪些字体是可变的?
  • 变量字体与哪个轴一起发货?

目前,我所看到的唯一推荐的探索可变字体及其坐标轴的方法是将字体加载到网页中,并使用开发人员工具中的Firefox字体编辑器手动获取数据。但目前谷歌字体中有112种可变字体,收集这些信息可能需要几天的时间。我的问题是:是否有一个更快的方法来获得元数据的可变字体在谷歌字体?

我正在做一个字体选择器插件,我遇到了一个类似的问题,所以我开始调查谷歌字体主要分发网站,直到我找到了我要找的。Google的字体站点执行对以下API端点的调用。

https://fonts.google.com/metadata/fonts

返回以下文本文件。

)]}'{"axisRegistry": [
{
"tag": "FILL",
"displayName": "Fill",
"min": 0.0,
"defaultValue": 0.0,
"max": 1.0,
"precision": -2,
"description": "The Fill axis is intended to provide a treatment of the design that fills in transparent forms with opaque ones (and sometimes interior opaque forms become transparent, to maintain contrasting shapes). Transitions often occur from the center, a side, or a corner, but can be in any direction. This can be useful in animation or interaction to convey a state transition. The numbers indicate proportion filled, from 0 (no treatment) to 1 (completely filled).",
"fallbacks": [
{
"name": "Normal",
"value": 0.0
},
{
"name": "Filled",
"value": 1.0
}
]
} ...],"familyMetadataList": [{
"family": "Alegreya",
"displayName": null,
"category": "Serif",
"size": 425570,
"subsets": [
"menu",
"cyrillic",
"cyrillic-ext",
"greek",
"greek-ext",
"latin",
"latin-ext",
"vietnamese"
],
"fonts": {
"400": {
"thickness": 4,
"slant": 1,
"width": 6,
"lineHeight": 1.361
},
"400i": {
"thickness": 4,
"slant": 4,
"width": 6,
"lineHeight": 1.361
},
"500": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"500i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"600": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"600i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"700": {
"thickness": 7,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"700i": {
"thickness": 6,
"slant": 4,
"width": 6,
"lineHeight": 1.361
},
"800": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"800i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"900": {
"thickness": 8,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"900i": {
"thickness": 8,
"slant": 4,
"width": 6,
"lineHeight": 1.361
}
},
"axes": [
{
"tag": "wght",
"min": 400.0,
"max": 900.0,
"defaultValue": 400.0
}
],
"unsupportedAxes": [],
"designers": [
"Juan Pablo del Peral",
"Huerta Tipográfica"
],
"lastModified": "2021-02-11",
"dateAdded": "2011-12-19",
"popularity": 159,
"trending": 828,
"defaultSort": 164,
"androidFragment": null,
"isNoto": false
}...],...}

请注意,虽然上面看起来像一个JSON文件,但它将被视为一个文本文件,所以你必须从文本文件的顶部删除这部分)]}',这样你就可以把它解析为一个JSON文件。唯一重要的顶级属性(就您的用例而言)是familyMetadataList"属性,顾名思义,它包含所有字体元数据,其中包括任何给定字体所具有的轴。您必须循环使用familyMetadataList"Prop并查看字体的axes成员是否有一个非空数组,从那里我们可以推断出它是一个变量字体。您可以做如下简单的操作来确定哪种字体是可变的。

const variableFonts=[];
const googleFontJSON = {
"familyMetadataList": [
{
"family": "Alegreya",
"displayName": null,
"category": "Serif",
"size": 425570,
"subsets": [
"menu",
"cyrillic",
"cyrillic-ext",
"greek",
"greek-ext",
"latin",
"latin-ext",
"vietnamese"
],
"fonts": {
"400": {
"thickness": 4,
"slant": 1,
"width": 6,
"lineHeight": 1.361
},
"400i": {
"thickness": 4,
"slant": 4,
"width": 6,
"lineHeight": 1.361
},
"500": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"500i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"600": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"600i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"700": {
"thickness": 7,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"700i": {
"thickness": 6,
"slant": 4,
"width": 6,
"lineHeight": 1.361
},
"800": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"800i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"900": {
"thickness": 8,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"900i": {
"thickness": 8,
"slant": 4,
"width": 6,
"lineHeight": 1.361
}
},
"axes": [
{
"tag": "wght",
"min": 400.0,
"max": 900.0,
"defaultValue": 400.0
}
],
"unsupportedAxes": [],
"designers": [
"Juan Pablo del Peral",
"Huerta Tipográfica"
],
"lastModified": "2021-02-11",
"dateAdded": "2011-12-19",
"popularity": 159,
"trending": 828,
"defaultSort": 164,
"androidFragment": null,
"isNoto": false
},
{
"family": "Alegreya SC",
"displayName": null,
"category": "Serif",
"size": 381295,
"subsets": [
"menu",
"cyrillic",
"cyrillic-ext",
"greek",
"greek-ext",
"latin",
"latin-ext",
"vietnamese"
],
"fonts": {
"400": {
"thickness": 4,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"400i": {
"thickness": 4,
"slant": 4,
"width": 7,
"lineHeight": 1.361
},
"500": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"500i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"700": {
"thickness": 6,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"700i": {
"thickness": 6,
"slant": 3,
"width": 7,
"lineHeight": 1.361
},
"800": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"800i": {
"thickness": null,
"slant": null,
"width": null,
"lineHeight": 1.361
},
"900": {
"thickness": 8,
"slant": 1,
"width": 7,
"lineHeight": 1.361
},
"900i": {
"thickness": 8,
"slant": 3,
"width": 7,
"lineHeight": 1.361
}
},
"axes": [],
"unsupportedAxes": [],
"designers": [
"Juan Pablo del Peral",
"Huerta Tipográfica"
],
"lastModified": "2021-03-24",
"dateAdded": "2011-12-19",
"popularity": 436,
"trending": 249,
"defaultSort": 443,
"androidFragment": null,
"isNoto": false
}
]}; // The array of font meta data
googleFontJSON.familyMetadataList.forEach(font => {     
if (font.axes.length) {
font.isVariable=true;
} else {
font.isVariable=false;
}
});
console.log(googleFontJSON);

如何分析数据当然完全是你自己的特权。祝你的项目顺利,史蒂文先生。您还可以通过在https://fonts.google.com/metadata/fonts上找到的轴注册表prop找到的JSON文件获得关于任何给定变量字体轴步骤的更多信息。只需检查精密支柱。例如,步长为0.1的轴,如"opsz"one_answers";wdth"将它们的精度设置为-1,轴的步长为0.01,如"CASL"one_answers";MONO"将它们的精度设置为-2。

"axisRegistry": [
{
"tag": "opsz",
"displayName": "Optical size",
"min": 6.0,
"defaultValue": 14.0,
"max": 144.0,
"precision": -1, //<=== Here
"description": "Adapt the ...",
"fallbacks": [
{
"name": "6pt",
"value": 6.0
},
{
"name": "7pt",
"value": 7.0
}...
]
},...

我喜欢Stranger1586的答案。但我还需要每个轴的步骤数据,以便正确构建滑块等UI元素。所以我决定写一个scraper来从https://fonts.google.com/variablefonts中抓取数据。该页面包含所有可变字体和所有支持轴的更新数据,根据谷歌字体的GitHub页面。

scraper为每个字体族创建一个包含轴数据的JSON文件。我希望这对有同样需要的人有所帮助。下面是代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.firefox.options import Options
from bs4 import BeautifulSoup
import json
def get_variable_fonts_data():
print('Opening: Google Variable Fonts page...')
options = Options()
options.headless = True
gecko_path = r'D:Anaconda3envspy37Libsite-packageshelium_implwebdriverswindowsgeckodriver.exe'
url = 'https://fonts.google.com/variablefonts'
browser = webdriver.Firefox(options=options, executable_path=gecko_path)
browser.get(url)
timeout = 10  # seconds
# Wait for the table element as it is not part of the page source but is generated with JavaScript
try:
WebDriverWait(browser, timeout).until(EC.presence_of_element_located((By.TAG_NAME, 'table')))
print('Generating font table')
except TimeoutException:
print("Loading took too much time!")
soup = BeautifulSoup(browser.page_source, 'html.parser')
table = soup.find('table')
table_head = table.find('thead').find('tr')
header_values = []
for cell in table_head.find_all('th'):
header_values.append(cell.encode_contents().decode("utf-8").strip())
table_body = table.find('tbody')
variable_fonts_data = {}
for row in table_body.find_all('tr'):
axis_data = {}
cells = row.find_all('td')
font_family_name = cells[0].find('a').encode_contents().decode("utf-8").strip()
if not (font_family_name in variable_fonts_data):
variable_fonts_data[font_family_name] = {'Axes': {}}
axis_data[header_values[2]] = cells[2].encode_contents().decode("utf-8").strip()  # Default
axis_data[header_values[3]] = cells[3].encode_contents().decode("utf-8").strip()  # Min
axis_data[header_values[4]] = cells[4].encode_contents().decode("utf-8").strip()  # Max
axis_data[header_values[5]] = cells[5].encode_contents().decode("utf-8").strip()  # Step
variable_fonts_data[font_family_name]['Axes'][cells[1].encode_contents().decode("utf-8").strip()] = axis_data
return variable_fonts_data

with open('google_variable_fonts.json', 'w') as fonts_file:
json.dump(get_variable_fonts_data(), fonts_file) 

最新更新