Merge branch 'master' of github.com:konvajs/konva

This commit is contained in:
Anton Lavrevov 2025-04-03 17:21:20 -05:00
commit 791a786c81
9 changed files with 66 additions and 100 deletions

View File

@ -70,7 +70,7 @@ export const Factory = {
attr: U, attr: U,
def?: Value<T, U> def?: Value<T, U>
) { ) {
var method = GET + Util._capitalize(attr); const method = GET + Util._capitalize(attr);
constructor.prototype[method] = constructor.prototype[method] =
constructor.prototype[method] || constructor.prototype[method] ||
@ -86,7 +86,7 @@ export const Factory = {
validator?: ValidatorFunc<Value<T, U>>, validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T> after?: AfterFunc<T>
) { ) {
var method = SET + Util._capitalize(attr); const method = SET + Util._capitalize(attr);
if (!constructor.prototype[method]) { if (!constructor.prototype[method]) {
Factory.overWriteSetter(constructor, attr, validator, after); Factory.overWriteSetter(constructor, attr, validator, after);
@ -99,7 +99,7 @@ export const Factory = {
validator?: ValidatorFunc<Value<T, U>>, validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T> after?: AfterFunc<T>
) { ) {
var method = SET + Util._capitalize(attr); const method = SET + Util._capitalize(attr);
constructor.prototype[method] = function (val) { constructor.prototype[method] = function (val) {
if (validator && val !== undefined && val !== null) { if (validator && val !== undefined && val !== null) {
val = validator.call(this, val, attr); val = validator.call(this, val, attr);
@ -180,7 +180,7 @@ export const Factory = {
constructor: T, constructor: T,
attr: U attr: U
) { ) {
var capitalizedAttr = Util._capitalize(attr), const capitalizedAttr = Util._capitalize(attr),
setter = SET + capitalizedAttr, setter = SET + capitalizedAttr,
getter = GET + capitalizedAttr; getter = GET + capitalizedAttr;

View File

@ -72,8 +72,8 @@ export function getNumberOrArrayOfNumbersValidator<T>(noOfElements: number) {
export function getNumberOrAutoValidator<T>() { export function getNumberOrAutoValidator<T>() {
if (Konva.isUnminified) { if (Konva.isUnminified) {
return function (val: T, attr: string): T { return function (val: T, attr: string): T {
var isNumber = Util._isNumber(val); const isNumber = Util._isNumber(val);
var isAuto = val === 'auto'; const isAuto = val === 'auto';
if (!(isNumber || isAuto)) { if (!(isNumber || isAuto)) {
Util.warn( Util.warn(
@ -175,7 +175,7 @@ export function getNumberArrayValidator<T>() {
export function getBooleanValidator<T>() { export function getBooleanValidator<T>() {
if (Konva.isUnminified) { if (Konva.isUnminified) {
return function (val: T, attr: string): T { return function (val: T, attr: string): T {
var isBool = val === true || val === false; const isBool = val === true || val === false;
if (!isBool) { if (!isBool) {
Util.warn( Util.warn(
_formatValue(val) + _formatValue(val) +

View File

@ -96,11 +96,7 @@ function filterGaussBlurRGBA(imageData, radius) {
width = imageData.width, width = imageData.width,
height = imageData.height; height = imageData.height;
let x, let p,
y,
i,
p,
yp,
yi, yi,
yw, yw,
r_sum, r_sum,
@ -135,7 +131,7 @@ function filterGaussBlurRGBA(imageData, radius) {
stackIn: any = null, stackIn: any = null,
stackOut: any = null; stackOut: any = null;
for (i = 1; i < div; i++) { for (let i = 1; i < div; i++) {
stack = stack.next = new BlurStack(); stack = stack.next = new BlurStack();
if (i === radiusPlus1) { if (i === radiusPlus1) {
stackEnd = stack; stackEnd = stack;
@ -146,7 +142,7 @@ function filterGaussBlurRGBA(imageData, radius) {
yw = yi = 0; yw = yi = 0;
for (y = 0; y < height; y++) { for (let y = 0; y < height; y++) {
r_in_sum = r_in_sum =
g_in_sum = g_in_sum =
b_in_sum = b_in_sum =
@ -169,7 +165,7 @@ function filterGaussBlurRGBA(imageData, radius) {
stack = stackStart; stack = stackStart;
for (i = 0; i < radiusPlus1; i++) { for (let i = 0; i < radiusPlus1; i++) {
stack.r = pr; stack.r = pr;
stack.g = pg; stack.g = pg;
stack.b = pb; stack.b = pb;
@ -177,7 +173,7 @@ function filterGaussBlurRGBA(imageData, radius) {
stack = stack.next; stack = stack.next;
} }
for (i = 1; i < radiusPlus1; i++) { for (let i = 1; i < radiusPlus1; i++) {
p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2); p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2);
r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i); r_sum += (stack.r = pr = pixels[p]) * (rbs = radiusPlus1 - i);
g_sum += (stack.g = pg = pixels[p + 1]) * rbs; g_sum += (stack.g = pg = pixels[p + 1]) * rbs;
@ -194,7 +190,7 @@ function filterGaussBlurRGBA(imageData, radius) {
stackIn = stackStart; stackIn = stackStart;
stackOut = stackEnd; stackOut = stackEnd;
for (x = 0; x < width; x++) { for (let x = 0; x < width; x++) {
pixels[yi + 3] = pa = (a_sum * mul_sum) >> shg_sum; pixels[yi + 3] = pa = (a_sum * mul_sum) >> shg_sum;
if (pa !== 0) { if (pa !== 0) {
pa = 255 / pa; pa = 255 / pa;
@ -246,7 +242,7 @@ function filterGaussBlurRGBA(imageData, radius) {
yw += width; yw += width;
} }
for (x = 0; x < width; x++) { for (let x = 0; x < width; x++) {
g_in_sum = g_in_sum =
b_in_sum = b_in_sum =
a_in_sum = a_in_sum =
@ -270,7 +266,7 @@ function filterGaussBlurRGBA(imageData, radius) {
stack = stackStart; stack = stackStart;
for (i = 0; i < radiusPlus1; i++) { for (let i = 0; i < radiusPlus1; i++) {
stack.r = pr; stack.r = pr;
stack.g = pg; stack.g = pg;
stack.b = pb; stack.b = pb;
@ -278,9 +274,9 @@ function filterGaussBlurRGBA(imageData, radius) {
stack = stack.next; stack = stack.next;
} }
yp = width; let yp = width;
for (i = 1; i <= radius; i++) { for (let i = 1; i <= radius; i++) {
yi = (yp + x) << 2; yi = (yp + x) << 2;
r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i); r_sum += (stack.r = pr = pixels[yi]) * (rbs = radiusPlus1 - i);
@ -303,7 +299,7 @@ function filterGaussBlurRGBA(imageData, radius) {
yi = x; yi = x;
stackIn = stackStart; stackIn = stackStart;
stackOut = stackEnd; stackOut = stackEnd;
for (y = 0; y < height; y++) { for (let y = 0; y < height; y++) {
p = yi << 2; p = yi << 2;
pixels[p + 3] = pa = (a_sum * mul_sum) >> shg_sum; pixels[p + 3] = pa = (a_sum * mul_sum) >> shg_sum;
if (pa > 0) { if (pa > 0) {

View File

@ -94,15 +94,12 @@ export const Enhance: Filter = function (imageData) {
bMin = 0; bMin = 0;
} }
let rMid, let rGoalMax: number,
rGoalMax, rGoalMin: number,
rGoalMin, gGoalMax: number,
gMid, gGoalMin: number,
gGoalMax, bGoalMax: number,
gGoalMin, bGoalMin: number;
bMid,
bGoalMax,
bGoalMin;
// If the enhancement is positive - stretch the histogram // If the enhancement is positive - stretch the histogram
if (enhanceAmount > 0) { if (enhanceAmount > 0) {
@ -114,13 +111,13 @@ export const Enhance: Filter = function (imageData) {
bGoalMin = bMin - enhanceAmount * (bMin - 0); bGoalMin = bMin - enhanceAmount * (bMin - 0);
// If the enhancement is negative - compress the histogram // If the enhancement is negative - compress the histogram
} else { } else {
rMid = (rMax + rMin) * 0.5; const rMid = (rMax + rMin) * 0.5;
rGoalMax = rMax + enhanceAmount * (rMax - rMid); rGoalMax = rMax + enhanceAmount * (rMax - rMid);
rGoalMin = rMin + enhanceAmount * (rMin - rMid); rGoalMin = rMin + enhanceAmount * (rMin - rMid);
gMid = (gMax + gMin) * 0.5; const gMid = (gMax + gMin) * 0.5;
gGoalMax = gMax + enhanceAmount * (gMax - gMid); gGoalMax = gMax + enhanceAmount * (gMax - gMid);
gGoalMin = gMin + enhanceAmount * (gMin - gMid); gGoalMin = gMin + enhanceAmount * (gMin - gMid);
bMid = (bMax + bMin) * 0.5; const bMid = (bMax + bMin) * 0.5;
bGoalMax = bMax + enhanceAmount * (bMax - bMid); bGoalMax = bMax + enhanceAmount * (bMax - bMid);
bGoalMin = bMin + enhanceAmount * (bMin - bMid); bGoalMin = bMin + enhanceAmount * (bMin - bMid);
} }

View File

@ -1,5 +1,5 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Filter, Node } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
/** /**
@ -46,13 +46,11 @@ export const HSV: Filter = function (imageData) {
bg = 0.587 * v - 0.586 * vsu - 1.05 * vsw, bg = 0.587 * v - 0.586 * vsu - 1.05 * vsw,
bb = 0.114 * v + 0.886 * vsu - 0.2 * vsw; bb = 0.114 * v + 0.886 * vsu - 0.2 * vsw;
let r, g, b, a;
for (let i = 0; i < nPixels; i += 4) { for (let i = 0; i < nPixels; i += 4) {
r = data[i + 0]; const r = data[i + 0];
g = data[i + 1]; const g = data[i + 1];
b = data[i + 2]; const b = data[i + 2];
a = data[i + 3]; const a = data[i + 3];
data[i + 0] = rr * r + rg * g + rb * b; data[i + 0] = rr * r + rg * g + rb * b;
data[i + 1] = gr * r + gg * g + gb * b; data[i + 1] = gr * r + gg * g + gb * b;

View File

@ -2,7 +2,7 @@ import { Factory } from '../Factory';
import { Filter, Node } from '../Node'; import { Filter, Node } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
function pixelAt(idata, x, y) { function pixelAt(idata, x: number, y: number) {
let idx = (y * idata.width + x) * 4; let idx = (y * idata.width + x) * 4;
const d: Array<number> = []; const d: Array<number> = [];
d.push( d.push(
@ -137,7 +137,7 @@ function dilateMask(mask, sw, sh) {
return maskResult; return maskResult;
} }
function smoothEdgeMask(mask, sw, sh) { function smoothEdgeMask(mask, sw: number, sh: number) {
const weights = [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9]; const weights = [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9];
const side = Math.round(Math.sqrt(weights.length)); const side = Math.round(Math.sqrt(weights.length));
const halfSide = Math.floor(side / 2); const halfSide = Math.floor(side / 2);

View File

@ -1,4 +1,3 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Util } from '../Util'; import { Util } from '../Util';
import { Node, Filter } from '../Node'; import { Node, Filter } from '../Node';
@ -22,23 +21,9 @@ export const Pixelate: Filter = function (imageData) {
let pixelSize = Math.ceil(this.pixelSize()), let pixelSize = Math.ceil(this.pixelSize()),
width = imageData.width, width = imageData.width,
height = imageData.height, height = imageData.height,
x,
y,
i,
//pixelsPerBin = pixelSize * pixelSize, //pixelsPerBin = pixelSize * pixelSize,
red,
green,
blue,
alpha,
nBinsX = Math.ceil(width / pixelSize), nBinsX = Math.ceil(width / pixelSize),
nBinsY = Math.ceil(height / pixelSize), nBinsY = Math.ceil(height / pixelSize),
xBinStart,
xBinEnd,
yBinStart,
yBinEnd,
xBin,
yBin,
pixelsInBin,
data = imageData.data; data = imageData.data;
if (pixelSize <= 0) { if (pixelSize <= 0) {
@ -46,31 +31,31 @@ export const Pixelate: Filter = function (imageData) {
return; return;
} }
for (xBin = 0; xBin < nBinsX; xBin += 1) { for (let xBin = 0; xBin < nBinsX; xBin += 1) {
for (yBin = 0; yBin < nBinsY; yBin += 1) { for (let yBin = 0; yBin < nBinsY; yBin += 1) {
// Initialize the color accumlators to 0 // Initialize the color accumlators to 0
red = 0; let red = 0;
green = 0; let green = 0;
blue = 0; let blue = 0;
alpha = 0; let alpha = 0;
// Determine which pixels are included in this bin // Determine which pixels are included in this bin
xBinStart = xBin * pixelSize; const xBinStart = xBin * pixelSize;
xBinEnd = xBinStart + pixelSize; const xBinEnd = xBinStart + pixelSize;
yBinStart = yBin * pixelSize; const yBinStart = yBin * pixelSize;
yBinEnd = yBinStart + pixelSize; const yBinEnd = yBinStart + pixelSize;
// Add all of the pixels to this bin! // Add all of the pixels to this bin!
pixelsInBin = 0; let pixelsInBin = 0;
for (x = xBinStart; x < xBinEnd; x += 1) { for (let x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) { if (x >= width) {
continue; continue;
} }
for (y = yBinStart; y < yBinEnd; y += 1) { for (let y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) { if (y >= height) {
continue; continue;
} }
i = (width * y + x) * 4; const i = (width * y + x) * 4;
red += data[i + 0]; red += data[i + 0];
green += data[i + 1]; green += data[i + 1];
blue += data[i + 2]; blue += data[i + 2];
@ -86,15 +71,15 @@ export const Pixelate: Filter = function (imageData) {
alpha = alpha / pixelsInBin; alpha = alpha / pixelsInBin;
// Draw this bin // Draw this bin
for (x = xBinStart; x < xBinEnd; x += 1) { for (let x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) { if (x >= width) {
continue; continue;
} }
for (y = yBinStart; y < yBinEnd; y += 1) { for (let y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) { if (y >= height) {
continue; continue;
} }
i = (width * y + x) * 4; const i = (width * y + x) * 4;
data[i + 0] = red; data[i + 0] = red;
data[i + 1] = green; data[i + 1] = green;
data[i + 2] = blue; data[i + 2] = blue;

View File

@ -73,7 +73,7 @@ export class Path extends Shape<PathConfig> {
context.quadraticCurveTo(p[0], p[1], p[2], p[3]); context.quadraticCurveTo(p[0], p[1], p[2], p[3]);
break; break;
case 'A': case 'A':
var cx = p[0], const cx = p[0],
cy = p[1], cy = p[1],
rx = p[2], rx = p[2],
ry = p[3], ry = p[3],
@ -82,9 +82,9 @@ export class Path extends Shape<PathConfig> {
psi = p[6], psi = p[6],
fs = p[7]; fs = p[7];
var r = rx > ry ? rx : ry; const r = rx > ry ? rx : ry;
var scaleX = rx > ry ? 1 : rx / ry; const scaleX = rx > ry ? 1 : rx / ry;
var scaleY = rx > ry ? ry / rx : 1; const scaleY = rx > ry ? ry / rx : 1;
context.translate(cx, cy); context.translate(cx, cy);
context.rotate(psi); context.rotate(psi);
@ -313,13 +313,13 @@ export class Path extends Shape<PathConfig> {
p[3] p[3]
); );
case 'A': case 'A':
var cx = p[0], const cx = p[0],
cy = p[1], cy = p[1],
rx = p[2], rx = p[2],
ry = p[3], ry = p[3],
theta = p[4],
dTheta = p[5], dTheta = p[5],
psi = p[6]; psi = p[6];
let theta = p[4];
theta += (dTheta * length) / cp.pathLength; theta += (dTheta * length) / cp.pathLength;
return Path.getPointOnEllipticalArc(cx, cy, rx, ry, theta, psi); return Path.getPointOnEllipticalArc(cx, cy, rx, ry, theta, psi);
} }
@ -491,7 +491,7 @@ export class Path extends Shape<PathConfig> {
// convert white spaces to commas // convert white spaces to commas
cs = cs.replace(new RegExp(' ', 'g'), ','); cs = cs.replace(new RegExp(' ', 'g'), ',');
// create pipes so that we can split the data // create pipes so that we can split the data
for (var n = 0; n < cc.length; n++) { for (let n = 0; n < cc.length; n++) {
cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]); cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]);
} }
// create array // create array
@ -504,7 +504,7 @@ export class Path extends Shape<PathConfig> {
const re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi; const re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi;
let match; let match;
for (n = 1; n < arr.length; n++) { for (let n = 1; n < arr.length; n++) {
let str = arr[n]; let str = arr[n];
let c = str.charAt(0); let c = str.charAt(0);
str = str.slice(1); str = str.slice(1);

View File

@ -242,9 +242,6 @@ export class Text extends Shape<TextConfig> {
lineHeightPx / 2; lineHeightPx / 2;
} }
var lineTranslateX = 0;
var lineTranslateY = 0;
if (direction === RTL) { if (direction === RTL) {
context.setAttr('direction', direction); context.setAttr('direction', direction);
} }
@ -266,15 +263,12 @@ export class Text extends Shape<TextConfig> {
// draw text lines // draw text lines
for (n = 0; n < textArrLen; n++) { for (n = 0; n < textArrLen; n++) {
var lineTranslateX = 0; let lineTranslateX = 0;
var lineTranslateY = 0; let lineTranslateY = 0;
var obj = textArr[n], const obj = textArr[n],
text = obj.text, text = obj.text,
width = obj.width, width = obj.width,
lastLine = obj.lastInParagraph, lastLine = obj.lastInParagraph;
spacesNumber,
oneWord,
lineWidth;
// horizontal alignment // horizontal alignment
context.save(); context.save();
@ -294,9 +288,7 @@ export class Text extends Shape<TextConfig> {
const x = lineTranslateX; const x = lineTranslateX;
const y = translateY + lineTranslateY + yOffset; const y = translateY + lineTranslateY + yOffset;
context.moveTo(x, y); context.moveTo(x, y);
spacesNumber = text.split(' ').length - 1; const lineWidth =
oneWord = spacesNumber === 0;
lineWidth =
align === JUSTIFY && !lastLine ? totalWidth - padding * 2 : width; align === JUSTIFY && !lastLine ? totalWidth - padding * 2 : width;
context.lineTo(x + Math.round(lineWidth), y); context.lineTo(x + Math.round(lineWidth), y);
@ -314,9 +306,7 @@ export class Text extends Shape<TextConfig> {
context.beginPath(); context.beginPath();
const yOffset = Konva._fixTextRendering ? -Math.round(fontSize / 4) : 0; const yOffset = Konva._fixTextRendering ? -Math.round(fontSize / 4) : 0;
context.moveTo(lineTranslateX, translateY + lineTranslateY + yOffset); context.moveTo(lineTranslateX, translateY + lineTranslateY + yOffset);
spacesNumber = text.split(' ').length - 1; const lineWidth =
oneWord = spacesNumber === 0;
lineWidth =
align === JUSTIFY && !lastLine ? totalWidth - padding * 2 : width; align === JUSTIFY && !lastLine ? totalWidth - padding * 2 : width;
context.lineTo( context.lineTo(
lineTranslateX + Math.round(lineWidth), lineTranslateX + Math.round(lineWidth),
@ -333,7 +323,7 @@ export class Text extends Shape<TextConfig> {
// be supported otherwise. // be supported otherwise.
if (direction !== RTL && (letterSpacing !== 0 || align === JUSTIFY)) { if (direction !== RTL && (letterSpacing !== 0 || align === JUSTIFY)) {
// var words = text.split(' '); // var words = text.split(' ');
spacesNumber = text.split(' ').length - 1; const spacesNumber = text.split(' ').length - 1;
const array = stringToArray(text); const array = stringToArray(text);
for (let li = 0; li < array.length; li++) { for (let li = 0; li < array.length; li++) {
const letter = array[li]; const letter = array[li];