Open trouvaille2023 opened 1 year ago
This happens because justify is based on spaces. I suppose the language you are using (japanese?) is not using any space.
Are you using splitByGrapheme to wrap the text? or manually hitting enter?
This happens because justify is based on spaces. I suppose the language you are using (japanese?) is not using any space.
Are you using splitByGrapheme to wrap the text? or manually hitting enter?
function App() {
let txt = '白鹤滩-浙江±800千伏特高压直流输电工程(下称白浙线)是全球首个混合级联特高压直流工程,在世界上首次研发“常规直流+柔性直流”的混合级联特高压直流输电技术,集成特高压直流输电大容量、远距离、低损耗,以及柔性直流输电控制灵活、系统支撑能力强的优势,示范引领意义重大。"';
txt = txt.repeat(5);
const init = (selector: any) => {
const dom = document.querySelector(selector) as HTMLDivElement;
const ele = document.createElement('canvas') as HTMLCanvasElement;
dom.replaceChildren(ele);
const canvas = new Canvas(ele, {
width: 700,
height: 800,
});
const textbox = new Textbox(txt, {
fontSize: 24,
width: 700,
splitByGrapheme: true,
textAlign: 'justify',
});
canvas.add(textbox);
canvas.renderAll();
}
useEffect(() => {
init('#box')
}, [])
return (
<div className="App" id='box'>
</div>
);
}
export default App;
This happens because justify is based on spaces. I suppose the language you are using (japanese?) is not using any space. Are you using splitByGrapheme to wrap the text? or manually hitting enter?
- The language is Chinese! Chinese! Chinese!, not japanese.
- I can't hitting enter manually.
- I used splitByGrapheme to wrap the text.
- I have provided the code case, please review it carefully.
function App() { let txt = '白鹤滩-浙江±800千伏特高压直流输电工程(下称白浙线)是全球首个混合级联特高压直流工程,在世界上首次研发“常规直流+柔性直流”的混合级联特高压直流输电技术,集成特高压直流输电大容量、远距离、低损耗,以及柔性直流输电控制灵活、系统支撑能力强的优势,示范引领意义重大。"'; txt = txt.repeat(5); const init = (selector: any) => { const dom = document.querySelector(selector) as HTMLDivElement; const ele = document.createElement('canvas') as HTMLCanvasElement; dom.replaceChildren(ele); const canvas = new Canvas(ele, { width: 700, height: 800, }); const textbox = new Textbox(txt, { fontSize: 24, width: 700, splitByGrapheme: true, textAlign: 'justify', }); canvas.add(textbox); canvas.renderAll(); } useEffect(() => { init('#box') }, []) return ( <div className="App" id='box'> </div> ); } export default App;
I m sorry for the confusion, is hard for me to recognize Chinese from Japanese unless i see that 2 or 3 glyphs i can recognize.
Said so, if there are no spaces, fabricJS does not know how to justify because the rules for rendering are based on english language.
I want to review this, but this is not something we can fix easily
This happens because justify is based on spaces. I suppose the language you are using (japanese?) is not using any space. Are you using splitByGrapheme to wrap the text? or manually hitting enter?
- The language is Chinese! Chinese! Chinese!, not japanese.
- I can't hitting enter manually.
- I used splitByGrapheme to wrap the text.
- I have provided the code case, please review it carefully.
function App() { let txt = '白鹤滩-浙江±800千伏特高压直流输电工程(下称白浙线)是全球首个混合级联特高压直流工程,在世界上首次研发“常规直流+柔性直流”的混合级联特高压直流输电技术,集成特高压直流输电大容量、远距离、低损耗,以及柔性直流输电控制灵活、系统支撑能力强的优势,示范引领意义重大。"'; txt = txt.repeat(5); const init = (selector: any) => { const dom = document.querySelector(selector) as HTMLDivElement; const ele = document.createElement('canvas') as HTMLCanvasElement; dom.replaceChildren(ele); const canvas = new Canvas(ele, { width: 700, height: 800, }); const textbox = new Textbox(txt, { fontSize: 24, width: 700, splitByGrapheme: true, textAlign: 'justify', }); canvas.add(textbox); canvas.renderAll(); } useEffect(() => { init('#box') }, []) return ( <div className="App" id='box'> </div> ); } export default App;
I m sorry for the confusion, is hard for me to recognize Chinese from Japanese unless i see that 2 or 3 glyphs i can recognize.
Said so, if there are no spaces, fabricJS does not know how to justify because the rules for rendering are based on english language.
I want to review this, but this is not something we can fix easily
In word processing, Chinese takes a Chinese character as the word boundary, and a Chinese character is a Chinese character without the need to use spaces to divide word boundaries. For example, in Chinese, "你好" means two Chinese characters.
eg:
const str = '我是中国人'
const res = str.split('')
cosnole.log(res)
The result out: ['我', '是', '中', '国', '人']
I have rewritten the enlargeSpaces function in fabric.js here
demo: https://yft.design
import { Textbox as OriginTextbox, classRegistry } from "fabric"
export class Textbox extends OriginTextbox {
enlargeSpaces() {
let diffSpace,
currentLineWidth,
numberOfSpaces,
accumulatedSpace,
line,
charBound,
spaces;
for (let i = 0, len = this._textLines.length; i < len; i++) {
if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) {
continue;
}
accumulatedSpace = 0;
line = this._textLines[i];
currentLineWidth = this.getLineWidth(i);
if (currentLineWidth < this.width && (spaces = this.textLines[i].split(''))) {
numberOfSpaces = spaces.length - 1;
diffSpace = (this.width - currentLineWidth) / numberOfSpaces;
for (let j = 0; j <= line.length; j++) {
charBound = this.__charBounds[i][j];
charBound.width += diffSpace;
charBound.kernedWidth += diffSpace;
charBound.left += accumulatedSpace;
accumulatedSpace += diffSpace;
}
}
}
}
}
classRegistry.setClass(Textbox, 'Textbox')
CheckList
Version
6.0.0-beta10
In What environments are you experiencing the problem?
Chrome
Node Version (if applicable)
20.0.0
Link To Reproduction
See steps
Steps To Reproduce
node version: 16.15.0 , 20.5.0 browser: Google Chrome 115 platform: MacOS 13. Windows 10 fabricjs version : 5.3.0, 6.0.0-beta10 and all versions
fabricjs:
Microsoft Word and css style:
My code:
Expected Behavior
It can be aligned on both ends of the rest of the lines except the last line like Microsoft Word or css style
Actual Behavior
When I set textAlign to justify, the right side is not aligned
Error Message & Stack Trace