中文版本翻译
This commit is contained in:
8676
package-lock.json
generated
8676
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
"debug": "node --inspect-brk node_modules/.bin/rollup -c",
|
||||
"dev": "DEV_PORT=\"${DEV_PORT:=5000}\" run-p watch serve",
|
||||
"watch": "rollup -cw",
|
||||
"serve": "serve --listen=$DEV_PORT --config ../../../serve.json .tmp/build/static",
|
||||
"serve": "serve --listen=5000 --config ../../../serve.json .tmp/build/static",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -20,27 +20,4 @@ async function main() {
|
||||
render(<App />, root);
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
// Analytics
|
||||
{
|
||||
// Determine the current display mode.
|
||||
const displayMode =
|
||||
navigator.standalone ||
|
||||
window.matchMedia('(display-mode: standalone)').matches
|
||||
? 'standalone'
|
||||
: 'browser';
|
||||
|
||||
// Setup analytics
|
||||
window.ga = window.ga || ((...args) => (ga.q = ga.q || []).push(args));
|
||||
ga('create', 'UA-128752250-1', 'auto');
|
||||
ga('set', 'transport', 'beacon');
|
||||
ga('set', 'dimension1', displayMode);
|
||||
ga('send', 'pageview', '/index.html', { title: 'Squoosh' });
|
||||
// Load the GA script without keeping the browser spinner going.
|
||||
addEventListener('load', () => {
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://www.google-analytics.com/analytics.js';
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
main();
|
@ -168,17 +168,17 @@ export default class Options extends Component<Props, State> {
|
||||
<div>
|
||||
<h3 class={style.optionsTitle}>
|
||||
<div class={style.titleAndButtons}>
|
||||
Edit
|
||||
编辑
|
||||
<button
|
||||
class={style.copyOverButton}
|
||||
title="Copy settings to other side"
|
||||
title="另一侧使用同样设置"
|
||||
onClick={this.onCopyToOtherSideClick}
|
||||
>
|
||||
<SwapIcon />
|
||||
</button>
|
||||
<button
|
||||
class={style.saveButton}
|
||||
title="Save side settings"
|
||||
title="保存本侧设置"
|
||||
onClick={this.onSaveSideSettingClick}
|
||||
>
|
||||
<SaveIcon />
|
||||
@ -195,7 +195,7 @@ export default class Options extends Component<Props, State> {
|
||||
? style.buttonOpacity
|
||||
: '')
|
||||
}
|
||||
title="Import saved side settings"
|
||||
title="导入本侧的设置"
|
||||
onClick={this.onImportSideSettingsClick}
|
||||
disabled={
|
||||
// Disabled if this side's settings haven't been saved
|
||||
@ -209,7 +209,7 @@ export default class Options extends Component<Props, State> {
|
||||
</div>
|
||||
</h3>
|
||||
<label class={style.sectionEnabler}>
|
||||
Resize
|
||||
尺寸
|
||||
<Toggle
|
||||
name="resize.enable"
|
||||
checked={!!processorState.resize.enabled}
|
||||
@ -229,7 +229,7 @@ export default class Options extends Component<Props, State> {
|
||||
</Expander>
|
||||
|
||||
<label class={style.sectionEnabler}>
|
||||
Reduce palette
|
||||
色彩
|
||||
<Toggle
|
||||
name="quantize.enable"
|
||||
checked={!!processorState.quantize.enabled}
|
||||
@ -248,7 +248,7 @@ export default class Options extends Component<Props, State> {
|
||||
)}
|
||||
</Expander>
|
||||
|
||||
<h3 class={style.optionsTitle}>Compress</h3>
|
||||
<h3 class={style.optionsTitle}>压缩</h3>
|
||||
|
||||
<section class={`${style.optionOneCell} ${style.optionsSection}`}>
|
||||
{supportedEncoderMap ? (
|
||||
@ -266,7 +266,7 @@ export default class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
) : (
|
||||
<Select large>
|
||||
<option>Loading…</option>
|
||||
<option>加载中...</option>
|
||||
</Select>
|
||||
)}
|
||||
</section>
|
||||
|
@ -123,7 +123,7 @@ export default class Results extends Component<Props, State> {
|
||||
class={showLoadingState ? style.downloadDisable : style.download}
|
||||
href={downloadUrl}
|
||||
download={imageFile ? imageFile.name : ''}
|
||||
title="Download"
|
||||
title="下载图片"
|
||||
onClick={this.onDownload}
|
||||
>
|
||||
<svg class={style.downloadBlobs} viewBox="0 0 89.6 86.9">
|
||||
|
@ -187,7 +187,7 @@ export class Options extends Component<Props, State> {
|
||||
value={quality}
|
||||
onInput={this._inputChange('quality', 'number')}
|
||||
>
|
||||
Quality:
|
||||
质量:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
@ -197,7 +197,7 @@ export class Options extends Component<Props, State> {
|
||||
checked={showAdvanced}
|
||||
onChange={linkState(this, 'showAdvanced')}
|
||||
/>
|
||||
Advanced settings
|
||||
高级设置
|
||||
</label>
|
||||
<Expander>
|
||||
{showAdvanced && (
|
||||
@ -235,7 +235,7 @@ export class Options extends Component<Props, State> {
|
||||
'number',
|
||||
)}
|
||||
>
|
||||
Alpha quality:
|
||||
Alpha 质量:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
@ -311,7 +311,7 @@ export class Options extends Component<Props, State> {
|
||||
value={effort}
|
||||
onInput={this._inputChange('effort', 'number')}
|
||||
>
|
||||
Effort:
|
||||
效果:
|
||||
</Range>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -114,7 +114,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.quality}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Quality:
|
||||
质量:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionReveal}>
|
||||
@ -122,13 +122,13 @@ export class Options extends Component<Props, State> {
|
||||
checked={showAdvanced}
|
||||
onChange={linkState(this, 'showAdvanced')}
|
||||
/>
|
||||
Advanced settings
|
||||
高级设置
|
||||
</label>
|
||||
<Expander>
|
||||
{showAdvanced ? (
|
||||
<div>
|
||||
<label class={style.optionTextFirst}>
|
||||
Channels:
|
||||
通道:
|
||||
<Select
|
||||
name="color_space"
|
||||
value={options.color_space}
|
||||
@ -143,7 +143,7 @@ export class Options extends Component<Props, State> {
|
||||
{options.color_space === MozJpegColorSpace.YCbCr ? (
|
||||
<div>
|
||||
<label class={style.optionToggle}>
|
||||
Auto subsample chroma
|
||||
自动色度子采样
|
||||
<Checkbox
|
||||
name="auto_subsample"
|
||||
checked={options.auto_subsample}
|
||||
@ -160,13 +160,13 @@ export class Options extends Component<Props, State> {
|
||||
value={options.chroma_subsample}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Subsample chroma by:
|
||||
色度进行子采样依据:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Separate chroma quality
|
||||
独立色度质量
|
||||
<Checkbox
|
||||
name="separate_chroma_quality"
|
||||
checked={options.separate_chroma_quality}
|
||||
@ -183,7 +183,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.chroma_quality}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Chroma quality:
|
||||
独立色度质量选项:
|
||||
</Range>
|
||||
</div>
|
||||
) : null}
|
||||
@ -192,7 +192,7 @@ export class Options extends Component<Props, State> {
|
||||
) : null}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Pointless spec compliance
|
||||
遵循协议规范
|
||||
<Checkbox
|
||||
name="baseline"
|
||||
checked={options.baseline}
|
||||
@ -202,7 +202,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{options.baseline ? null : (
|
||||
<label class={style.optionToggle}>
|
||||
Progressive rendering
|
||||
渐进式渲染
|
||||
<Checkbox
|
||||
name="progressive"
|
||||
checked={options.progressive}
|
||||
@ -214,7 +214,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{options.baseline ? (
|
||||
<label class={style.optionToggle}>
|
||||
Optimize Huffman table
|
||||
优化 Huffman 表
|
||||
<Checkbox
|
||||
name="optimize_coding"
|
||||
checked={options.optimize_coding}
|
||||
@ -231,11 +231,11 @@ export class Options extends Component<Props, State> {
|
||||
value={options.smoothing}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Smoothing:
|
||||
平滑:
|
||||
</Range>
|
||||
</div>
|
||||
<label class={style.optionTextFirst}>
|
||||
Quantization:
|
||||
量化:
|
||||
<Select
|
||||
name="quant_table"
|
||||
value={options.quant_table}
|
||||
@ -253,7 +253,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionToggle}>
|
||||
Trellis multipass
|
||||
Trellis multipass 算法
|
||||
<Checkbox
|
||||
name="trellis_multipass"
|
||||
checked={options.trellis_multipass}
|
||||
@ -263,7 +263,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{options.trellis_multipass ? (
|
||||
<label class={style.optionToggle}>
|
||||
Optimize zero block runs
|
||||
优化零块数量
|
||||
<Checkbox
|
||||
name="trellis_opt_zero"
|
||||
checked={options.trellis_opt_zero}
|
||||
@ -273,7 +273,7 @@ export class Options extends Component<Props, State> {
|
||||
) : null}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Optimize after trellis quantization
|
||||
优化后量化处理
|
||||
<Checkbox
|
||||
name="trellis_opt_table"
|
||||
checked={options.trellis_opt_table}
|
||||
@ -288,7 +288,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.trellis_loops}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Trellis quantization passes:
|
||||
Trellis 量化 Passes:
|
||||
</Range>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -53,13 +53,13 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{extendedSettings ? (
|
||||
<label class={style.optionTextFirst}>
|
||||
Type:
|
||||
类型:
|
||||
<Select
|
||||
name="zx"
|
||||
value={'' + options.zx}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<option value="0">Standard</option>
|
||||
<option value="0">标准</option>
|
||||
<option value="1">ZX</option>
|
||||
</Select>
|
||||
</label>
|
||||
@ -75,7 +75,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.maxNumColors}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Colors:
|
||||
颜色:
|
||||
</Range>
|
||||
</div>
|
||||
)}
|
||||
@ -89,7 +89,7 @@ export class Options extends Component<Props, State> {
|
||||
value={options.dither}
|
||||
onInput={this.onChange}
|
||||
>
|
||||
Dithering:
|
||||
抖动:
|
||||
</Range>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -232,7 +232,7 @@ export class Options extends Component<Props, State> {
|
||||
onSubmit={preventDefault}
|
||||
>
|
||||
<label class={style.optionTextFirst}>
|
||||
Method:
|
||||
算法:
|
||||
<Select
|
||||
name="resizeMethod"
|
||||
value={options.method}
|
||||
@ -251,7 +251,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionTextFirst}>
|
||||
Preset:
|
||||
比例:
|
||||
<Select value={this.getPreset()} onChange={this.onPresetChange}>
|
||||
{sizePresets.map((preset) => (
|
||||
<option value={preset}>{preset * 100}%</option>
|
||||
@ -260,7 +260,7 @@ export class Options extends Component<Props, State> {
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionTextFirst}>
|
||||
Width:
|
||||
宽度:
|
||||
<input
|
||||
required
|
||||
class={style.textField}
|
||||
@ -272,7 +272,7 @@ export class Options extends Component<Props, State> {
|
||||
/>
|
||||
</label>
|
||||
<label class={style.optionTextFirst}>
|
||||
Height:
|
||||
高度:
|
||||
<input
|
||||
required
|
||||
class={style.textField}
|
||||
@ -286,7 +286,7 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{isWorkerOptions(options) ? (
|
||||
<label class={style.optionToggle}>
|
||||
Premultiply alpha channel
|
||||
Aplha 通道预乘
|
||||
<Checkbox
|
||||
name="premultiply"
|
||||
checked={options.premultiply}
|
||||
@ -296,7 +296,7 @@ export class Options extends Component<Props, State> {
|
||||
) : null}
|
||||
{isWorkerOptions(options) ? (
|
||||
<label class={style.optionToggle}>
|
||||
Linear RGB
|
||||
使用线性 RGB
|
||||
<Checkbox
|
||||
name="linearRGB"
|
||||
checked={options.linearRGB}
|
||||
@ -306,7 +306,7 @@ export class Options extends Component<Props, State> {
|
||||
) : null}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Maintain aspect ratio
|
||||
保持宽高比
|
||||
<Checkbox
|
||||
name="maintainAspect"
|
||||
checked={maintainAspect}
|
||||
@ -316,14 +316,14 @@ export class Options extends Component<Props, State> {
|
||||
<Expander>
|
||||
{maintainAspect ? null : (
|
||||
<label class={style.optionTextFirst}>
|
||||
Fit method:
|
||||
填充效果:
|
||||
<Select
|
||||
name="fitMethod"
|
||||
value={options.fitMethod}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<option value="stretch">Stretch</option>
|
||||
<option value="contain">Contain</option>
|
||||
<option value="stretch">拉伸</option>
|
||||
<option value="contain">填充</option>
|
||||
</Select>
|
||||
</label>
|
||||
)}
|
||||
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 26 KiB |
@ -3,7 +3,6 @@ import { h, Component } from 'preact';
|
||||
import { linkRef } from 'shared/prerendered-app/util';
|
||||
import '../../custom-els/loading-spinner';
|
||||
import logo from 'url:./imgs/logo.svg';
|
||||
import githubLogo from 'url:./imgs/github-logo.svg';
|
||||
import largePhoto from 'url:./imgs/demos/demo-large-photo.jpg';
|
||||
import artwork from 'url:./imgs/demos/demo-artwork.jpg';
|
||||
import deviceScreen from 'url:./imgs/demos/demo-device-screen.png';
|
||||
@ -207,14 +206,14 @@ export default class Intro extends Component<Props, State> {
|
||||
try {
|
||||
clipboardItems = await navigator.clipboard.read();
|
||||
} catch (err) {
|
||||
this.props.showSnack!(`No permission to access clipboard`);
|
||||
this.props.showSnack!(`没有剪贴板访问权限`);
|
||||
return;
|
||||
}
|
||||
|
||||
const blob = await getImageClipboardItem(clipboardItems);
|
||||
|
||||
if (!blob) {
|
||||
this.props.showSnack!(`No image found in the clipboard`);
|
||||
this.props.showSnack!(`剪贴板中没有找到图片`);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -244,7 +243,7 @@ export default class Intro extends Component<Props, State> {
|
||||
<img
|
||||
class={style.logo}
|
||||
src={logoWithText}
|
||||
alt="Squoosh"
|
||||
alt="图压宝"
|
||||
width="539"
|
||||
height="162"
|
||||
/>
|
||||
@ -285,13 +284,13 @@ export default class Intro extends Component<Props, State> {
|
||||
</svg>
|
||||
</button>
|
||||
<div>
|
||||
<span class={style.dropText}>Drop </span>OR{' '}
|
||||
<span class={style.dropText}>拖拽 </span>或者{' '}
|
||||
{supportsClipboardAPI ? (
|
||||
<button class={style.pasteBtn} onClick={this.onPasteClick}>
|
||||
Paste
|
||||
粘贴图片到此
|
||||
</button>
|
||||
) : (
|
||||
'Paste'
|
||||
'粘贴图片到此'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -310,7 +309,7 @@ export default class Intro extends Component<Props, State> {
|
||||
</svg>
|
||||
<div class={style.contentPadding}>
|
||||
<p class={style.demoTitle}>
|
||||
Or <strong>try one</strong> of these:
|
||||
<strong>尝试 </strong>如下图片的压缩效果:
|
||||
</p>
|
||||
<ul class={style.demos}>
|
||||
{demos.map((demo, i) => (
|
||||
@ -355,10 +354,9 @@ export default class Intro extends Component<Props, State> {
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Small</h2>
|
||||
<h2 class={style.infoTitle}>体积更小</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Smaller images mean faster load times. Squoosh can reduce
|
||||
file size and maintain high quality.
|
||||
在保证图片清晰的前提下减小体积,提升加载速度
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
@ -380,11 +378,9 @@ export default class Intro extends Component<Props, State> {
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Simple</h2>
|
||||
<h2 class={style.infoTitle}>简单</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Open your image, inspect the differences, then save
|
||||
instantly. Feeling adventurous? Adjust the settings for even
|
||||
smaller files.
|
||||
打开图片,比较压缩前后差异,下载新图片,就这么简单!
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
@ -406,10 +402,9 @@ export default class Intro extends Component<Props, State> {
|
||||
<SlideOnScroll>
|
||||
<div class={style.infoContent}>
|
||||
<div class={style.infoTextWrapper}>
|
||||
<h2 class={style.infoTitle}>Secure</h2>
|
||||
<h2 class={style.infoTitle}>安全</h2>
|
||||
<p class={style.infoCaption}>
|
||||
Worried about privacy? Images never leave your device since
|
||||
Squoosh does all the work locally.
|
||||
您可以将此网页作为应用安装,您的图片仅在本地处理,不会上传到服务器。
|
||||
</p>
|
||||
</div>
|
||||
<div class={style.infoImgWrapper}>
|
||||
@ -438,16 +433,9 @@ export default class Intro extends Component<Props, State> {
|
||||
<footer class={style.footerItems}>
|
||||
<a
|
||||
class={style.footerLink}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh/blob/dev/README.md#privacy"
|
||||
href="#"
|
||||
>
|
||||
Privacy
|
||||
</a>
|
||||
<a
|
||||
class={style.footerLinkWithLogo}
|
||||
href="https://github.com/GoogleChromeLabs/squoosh"
|
||||
>
|
||||
<img src={githubLogo} alt="" width="10" height="10" />
|
||||
Source on Github
|
||||
隐私政策
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
@ -455,7 +443,7 @@ export default class Intro extends Component<Props, State> {
|
||||
</footer>
|
||||
{beforeInstallEvent && (
|
||||
<button class={style.installBtn} onClick={this.onInstallClick}>
|
||||
Install
|
||||
作为应用安装
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
@ -55,8 +55,8 @@ interface Output {
|
||||
const toOutput: Output = {
|
||||
'index.html': renderPage(<IndexPage />),
|
||||
'manifest.json': JSON.stringify({
|
||||
name: 'Squoosh',
|
||||
short_name: 'Squoosh',
|
||||
name: '图压宝',
|
||||
short_name: '图压宝',
|
||||
start_url: '/?utm_medium=PWA&utm_source=launcher',
|
||||
display: 'standalone',
|
||||
orientation: 'any',
|
||||
|
@ -27,14 +27,14 @@ interface Props {}
|
||||
const Index: FunctionalComponent<Props> = () => (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Squoosh</title>
|
||||
<title>图压宝</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Squoosh is the ultimate image optimizer that allows you to compress and compare images with different codecs in your browser."
|
||||
content="图压宝 is the ultimate image optimizer that allows you to compress and compare images with different codecs in your browser."
|
||||
/>
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@SquooshApp" />
|
||||
<meta property="og:title" content="Squoosh" />
|
||||
<meta name="twitter:site" content="@图压宝" />
|
||||
<meta property="og:title" content="图压宝" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content={`${siteOrigin}${ogImage}`} />
|
||||
<meta
|
||||
@ -50,7 +50,7 @@ const Index: FunctionalComponent<Props> = () => (
|
||||
/>
|
||||
<meta
|
||||
name="og:description"
|
||||
content="Squoosh is the ultimate image optimizer that allows you to compress and compare images with different codecs in your browser."
|
||||
content="图压宝 is the ultimate image optimizer that allows you to compress and compare images with different codecs in your browser."
|
||||
/>
|
||||
<meta
|
||||
name="viewport"
|
||||
|
Reference in New Issue
Block a user