mirror of
https://github.com/konvajs/konva.git
synced 2026-02-24 20:26:01 +08:00
Merge pull request #2012 from HusnainTaj/feat/text-underline-offset
Add option to adjust underline text decoration offset for Text Shape
This commit is contained in:
@@ -151,7 +151,7 @@ class TweenEngine {
|
||||
}
|
||||
|
||||
export interface TweenConfig extends NodeConfig {
|
||||
easing?: typeof Easings[keyof typeof Easings];
|
||||
easing?: (typeof Easings)[keyof typeof Easings];
|
||||
yoyo?: boolean;
|
||||
onReset?: Function;
|
||||
onFinish?: Function;
|
||||
|
||||
@@ -452,7 +452,7 @@ let _isCanvasFarblingActive: boolean | null = null;
|
||||
const req =
|
||||
(typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame) ||
|
||||
function (f) {
|
||||
setTimeout(f, 16); // 60fps ≈ 16.67ms per frame
|
||||
setTimeout(f, 16); // 60fps ≈ 16.67ms per frame
|
||||
};
|
||||
/**
|
||||
* @namespace Util
|
||||
|
||||
@@ -70,6 +70,7 @@ export interface TextConfig extends ShapeConfig {
|
||||
fontStyle?: string;
|
||||
fontVariant?: string;
|
||||
textDecoration?: string;
|
||||
underlineOffset?: number;
|
||||
align?: string;
|
||||
verticalAlign?: string;
|
||||
padding?: number;
|
||||
@@ -183,6 +184,7 @@ function checkDefaultFill(config?: TextConfig) {
|
||||
* @param {String} [config.fontStyle] can be 'normal', 'italic', or 'bold', '500' or even 'italic bold'. 'normal' is the default.
|
||||
* @param {String} [config.fontVariant] can be normal or small-caps. Default is normal
|
||||
* @param {String} [config.textDecoration] can be line-through, underline or empty string. Default is empty string.
|
||||
* @param {String} [config.underlineOffset] offset for underline line. Default is calculated based on font size.
|
||||
* @param {String} config.text
|
||||
* @param {String} [config.align] can be left, center, right or justify
|
||||
* @param {String} [config.verticalAlign] can be top, middle or bottom
|
||||
@@ -239,6 +241,7 @@ export class Text extends Shape<TextConfig> {
|
||||
charRenderFunc = this.charRenderFunc(),
|
||||
fill = this.fill(),
|
||||
textDecoration = this.textDecoration(),
|
||||
underlineOffset = this.underlineOffset(),
|
||||
shouldUnderline = textDecoration.indexOf('underline') !== -1,
|
||||
shouldLineThrough = textDecoration.indexOf('line-through') !== -1,
|
||||
n;
|
||||
@@ -299,9 +302,11 @@ export class Text extends Shape<TextConfig> {
|
||||
context.save();
|
||||
context.beginPath();
|
||||
|
||||
const yOffset = !Konva.legacyTextRendering
|
||||
? Math.round(fontSize / 4)
|
||||
: Math.round(fontSize / 2);
|
||||
const yOffset =
|
||||
underlineOffset ??
|
||||
(!Konva.legacyTextRendering
|
||||
? Math.round(fontSize / 4)
|
||||
: Math.round(fontSize / 2));
|
||||
const x = lineTranslateX;
|
||||
const y = translateY + lineTranslateY + yOffset;
|
||||
context.moveTo(x, y);
|
||||
@@ -765,6 +770,7 @@ export class Text extends Shape<TextConfig> {
|
||||
padding: GetSet<number, this>;
|
||||
lineHeight: GetSet<number, this>;
|
||||
textDecoration: GetSet<string, this>;
|
||||
underlineOffset: GetSet<number, this>;
|
||||
text: GetSet<string, this>;
|
||||
wrap: GetSet<string, this>;
|
||||
ellipsis: GetSet<boolean, this>;
|
||||
@@ -1052,6 +1058,26 @@ Factory.addGetterSetter(Text, 'text', '', getStringValidator());
|
||||
|
||||
Factory.addGetterSetter(Text, 'textDecoration', '');
|
||||
|
||||
/**
|
||||
* get/set text underline decoration offset. Offset for underline line. Default is calculated based on font size.
|
||||
* @name Konva.Text#underlineOffset
|
||||
* @method
|
||||
* @param {Number} underlineOffset
|
||||
* @returns {Number}
|
||||
* @example
|
||||
* // get underline offset
|
||||
* var underlineOffset = text.underlineOffset();
|
||||
*
|
||||
* // set underline offset
|
||||
* text.underlineOffset(5);
|
||||
*/
|
||||
Factory.addGetterSetter(
|
||||
Text,
|
||||
'underlineOffset',
|
||||
undefined,
|
||||
getNumberValidator()
|
||||
);
|
||||
|
||||
/**
|
||||
* get/set per-character render hook. The callback is invoked for each grapheme before drawing.
|
||||
* It can mutate the provided context (e.g. translate, rotate, change styles) and should return void.
|
||||
|
||||
@@ -2003,4 +2003,41 @@ describe('Text', function () {
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('text with underline offset', function () {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: 10,
|
||||
y: 10,
|
||||
text: 'hello\nworld',
|
||||
fontSize: 80,
|
||||
fill: 'red',
|
||||
textDecoration: 'underline',
|
||||
underlineOffset: 16,
|
||||
});
|
||||
|
||||
layer.add(text);
|
||||
stage.add(layer);
|
||||
|
||||
const trace = layer.getContext().getTrace();
|
||||
|
||||
if (Konva._renderBackend === 'web') {
|
||||
assert.equal(
|
||||
trace,
|
||||
'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 80px Arial;textBaseline=alphabetic;textAlign=left;translate(0,0);save();save();beginPath();moveTo(0,83.5);lineTo(169,83.5);stroke();restore();fillStyle=red;fillText(hello,0,67.5);restore();save();save();beginPath();moveTo(0,163.5);lineTo(191,163.5);stroke();restore();fillStyle=red;fillText(world,0,147.5);restore();restore();'
|
||||
);
|
||||
} else if (Konva._renderBackend === 'node-canvas') {
|
||||
assert.equal(
|
||||
trace,
|
||||
'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 80px Arial;textBaseline=alphabetic;textAlign=left;translate(0,0);save();save();beginPath();moveTo(0,84);lineTo(169,84);stroke();restore();fillStyle=red;fillText(hello,0,68);restore();save();save();beginPath();moveTo(0,164);lineTo(191,164);stroke();restore();fillStyle=red;fillText(world,0,148);restore();restore();'
|
||||
);
|
||||
} else {
|
||||
assert.equal(
|
||||
trace,
|
||||
'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 80px Arial;textBaseline=alphabetic;textAlign=left;translate(0,0);save();save();beginPath();moveTo(0,83.734);lineTo(169,83.734);stroke();restore();fillStyle=red;fillText(hello,0,67.734);restore();save();save();beginPath();moveTo(0,163.734);lineTo(191,163.734);stroke();restore();fillStyle=red;fillText(world,0,147.734);restore();restore();'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user