mirror of
https://github.com/tengge1/ShadowEditor.git
synced 2026-01-25 15:08:11 +00:00
添加三维文字。
This commit is contained in:
parent
e2f860e62f
commit
8ceb5857fd
10
README.md
10
README.md
@ -21,6 +21,7 @@ Supported Languages: 中文 / [繁體中文](README-tw.md) / [English](README-en
|
||||
4. `Web.config`中增加`.json`的`MIME-Type`,避免去掉`.*`和`.`的`MIME-Type`后,由于部分iis缺少`.json`的`MIME-Type`导致整个后端报500错误。
|
||||
5. 禁用资源、上传、备份目录的执行权限。
|
||||
6. 修复添加不缩放文字,点击关闭按钮无法关闭窗口的bug。
|
||||
7. 添加三维文字。(支持英文、汉字)
|
||||
|
||||
## v0.4.0更新【[更新日志](docs-dev/update/UpdateLog.md)】
|
||||
|
||||
@ -106,14 +107,7 @@ net start MongoDB
|
||||
|
||||
注意:发布网站部署,Web目录外面需要多加一层文件夹,用于存放日志、数据库备份等不能公开的资源。
|
||||
|
||||
6. 为了保存各种类型文件能正常下载,会在iis上添加以下两个MIME类型,正式部署请注意安全。
|
||||
|
||||
| 文件扩展名 | MIME类型 | 说明 |
|
||||
| --------- | -------- | ---- |
|
||||
| .* | application/octet-stream | 各种格式后缀文件 |
|
||||
| . | application/octet-stream | 无后缀文件 |
|
||||
|
||||
7. 编译文档,请安装gitbook。
|
||||
6. 编译文档,请安装gitbook。
|
||||
|
||||
```bash
|
||||
npm install -g gitbook-cli
|
||||
|
||||
@ -427,7 +427,7 @@
|
||||
"Label": "标签",
|
||||
"Darker": "变暗",
|
||||
"DefaultCamera": "默认相机",
|
||||
"Sone Words": "一些文字",
|
||||
"Some Words": "一些文字",
|
||||
"Body": "身体",
|
||||
"Pie Chart": "饼状图",
|
||||
"Gamma Input": "γ输入",
|
||||
@ -974,7 +974,7 @@
|
||||
".ttc to .ttf": ".ttc转.ttf",
|
||||
"Convert successfully!": "转换成功!",
|
||||
"Unscaled Text": "不缩放文字",
|
||||
"3D Text": "3D文字",
|
||||
"3D Text": "三维文字",
|
||||
"Basic Geometry": "基本几何体",
|
||||
"Curve": "曲线",
|
||||
"Mark": "标注",
|
||||
@ -988,6 +988,5 @@
|
||||
"Only font file (.ttf) is allowed to upload.": "只允许上传字体文件(.ttf)。",
|
||||
"The file is already existed.": "文件已经存在。",
|
||||
"Create Time": "创建时间",
|
||||
"Pleast upload typeface first.": "请先上传字体。",
|
||||
"Message": "消息"
|
||||
"Pleast upload typeface first.": "请先上传字体。"
|
||||
}
|
||||
@ -207,7 +207,7 @@ class ObjectMenu extends React.Component {
|
||||
handleAddUnscaledText() {
|
||||
app.prompt({
|
||||
title: _t('Please input'),
|
||||
value: _t('Sone Words'),
|
||||
value: _t('Some Words'),
|
||||
onOK: (value) => {
|
||||
app.editor.execute(new AddObjectCommand(new UnscaledText(value)));
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import './css/Add3DTextWindow.css';
|
||||
import { Window, Content, Buttons, Form, FormControl, Label, Input, Button, CheckBox, Select } from '../../../third_party';
|
||||
import ThreeDText from '../../../object/text/ThreeDText';
|
||||
import AddObjectCommand from '../../../command/AddObjectCommand';
|
||||
import TypefaceUtils from '../../../utils/TypefaceUtils';
|
||||
|
||||
/**
|
||||
* 添加3D文字窗口
|
||||
@ -17,11 +18,11 @@ class Add3DTextWindow extends React.Component {
|
||||
text: _t('Some Words'),
|
||||
fonts: {}, // 所有字体
|
||||
font: '', // 字体
|
||||
size: 20, // 尺寸
|
||||
height: 24, // 厚度
|
||||
size: 16, // 尺寸
|
||||
height: 4, // 厚度
|
||||
bevelEnabled: true, // 倒角
|
||||
bevelSize: 2, // 倒角尺寸
|
||||
bevelThickness: 2 // 倒角厚度
|
||||
bevelSize: 0.5, // 倒角尺寸
|
||||
bevelThickness: 0.5 // 倒角厚度
|
||||
};
|
||||
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
@ -131,7 +132,8 @@ class Add3DTextWindow extends React.Component {
|
||||
});
|
||||
|
||||
this.setState({
|
||||
fonts
|
||||
fonts,
|
||||
font: this.fonts[0].ID
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -146,14 +148,28 @@ class Add3DTextWindow extends React.Component {
|
||||
handleSave() {
|
||||
const { text, font, size, height, bevelEnabled, bevelSize, bevelThickness } = this.state;
|
||||
|
||||
app.editor.execute(new AddObjectCommand(new ThreeDText(text, {
|
||||
font,
|
||||
size,
|
||||
height,
|
||||
bevelEnabled,
|
||||
bevelSize,
|
||||
bevelThickness
|
||||
})));
|
||||
if (font === '') {
|
||||
app.toast(_t('Pleast upload typeface first.'), 'warn');
|
||||
return;
|
||||
}
|
||||
|
||||
const fontData = this.fonts.filter(n => n.ID === font)[0];
|
||||
|
||||
fetch(`${app.options.server}${fontData.Url}`).then(response => {
|
||||
response.arrayBuffer().then(buffer => {
|
||||
TypefaceUtils.convertTtfToJson(buffer, false, text).then(obj => {
|
||||
app.editor.execute(new AddObjectCommand(new ThreeDText(text, {
|
||||
font: new THREE.Font(JSON.parse(obj.result)),
|
||||
size,
|
||||
height,
|
||||
bevelEnabled,
|
||||
bevelSize,
|
||||
bevelThickness
|
||||
})));
|
||||
this.handleClose();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
handleClose() {
|
||||
|
||||
@ -1,105 +1,16 @@
|
||||
import UnscaledTextVertexShader from './shader/unscaled_text_vertex.glsl';
|
||||
import UnscaledTextFragmentShader from './shader/unscaled_text_fragment.glsl';
|
||||
import CanvasUtils from '../../utils/CanvasUtils';
|
||||
|
||||
let ID = -1;
|
||||
|
||||
/**
|
||||
* 3D文字
|
||||
*/
|
||||
class ThreeDText extends THREE.Mesh {
|
||||
constructor(text = '') {
|
||||
const canvas = document.createElement('canvas');
|
||||
|
||||
let geometry = new THREE.PlaneBufferGeometry();
|
||||
let material = new THREE.ShaderMaterial({
|
||||
vertexShader: UnscaledTextVertexShader,
|
||||
fragmentShader: UnscaledTextFragmentShader,
|
||||
uniforms: {
|
||||
tDiffuse: {
|
||||
value: new THREE.CanvasTexture(canvas)
|
||||
},
|
||||
width: {
|
||||
value: 1.0 // canvas width
|
||||
},
|
||||
height: {
|
||||
value: 1.0 // canvas height
|
||||
},
|
||||
domWidth: {
|
||||
value: 1422.0 // dom width
|
||||
},
|
||||
domHeight: {
|
||||
value: 715.0 // dom height
|
||||
}
|
||||
},
|
||||
transparent: true
|
||||
constructor(text = '', options) {
|
||||
const geometry = new THREE.TextBufferGeometry(text, options);
|
||||
const material = new THREE.MeshPhongMaterial({
|
||||
color: 0xffffff
|
||||
});
|
||||
|
||||
super(geometry, material);
|
||||
|
||||
this.userData.type = 'text';
|
||||
this.setText(text);
|
||||
|
||||
app.on(`resize.${this.constructor.name}${ID--}`, this.onResize.bind(this));
|
||||
}
|
||||
|
||||
setText(text) {
|
||||
let fontSize = 16;
|
||||
let padding = 4;
|
||||
|
||||
this.name = text;
|
||||
this.userData.text = text;
|
||||
|
||||
// 设置样式并计算文字宽度和高度
|
||||
let map = this.material.uniforms.tDiffuse.value;
|
||||
let canvas = map.image;
|
||||
let context = canvas.getContext('2d');
|
||||
|
||||
context.font = `${fontSize}px "Microsoft YaHei"`;
|
||||
|
||||
const width = context.measureText(text).width;
|
||||
const width2 = CanvasUtils.makePowerOfTwo(width + padding * 2);
|
||||
const height2 = CanvasUtils.makePowerOfTwo(fontSize + padding * 2);
|
||||
|
||||
canvas.width = width2;
|
||||
canvas.height = height2;
|
||||
|
||||
const domWidth = app.editor.renderer.domElement.width;
|
||||
const domHeight = app.editor.renderer.domElement.height;
|
||||
|
||||
this.material.uniforms.width.value = width2;
|
||||
this.material.uniforms.height.value = height2;
|
||||
this.material.uniforms.domWidth.value = domWidth;
|
||||
this.material.uniforms.domHeight.value = domHeight;
|
||||
|
||||
// 设置样式并绘制文字
|
||||
context = canvas.getContext('2d');
|
||||
|
||||
context.imageSmoothingQuality = 'high';
|
||||
context.textBaseline = 'middle';
|
||||
context.textAlign = 'center';
|
||||
context.lineWidth = 2;
|
||||
|
||||
let halfWidth = width2 / 2;
|
||||
let halfHeight = height2 / 2;
|
||||
|
||||
// 画描边
|
||||
context.font = `${fontSize}px "Microsoft YaHei"`;
|
||||
context.strokeStyle = '#000';
|
||||
context.strokeText(text, halfWidth, halfHeight);
|
||||
|
||||
// 画文字
|
||||
context.fillStyle = '#fff';
|
||||
context.fillText(text, halfWidth, halfHeight);
|
||||
|
||||
// 更新贴图
|
||||
map.needsUpdate = true;
|
||||
}
|
||||
|
||||
onResize() {
|
||||
const { width, height } = app.editor.renderer.domElement;
|
||||
this.material.uniforms.domWidth.value = width;
|
||||
this.material.uniforms.domHeight.value = height;
|
||||
this.userData.type = '3dtext';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user