mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 05:10:26 +08:00
Merge branch 'konvajs:master' into master
This commit is contained in:
commit
f0a60496e3
@ -3,6 +3,15 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## 9.3.20 (2025-03-20)
|
||||||
|
|
||||||
|
- Fix text rendering when ellipses are used
|
||||||
|
|
||||||
|
## 9.3.19 (2025-03-12)
|
||||||
|
|
||||||
|
- Typescript fixes
|
||||||
|
- Memory leak fixes
|
||||||
|
|
||||||
## 9.3.18 (2024-12-23)
|
## 9.3.18 (2024-12-23)
|
||||||
|
|
||||||
- Fixed emoji split in multiple lines
|
- Fixed emoji split in multiple lines
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "konva",
|
"name": "konva",
|
||||||
"version": "9.3.18",
|
"version": "9.3.20",
|
||||||
"description": "HTML5 2d canvas library.",
|
"description": "HTML5 2d canvas library.",
|
||||||
"author": "Anton Lavrenov",
|
"author": "Anton Lavrenov",
|
||||||
"files": [
|
"files": [
|
||||||
|
18
release.sh
18
release.sh
@ -49,7 +49,7 @@ echo "build for $1"
|
|||||||
npm run build >/dev/null
|
npm run build >/dev/null
|
||||||
git commit -am "build for $1" --allow-empty >/dev/null
|
git commit -am "build for $1" --allow-empty >/dev/null
|
||||||
|
|
||||||
echo "update CDN link in REAME"
|
echo "update CDN link in README"
|
||||||
perl -i -pe "s|${old_cdn_min}|${new_cdn_min}|g" ./README.md >/dev/null
|
perl -i -pe "s|${old_cdn_min}|${new_cdn_min}|g" ./README.md >/dev/null
|
||||||
git commit -am "update cdn link" --allow-empty >/dev/null
|
git commit -am "update cdn link" --allow-empty >/dev/null
|
||||||
|
|
||||||
@ -61,17 +61,17 @@ git push >/dev/null
|
|||||||
git push --tags >/dev/null
|
git push --tags >/dev/null
|
||||||
npm publish
|
npm publish
|
||||||
|
|
||||||
echo "copy konva.js into konva-site"
|
# echo "copy konva.js into konva-site"
|
||||||
cp ./konva.js ../konva-site/
|
# cp ./konva.js ../konva-site/
|
||||||
cd ../konva-site
|
# cd ../konva-site
|
||||||
|
|
||||||
echo "replace CDN links"
|
# echo "replace CDN links"
|
||||||
|
|
||||||
|
|
||||||
find source themes/hexo3/layout react-demos vue-demos main-demo -name "*.json" -exec perl -i -pe "s|${old_version}|${new_version}|g" {} + >/dev/null
|
# find source themes/hexo3/layout react-demos vue-demos main-demo -name "*.json" -exec perl -i -pe "s|${old_version}|${new_version}|g" {} + >/dev/null
|
||||||
find source themes/hexo3/layout react-demos vue-demos main-demo -name "*.html" -exec perl -i -pe "s|${old_version}|${new_version}|g" {} + >/dev/null
|
# find source themes/hexo3/layout react-demos vue-demos main-demo -name "*.html" -exec perl -i -pe "s|${old_version}|${new_version}|g" {} + >/dev/null
|
||||||
|
|
||||||
echo "regenerate site"
|
# echo "regenerate site"
|
||||||
./deploy.sh >/dev/null
|
# ./deploy.sh >/dev/null
|
||||||
|
|
||||||
echo "DONE!"
|
echo "DONE!"
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// import resolve from 'rollup-plugin-node-resolve';
|
// import resolve from 'rollup-plugin-node-resolve';
|
||||||
import typescript from 'rollup-plugin-typescript2';
|
import typescript from 'rollup-plugin-typescript2';
|
||||||
|
|
||||||
const pkg = require('./package.json');
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input: `src/index.ts`,
|
input: `src/index.ts`,
|
||||||
output: [
|
output: [
|
@ -11,7 +11,7 @@ import { _registerNode } from './Global';
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @memberof Konva
|
* @memberof Konva
|
||||||
* @augments Konva.Layer
|
* @augments Konva.Layer
|
||||||
* @@containerParams
|
@@containerParams
|
||||||
* @example
|
* @example
|
||||||
* var layer = new Konva.FastLayer();
|
* var layer = new Konva.FastLayer();
|
||||||
*/
|
*/
|
||||||
|
@ -40,9 +40,16 @@ export interface ImageConfig extends ShapeConfig {
|
|||||||
* imageObj.src = '/path/to/image.jpg'
|
* imageObj.src = '/path/to/image.jpg'
|
||||||
*/
|
*/
|
||||||
export class Image extends Shape<ImageConfig> {
|
export class Image extends Shape<ImageConfig> {
|
||||||
|
private _loadListener: () => void;
|
||||||
|
|
||||||
constructor(attrs: ImageConfig) {
|
constructor(attrs: ImageConfig) {
|
||||||
super(attrs);
|
super(attrs);
|
||||||
this.on('imageChange.konva', () => {
|
this._loadListener = () => {
|
||||||
|
this._requestDraw();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.on('imageChange.konva', (props: any) => {
|
||||||
|
this._removeImageLoad(props.oldVal);
|
||||||
this._setImageLoad();
|
this._setImageLoad();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -59,11 +66,19 @@ export class Image extends Shape<ImageConfig> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (image && image['addEventListener']) {
|
if (image && image['addEventListener']) {
|
||||||
image['addEventListener']('load', () => {
|
image['addEventListener']('load', this._loadListener);
|
||||||
this._requestDraw();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_removeImageLoad(image: any) {
|
||||||
|
if (image && image['removeEventListener']) {
|
||||||
|
image['removeEventListener']('load', this._loadListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destroy() {
|
||||||
|
this._removeImageLoad(this.image());
|
||||||
|
super.destroy();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
_useBufferCanvas() {
|
_useBufferCanvas() {
|
||||||
const hasCornerRadius = !!this.cornerRadius();
|
const hasCornerRadius = !!this.cornerRadius();
|
||||||
const hasShadow = this.hasShadow();
|
const hasShadow = this.hasShadow();
|
||||||
|
@ -534,12 +534,23 @@ export class Text extends Shape<TextConfig> {
|
|||||||
// Convert array indices to string
|
// Convert array indices to string
|
||||||
lineArray = stringToArray(line),
|
lineArray = stringToArray(line),
|
||||||
substr = lineArray.slice(0, mid + 1).join(''),
|
substr = lineArray.slice(0, mid + 1).join(''),
|
||||||
substrWidth = this._getTextWidth(substr) + additionalWidth;
|
substrWidth = this._getTextWidth(substr);
|
||||||
|
|
||||||
if (substrWidth <= maxWidth) {
|
// Only add ellipsis width when we need to consider truncation
|
||||||
|
// for the current line (when it might be the last visible line)
|
||||||
|
const shouldConsiderEllipsis =
|
||||||
|
shouldAddEllipsis &&
|
||||||
|
fixedHeight &&
|
||||||
|
currentHeightPx + lineHeightPx > maxHeightPx;
|
||||||
|
|
||||||
|
const effectiveWidth = shouldConsiderEllipsis
|
||||||
|
? substrWidth + additionalWidth
|
||||||
|
: substrWidth;
|
||||||
|
|
||||||
|
if (effectiveWidth <= maxWidth) {
|
||||||
low = mid + 1;
|
low = mid + 1;
|
||||||
match = substr;
|
match = substr;
|
||||||
matchWidth = substrWidth;
|
matchWidth = substrWidth; // Store actual text width without ellipsis
|
||||||
} else {
|
} else {
|
||||||
high = mid;
|
high = mid;
|
||||||
}
|
}
|
||||||
|
@ -17,25 +17,9 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.test {
|
|
||||||
position: absolute;
|
|
||||||
color: red;
|
|
||||||
font-size: 20px;
|
|
||||||
font-family: Arial;
|
|
||||||
border: 0;
|
|
||||||
background-color: transparent;
|
|
||||||
outline: none;
|
|
||||||
resize: none;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: 1;
|
|
||||||
padding: 0px;
|
|
||||||
letter-spacing: 20px;
|
|
||||||
width: 500px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
<!-- <script src="https://cdn.rawgit.com/hammerjs/touchemulator/master/touch-emulator.js"></script> -->
|
<!-- <script src="https://cdn.rawgit.com/hammerjs/touchemulator/master/touch-emulator.js"></script> -->
|
||||||
|
<script src="https://unpkg.com/gifler@0.1.0/gifler.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// TouchEmulator();
|
// TouchEmulator();
|
||||||
</script>
|
</script>
|
||||||
@ -52,36 +36,49 @@
|
|||||||
<script type="module">
|
<script type="module">
|
||||||
import Konva from '../src/index.ts';
|
import Konva from '../src/index.ts';
|
||||||
|
|
||||||
var stageWidth = window.innerWidth;
|
var width = window.innerWidth;
|
||||||
var stageHeight = window.innerHeight;
|
var height = window.innerHeight;
|
||||||
|
|
||||||
Konva._fixTextRendering = true;
|
|
||||||
|
|
||||||
var stage = new Konva.Stage({
|
var stage = new Konva.Stage({
|
||||||
container: 'container',
|
container: 'container',
|
||||||
width: stageWidth,
|
width: width,
|
||||||
height: stageHeight,
|
height: height,
|
||||||
});
|
});
|
||||||
|
|
||||||
Konva._fixTextRendering = true;
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
const layer = new Konva.Layer();
|
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
const shape = new Konva.Text({
|
var canvas = document.createElement('canvas');
|
||||||
x: 50,
|
// use external library to parse and draw gif animation
|
||||||
y: 50,
|
function onDrawFrame(ctx, frame) {
|
||||||
text: 'Hello',
|
// update canvas size
|
||||||
fontSize: 20,
|
canvas.width = frame.width;
|
||||||
fontFamily: 'Arial',
|
canvas.height = frame.height;
|
||||||
letterSpacing: 20,
|
// update canvas that we are using for Konva.Image
|
||||||
align: 'center',
|
ctx.drawImage(frame.buffer, 0, 0);
|
||||||
width: 500,
|
// redraw the layer
|
||||||
});
|
layer.draw();
|
||||||
layer.add(shape);
|
}
|
||||||
|
|
||||||
text.style.top = shape.y() + 'px';
|
gifler('https://konvajs.org/assets/yoda.gif').frames(canvas, onDrawFrame);
|
||||||
text.style.left = shape.x() + 'px';
|
|
||||||
|
function testKonvaImage() {
|
||||||
|
setInterval(() => {
|
||||||
|
const image = new Konva.Image({
|
||||||
|
image: canvas,
|
||||||
|
x: Math.random() * width,
|
||||||
|
y: Math.random() * height,
|
||||||
|
});
|
||||||
|
layer.add(image);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
image.image(canvas);
|
||||||
|
image.destroy();
|
||||||
|
}, 500);
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
testKonvaImage();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -572,7 +572,7 @@ describe('Text', function () {
|
|||||||
if (isBrowser) {
|
if (isBrowser) {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
layer.getContext().getTrace(false, true),
|
layer.getContext().getTrace(false, true),
|
||||||
"clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 14px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(HEADING,18,7);restore();save();fillStyle=black;fillText(,50,21);restore();save();fillStyle=black;fillText(All the world's,7,35);restore();save();fillStyle=black;fillText(a stage,,25,49);restore();save();fillStyle=black;fillText(merely,28,63);restore();save();fillStyle=black;fillText(players. They,7,77);restore();save();fillStyle=black;fillText(have…,27,91);restore();restore();"
|
"clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 14px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(HEADING,18,7);restore();save();fillStyle=black;fillText(,50,21);restore();save();fillStyle=black;fillText(All the world's a,1,35);restore();save();fillStyle=black;fillText(stage, merely,7,49);restore();save();fillStyle=black;fillText(players. They,7,63);restore();save();fillStyle=black;fillText(have theirrrrrrr,5,77);restore();save();fillStyle=black;fillText(exits and…,14,91);restore();restore();"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user