Showing preview only (1,998K chars total). Download the full file or copy to clipboard to get everything.
Repository: konvajs/konva
Branch: master
Commit: 811d62a3f458
Files: 162
Total size: 1.9 MB
Directory structure:
gitextract_6dbjwh6u/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE.md
│ └── workflows/
│ ├── build.yml
│ ├── prettier.yml
│ ├── release.yml
│ ├── test-browser.yml
│ └── test-node.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── gulpfile.mjs
├── package.json
├── release.sh
├── resources/
│ ├── doc-includes/
│ │ ├── ContainerParams.txt
│ │ ├── NodeParams.txt
│ │ └── ShapeParams.txt
│ └── jsdoc.conf.json
├── rollup.config.mjs
├── src/
│ ├── Animation.ts
│ ├── BezierFunctions.ts
│ ├── Canvas.ts
│ ├── Container.ts
│ ├── Context.ts
│ ├── Core.ts
│ ├── DragAndDrop.ts
│ ├── Factory.ts
│ ├── FastLayer.ts
│ ├── Global.ts
│ ├── Group.ts
│ ├── Layer.ts
│ ├── Node.ts
│ ├── PointerEvents.ts
│ ├── Shape.ts
│ ├── Stage.ts
│ ├── Tween.ts
│ ├── Util.ts
│ ├── Validators.ts
│ ├── _CoreInternals.ts
│ ├── _FullInternals.ts
│ ├── canvas-backend.ts
│ ├── filters/
│ │ ├── Blur.ts
│ │ ├── Brighten.ts
│ │ ├── Brightness.ts
│ │ ├── Contrast.ts
│ │ ├── Emboss.ts
│ │ ├── Enhance.ts
│ │ ├── Grayscale.ts
│ │ ├── HSL.ts
│ │ ├── HSV.ts
│ │ ├── Invert.ts
│ │ ├── Kaleidoscope.ts
│ │ ├── Mask.ts
│ │ ├── Noise.ts
│ │ ├── Pixelate.ts
│ │ ├── Posterize.ts
│ │ ├── RGB.ts
│ │ ├── RGBA.ts
│ │ ├── Sepia.ts
│ │ ├── Solarize.ts
│ │ └── Threshold.ts
│ ├── index.ts
│ ├── shapes/
│ │ ├── Arc.ts
│ │ ├── Arrow.ts
│ │ ├── Circle.ts
│ │ ├── Ellipse.ts
│ │ ├── Image.ts
│ │ ├── Label.ts
│ │ ├── Line.ts
│ │ ├── Path.ts
│ │ ├── Rect.ts
│ │ ├── RegularPolygon.ts
│ │ ├── Ring.ts
│ │ ├── Sprite.ts
│ │ ├── Star.ts
│ │ ├── Text.ts
│ │ ├── TextPath.ts
│ │ ├── Transformer.ts
│ │ └── Wedge.ts
│ ├── skia-backend.ts
│ └── types.ts
├── test/
│ ├── assets/
│ │ ├── tiger.ts
│ │ └── worldMap.ts
│ ├── bunnies.html
│ ├── ifame.html
│ ├── import-test.cjs
│ ├── import-test.mjs
│ ├── manual/
│ │ ├── Blur-test.ts
│ │ ├── Brighten-test.ts
│ │ ├── Contrast-test.ts
│ │ ├── Emboss-test.ts
│ │ ├── Enhance-test.ts
│ │ ├── Grayscale-test.ts
│ │ ├── HSL-test.ts
│ │ ├── HSV-test.ts
│ │ ├── Invert-test.ts
│ │ ├── Kaleidoscope-test.ts
│ │ ├── Manual-test.ts
│ │ ├── Mask-test.ts
│ │ ├── Noise-test.ts
│ │ ├── Pixelate-test.ts
│ │ ├── Posterize-test.ts
│ │ ├── RGB-test.ts
│ │ ├── RGBA-test.ts
│ │ ├── Sepia-test.ts
│ │ ├── Solarize-test.ts
│ │ └── Threshold-test.ts
│ ├── manual-tests.html
│ ├── node-canvas-global-setup.mjs
│ ├── node-skia-global-setup.mjs
│ ├── performance/
│ │ ├── bunnies_native.html
│ │ ├── creating_elements.html
│ │ └── jump-shape.html
│ ├── runner.js
│ ├── sandbox.html
│ ├── text-paths.html
│ ├── typescript/
│ │ └── event-delegation-test.ts
│ ├── unit/
│ │ ├── Animation-test.ts
│ │ ├── Arc-test.ts
│ │ ├── Arrow-test.ts
│ │ ├── AutoDraw-test.ts
│ │ ├── Blob-test.ts
│ │ ├── Canvas-test.ts
│ │ ├── Circle-test.ts
│ │ ├── Container-test.ts
│ │ ├── Context-test.ts
│ │ ├── DragAndDrop-test.ts
│ │ ├── DragAndDropEvents-test.ts
│ │ ├── Ellipse-test.ts
│ │ ├── Filter-test.ts
│ │ ├── Global-test.ts
│ │ ├── Group-test.ts
│ │ ├── Image-test.ts
│ │ ├── Label-test.ts
│ │ ├── Layer-test.ts
│ │ ├── Line-test.ts
│ │ ├── MouseEvents-test.ts
│ │ ├── Node-cache-test.ts
│ │ ├── Node-test.ts
│ │ ├── Path-test.ts
│ │ ├── PointerEvents-test.ts
│ │ ├── Polygon-test.ts
│ │ ├── Rect-test.ts
│ │ ├── RegularPolygon-test.ts
│ │ ├── Ring-test.ts
│ │ ├── Shape-test.ts
│ │ ├── Spline-test.ts
│ │ ├── Sprite-test.ts
│ │ ├── Stage-test.ts
│ │ ├── Star-test.ts
│ │ ├── Text-test.ts
│ │ ├── TextPath-test.ts
│ │ ├── TouchEvents-test.ts
│ │ ├── Transformer-test.ts
│ │ ├── Tween-test.ts
│ │ ├── Util-test.ts
│ │ ├── Wedge-test.ts
│ │ ├── imagediff.ts
│ │ └── test-utils.ts
│ └── unit-tests.html
├── tsconfig.json
└── tsconfig.test.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [lavrton]
patreon: lavrton
open_collective: konva
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
Thank you for submitting an issue!
Please make sure to check current open and closed issues to see if your question has been asked or answered before.
If you have just a question (not a bug or a feature request) it is better to ask it in [Stackoverflow](http://stackoverflow.com/questions/tagged/konvajs).
If you have a bug, please, try to create a reproducible example with jsfiddle (or any similar service).
You can use [this JSBIN](https://jsbin.com/necojavuma/edit?js,output) as a template.
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [23.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run build
================================================
FILE: .github/workflows/prettier.yml
================================================
name: check formatting
on:
pull_request:
jobs:
fmt-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: 'latest'
- run: npm install
- run: npm run fmt:check
================================================
FILE: .github/workflows/release.yml
================================================
---
name: 'tagged-release'
on:
push:
tags:
- '*'
jobs:
tagged-release:
name: 'Tagged Release'
runs-on: 'ubuntu-latest'
steps:
# ...
- name: 'Build & test'
run: |
echo "done!"
- uses: 'marvinpinto/action-automatic-releases@latest'
with:
repo_token: '${{ secrets.GITHUB_TOKEN }}'
prerelease: false
================================================
FILE: .github/workflows/test-browser.yml
================================================
name: Test Browser
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run test:browser
================================================
FILE: .github/workflows/test-node.yml
================================================
name: Test NodeJS
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [23.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run test:node
================================================
FILE: .gitignore
================================================
dist
es
.parcel-cache
test-build
documentation
analysis
node_modules
bower_components
phantomjs.exe
docs
homedocs
jsdoc-template
api
package-lock.json
lib
src_old
*.zip
*_cache
types
out.png
cmj
.test-temp
.history
.claude
# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.vi
*~
*.sass-cache
# OS or Editor folders
.DS_Store
Thumbs.db
.cache
.project
.settings
.tmproj
*.esproj
nbproject
*.sublime-project
*.sublime-workspace
*.md.html
.vscode
# Dreamweaver added files
_notes
dwsync.xml
# Komodo
*.komodoproject
.komodotools
# Folders to ignore
.hg
.svn
.CVS
intermediate
publish
.idea
konva.js
konva.min.js
================================================
FILE: CHANGELOG.md
================================================
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## 10.2.3 (2026-03-16)
- More crash fixes
## 10.2.1 (2026-03-13)
- Fix possible crash
## 10.2.0 (2026-01-15)
- Added `rotateAnchorAngle` property to `Transformer` to control the position of the rotation anchor around the bounding box
## 10.1.0 (2026-01-14)
- Added underline offset option and related test for Text Annotation
- Fixed large memory usage on cache
- Fix bounding box calculation for bezier lines
- Fixed cached render with buffer canvas is used
## 10.0.12 (2025-11-21)
- Better canvas farbling detection logic
## 10.0.11 (2025-11-20)
- Fixed broken release
## 10.0.10 (2025-11-20)
- Update hit detection system to handle canvas farbling. Hit detection should work better on Brave browser. Thanks [@wiverson](https://github.com/wiverson) to the idea and implementation idea.
## 10.0.9 (2025-11-08)
- Fixed line-through rendering when letter spacing is used
## 10.0.8 (2025-10-24)
- Fixed opacity level when a cached shape has opacity, fill and stroke
## 10.0.7 (2025-10-22)
- Fixed image element size re-calculation when change is changed with transformer is used.
## 10.0.6 (2025-10-22)
- Better `Image.getClientRect()` calculation if an instance has no image attached yet
## 10.0.5 (2025-10-22)
- Simplify types to fix TS errors
## 10.0.4 (2025-10-21)
- Remove logs
## 10.0.3 (2025-10-21)
- Add text decoration options to TextPath: support for 'line-through' and combined styles with 'underline'
## 10.0.2 (2025-09-10)
- Fixed internal calculations for `TextPath` to return correct width and height
## 10.0.1 (2025-09-09)
- Fixed `line-through` render for center/right aligned text
## 10.0.0 (2025-09-07)
### Breaking Changes
- **Breaking**: Konva module is fully migrated from CommonJS modules to ES modules. It may break some older bundlers and CommonJS environments. In CommonJS environment you have to use default property from require:
```js
// before
const Konva = require('konva');
// after
const Konva = require('konva').default;
```
- **Breaking:** Dropped default support for node.js environment. Now you have to explicitly import it:
```bash
npm install canvas
```
```js
import Konva from 'konva';
import 'konva/canvas-backend';
```
Motivation: With increased usage of `konva` in SSR environments like Next.js, loading native canvas rendering on the server is unnecessary since we don't render canvas content server-side. Removing this requirement simplifies setup by avoiding native modules when they aren't needed.
- Improved text positioning to match DOM/CSS rendering. To restore previous behaviour use `Konva.legacyTextRendering = true`. This should NOT break major part of the apps. But if you care about pixel-perfect position of text elements, that change may effect you.
### New Features
- Added new `skia` render backend for node.js:
```bash
npm install skia-canvas
```
```js
import Konva from 'konva';
import 'konva/skia-backend';
```
- Native filters support via `node.filters(['blur(10px)'])`. Native fitlers works MUCH faster if supported nativily (Chrome, Firefox). If there is no native support, Konva will automatially fallback to functional filter (on Safari).
```js
node.filters(['blur(10px')]);
node.cache();
```
- New property `charRenderFunc` for `Konva.Text` for controlling "per-character-render". May be useful any character animations:
```js
var text = new Konva.Text({
x: 10,
y: 10,
text: 'AB',
fontSize: 20,
charRenderFunc: function ({ context, index }) {
if (index === 1) {
// shift only the second character
context.translate(0, 10);
}
},
});
```
- **New**: Added `Konva.Filters.Brightness` filter in replace of deprecated `Konva.Filters.Brighten` to better match with css filters logic.
- Added `cornerRadius` support for `Konva.RegularPolygon`
- Added `miterLimit` property support for `Konva.Shape` to control line join appearance
### Bug Fixes
- Fixed corner radius render for `Konva.Rect` when negative width or height are used
- Fixed TextPath rendering on right align for some fonts
- Fixed crash when node inside transformer was destroyed
- Fixed mouseup + click events order when clicked on empty area of stage
- Fixed transformer drag behavior with non-draggable nodes
### Technical Improvements
- **Performance**: Rewrote Emboss and Solarize filters for improved performance and usability
- Changed return type of `node.toImage()`
- Brave detection and warning
## 9.3.22 (2025-07-08)
- Fixed possible crash on `node.to()` method
## 9.3.21 (2025-07-07)
- Fixed memory leaks on Tween destroy
- Fixed incorrect export of stage/layer when internal nodes used buffer canvas for rendering
- Fixed incorrect render of cached node when buffer canvas is used
- Fixed incorrect path lenth calculations
- Fixed `pointerleave` bubbling
- Added `pointerleave` event in `Stage`
## 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)
- Fixed emoji split in multiple lines
## 9.3.17 (2024-12-23)
- Fixed `Arrow.getClientRect()`
- Fixed emoji rendering with letterSpacing
- Fixed line-through for justify text
- Changes in letter spacing width calculations to match DOM rendering
## 9.3.16 (2024-10-21)
- Fix freeze on ios on touch cancel event
- Typescript fixes
## 9.3.15 (2024-09-09)
- fix letter spacing for Hindi text
- ts fixes
### 9.3.14 (2024-07-16)
- Fix shadow + corner radius for images
- Support `fillRule` for `Konva.Shape` on hit graph
### 9.3.13 (2024-07-05)
- Fallback for `Konva.Text.measureSize()` when 2d context doesn't return full data
### 9.3.12 (2024-06-20)
- Fix stopped transforming when it was triggered by multi-touch
- Fix svg `path.getPointAtLength()` calculations in some cases
- Fix `shape.getClientRect()` when any of parents is cached
### 9.3.11 (2024-05-23)
- Fix chrome clear canvas issue
- Typescript fixes
### 9.3.9 (2024-05-20)
- Fix underline and line-through for `Konva.Text` when `Konva._fixTextRendering = true`
### 9.3.8 (2024-05-15)
- Fix click events fires on stage
- Temporary `Konva._fixTextRendering = true` flag to fix inconsistent text
### 9.3.6 (2024-03-04)
- Fix transformer bug to enable hit graph back
### 9.3.5 (2024-03-04)
- `tranformer` event will be triggered AFTER all data of transformer is updated
- Improve performance of transformer
### 9.3.4 (2024-03-03)
- Fix clipping with zero size
### 9.3.3 (2024-02-09)
- Another fix for exporting buffered shapes
### 9.3.2 (2024-01-26)
- Fix large memory usage on node export
### 9.3.1 (2024-01-17)
- Fix Pixelate filter work/fix caching size
- Fix node export when large buffer canvas is used
### 9.3.0 (2023-12-20)
- New attribute `rotateLineVisible` for `Konva.Transformer` to show/hide rotate line
### 9.2.3 (2023-10-31)
- Better `Konva.Transformer` work when it has `flipEnabled = false`.
### 9.2.2 (2023-09-14)
- Better RTL support
- Some typescript fixes
### 9.2.1 (2023-09-14)
- Fix text rendering when text has both underline and shadow
- Typescript fixes
### 9.2.0 (2023-05-14)
- More controls on clipping
- `fillRule` for `Konva.Shape`
### 9.1.0 (2023-05-14)
- New `anchorStyleFunc` for `Konva.Transformer` to customize anchor style
### 9.0.2 (2023-05-14)
- Better text rendering when it has stroke
### 9.0.1 (2023-04-17)
- Better performance for any instance creation
- Little typescript fixes
### 9.0.0 (2023-04-13)
- Migrate the npm package from ES back to CommonJS
### 8.4.4 (2023-04-05)
- Some fixes for `Konva.TextPath` calculations and rendering.
- Resolve "willReadFrequently" warning in Chrome
### 8.4.3 (2023-03-23)
- Typescript fixes
- Better validation for `Konva.Transfomer` `nodes` property
### 8.4.2 (2023-01-20)
- Fix justify on text with limited height
### 8.4.1 (2023-01-19)
- Typescript fixes for `container.add()` method. Ability to use empty array as argument. E.g. `container.add(...emptyArray)`
- Fix underline for justify text
- Fix gradient display on underline or line-through text
### 8.4.0 (2023-01-05)
- Add support for `cornerRadius` for Konva.Image
- Fix cloning of `Konva.Transformer`
### 8.3.14 (2022-11-09)
- Automatically release (destroy) used canvas elements. Should fix safari memory issues
### 8.3.13 (2022-10-03)
- Typescript fixes
- Better non-passive events usage
- Better 2d context usage to avoid Chrome warnings
### 8.3.12 (2022-08-29)
- `ellipsis` fixes for `Konva.Text`
- Allow reset component attributes via overloader
### 8.3.11 (2022-08-05)
- Fix `Konva.Label` position when tag attributes are changed
- Fix incorrect ellipsis display for `Konva.Text`
- Fix `click` event trigger on parent containers on touch devices
- Fix incorrect `mouseleave` event trigger when drag is finished
### 8.3.10 (2022-06-20)
- Skip `Konva.Transformer` in `container.getClientRect()` calculations
### 8.3.9 (2022-05-27)
- Typescript fixes
### 8.3.8 (2022-05-05)
- Disable all exports in `package.json`
### 8.3.7 (2022-05-04)
- Migrate to CommonJS exports only
### 8.3.6 (2022-04-27)
- Better exports definitions. Importing `Konva` should work better in different bundlers and test environments.
- `imageSmoothingEnabled` option for `node.toDataURL()`, `node.toCanvas()` and `node.toImage()`
## 8.3.5 (2022-03-21)
- Quick fix for `toCanvas()` and `toDataURL()` size calculation.
## 8.3.4 (2022-03-13)
- Fix characters positions calculations on `fontFamily` changes in `TextPath`.
- Remove rounding in `node.getClientRect()` results
- Fix event object on `transformstart` event.
## 8.3.3 (2022-02-23)
- Fix `justify` align for text with several paragraphs.
## 8.3.2
- Remove source maps for webpack builds
## 8.3.1 (2021-12-09)
- Fix `dbltap` event in Safari
- A bit faster `node.moveToTop()` when node is already on top
- Better client rect calculations for `Konva.Arc` shape.
## 8.3.0 (2021-11-15)
- new `transformer.anchorDragBoundFunc` method.
## 8.2.4 (2021-11-15)
- Fix not working `Konva.Transformer` when several transformers were used
## 8.2.2
- Fix `Konva.Arrow` rendering when it has two pointers
## 8.2.1
- Fix `package.json` exports.
## 8.2.0
- Restore build in CommonJS. `const Konva = require('konva/cmj').default;`
- Fix arrow rendering when dash is used
- Fix `dbltap` trigger when multi-touch is used
## 8.1.4
- Fix `dblclick` event when `cancelBubble` is used.
## 8.1.3
- Fix `fillPattern` cache invalidation on shapes
## 8.1.2
- Fix memory leak for `Konva.Image`
## 8.1.1
- Fix `Konva.Transformer` dragging draw when `shouldOverdrawWholeArea = true`.
- Fix auto redraw when `container.removeChildren()` or `container.destroyChildren()` are used
## 8.1.0
- New property `useSingleNodeRotation` for `Konva.Transformer`.
## 8.0.4
- Fix fill pattern updates on `fillPatternX` and `fillPatternY` changes.
## 8.0.2
- Fix some transform caches
- Fix cache with hidden shapes
## 8.0.1
- Some typescript fixes
## 8.0.0
This is a very large release! The long term of `Konva` API is to make it simpler and faster. So when possible I am trying to optimize the code and remove unpopular/confusing API methods.
**BREAKING:**
- `Konva.Collection` is removed. `container.children` is a simple array now. `container.find()` will returns an array instead of `Konva.Collection()` instance.
`Konva.Collection` was confusing for many users. Also it was slow and worked with a bit of magic. So I decided to get rif of it. Now we are going to use good old arrays.
```js
// old code:
group.find('Shape').visible(false);
// new code:
group.find('Shape').forEach((shape) => shape.visible(false));
```
- argument `selector` is removed from `node.getIntersection(pos)` API. I don't think you even knew about it.
- `Konva.Util.extend` is removed.
- All "content" events from `Konva.Stage` are removed. E.g. instead of `contentMousemove` just use `mousemove` event.
**New features:**
- All updates on canvas will do automatic redraw with `layer.batchDraw()`. This features is configurable with `Konva.autoDrawEnabled` property. Konva will automatically redraw layer when you change any property, remove or add nodes, do caching. So you don't need to call `layer.draw()` or `layer.batchDraw()` in most of the cases.
- New method `layer.getNativeCanvasElement()`
- new `flipEnabled` property for `Konva.Transformer`
- new `node.isClientRectOnScreen()` method
- Added `Konva.Util.degToRad` and `Konva.Util.radToDeg`
- Added `node.getRelativePointerPosition()`
**Changes and fixes:**
- **Full migration to ES modules package (!), commonjs code is removed.**
- **`konva-node` is merged into `konva` npm package. One package works for both environments.**
- Full event system rewrite. Much better `pointer` events support.
- Fix `TextPath` recalculations on `fontSize` change
- Better typescript support. Now every module has its own `*.d.ts` file.
- Removed `Konva.UA`, `Konva._parseUA` (it was used for old browser detection)
- Fixed Arrow head position when an arrow has tension
- `textPath.getKerning()` is removed
- Fix `a` command parsing for `Konva.Path`
- Fix fill pattern for `Konva.Text` when the pattern has an offset or rotation
- `Konva.names` and `Konva.ids` are removed
- `Konva.captureTouchEventsEnabled` is renamed to `Konva.capturePointerEventsEnabled`
## 7.2.5
- Fix transform update on `letterSpacing` change of `Konva.Text`
## 7.2.4
- Fix wrong `mouseleave` trigger for `Konva.Stage`
## 7.2.3
- Fix transformer rotation when parent of a node is rotated too.
## 7.2.2
- Fix wrong size calculations for `Konva.Line` with tension
- Fix `shape.intersects()` behavior when a node is dragged
- Fix ellipsis rendering for `Konva.Text`
## 7.2.1
- Fix correct rendering of `Konva.Label` when heigh of text is changed
- Fix correct `transformstart` and `transformend` events when several nodes are attached with `Konva.Transformer`
## 7.2.0
- New property `fillAfterStrokeEnabled` for `Konva.Shape`. See API docs for more information.
- Fix for `Konva.Transformer` when it may fail to draw.
- Fix rendering of `TextPath` one more time.
## 7.1.9
- Fix autodrawing for `Konva.Transformer` when it is on a different layer
- Fix `Konva.RegularPolygon` size calculations.
## 7.1.8
- Fix incorrect rendering of `TextPath` in some cases. (again)
## 7.1.7
- Fix incorrect rendering of `TextPath` in some cases.
## 7.1.6
- Fix for correct image/dataURL/canvas exports for `Konva.Stage`.
## 7.1.5
- Performance fixes for dragging many nodes with `Konva.Transformer`.
- Documentation updates
## 7.1.4
- Perf fixes
- Change events trigger flow, so adding new events INSIDE event callback will work correctly.
- Fix double `dragend`, `dragstart`, `dragmove` triggers on `Konva.Transformer`
## 7.1.3
- Text rendering fixes
## 7.1.2
- fix ellipses behavior for `Konva.Text`.
- fix scaled fill pattern for text.
## 7.1.1
- fixes for `dragstart` event when `Konva.Transformer` is used. `dragstart` event will have correct native `evt` reference
- Better unicode support in `Konva.Text` and `Konva.TextPath`. Emoji should work better now 👍
## 7.1.0
- Multi row support for `ellipsis` config for `Konva.Text`
- Better `Konva.Transfomer` behavior when single attached node is programmatically rotated.
## 7.0.7
- fixes for `dragstart` event when `Konva.Transformer` is used. `dragstart` will not bubble from transformer.
- `string` and `fill` properties validation can accept `CanvasGradient` as valid value
## 7.0.6
- Better performance for stage dragging
## 7.0.5
- Fixes for `node.cache()` function.
## 7.0.4
- Add `onUpdate` callbacks to `Konva.Tween` configuration and `node.to()` method.
- Up to 6x faster initializations of objects, like `const shape = new Konva.Shape()`.
## 7.0.3 - 2020-07-09
- Fix wring `dragend` trigger on `draggable` property change inside `click`
- Fix incorrect text rendering with `letterSpacing !== 0`
- Typescript fixes
## 7.0.2 - 2020-06-30
- Fix wrong trigger `dbltap` and `click` on mobile
## 7.0.1 - 2020-06-29
- Fixes for different font families support.
- Fixes for `Konva.Transformer` positions
- Types fixes for better Typescript support
## 7.0.0 - 2020-06-23
- **BREAKING** `inherit` option is removed from `visible` and `listening`. They now just have boolean values `true` or `false`. If you do `group.listening(false);` then whole group and all its children will be removed from the hitGraph (and they will not listen to events). Probably 99% `Konva` applications will be not affected by this _breaking change_.
- **Many performance fixes and code size optimizations. Up to 70% performance boost for many moving nodes.**
- `layer.hitGraphEnabled()` is deprecated. Just use `layer.listening(false)` instead
- Better support for font families with spaces inside (like `Font Awesome 5`).
- Fix wrong `dblclick` and `dbltap` triggers
- Deprecate `Konva.FastLayer`. Use `new Konva.Layer({ listening: false });` instead.
- `dragmove` event will be fired on `Konva.Transformer` too when you drag a node.
- `dragmove` triggers only after ALL positions of dragging nodes are changed
## 6.0.0 - 2020-05-08
- **BREAKING!** `boundBoxFunc` of `Konva.Transformer` works in absolute coordinates of whole transformer. Previously in was working in local coordinates of transforming node.
- Many `Konva.Transformer` fixes. Now it works correctly when you transform several rotated shapes.
- Fix for wrong `mouseleave` and `mouseout` fire on shape remove/destroy.
## 5.0.3 - 2020-05-01
- Fixes for `boundBoxFunc` of `Konva.Transformer`.
## 5.0.2 - 2020-04-23
- Deatach fixes for `Konva.Transformer`
## 5.0.1 - 2020-04-22
- Fixes for `Konva.Transformer` when parent scale is changed
- Fixes for `Konva.Transformer` when parent is draggable
- Performance optimizations
## 5.0.0 - 2020-04-21
- **New `Konva.Transformer` implementation!**. Old API should work. But I marked this release is `major` (breaking) just for smooth updates. Changes:
- Support of transforming multiple nodes at once: `tr.nodes([shape1, shape2])`.
- `tr.node()`, `tr.setNode()`, `tr.attachTo()` methods are deprecated. Use `tr.nodes(array)` instead
- Fixes for center scaling
- Fixes for better `padding` support
- `Transformer` can be placed anywhere in the tree of a stage tree (NOT just inside a parent of attached node).
- Fix `imageSmoothEnabled` resets when stage is resized
- Memory usage optimizations when a node is cached
## 4.2.2 - 2020-03-26
- Fix hit stroke issues
## 4.2.1 - 2020-03-26
- Fix some issues with `mouseenter` and `mouseleave` events.
- Deprecate `hitStrokeEnabled` property
- Fix rounding issues for `getClientRect()` for some shapes
## 4.2.0 - 2020-03-14
- Add `rotationSnapTolerance` property to `Konva.Transformer`.
- Add `getActiveAnchor()` method to `Konva.Transformer`
- Fix hit for non-closed `Konva.Path`
- Some fixes for experimental Offscreen canvas support inside a worker
## 4.1.6 - 2020-02-25
- Events fixes for `Konva.Transformer`
- Now `Konva` will keep `id` in a cloned node
- Better error messages on tainted canvas issues
## 4.1.5 - 2020-02-16
- Fixes for `path.getClientRect()` function calculations
## 4.1.4 - 2020-02-10
- Fix wrong internal caching of absolute attributes
- Fix `Konva.Transformer` behavior on scaled with CSS stage
## 4.1.3 - 2020-01-30
- Fix line with tension calculations
- Add `node.getAbsoluteRotation()` method
- Fix cursor on anchors for rotated parent
## 4.1.2 - 2020-01-08
- Fix possible `NaN` in content calculations
## 4.1.1 - 2020-01-07
- Add ability to use `width = 0` and `height = 0` for `Konva.Image`.
- Fix `cache()` method of `Konva.Arrow()`
- Add `Transform` to `Konva` default exports. So `Konva.Transform` is available now.
## 4.1.0 - 2019-12-23
- Make events work on some CSS transforms
- Fix caching on float dimensions
- Fix `mouseleave` event on stage.
- Increase default anchor size for `Konva.Transformer` on touch devices
## 4.0.18 - 2019-11-20
- Fix `path.getClientRect()` calculations for `Konva.Path`
- Fix wrong fire of `click` and `tap` events on stopped drag events.
## 4.0.17 - 2019-11-08
- Allow hitStrokeWidth usage, even if a shape has not stroke visible
- Better IE11 support
## 4.0.16 - 2019-10-21
- Warn on undefined return value of `dragBoundFunc`.
- Better calculations for `container.getClientRect()`
## 4.0.15 - 2019-10-15
- TS fixes
- Better calculations for `TextPath` with align = right
- Better `textPath.getClientRect()`
## 4.0.14 - 2019-10-11
- TS fixes
- Fix globalCompositeOperation + cached hit detections.
- Fix absolute position calculations for cached parent
## 4.0.13 - 2019-10-02
- Fix `line.getClientRect()` calculations for line with a tension or low number of points
## 4.0.12 - 2019-09-17
- Fix some bugs when `Konva.Transformer` has `padding > 0`
## 4.0.10 - 2019-09-10
- Fix drag position handling
- Fix multiple selector for find() method
## 4.0.9 - 2019-09-06
- Fix `Konva.Transformer` behavior on mirrored nodes
- Fix `stage.getPointerPosition()` logic.
## 4.0.8 - 2019-09-05
- Fix `dragend` event on click
- Revert fillPatternScale for text fix.
## 4.0.7 - 2019-09-03
- Fixed evt object on `dragstart`
- Fixed double tap trigger after dragging
## 4.0.6 - 2019-08-31
- Fix fillPatternScale for text
## 4.0.5 - 2019-08-17
- Fix `dragstart` flow when `node.startDrag()` is called.
- Fix `tap` and `dbltap` double trigger on stage
## 4.0.4 - 2019-08-12
- Add `node.isCached()` method
- Fix nested dragging bug
## 4.0.3 - 2019-08-08
- Slightly changed `mousemove` event flow. It triggers for first `mouseover` event too
- Better `Konva.hitOnDragEnabled` support for mouse inputs
## 4.0.2 - 2019-08-08
- Fixed `node.startDrag()` behavior. We can call it at any time.
## 4.0.1 - 2019-08-07
- Better `Konva.Arrow` + tension drawing
- Typescript fixes
## 4.0.0 - 2019-08-05
Basically the release doesn't have any breaking changes. You may only have issues if you are using something from `Konva.DD` object (which is private and never documented). Otherwise you should be fine. `Konva` has major upgrade about touch events system and drag&drop flow. The API is exactly the same. But the internal refactoring is huge so I decided to make a major version. Please upgrade carefully. Report about any issues you have.
- Better multi-touch support. Now we can trigger several `touch` events on one or many nodes.
- New drag&drop implementation. You can drag several shapes at once with several pointers.
- HSL colors support
## 3.4.1 - 2019-07-18
- Fix wrong double tap trigger
## 3.4.0 - 2019-07-12
- TS types fixes
- Added support for different values for `cornerRadius` of `Konva.Rect`
## 3.3.3 - 2019-06-07
- Some fixes for better support `konva-node`
- TS types fixes
## 3.3.2 - 2019-06-03
- TS types fixes
## 3.3.1 - 2019-05-28
- Add new property `imageSmoothingEnabled` to the node caching
- Even more ts fixes. Typescript need a lot of attention, you know...
## 3.3.0 - 2019-05-28
- Enable strict mode for ts types
- Add new property `imageSmoothingEnabled` to the layer
## 3.2.7 - 2019-05-27
- Typescript fixes
- Experimental pointer events support. Do `Konva._pointerEventsEnabled = true;` to enable
- Fix some `Konva.Transformer` bugs.
## 3.2.6 - 2019-05-09
- Typescript fixes again
## 3.2.5 - 2019-04-17
- Show a warning when `Konva.Transformer` and attaching node have different parents.
- Typescript fixes
## 3.2.4 - 2019-04-05
- Fix some stage events. `mouseenter` and `mouseleave` should work correctly on empty spaces
- Fix some typescript types
- Better detection of production mode (no extra warnings)
## 3.2.3 - 2019-03-21
- Fix `hasName` method for empty name cases
## 3.2.2 - 2019-03-19
- Remove `dependencies` from npm package
## 3.2.1 - 2019-03-18
- Better `find` and `findOne` lookup. Now we should not care about duplicate ids.
- Better typescript definitions
## 3.2.0 - 2019-03-10
- new property `shape.hitStrokeWidth(10)`
- Better typescript definitions
- Remove `Object.assign` usage (for IE11 support)
## 3.1.7 - 2019-03-06
- Better modules and TS types
## 3.1.6 - 2019-02-27
- Fix commonjs exports
- Fix global injections
## 3.1.0 - 2019-02-27
- Make `Konva` modular: `import Konva from 'konva/lib/Core';`;
- Fix incorrect `Transformer` behavior
- Fix drag&drop for touch devices
## 3.0.0 - 2019-02-25
## Breaking
Customs builds are temporary removed from npm package. You can not use `import Konva from 'konva/src/Core';`.
This feature will be added back later.
### Possibly breaking
That changes are private and internal specific. They should not break most of `Konva` apps.
- `Konva.Util.addMethods` is removed
- `Konva.Util._removeLastLetter` is removed
- `Konva.Util._getImage` is removed
- `Konv.Util._getRGBAString` is removed
- `Konv.Util._merge` is removed
- Removed polyfill for `requestAnimationFrame`.
- `id` and `name` properties defaults are empty strings, not `undefined`
- internal `_cache` property was updated to use es2015 `Map` instead of `{}`.
- `Konva.Validators` is removed.
### Added
- Show a warning when a stage has too many layers
- Show a warning on duplicate ids
- Show a warning on weird class in `Node.create` parsing from JSON
- Show a warning for incorrect value for component setters.
- Show a warning for incorrect value for `zIndex` property.
- Show a warning when user is trying to reuse destroyed shape.
- new publish method `measureSize(string)` for `Konva.Text`
- You can configure what mouse buttons can be used for drag&drop. To enable right button you can use `Konva.dragButtons = [0, 1]`.
- Now you can hide stage `stage.visible(false)`. It will set its container display style to "none".
- New method `stage.setPointersPositions(event)`. Usually you don't need to use it manually.
- New method `layer.toggleHitCanvas()` to show and debug hit areas
### Changed
- Full rewrite to Typescript with tons of refactoring and small optimizations. The public API should be 100% the same
- Fixed `patternImage` and `radialGradient` for `Konva.Text`
- `Konva.Util._isObject` is renamed to `Konva.Util._isPlainObject`.
- A bit changed behavior of `removeId` (private method), now it doesn't clear node ref, if object is changed.
- simplified `batchDraw` method (it doesn't use `Konva.Animation`) now.
- Performance improvements for shapes will image patterns, linear and radial fills
- `text.getTextHeight()` is deprecated. Use `text.height()` or `text.fontSize()` instead.
- Private method `stage._setPointerPosition()` is deprecated. Use `stage.setPointersPositions(event)`;
### Fixed
- Better mouse support on mobile devices (yes, that is possible to connect mouse to mobile)
- Better implementation of `mouseover` event for stage
- Fixed underline drawing for text with `lineHeight !== 1`
- Fixed some caching behavior when a node has `globalCompositeOperation`.
- Fixed automatic updates for `Konva.Transformer`
- Fixed container change for a stage.
- Fixed warning for `width` and `height` attributes for `Konva.Text`
- Fixed gradient drawing for `Konva.Text`
- Fixed rendering with `strokeWidth = 0`
## 2.6.0 - 2018-12-14
### Changed
- Performance fixes when cached node has many children
- Better drawing for shape with `strokeScaleEnabled = false` on HDPI devices
### Added
- New `ignoreStroke` for `Konva.Transformer`. Good to use when a shape has `strokeScaleEnabled = false`
### Changed
- `getKerning` TextPath API is deprecated. Use `kerningFunc` instead.
## 2.5.1 - 2018-11-08
### Changed
- Use custom functions for `trimRight` and `trimLeft` (for better browsers support)
## 2.5.0 - 2018-10-24
### Added
- New `anchorCornerRadius` for `Konva.Transformer`
### Fixed
- Performance fixes for caching
### Changed
- `dragstart` event behavior is a bit changed. It will fire BEFORE actual position of a node is changed.
## 2.4.2 - 2018-10-12
### Fixed
- Fixed a wrong cache when a shape inside group has `listening = false`
## 2.4.1 - 2018-10-08
### Changed
- Added some text trim logic to wrap in better
### Fixed
- `getClientRect` for complex paths fixes
- `getClientRect` calculation fix for groups
- Update `Konva.Transformer` on `rotateEnabled` change
- Fix click stage event on dragend
- Fix some Transformer cursor behavior
## 2.4.0 - 2018-09-19
### Added
- Centered resize with ALT key for `Konva.Transformer`
- New `centeredScaling` for `Konva.Transformer`
### Fixed
- Tween support for gradient properties
- Add `user-select: none` to the stage container to fix some "selected contend around" issues
## 2.3.0 - 2018-08-30
### Added
- new methods `path.getLength()` and `path.getPointAtLength(val)`
- `verticalAlign` for `Konva.Text`
## 2.2.2 - 2018-08-21
### Changed
- Default duration for tweens and `node.to()` methods is now 300ms
- Typescript fixes
- Automatic validations for many attributes
## 2.2.1 - 2018-08-10
### Added
- New properties for `Konva.Transformer`: `borderStroke`, `borderStrokeWidth`, `borderDash`, `anchorStroke`, `anchorStrokeWidth`, `anchorSize`.
### Changed
- Some properties of `Konva.Transformer` are renamed. `lineEnabled` -> `borderEnabled`. `rotateHandlerOffset` -> `rotateAnchorOffset`, `enabledHandlers` -> `enabledAnchors`.
## 2.1.8 - 2018-08-01
### Fixed
- Some `Konva.Transformer` fixes
- Typescript fixes
- `stage.toDataURL()` fixes when it has hidden layers
- `shape.toDataURL()` automatically adjust position and size of resulted image
## 2.1.7 - 2018-07-03
### Fixed
- `toObject` fixes
## 2.1.7 - 2018-07-03
### Fixed
- Some drag&drop fixes
## 2.1.6 - 2018-06-16
### Fixed
- Removed wrong dep
- Typescript fixes
## 2.1.5 - 2018-06-15
### Fixed
- Typescript fixes
- add shape as second argument for `sceneFunc` and `hitFunc`
## 2.1.4 - 2018-06-15
### Fixed
- Fixed `Konva.Text` justify drawing for a text with decoration
- Added methods `data()`,`setData()` and `getData()` methods to `Konva.TextPath`
- Correct cache reset for `Konva.Transformer`
## 2.1.3 - 2018-05-17
### Fixed
- `Konva.Transformer` automatically track shape changes
- `Konva.Transformer` works with shapes with offset too
## 2.1.2 - 2018-05-16
### Fixed
- Cursor fixes for `Konva.Transformer`
- Fixed lineHeight behavior for `Konva.Text`
- Some performance optimizations for `Konva.Text`
- Better wrap algorithm for `Konva.Text`
- fixed `Konva.Arrow` with tension != 0
- Some fixes for `Konva.Transformer`
## 2.0.3 - 2018-04-21
### Added
- Typescript defs for `Konva.Transformer`
- Typescript defs for `globalCompositeOperation`
## Changes
- Fixed flow for `contextmenu` event. Now it will be triggered on shapes too
- `find()` method for Containers can use a function as a parameter
### Fixed
- some bugs fixes for `group.getClientRect()`
- `Konva.Arrow` will not draw dash for pointers
- setAttr will trigger change event if new value is the same Object
- better behavior of `dblclick` event when you click fast on different shapes
- `stage.toDataURL` will use `pixelRatio = 1` by default.
## 2.0.2 - 2018-03-15
### Fixed
- Even more bugs fixes for `Konva.Transformer`
## 2.0.1 - 2018-03-15
### Fixed
- Several bugs fixes for `Konva.Transformer`
## 2.0.0 - 2018-03-15
### Added
- new `Konva.Transformer`. It is a special group that allow simple resizing and rotation of a shape.
- Add ability to remove event by callback `node.off('event', callback)`.
- new `Konva.Filters.Contrast`.
- new `Konva.Util.haveIntersection()` to detect simple collusion
- add `Konva.Text.ellipsis` to add '…' to text string if width is fixed and wrap is set to 'none'
- add gradients for strokes
## Changed
- stage events are slightly changed. `mousedown`, `click`, `mouseup`, `dblclick`, `touchstart`, `touchend`, `tap`, `dbltap` will be triggered when clicked on empty areas too
### Fixed
- Some typescript fixes
- Pixelate filter fixes
- Fixes for path data parsing
- Fixed shadow size calculation
## Removed
- Some deprecated methods are removed. If previous version was working without deprecation warnings for you, this one will work fine too.
## 1.7.6 - 2017-11-01
### Fixed
- Some typescript fixes
## 1.7.4 - 2017-10-30
### Fixed
- `isBrowser` detection for electron
## 1.7.3 - 2017-10-19
### Changed
- Changing size of a stage will redraw it in synchronous way
### Fixed
- Some fixes special for nodejs
## 1.7.2 - 2017-10-11
### Fixed
- Fixed `Konva.document is undefined`
## 1.7.1 - 2017-10-11
### Changed
- Konva for browser env and Konva for nodejs env are separate packages now. You can use `konva-node` for NodeJS env.
## 1.7.0 - 2017-10-08
### Fixed
- Several typescript fixes
### Changed
- Default value for `dragDistance` is changed to 3px.
- Fix rare error throw on drag
- Caching with height = 0 or width = 0 with throw async error. Caching will be ignored.
## 1.6.8 - 2017-08-19
### Changed
- The `node.getClientRect()` calculation is changed a bit. It is more powerfull and correct. Also it takes parent transform into account. See docs.
- Upgrade nodejs deps
## 1.6.7 - 2017-07-28
### Fixed
- Fix bug with double trigger wheel in Firefox
- Fix `node.getClientRect()` calculation in a case of Group + invisible child
- Fix dblclick issue https://github.com/konvajs/konva/issues/252
## 1.6.3 - 2017-05-24
### Fixed
- Fixed bug with pointer detection. css 3d transformed stage will not work now.
## 1.6.2 - 2017-05-08
### Fixed
- Fixed bug with automatic shadow for negative scale values
## 1.6.1 - 2017-04-25
### Fixed
- Fix pointer position detection
### Changed
- moved `globalCompositeOperation` property to `Konva.Node`
## 1.6.0 - 2017-04-21
### Added
- support of globalCompositeOperation for `Konva.Shape`
### Fixed
- getAllIntersections now works ok for Text shapes (https://github.com/konvajs/konva/issues/224)
### Changed
- Konva a bit changed a way to detect pointer position. Now it should be OK to apply css transform on Konva container. https://github.com/konvajs/konva/pull/215
## 1.5.0 - 2017-03-20
### Added
- support for `lineDashOffset` property for `Konva.Shape`.
## 1.4.0 - 2017-02-07
## Added
- `textDecoration` of `Konva.Text` now supports `line-through`
## 1.3.0 - 2017-01-10
## Added
- new align value for `Konva.Text` and `Konva.TextPath`: `justify`
- new property for `Konva.Text` and `Konva.TextPath`: `textDecoration`. Right now it sports only '' (no decoration) and 'underline' values.
- new property for `Konva.Text`: `letterSpacing`
- new event `contentContextmenu` for `Konva.Stage`
- `align` support for `Konva.TextPath`
- new method `toCanvas()` for converting a node into canvas element
### Changed
- changing a size of `Konva.Stage` will update it in async way (via `batchDraw`).
- `shadowOffset` respect pixel ratio now
### Fixed
- Fixed bug when `Konva.Tag` width was not changing its width dynamically
- Fixed "calling remove() for dragging shape will throw an error"
- Fixed wrong opacity level for cached group with opacity
- More consistent shadows on HDPI screens
- Fixed memory leak for nodes with several names
## 1.2.2 - 2016-09-15
### Fixed
- refresh stage hit and its `dragend`
- `getClientRect` calculations
## 1.2.0 - 2016-09-15
## Added
- new properties for `Konva.TextPath`: `letterSpacing` and `textBaseline`.
## 1.1.4 - 2016-09-13
### Fixed
- Prevent throwing an error when text property of `Konva.Text` = undefined or null
## 1.1.3 - 2016-09-12
### Changed
- Better hit function for `TextPath`.
- Validation of `Shape` filters.
## 1.1.2 - 2016-09-10
### Fixed
- Fixed "Dragging Group on mobile view throws "missing preventDefault" error" #169
## 1.1.1 - 2016-08-30
### Fixed
- Fixed #166 bug of drag&drop
## 1.1.0 - 2016-08-21
## Added
- new property of `Konva.Shape` - `preventDefault`.
## 1.0.3 - 2016-08-14
### Fixed
- Fixed some typescript definitions
## 1.0.2 - 2016-07-08
## Changed
- `Konva.Text` will interpret undefined `width` and `height` as `AUTO`
## 1.0.1 - 2016-07-05
### Changed
- you can now unset property by `node.x(undefined)` or `node.setAttr('x', null)`
### Fixed
- Bug fix for case when `touchend` event throws error
## 1.0.0 - 2016-07-05
### Fixed
- Bug fix for case when `touchend` event throws error
## 0.15.0 - 2016-06-18
## Added
- Custom clip function
## 0.14.0 - 2016-06-17
### Fixed
- fixes in typescript definitions
- fixes for bug with `mouseenter` event on deep nesting case
## 0.13.9 - 2016-05-14
### Changed
- typescript definition in npm package
- node@5.10.1, canvas@1.3.14, jsdom@8.5.0 support
- `Konva.Path` will be filled when it is not closed
- `Animation.start()` will not not immediate sync draw. This should improve performance a little.
- Warning when node for `Tween` is not in layer yet.
- `removeChildren()` remove only first level children. So it will not remove grandchildren.
## 0.12.4 - 2016-04-19
### Changed
- `batchDraw` will do not immediate `draw()`
### Fixed
- fix incorrect shadow offset on rotation
## 0.12.3 - 2016-04-07
### Fixed
- `batchDraw` function works less time now
- lighter npm package
## 0.12.2 - 2016-03-31
### Fixed
- repair `cancelBubble` event property behaviour
- fix wrong `Path` `getClientRect()` calculation
- better HDPI support
- better typescript definitions
- node 0.12 support
### Changed
- more universal stage container selector
- `mousewheel` event changed to `wheel`
## 0.11.1 - 2016-01-16
### Fixed
- correct `Konva.Arrow` drawing. Now it works better.
- Better support for dragging when mouse out of stage
- Better corner radius for `Label` shape
- `contentTap` event for stage
### Added
- event delegation. You can use it in this way: `layer.on('click', 'Circle', handler);`
- new `node.findAncestors(selector)` and `node.findAncestor(selector)` functions
- optional selector parameter for `stage.getIntersection` and `layer.getIntersection`
- show warning message if several instances of Konva are added to page.
### Changed
- `moveTo` and some other methods return `this`
- `getAbsolutePosition` support optional relative parent argument (useful to find absolute position inside of some of parent nodes)
- `change` event will be not fired if changed value is the same as old value
## 0.10.0 - 2015-10-27
### Added
- RGBA filter. Thanks to [@codefo](https://github.com/codefo)
- `stroke` and `fill` support for `Konva.Sprite`
### Fixed
- Correct calculation in `getClientRect` method of `Konva.Line` and `Konva.Container`.
- Correct `toObject()` behaviour for node with attrs with extended native prototypes
- Fixed bug for caching where buffer canvas is required
### Changed
- Dragging works much better. If your pointer is out of stage content dragging will still continue.
- `Konva.Node.create` now works with objects.
- `Konva.Tween` now supports tweening points to state with different length
## 0.9.5 - 2015-05-28
### Fixed
- `to` will not throw error if no `onFinish` callback
- HDPI support for desktop
- Fix bug when filters are not correct for HDPI
- Fix bug when hit area is not correct for HDPI
- Fix bug for incorrect `getClientRect` calculation
- Repair fill gradient for text
### Changed
- context wrapper is more capable with native context.
So you can use `context.fillStyle` property in your `sceneFunc` without accessing native context.
- `toDataURL` now handles pixelRatio. you can pass `config.pixelRatio` argument
- Correct `clone()` for custom nodes
- `FastLayer` can now have transforms
- `stage.toDataURL()` method now works synchronously. So `callback` argument is not required.
- `container.find(selector)` method now has a validation step. So if you forgot to add `#` or `.` you will see a warning message in the console.
### Added
- new `Konva.Image.fromURL` method
### Deprecated
- `fillRed`, `fillGreen`, `fillBlue`, `fillAlpha` are deprecated. Use `fill` instead.
- `strokeRed`, `strokeGreen`, `strokeBlue`, `strokeAlpha` are deprecated. Use `stroke` instead.
- `shadowRed`, `shadowGreen`, `shadowBlue`, `shadowAlpha` are deprecated. Use `shadow` instead.
- `dashArray` is deprecated. Use `dash` instead.
- `drawFunc` is deprecated. Use `sceneFunc` instead.
- `drawHitFunc` is deprecated. Use `hitFunc` instead.
- `rotateDeg` is deprecated. Use `rotate` instead.
## 0.9.0 - 2015-02-27
### Fixed
- cache algorithm has A LOT OF updates.
### Changed
- `scale` now affects `shadowOffset`
- performance optimization (remove some unnecessary draws)
- more expected drawing when shape has opacity, stroke and shadow
- HDPI for caching.
- Cache should work much better. Now you don't need to pass bounding box {x,y,width,height} to `cache` method for all buildin Konva shapes. (only for your custom `Konva.Shape` instance).
- `Tween` now supports color properties (`fill`, `stroke`, `shadowColor`)
### Added
- new methods for working with node's name: `addName`, `removeName`, `hasName`.
- new `perfectDrawEnabled` property for shape. See [http://konvajs.org/docs/performance/Disable_Perfect_Draw.html](http://konvajs.org/docs/performance/Disable_Perfect_Draw.html)
- new `shadowForStrokeEnabled` property for shape. See [http://konvajs.org/docs/performance/All_Performance_Tips.html](http://konvajs.org/docs/performance/All_Performance_Tips.html)
- new `getClientRect` method.
- new `to` method for every node for shorter tweening
## 0.8.0 - 2015-02-04
- Bug Fixes
- browser crashing on pointer events fixed
- optimized `getIntersection` function
- Enhancements
- `container.findOne()` method
- new `strokeHitEnabled` property. Useful for performance optimizations
- typescript definitions. see `/resources/konva.d.ts`
## Rebranding release 2015-01-28
Differences from last official `KineticJS` release
- Bug Fixes
- `strokeScaleEnabled = false` is disabled for text as I can not find a way to implement this
- `strokeScaleEnabled = false` for Line now creates a correct hit graph
- working "this-example" as name for nodes
- Konva.Text() with no config will not throw exception
- Konva.Line() with no config will not throw exception
- Correct stage resizing with `FastLayer`
- `batchDraw` method for `FastLayer`
- Correct mouseover/mouseout/mouseenter/mouseleave events for groups
- cache node before adding to layer
- `intersects` function now works for shapes with shadow
- Enhancements
- `cornerRadius` of Rect is limited by `width/2` and `height/2`
- `black` is default fill for text
- true class extending. Now `rect instanceOf Konva.Shape` will return true
- while dragging you can redraw layer that is not under drag. hit graph will be updated in this case
- now you can move object that is dragging into another layer.
- new `frameOffsets` attribute for `Konva.Sprite`
- much better dragging performance
- `browserify` support
- applying opacity to cached node
- remove all events with `node.off()`
- mouse dragging only with left button
- opacity now affects cached shapes
- Label corner radius
- smart changing `width`, `height`, `radius` attrs for circle, start, ellipse, ring.
- `mousewheel` support. Thanks [@vmichnowicz](https://github.com/vmichnowicz)
- new Arrow plugin
- multiple names: `node.name('foo bar'); container.find('.foo');` (thanks [@mattslocum](https://github.com/mattslocum))
- `Container.findOne()`
================================================
FILE: LICENSE
================================================
MIT License
Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<p align="center">
<img src="https://konvajs.org/img/icon.png" alt="Konva logo" height="60" />
</p>
<h1 align="center">Konva</h1>
[](https://opencollective.com/konva)
[](http://badge.fury.io/js/konva)
[](https://github.com/konvajs/konva/actions/workflows/test-browser.ym)
[](https://github.com/konvajs/konva/actions/workflows/test-node.ym)[](https://cdnjs.com/libraries/konva)
Konva is an HTML5 Canvas JavaScript framework that enables high performance animations, transitions, node nesting, layering, filtering, caching, event handling for desktop and mobile applications, and much more.
You can draw things onto the stage, add event listeners to them, move them, scale them, and rotate them independently from other shapes to support high performance animations, even if your application uses thousands of shapes. Served hot with a side of awesomeness.
This repository began as a GitHub fork of [ericdrowell/KineticJS](https://github.com/ericdrowell/KineticJS).
- **Visit:** The [Home Page](http://konvajs.org/) and follow on [Twitter](https://twitter.com/lavrton)
- **Discover:** [Tutorials](http://konvajs.org/docs/index.html), [API Documentation](http://konvajs.org/api/Konva.html)
- **Help:** [StackOverflow](http://stackoverflow.com/questions/tagged/konvajs), [Discord Chat](https://discord.gg/8FqZwVT)
# Quick Look
```html
<script src="https://unpkg.com/konva@10.0.0-1/konva.min.js"></script>
<div id="container"></div>
<script>
var stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
});
// add canvas element
var layer = new Konva.Layer();
stage.add(layer);
// create shape
var box = new Konva.Rect({
x: 50,
y: 50,
width: 100,
height: 50,
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 4,
draggable: true,
});
layer.add(box);
// add cursor styling
box.on('mouseover', function () {
document.body.style.cursor = 'pointer';
});
box.on('mouseout', function () {
document.body.style.cursor = 'default';
});
</script>
```
# Browsers support
Konva works in all modern mobile and desktop browsers. A browser need to be capable to run javascript code from ES2015 spec. For older browsers you may need polyfills for missing functions.
At the current moment `Konva` doesn't work in IE11 directly. To make it work you just need to provide some polyfills such as `Array.prototype.find`, `String.prototype.trimLeft`, `String.prototype.trimRight`, `Array.from`.
# Debugging
The Chrome inspector simply shows the canvas element. To see the Konva objects and their details, install the konva-dev extension at https://github.com/konvajs/konva-devtool.
# Loading and installing Konva
Konva supports UMD loading. So you can use all possible variants to load the framework into your project:
### Load Konva via classical `<script>` tag from CDN:
```html
<script src="https://unpkg.com/konva@10.0.0-1/konva.min.js"></script>
```
### Install with npm:
```bash
npm install konva --save
```
```javascript
// The modern way (e.g. an ES6-style import for webpack, parcel)
import Konva from 'konva';
```
#### Typescript usage
Add DOM definitions into your `tsconfig.json`:
```
{
"compilerOptions": {
"lib": [
"es6",
"dom"
]
}
}
```
### 3 Minimal bundle
```javascript
import Konva from 'konva/lib/Core';
// Now you have a Konva object with Stage, Layer, FastLayer, Group, Shape and some additional utils function.
// Also core currently already have support for drag&drop and animations.
// BUT there are no shapes (rect, circle, etc), no filters.
// but you can simply add anything you need:
import { Rect } from 'konva/lib/shapes/Rect';
// importing a shape will automatically inject it into Konva object
var rect1 = new Rect();
// or:
var shape = new Konva.Rect();
// for filters you can use this:
import { Blur } from 'konva/lib/filters/Blur';
```
### 4 NodeJS env
In order to run `konva` in nodejs environment you also need to install `canvas` or `skia-canvas` package manually for rendering backend.
```bash
# node-canvas backend
npm install konva canvas
# skia-canvas backend
npm install konva skia-canvas
```
Then you can use the same Konva API and all Konva demos will work just fine. You just don't need to use `container` attribute in your stage.
```js
import Konva from 'konva';
import 'konva/canvas-backend'; // or import 'konva/skia-backend';
const stage = new Konva.Stage({
width: 500,
height: 500,
});
// then all regular Konva code will work
```
# Backers


- [myposter GmbH](https://www.myposter.de/)
- [queue.gg](https://queue.gg/)
# Change log
See [CHANGELOG.md](https://github.com/konvajs/konva/blob/master/CHANGELOG.md).
## Building the Konva Framework
To make a full build run `npm run build`. The command will compile all typescript files, combine then into one bundle and run minifier.
## Testing
Konva uses Mocha for testing.
- If you need run test only one time run `npm run test`.
- While developing it is easy to use `npm start`. Just run it and go to [http://localhost:1234/unit-tests.html](http://localhost:1234/unit-tests.html). The watcher will rebuild the bundle on any change.
Konva is covered with hundreds of tests and well over a thousand assertions.
Konva uses TDD (test driven development) which means that every new feature or bug fix is accompanied with at least one new test.
## Generate documentation
Run `npx gulp api` which will build the documentation files and place them in the `api` folder.
# Pull Requests
I'd be happy to review any pull requests that may better the Konva project,
in particular if you have a bug fix, enhancement, or a new shape (see `src/shapes` for examples). Before doing so, please first make sure that all of the tests pass (`npm run test`).
## Contributors
### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/konva/contribute)]
#### Individuals
<a href="https://opencollective.com/konva"><img src="https://opencollective.com/konva/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/konva/contribute)]
<a href="https://opencollective.com/konva/organization/0/website"><img src="https://opencollective.com/konva/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/1/website"><img src="https://opencollective.com/konva/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/2/website"><img src="https://opencollective.com/konva/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/3/website"><img src="https://opencollective.com/konva/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/4/website"><img src="https://opencollective.com/konva/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/5/website"><img src="https://opencollective.com/konva/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/6/website"><img src="https://opencollective.com/konva/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/7/website"><img src="https://opencollective.com/konva/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/8/website"><img src="https://opencollective.com/konva/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/konva/organization/9/website"><img src="https://opencollective.com/konva/organization/9/avatar.svg"></a>
================================================
FILE: gulpfile.mjs
================================================
import gulp from 'gulp';
import rename from 'gulp-rename';
import uglify from 'gulp-uglify-es';
import replace from 'gulp-replace';
import jsdoc from 'gulp-jsdoc3';
import connect from 'gulp-connect';
import gutil from 'gulp-util';
import fs from 'fs';
var NodeParams = fs
.readFileSync('./resources/doc-includes/NodeParams.txt')
.toString();
var ContainerParams = fs
.readFileSync('./resources/doc-includes/ContainerParams.txt')
.toString();
var ShapeParams = fs
.readFileSync('./resources/doc-includes/ShapeParams.txt')
.toString();
const conf = JSON.parse(fs.readFileSync('./package.json'));
function build() {
return gulp
.src(['./konva.js'])
.pipe(replace('@@shapeParams', ShapeParams))
.pipe(replace('@@nodeParams', NodeParams))
.pipe(replace('@@containerParams', ContainerParams))
.pipe(replace('@@version', conf.version))
.pipe(replace('@@date', new Date().toDateString()));
}
gulp.task('update-version-lib', function () {
return gulp
.src(['./lib/Global.js'])
.pipe(replace('@@version', conf.version))
.pipe(rename('Global.js'))
.pipe(gulp.dest('./lib'));
});
gulp.task('update-version-cmj', function () {
return gulp
.src(['./cmj/Global.js'])
.pipe(replace('@@version', conf.version))
.pipe(rename('Global.js'))
.pipe(gulp.dest('./cmj'));
});
gulp.task('update-version-es-to-cmj-index', function () {
return gulp
.src(['./lib/index.js'])
.pipe(
replace(`import { Konva } from './_F`, `import { Konva } from '../cmj/_F`)
)
.pipe(rename('index.js'))
.pipe(gulp.dest('./lib'));
});
gulp.task('update-version-es-to-cmj-node', function () {
return gulp
.src(['./lib/index-node.js'])
.pipe(
replace(`import { Konva } from './_F`, `import { Konva } from '../cmj/_F`)
)
.pipe(rename('index-node.js'))
.pipe(gulp.dest('./lib'));
});
// create usual build konva.js and konva.min.js
gulp.task('pre-build', function () {
return build()
.pipe(rename('konva.js'))
.pipe(gulp.dest('./'))
.pipe(
uglify.default({ output: { comments: /^!|@preserve|@license|@cc_on/i } })
)
.on('error', function (err) {
gutil.log(gutil.colors.red('[Error]'), err.toString());
})
.pipe(rename('konva.min.js'))
.pipe(gulp.dest('./'));
});
gulp.task(
'build',
gulp.parallel([
'update-version-lib',
// 'update-version-cmj',
// 'update-version-es-to-cmj-index',
// 'update-version-es-to-cmj-node',
'pre-build',
])
);
// local server for better development
gulp.task('server', function () {
connect.server();
});
// // generate documentation
gulp.task('api', function () {
return gulp.src('./konva.js').pipe(
jsdoc({
opts: {
destination: './api',
},
})
);
});
gulp.task('default', gulp.parallel(['server']));
================================================
FILE: package.json
================================================
{
"name": "konva",
"version": "10.2.3",
"description": "HTML5 2d canvas library.",
"author": "Anton Lavrenov",
"type": "module",
"files": [
"README.md",
"konva.js",
"konva.min.js",
"lib"
],
"exports": {
".": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
},
"./lib/*": {
"types": "./lib/*.d.ts",
"default": "./lib/*.js"
},
"./lib/*.js": {
"types": "./lib/*.d.ts",
"default": "./lib/*.js"
},
"./canvas-backend": {
"types": "./lib/canvas-backend.d.ts",
"default": "./lib/canvas-backend.js"
},
"./skia-backend": {
"types": "./lib/skia-backend.d.ts",
"default": "./lib/skia-backend.js"
}
},
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"scripts": {
"start": "npm run test:watch",
"compile": "npm run clean && npm run tsc && npm run rollup",
"build": "npm run compile && gulp build",
"fmt": "prettier --write .",
"fmt:check": "prettier --check .",
"test:import": "npm run build && node ./test/import-test.cjs && node ./test/import-test.mjs",
"test": "npm run test:browser && npm run test:node && npm run test:import",
"test:build": "PARCEL_WORKER_BACKEND=process parcel build ./test/unit-tests.html --dist-dir ./test-build --target none --public-url ./ --no-source-maps",
"test:browser": "npm run test:build && mocha-headless-chrome -f ./test-build/unit-tests.html -a disable-web-security -a no-sandbox -a disable-setuid-sandbox",
"test:watch": "rimraf ./.parcel-cache && PARCEL_WORKERS=0 parcel serve ./test/unit-tests.html ./test/manual-tests.html ./test/sandbox.html ./test/text-paths.html ./test/bunnies.html",
"test:node:canvas": "mocha -r tsx -r ./test/node-canvas-global-setup.mjs --extension ts --recursive './test/unit/' --exit",
"test:node:skia": "mocha -r tsx -r ./test/node-skia-global-setup.mjs --extension ts --recursive './test/unit/' --exit",
"test:node": "npm run test:node:canvas && npm run test:node:skia",
"tsc": "tsc --removeComments",
"rollup": "rollup -c",
"clean": "rimraf ./lib && rimraf ./types && rimraf ./cmj && rimraf ./test-build",
"watch": "rollup -c -w",
"size": "size-limit"
},
"targets": {
"none": {}
},
"funding": [
{
"type": "patreon",
"url": "https://www.patreon.com/lavrton"
},
{
"type": "opencollective",
"url": "https://opencollective.com/konva"
},
{
"type": "github",
"url": "https://github.com/sponsors/lavrton"
}
],
"size-limit": [
{
"limit": "45 KB",
"path": "./lib/index.js"
},
{
"limit": "26 KB",
"path": "./lib/Core.js"
},
{
"path": "./konva.min.js"
}
],
"devDependencies": {
"@parcel/transformer-image": "2.15.4",
"@size-limit/preset-big-lib": "^11.2.0",
"@types/mocha": "^10.0.10",
"canvas": "^3.2.1",
"chai": "6.2.2",
"filehound": "^1.17.6",
"gulp": "^5.0.1",
"gulp-concat": "^2.6.1",
"gulp-connect": "^5.7.0",
"gulp-exec": "^5.0.0",
"gulp-jsdoc3": "^3.0.0",
"gulp-rename": "^2.1.0",
"gulp-replace": "^1.1.4",
"gulp-typescript": "^5.0.1",
"gulp-uglify": "^3.0.2",
"gulp-uglify-es": "^3.0.0",
"gulp-util": "^3.0.8",
"mocha": "^10",
"mocha-headless-chrome": "^4.0.0",
"parcel": "2.15.4",
"prettier": "^3.7.4",
"process": "^0.11.10",
"rimraf": "^6.1.2",
"rollup": "^4.55.1",
"rollup-plugin-typescript2": "^0.36.0",
"size-limit": "^11.2.0",
"skia-canvas": "^3.0.4",
"ts-mocha": "^11.1.0",
"ts-node": "^10.9.2",
"tsx": "^4.21.0",
"typescript": "^5.9.3"
},
"keywords": [
"canvas",
"animations",
"graphic",
"html5"
],
"prettier": {
"singleQuote": true,
"trailingComma": "es5"
},
"bugs": {
"url": "https://github.com/konvajs/konva/issues"
},
"homepage": "http://konvajs.org/",
"readmeFilename": "README.md",
"repository": {
"type": "git",
"url": "git://github.com/konvajs/konva.git"
},
"license": "MIT"
}
================================================
FILE: release.sh
================================================
#!/usr/bin/env bash
set -e
old_version="$(git describe --abbrev=0 --tags)"
new_version=$1
old_cdn_min="https://unpkg.com/konva@${old_version}/konva.min.js"
new_cdn_min="https://unpkg.com/konva@${new_version}/konva.min.js"
# make sure new version parameter is passed
if [ -z "$1" ]
then
echo "ERROR - pass new version. usage release.sh 0.11.0"
exit 2
fi
# make sure changle log updated
while true; do
read -p "Did you update CHANGELOG.md? " yn
case $yn in
[Yy]* ) break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
echo "Old version: ${old_version}"
echo "New version: ${new_version}"
echo "Pulling"
git pull >/dev/null
echo "build and test"
npm run build >/dev/null
# npm run test
echo "commit change log updates"
git commit -am "update CHANGELOG with new version" --allow-empty >/dev/null
echo "npm version $1 --no-git-tag-version"
npm version $1 --no-git-tag-version --allow-same-version >/dev/null
echo "build for $1"
npm run build >/dev/null
git commit -am "build for $1" --allow-empty >/dev/null
echo "update CDN link in README"
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
echo "create new git tag"
git tag $1 >/dev/null
cd ../konva
git push >/dev/null
git push --tags >/dev/null
npm publish
echo "DONE!"
================================================
FILE: resources/doc-includes/ContainerParams.txt
================================================
* @param {Object} [config.clip] set clip
* @param {Number} [config.clipX] set clip x
* @param {Number} [config.clipY] set clip y
* @param {Number} [config.clipWidth] set clip width
* @param {Number} [config.clipHeight] set clip height
* @param {Function} [config.clipFunc] set clip func
================================================
FILE: resources/doc-includes/NodeParams.txt
================================================
@param {Number} [config.x]
* @param {Number} [config.y]
* @param {Number} [config.width]
* @param {Number} [config.height]
* @param {Boolean} [config.visible]
* @param {Boolean} [config.listening] whether or not the node is listening for events
* @param {String} [config.id] unique id
* @param {String} [config.name] non-unique name
* @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1
* @param {Object} [config.scale] set scale
* @param {Number} [config.scaleX] set scale x
* @param {Number} [config.scaleY] set scale y
* @param {Number} [config.rotation] rotation in degrees
* @param {Object} [config.offset] offset from center point and rotation point
* @param {Number} [config.offsetX] set offset x
* @param {Number} [config.offsetY] set offset y
* @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop
* the entire stage by dragging any portion of the stage
* @param {Number} [config.dragDistance]
* @param {Function} [config.dragBoundFunc]
================================================
FILE: resources/doc-includes/ShapeParams.txt
================================================
@param {String} [config.fill] fill color
* @param {Image} [config.fillPatternImage] fill pattern image
* @param {Number} [config.fillPatternX]
* @param {Number} [config.fillPatternY]
* @param {Object} [config.fillPatternOffset] object with x and y component
* @param {Number} [config.fillPatternOffsetX]
* @param {Number} [config.fillPatternOffsetY]
* @param {Object} [config.fillPatternScale] object with x and y component
* @param {Number} [config.fillPatternScaleX]
* @param {Number} [config.fillPatternScaleY]
* @param {Number} [config.fillPatternRotation]
* @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat"
* @param {Object} [config.fillLinearGradientStartPoint] object with x and y component
* @param {Number} [config.fillLinearGradientStartPointX]
* @param {Number} [config.fillLinearGradientStartPointY]
* @param {Object} [config.fillLinearGradientEndPoint] object with x and y component
* @param {Number} [config.fillLinearGradientEndPointX]
* @param {Number} [config.fillLinearGradientEndPointY]
* @param {Array} [config.fillLinearGradientColorStops] array of color stops
* @param {Object} [config.fillRadialGradientStartPoint] object with x and y component
* @param {Number} [config.fillRadialGradientStartPointX]
* @param {Number} [config.fillRadialGradientStartPointY]
* @param {Object} [config.fillRadialGradientEndPoint] object with x and y component
* @param {Number} [config.fillRadialGradientEndPointX]
* @param {Number} [config.fillRadialGradientEndPointY]
* @param {Number} [config.fillRadialGradientStartRadius]
* @param {Number} [config.fillRadialGradientEndRadius]
* @param {Array} [config.fillRadialGradientColorStops] array of color stops
* @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true
* @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration
* @param {String} [config.stroke] stroke color
* @param {Number} [config.strokeWidth] stroke width
* @param {Boolean} [config.fillAfterStrokeEnabled]. Should we draw fill AFTER stroke? Default is false.
* @param {Number} [config.hitStrokeWidth] size of the stroke on hit canvas. The default is "auto" - equals to strokeWidth
* @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true
* @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true
* @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shadow for stroke. The default is true
* @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true
* @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true
* @param {String} [config.lineJoin] can be miter, round, or bevel. The default
* is miter
* @param {String} [config.lineCap] can be butt, round, or square. The default
* is butt
* @param {String} [config.shadowColor]
* @param {Number} [config.shadowBlur]
* @param {Object} [config.shadowOffset] object with x and y component
* @param {Number} [config.shadowOffsetX]
* @param {Number} [config.shadowOffsetY]
* @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number
* between 0 and 1
* @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true
* @param {Array} [config.dash]
* @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true
================================================
FILE: resources/jsdoc.conf.json
================================================
{
"path": "ink-docstrap",
"tags": {
"allowUnknownTags": true
},
"plugins": ["plugins/markdown"],
"templates": {
"cleverLinks": false,
"monospaceLinks": false,
"dateFormat": "ddd MMM Do YYYY",
"outputSourceFiles": true,
"outputSourcePath": true,
"systemName": "Konva",
"footer": "",
"copyright": "Konva Copyright © 2015 The contributors to the Konva project.",
"navType": "vertical",
"theme": "cosmo",
"linenums": true,
"collapseSymbols": false,
"inverseNav": true,
"highlightTutorialCode": true
},
"markdown": {
"parser": "gfm",
"hardwrap": true
}
}
================================================
FILE: rollup.config.mjs
================================================
// import resolve from 'rollup-plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2';
export default {
input: `src/index.ts`,
output: [
{
file: 'konva.js',
name: 'Konva',
format: 'umd',
sourcemap: false,
freeze: false,
},
],
external: [],
watch: {
include: 'src/**',
},
plugins: [
// Compile TypeScript files
typescript({
useTsconfigDeclarationDir: true,
abortOnError: false,
removeComments: false,
tsconfigOverride: {
compilerOptions: {
module: 'ES2020',
},
},
}),
],
};
================================================
FILE: src/Animation.ts
================================================
import { glob } from './Global.ts';
import type { Layer } from './Layer.ts';
import type { IFrame, AnimationFn } from './types.ts';
import { Util } from './Util.ts';
const now = (function (): () => number {
if (glob.performance && glob.performance.now) {
return function () {
return glob.performance.now();
};
}
return function () {
return new Date().getTime();
};
})();
/**
* Animation constructor.
* @constructor
* @memberof Konva
* @param {AnimationFn} func function executed on each animation frame. The function is passed a frame object, which contains
* timeDiff, lastTime, time, and frameRate properties. The timeDiff property is the number of milliseconds that have passed
* since the last animation frame. The time property is the time in milliseconds that elapsed from the moment the animation started
* to the current animation frame. The lastTime property is a `time` value from the previous frame. The frameRate property is the current frame rate in frames / second.
* Return false from function, if you don't need to redraw layer/layers on some frames.
* @param {Konva.Layer|Array} [layers] layer(s) to be redrawn on each animation frame. Can be a layer, an array of layers, or null.
* Not specifying a node will result in no redraw.
* @example
* // move a node to the right at 50 pixels / second
* var velocity = 50;
*
* var anim = new Konva.Animation(function(frame) {
* var dist = velocity * (frame.timeDiff / 1000);
* node.move({x: dist, y: 0});
* }, layer);
*
* anim.start();
*/
export class Animation {
func: AnimationFn;
id = Animation.animIdCounter++;
layers: Layer[];
frame: IFrame = {
time: 0,
timeDiff: 0,
lastTime: now(),
frameRate: 0,
};
constructor(func: AnimationFn, layers?) {
this.func = func;
this.setLayers(layers);
}
/**
* set layers to be redrawn on each animation frame
* @method
* @name Konva.Animation#setLayers
* @param {Konva.Layer|Array} [layers] layer(s) to be redrawn. Can be a layer, an array of layers, or null. Not specifying a node will result in no redraw.
* @return {Konva.Animation} this
*/
setLayers(layers: null | Layer | Layer[]) {
let lays: Layer[] = [];
// if passing in no layers
if (layers) {
lays = Array.isArray(layers) ? layers : [layers];
}
this.layers = lays;
return this;
}
/**
* get layers
* @method
* @name Konva.Animation#getLayers
* @return {Array} Array of Konva.Layer
*/
getLayers() {
return this.layers;
}
/**
* add layer. Returns true if the layer was added, and false if it was not
* @method
* @name Konva.Animation#addLayer
* @param {Konva.Layer} layer to add
* @return {Bool} true if layer is added to animation, otherwise false
*/
addLayer(layer: Layer) {
const layers = this.layers;
const len = layers.length;
// don't add the layer if it already exists
for (let n = 0; n < len; n++) {
if (layers[n]._id === layer._id) {
return false;
}
}
this.layers.push(layer);
return true;
}
/**
* determine if animation is running or not. returns true or false
* @method
* @name Konva.Animation#isRunning
* @return {Bool} is animation running?
*/
isRunning() {
const a = Animation;
const animations = a.animations;
const len = animations.length;
for (let n = 0; n < len; n++) {
if (animations[n].id === this.id) {
return true;
}
}
return false;
}
/**
* start animation
* @method
* @name Konva.Animation#start
* @return {Konva.Animation} this
*/
start() {
this.stop();
this.frame.timeDiff = 0;
this.frame.lastTime = now();
Animation._addAnimation(this);
return this;
}
/**
* stop animation
* @method
* @name Konva.Animation#stop
* @return {Konva.Animation} this
*/
stop() {
Animation._removeAnimation(this);
return this;
}
_updateFrameObject(time: number) {
this.frame.timeDiff = time - this.frame.lastTime;
this.frame.lastTime = time;
this.frame.time += this.frame.timeDiff;
this.frame.frameRate = 1000 / this.frame.timeDiff;
}
static animations: Array<Animation> = [];
static animIdCounter = 0;
static animRunning = false;
static _addAnimation(anim) {
this.animations.push(anim);
this._handleAnimation();
}
static _removeAnimation(anim) {
const id = anim.id;
const animations = this.animations;
const len = animations.length;
for (let n = 0; n < len; n++) {
if (animations[n].id === id) {
this.animations.splice(n, 1);
break;
}
}
}
static _runFrames() {
const layerHash = {};
const animations = this.animations;
/*
* loop through all animations and execute animation
* function. if the animation object has specified node,
* we can add the node to the nodes hash to eliminate
* drawing the same node multiple times. The node property
* can be the stage itself or a layer
*/
/*
* WARNING: don't cache animations.length because it could change while
* the for loop is running, causing a JS error
*/
for (let n = 0; n < animations.length; n++) {
const anim = animations[n];
const layers = anim.layers;
const func = anim.func;
anim._updateFrameObject(now());
const layersLen = layers.length;
// if animation object has a function, execute it
let needRedraw;
if (func) {
// allow anim bypassing drawing
needRedraw = func.call(anim, anim.frame) !== false;
} else {
needRedraw = true;
}
if (!needRedraw) {
continue;
}
for (let i = 0; i < layersLen; i++) {
const layer = layers[i];
if (layer._id !== undefined) {
layerHash[layer._id] = layer;
}
}
}
for (const key in layerHash) {
if (!layerHash.hasOwnProperty(key)) {
continue;
}
layerHash[key].batchDraw();
}
}
static _animationLoop() {
const Anim = Animation;
if (Anim.animations.length) {
Anim._runFrames();
Util.requestAnimFrame(Anim._animationLoop);
} else {
Anim.animRunning = false;
}
}
static _handleAnimation() {
if (!this.animRunning) {
this.animRunning = true;
Util.requestAnimFrame(this._animationLoop);
}
}
}
================================================
FILE: src/BezierFunctions.ts
================================================
// Credits: rveciana/svg-path-properties
// Legendre-Gauss abscissae (xi values, defined at i=n as the roots of the nth order Legendre polynomial Pn(x))
export const tValues = [
[],
[],
[
-0.5773502691896257645091487805019574556476,
0.5773502691896257645091487805019574556476,
],
[
0, -0.7745966692414833770358530799564799221665,
0.7745966692414833770358530799564799221665,
],
[
-0.3399810435848562648026657591032446872005,
0.3399810435848562648026657591032446872005,
-0.8611363115940525752239464888928095050957,
0.8611363115940525752239464888928095050957,
],
[
0, -0.5384693101056830910363144207002088049672,
0.5384693101056830910363144207002088049672,
-0.9061798459386639927976268782993929651256,
0.9061798459386639927976268782993929651256,
],
[
0.6612093864662645136613995950199053470064,
-0.6612093864662645136613995950199053470064,
-0.2386191860831969086305017216807119354186,
0.2386191860831969086305017216807119354186,
-0.9324695142031520278123015544939946091347,
0.9324695142031520278123015544939946091347,
],
[
0, 0.4058451513773971669066064120769614633473,
-0.4058451513773971669066064120769614633473,
-0.7415311855993944398638647732807884070741,
0.7415311855993944398638647732807884070741,
-0.9491079123427585245261896840478512624007,
0.9491079123427585245261896840478512624007,
],
[
-0.1834346424956498049394761423601839806667,
0.1834346424956498049394761423601839806667,
-0.5255324099163289858177390491892463490419,
0.5255324099163289858177390491892463490419,
-0.7966664774136267395915539364758304368371,
0.7966664774136267395915539364758304368371,
-0.9602898564975362316835608685694729904282,
0.9602898564975362316835608685694729904282,
],
[
0, -0.8360311073266357942994297880697348765441,
0.8360311073266357942994297880697348765441,
-0.9681602395076260898355762029036728700494,
0.9681602395076260898355762029036728700494,
-0.3242534234038089290385380146433366085719,
0.3242534234038089290385380146433366085719,
-0.6133714327005903973087020393414741847857,
0.6133714327005903973087020393414741847857,
],
[
-0.1488743389816312108848260011297199846175,
0.1488743389816312108848260011297199846175,
-0.4333953941292471907992659431657841622,
0.4333953941292471907992659431657841622,
-0.6794095682990244062343273651148735757692,
0.6794095682990244062343273651148735757692,
-0.8650633666889845107320966884234930485275,
0.8650633666889845107320966884234930485275,
-0.9739065285171717200779640120844520534282,
0.9739065285171717200779640120844520534282,
],
[
0, -0.2695431559523449723315319854008615246796,
0.2695431559523449723315319854008615246796,
-0.5190961292068118159257256694586095544802,
0.5190961292068118159257256694586095544802,
-0.7301520055740493240934162520311534580496,
0.7301520055740493240934162520311534580496,
-0.8870625997680952990751577693039272666316,
0.8870625997680952990751577693039272666316,
-0.9782286581460569928039380011228573907714,
0.9782286581460569928039380011228573907714,
],
[
-0.1252334085114689154724413694638531299833,
0.1252334085114689154724413694638531299833,
-0.3678314989981801937526915366437175612563,
0.3678314989981801937526915366437175612563,
-0.587317954286617447296702418940534280369,
0.587317954286617447296702418940534280369,
-0.7699026741943046870368938332128180759849,
0.7699026741943046870368938332128180759849,
-0.9041172563704748566784658661190961925375,
0.9041172563704748566784658661190961925375,
-0.9815606342467192506905490901492808229601,
0.9815606342467192506905490901492808229601,
],
[
0, -0.2304583159551347940655281210979888352115,
0.2304583159551347940655281210979888352115,
-0.4484927510364468528779128521276398678019,
0.4484927510364468528779128521276398678019,
-0.6423493394403402206439846069955156500716,
0.6423493394403402206439846069955156500716,
-0.8015780907333099127942064895828598903056,
0.8015780907333099127942064895828598903056,
-0.9175983992229779652065478365007195123904,
0.9175983992229779652065478365007195123904,
-0.9841830547185881494728294488071096110649,
0.9841830547185881494728294488071096110649,
],
[
-0.1080549487073436620662446502198347476119,
0.1080549487073436620662446502198347476119,
-0.3191123689278897604356718241684754668342,
0.3191123689278897604356718241684754668342,
-0.5152486363581540919652907185511886623088,
0.5152486363581540919652907185511886623088,
-0.6872929048116854701480198030193341375384,
0.6872929048116854701480198030193341375384,
-0.8272013150697649931897947426503949610397,
0.8272013150697649931897947426503949610397,
-0.928434883663573517336391139377874264477,
0.928434883663573517336391139377874264477,
-0.986283808696812338841597266704052801676,
0.986283808696812338841597266704052801676,
],
[
0, -0.2011940939974345223006283033945962078128,
0.2011940939974345223006283033945962078128,
-0.3941513470775633698972073709810454683627,
0.3941513470775633698972073709810454683627,
-0.5709721726085388475372267372539106412383,
0.5709721726085388475372267372539106412383,
-0.7244177313601700474161860546139380096308,
0.7244177313601700474161860546139380096308,
-0.8482065834104272162006483207742168513662,
0.8482065834104272162006483207742168513662,
-0.9372733924007059043077589477102094712439,
0.9372733924007059043077589477102094712439,
-0.9879925180204854284895657185866125811469,
0.9879925180204854284895657185866125811469,
],
[
-0.0950125098376374401853193354249580631303,
0.0950125098376374401853193354249580631303,
-0.281603550779258913230460501460496106486,
0.281603550779258913230460501460496106486,
-0.45801677765722738634241944298357757354,
0.45801677765722738634241944298357757354,
-0.6178762444026437484466717640487910189918,
0.6178762444026437484466717640487910189918,
-0.7554044083550030338951011948474422683538,
0.7554044083550030338951011948474422683538,
-0.8656312023878317438804678977123931323873,
0.8656312023878317438804678977123931323873,
-0.9445750230732325760779884155346083450911,
0.9445750230732325760779884155346083450911,
-0.9894009349916499325961541734503326274262,
0.9894009349916499325961541734503326274262,
],
[
0, -0.1784841814958478558506774936540655574754,
0.1784841814958478558506774936540655574754,
-0.3512317634538763152971855170953460050405,
0.3512317634538763152971855170953460050405,
-0.5126905370864769678862465686295518745829,
0.5126905370864769678862465686295518745829,
-0.6576711592166907658503022166430023351478,
0.6576711592166907658503022166430023351478,
-0.7815140038968014069252300555204760502239,
0.7815140038968014069252300555204760502239,
-0.8802391537269859021229556944881556926234,
0.8802391537269859021229556944881556926234,
-0.9506755217687677612227169578958030214433,
0.9506755217687677612227169578958030214433,
-0.9905754753144173356754340199406652765077,
0.9905754753144173356754340199406652765077,
],
[
-0.0847750130417353012422618529357838117333,
0.0847750130417353012422618529357838117333,
-0.2518862256915055095889728548779112301628,
0.2518862256915055095889728548779112301628,
-0.4117511614628426460359317938330516370789,
0.4117511614628426460359317938330516370789,
-0.5597708310739475346078715485253291369276,
0.5597708310739475346078715485253291369276,
-0.6916870430603532078748910812888483894522,
0.6916870430603532078748910812888483894522,
-0.8037049589725231156824174550145907971032,
0.8037049589725231156824174550145907971032,
-0.8926024664975557392060605911271455154078,
0.8926024664975557392060605911271455154078,
-0.9558239495713977551811958929297763099728,
0.9558239495713977551811958929297763099728,
-0.9915651684209309467300160047061507702525,
0.9915651684209309467300160047061507702525,
],
[
0, -0.1603586456402253758680961157407435495048,
0.1603586456402253758680961157407435495048,
-0.3165640999636298319901173288498449178922,
0.3165640999636298319901173288498449178922,
-0.4645707413759609457172671481041023679762,
0.4645707413759609457172671481041023679762,
-0.6005453046616810234696381649462392798683,
0.6005453046616810234696381649462392798683,
-0.7209661773352293786170958608237816296571,
0.7209661773352293786170958608237816296571,
-0.8227146565371428249789224867127139017745,
0.8227146565371428249789224867127139017745,
-0.9031559036148179016426609285323124878093,
0.9031559036148179016426609285323124878093,
-0.960208152134830030852778840687651526615,
0.960208152134830030852778840687651526615,
-0.9924068438435844031890176702532604935893,
0.9924068438435844031890176702532604935893,
],
[
-0.0765265211334973337546404093988382110047,
0.0765265211334973337546404093988382110047,
-0.227785851141645078080496195368574624743,
0.227785851141645078080496195368574624743,
-0.3737060887154195606725481770249272373957,
0.3737060887154195606725481770249272373957,
-0.5108670019508270980043640509552509984254,
0.5108670019508270980043640509552509984254,
-0.6360536807265150254528366962262859367433,
0.6360536807265150254528366962262859367433,
-0.7463319064601507926143050703556415903107,
0.7463319064601507926143050703556415903107,
-0.8391169718222188233945290617015206853296,
0.8391169718222188233945290617015206853296,
-0.9122344282513259058677524412032981130491,
0.9122344282513259058677524412032981130491,
-0.963971927277913791267666131197277221912,
0.963971927277913791267666131197277221912,
-0.9931285991850949247861223884713202782226,
0.9931285991850949247861223884713202782226,
],
[
0, -0.1455618541608950909370309823386863301163,
0.1455618541608950909370309823386863301163,
-0.288021316802401096600792516064600319909,
0.288021316802401096600792516064600319909,
-0.4243421202074387835736688885437880520964,
0.4243421202074387835736688885437880520964,
-0.551618835887219807059018796724313286622,
0.551618835887219807059018796724313286622,
-0.667138804197412319305966669990339162597,
0.667138804197412319305966669990339162597,
-0.7684399634756779086158778513062280348209,
0.7684399634756779086158778513062280348209,
-0.8533633645833172836472506385875676702761,
0.8533633645833172836472506385875676702761,
-0.9200993341504008287901871337149688941591,
0.9200993341504008287901871337149688941591,
-0.9672268385663062943166222149076951614246,
0.9672268385663062943166222149076951614246,
-0.9937521706203895002602420359379409291933,
0.9937521706203895002602420359379409291933,
],
[
-0.0697392733197222212138417961186280818222,
0.0697392733197222212138417961186280818222,
-0.2078604266882212854788465339195457342156,
0.2078604266882212854788465339195457342156,
-0.3419358208920842251581474204273796195591,
0.3419358208920842251581474204273796195591,
-0.4693558379867570264063307109664063460953,
0.4693558379867570264063307109664063460953,
-0.5876404035069115929588769276386473488776,
0.5876404035069115929588769276386473488776,
-0.6944872631866827800506898357622567712673,
0.6944872631866827800506898357622567712673,
-0.7878168059792081620042779554083515213881,
0.7878168059792081620042779554083515213881,
-0.8658125777203001365364256370193787290847,
0.8658125777203001365364256370193787290847,
-0.9269567721871740005206929392590531966353,
0.9269567721871740005206929392590531966353,
-0.9700604978354287271239509867652687108059,
0.9700604978354287271239509867652687108059,
-0.994294585482399292073031421161298980393,
0.994294585482399292073031421161298980393,
],
[
0, -0.1332568242984661109317426822417661370104,
0.1332568242984661109317426822417661370104,
-0.264135680970344930533869538283309602979,
0.264135680970344930533869538283309602979,
-0.390301038030290831421488872880605458578,
0.390301038030290831421488872880605458578,
-0.5095014778460075496897930478668464305448,
0.5095014778460075496897930478668464305448,
-0.6196098757636461563850973116495956533871,
0.6196098757636461563850973116495956533871,
-0.7186613631319501944616244837486188483299,
0.7186613631319501944616244837486188483299,
-0.8048884016188398921511184069967785579414,
0.8048884016188398921511184069967785579414,
-0.8767523582704416673781568859341456716389,
0.8767523582704416673781568859341456716389,
-0.9329710868260161023491969890384229782357,
0.9329710868260161023491969890384229782357,
-0.9725424712181152319560240768207773751816,
0.9725424712181152319560240768207773751816,
-0.9947693349975521235239257154455743605736,
0.9947693349975521235239257154455743605736,
],
[
-0.0640568928626056260850430826247450385909,
0.0640568928626056260850430826247450385909,
-0.1911188674736163091586398207570696318404,
0.1911188674736163091586398207570696318404,
-0.3150426796961633743867932913198102407864,
0.3150426796961633743867932913198102407864,
-0.4337935076260451384870842319133497124524,
0.4337935076260451384870842319133497124524,
-0.5454214713888395356583756172183723700107,
0.5454214713888395356583756172183723700107,
-0.6480936519369755692524957869107476266696,
0.6480936519369755692524957869107476266696,
-0.7401241915785543642438281030999784255232,
0.7401241915785543642438281030999784255232,
-0.8200019859739029219539498726697452080761,
0.8200019859739029219539498726697452080761,
-0.8864155270044010342131543419821967550873,
0.8864155270044010342131543419821967550873,
-0.9382745520027327585236490017087214496548,
0.9382745520027327585236490017087214496548,
-0.9747285559713094981983919930081690617411,
0.9747285559713094981983919930081690617411,
-0.9951872199970213601799974097007368118745,
0.9951872199970213601799974097007368118745,
],
];
// Legendre-Gauss weights (wi values, defined by a function linked to in the Bezier primer article)
export const cValues = [
[],
[],
[1.0, 1.0],
[
0.8888888888888888888888888888888888888888,
0.5555555555555555555555555555555555555555,
0.5555555555555555555555555555555555555555,
],
[
0.6521451548625461426269360507780005927646,
0.6521451548625461426269360507780005927646,
0.3478548451374538573730639492219994072353,
0.3478548451374538573730639492219994072353,
],
[
0.5688888888888888888888888888888888888888,
0.4786286704993664680412915148356381929122,
0.4786286704993664680412915148356381929122,
0.2369268850561890875142640407199173626432,
0.2369268850561890875142640407199173626432,
],
[
0.3607615730481386075698335138377161116615,
0.3607615730481386075698335138377161116615,
0.4679139345726910473898703439895509948116,
0.4679139345726910473898703439895509948116,
0.1713244923791703450402961421727328935268,
0.1713244923791703450402961421727328935268,
],
[
0.4179591836734693877551020408163265306122,
0.3818300505051189449503697754889751338783,
0.3818300505051189449503697754889751338783,
0.2797053914892766679014677714237795824869,
0.2797053914892766679014677714237795824869,
0.1294849661688696932706114326790820183285,
0.1294849661688696932706114326790820183285,
],
[
0.3626837833783619829651504492771956121941,
0.3626837833783619829651504492771956121941,
0.3137066458778872873379622019866013132603,
0.3137066458778872873379622019866013132603,
0.2223810344533744705443559944262408844301,
0.2223810344533744705443559944262408844301,
0.1012285362903762591525313543099621901153,
0.1012285362903762591525313543099621901153,
],
[
0.3302393550012597631645250692869740488788,
0.1806481606948574040584720312429128095143,
0.1806481606948574040584720312429128095143,
0.0812743883615744119718921581105236506756,
0.0812743883615744119718921581105236506756,
0.3123470770400028400686304065844436655987,
0.3123470770400028400686304065844436655987,
0.2606106964029354623187428694186328497718,
0.2606106964029354623187428694186328497718,
],
[
0.295524224714752870173892994651338329421,
0.295524224714752870173892994651338329421,
0.2692667193099963550912269215694693528597,
0.2692667193099963550912269215694693528597,
0.2190863625159820439955349342281631924587,
0.2190863625159820439955349342281631924587,
0.1494513491505805931457763396576973324025,
0.1494513491505805931457763396576973324025,
0.0666713443086881375935688098933317928578,
0.0666713443086881375935688098933317928578,
],
[
0.272925086777900630714483528336342189156,
0.2628045445102466621806888698905091953727,
0.2628045445102466621806888698905091953727,
0.2331937645919904799185237048431751394317,
0.2331937645919904799185237048431751394317,
0.1862902109277342514260976414316558916912,
0.1862902109277342514260976414316558916912,
0.1255803694649046246346942992239401001976,
0.1255803694649046246346942992239401001976,
0.0556685671161736664827537204425485787285,
0.0556685671161736664827537204425485787285,
],
[
0.2491470458134027850005624360429512108304,
0.2491470458134027850005624360429512108304,
0.2334925365383548087608498989248780562594,
0.2334925365383548087608498989248780562594,
0.2031674267230659217490644558097983765065,
0.2031674267230659217490644558097983765065,
0.160078328543346226334652529543359071872,
0.160078328543346226334652529543359071872,
0.1069393259953184309602547181939962242145,
0.1069393259953184309602547181939962242145,
0.047175336386511827194615961485017060317,
0.047175336386511827194615961485017060317,
],
[
0.2325515532308739101945895152688359481566,
0.2262831802628972384120901860397766184347,
0.2262831802628972384120901860397766184347,
0.2078160475368885023125232193060527633865,
0.2078160475368885023125232193060527633865,
0.1781459807619457382800466919960979955128,
0.1781459807619457382800466919960979955128,
0.1388735102197872384636017768688714676218,
0.1388735102197872384636017768688714676218,
0.0921214998377284479144217759537971209236,
0.0921214998377284479144217759537971209236,
0.0404840047653158795200215922009860600419,
0.0404840047653158795200215922009860600419,
],
[
0.2152638534631577901958764433162600352749,
0.2152638534631577901958764433162600352749,
0.2051984637212956039659240656612180557103,
0.2051984637212956039659240656612180557103,
0.1855383974779378137417165901251570362489,
0.1855383974779378137417165901251570362489,
0.1572031671581935345696019386238421566056,
0.1572031671581935345696019386238421566056,
0.1215185706879031846894148090724766259566,
0.1215185706879031846894148090724766259566,
0.0801580871597602098056332770628543095836,
0.0801580871597602098056332770628543095836,
0.0351194603317518630318328761381917806197,
0.0351194603317518630318328761381917806197,
],
[
0.2025782419255612728806201999675193148386,
0.1984314853271115764561183264438393248186,
0.1984314853271115764561183264438393248186,
0.1861610000155622110268005618664228245062,
0.1861610000155622110268005618664228245062,
0.1662692058169939335532008604812088111309,
0.1662692058169939335532008604812088111309,
0.1395706779261543144478047945110283225208,
0.1395706779261543144478047945110283225208,
0.1071592204671719350118695466858693034155,
0.1071592204671719350118695466858693034155,
0.0703660474881081247092674164506673384667,
0.0703660474881081247092674164506673384667,
0.0307532419961172683546283935772044177217,
0.0307532419961172683546283935772044177217,
],
[
0.1894506104550684962853967232082831051469,
0.1894506104550684962853967232082831051469,
0.1826034150449235888667636679692199393835,
0.1826034150449235888667636679692199393835,
0.1691565193950025381893120790303599622116,
0.1691565193950025381893120790303599622116,
0.1495959888165767320815017305474785489704,
0.1495959888165767320815017305474785489704,
0.1246289712555338720524762821920164201448,
0.1246289712555338720524762821920164201448,
0.0951585116824927848099251076022462263552,
0.0951585116824927848099251076022462263552,
0.0622535239386478928628438369943776942749,
0.0622535239386478928628438369943776942749,
0.0271524594117540948517805724560181035122,
0.0271524594117540948517805724560181035122,
],
[
0.1794464703562065254582656442618856214487,
0.1765627053669926463252709901131972391509,
0.1765627053669926463252709901131972391509,
0.1680041021564500445099706637883231550211,
0.1680041021564500445099706637883231550211,
0.1540457610768102880814315948019586119404,
0.1540457610768102880814315948019586119404,
0.1351363684685254732863199817023501973721,
0.1351363684685254732863199817023501973721,
0.1118838471934039710947883856263559267358,
0.1118838471934039710947883856263559267358,
0.0850361483171791808835353701910620738504,
0.0850361483171791808835353701910620738504,
0.0554595293739872011294401653582446605128,
0.0554595293739872011294401653582446605128,
0.0241483028685479319601100262875653246916,
0.0241483028685479319601100262875653246916,
],
[
0.1691423829631435918406564701349866103341,
0.1691423829631435918406564701349866103341,
0.1642764837458327229860537764659275904123,
0.1642764837458327229860537764659275904123,
0.1546846751262652449254180038363747721932,
0.1546846751262652449254180038363747721932,
0.1406429146706506512047313037519472280955,
0.1406429146706506512047313037519472280955,
0.1225552067114784601845191268002015552281,
0.1225552067114784601845191268002015552281,
0.1009420441062871655628139849248346070628,
0.1009420441062871655628139849248346070628,
0.0764257302548890565291296776166365256053,
0.0764257302548890565291296776166365256053,
0.0497145488949697964533349462026386416808,
0.0497145488949697964533349462026386416808,
0.0216160135264833103133427102664524693876,
0.0216160135264833103133427102664524693876,
],
[
0.1610544498487836959791636253209167350399,
0.1589688433939543476499564394650472016787,
0.1589688433939543476499564394650472016787,
0.152766042065859666778855400897662998461,
0.152766042065859666778855400897662998461,
0.1426067021736066117757461094419029724756,
0.1426067021736066117757461094419029724756,
0.1287539625393362276755157848568771170558,
0.1287539625393362276755157848568771170558,
0.1115666455473339947160239016817659974813,
0.1115666455473339947160239016817659974813,
0.0914900216224499994644620941238396526609,
0.0914900216224499994644620941238396526609,
0.0690445427376412265807082580060130449618,
0.0690445427376412265807082580060130449618,
0.0448142267656996003328381574019942119517,
0.0448142267656996003328381574019942119517,
0.0194617882297264770363120414644384357529,
0.0194617882297264770363120414644384357529,
],
[
0.1527533871307258506980843319550975934919,
0.1527533871307258506980843319550975934919,
0.1491729864726037467878287370019694366926,
0.1491729864726037467878287370019694366926,
0.1420961093183820513292983250671649330345,
0.1420961093183820513292983250671649330345,
0.1316886384491766268984944997481631349161,
0.1316886384491766268984944997481631349161,
0.118194531961518417312377377711382287005,
0.118194531961518417312377377711382287005,
0.1019301198172404350367501354803498761666,
0.1019301198172404350367501354803498761666,
0.0832767415767047487247581432220462061001,
0.0832767415767047487247581432220462061001,
0.0626720483341090635695065351870416063516,
0.0626720483341090635695065351870416063516,
0.040601429800386941331039952274932109879,
0.040601429800386941331039952274932109879,
0.0176140071391521183118619623518528163621,
0.0176140071391521183118619623518528163621,
],
[
0.1460811336496904271919851476833711882448,
0.1445244039899700590638271665537525436099,
0.1445244039899700590638271665537525436099,
0.1398873947910731547221334238675831108927,
0.1398873947910731547221334238675831108927,
0.132268938633337461781052574496775604329,
0.132268938633337461781052574496775604329,
0.1218314160537285341953671771257335983563,
0.1218314160537285341953671771257335983563,
0.1087972991671483776634745780701056420336,
0.1087972991671483776634745780701056420336,
0.0934444234560338615532897411139320884835,
0.0934444234560338615532897411139320884835,
0.0761001136283793020170516533001831792261,
0.0761001136283793020170516533001831792261,
0.0571344254268572082836358264724479574912,
0.0571344254268572082836358264724479574912,
0.0369537897708524937999506682993296661889,
0.0369537897708524937999506682993296661889,
0.0160172282577743333242246168584710152658,
0.0160172282577743333242246168584710152658,
],
[
0.1392518728556319933754102483418099578739,
0.1392518728556319933754102483418099578739,
0.1365414983460151713525738312315173965863,
0.1365414983460151713525738312315173965863,
0.1311735047870623707329649925303074458757,
0.1311735047870623707329649925303074458757,
0.1232523768105124242855609861548144719594,
0.1232523768105124242855609861548144719594,
0.1129322960805392183934006074217843191142,
0.1129322960805392183934006074217843191142,
0.1004141444428809649320788378305362823508,
0.1004141444428809649320788378305362823508,
0.0859416062170677274144436813727028661891,
0.0859416062170677274144436813727028661891,
0.0697964684245204880949614189302176573987,
0.0697964684245204880949614189302176573987,
0.0522933351526832859403120512732112561121,
0.0522933351526832859403120512732112561121,
0.0337749015848141547933022468659129013491,
0.0337749015848141547933022468659129013491,
0.0146279952982722006849910980471854451902,
0.0146279952982722006849910980471854451902,
],
[
0.1336545721861061753514571105458443385831,
0.132462039404696617371642464703316925805,
0.132462039404696617371642464703316925805,
0.1289057221880821499785953393997936532597,
0.1289057221880821499785953393997936532597,
0.1230490843067295304675784006720096548158,
0.1230490843067295304675784006720096548158,
0.1149966402224113649416435129339613014914,
0.1149966402224113649416435129339613014914,
0.1048920914645414100740861850147438548584,
0.1048920914645414100740861850147438548584,
0.0929157660600351474770186173697646486034,
0.0929157660600351474770186173697646486034,
0.0792814117767189549228925247420432269137,
0.0792814117767189549228925247420432269137,
0.0642324214085258521271696151589109980391,
0.0642324214085258521271696151589109980391,
0.0480376717310846685716410716320339965612,
0.0480376717310846685716410716320339965612,
0.0309880058569794443106942196418845053837,
0.0309880058569794443106942196418845053837,
0.0134118594871417720813094934586150649766,
0.0134118594871417720813094934586150649766,
],
[
0.1279381953467521569740561652246953718517,
0.1279381953467521569740561652246953718517,
0.1258374563468282961213753825111836887264,
0.1258374563468282961213753825111836887264,
0.121670472927803391204463153476262425607,
0.121670472927803391204463153476262425607,
0.1155056680537256013533444839067835598622,
0.1155056680537256013533444839067835598622,
0.1074442701159656347825773424466062227946,
0.1074442701159656347825773424466062227946,
0.0976186521041138882698806644642471544279,
0.0976186521041138882698806644642471544279,
0.086190161531953275917185202983742667185,
0.086190161531953275917185202983742667185,
0.0733464814110803057340336152531165181193,
0.0733464814110803057340336152531165181193,
0.0592985849154367807463677585001085845412,
0.0592985849154367807463677585001085845412,
0.0442774388174198061686027482113382288593,
0.0442774388174198061686027482113382288593,
0.0285313886289336631813078159518782864491,
0.0285313886289336631813078159518782864491,
0.0123412297999871995468056670700372915759,
0.0123412297999871995468056670700372915759,
],
];
// LUT for binomial coefficient arrays per curve order 'n'
export const binomialCoefficients = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]];
export const getCubicArcLength = (xs: number[], ys: number[], t: number) => {
let sum: number;
let correctedT: number;
/*if (xs.length >= tValues.length) {
throw new Error('too high n bezier');
}*/
const n = 20;
const z = t / 2;
sum = 0;
for (let i = 0; i < n; i++) {
correctedT = z * tValues[n][i] + z;
sum += cValues[n][i] * BFunc(xs, ys, correctedT);
}
return z * sum;
};
export const getQuadraticArcLength = (
xs: number[],
ys: number[],
t: number
) => {
if (t === undefined) {
t = 1;
}
const ax = xs[0] - 2 * xs[1] + xs[2];
const ay = ys[0] - 2 * ys[1] + ys[2];
const bx = 2 * xs[1] - 2 * xs[0];
const by = 2 * ys[1] - 2 * ys[0];
const A = 4 * (ax * ax + ay * ay);
const B = 4 * (ax * bx + ay * by);
const C = bx * bx + by * by;
if (A === 0) {
return (
t * Math.sqrt(Math.pow(xs[2] - xs[0], 2) + Math.pow(ys[2] - ys[0], 2))
);
}
const b = B / (2 * A);
const c = C / A;
const u = t + b;
const k = c - b * b;
const uuk = u * u + k > 0 ? Math.sqrt(u * u + k) : 0;
const bbk = b * b + k > 0 ? Math.sqrt(b * b + k) : 0;
const term =
b + Math.sqrt(b * b + k) !== 0
? k * Math.log(Math.abs((u + uuk) / (b + bbk)))
: 0;
return (Math.sqrt(A) / 2) * (u * uuk - b * bbk + term);
};
function BFunc(xs: number[], ys: number[], t: number) {
const xbase = getDerivative(1, t, xs);
const ybase = getDerivative(1, t, ys);
const combined = xbase * xbase + ybase * ybase;
return Math.sqrt(combined);
}
/**
* Compute the curve derivative (hodograph) at t.
*/
const getDerivative = (derivative: number, t: number, vs: number[]): number => {
// the derivative of any 't'-less function is zero.
const n = vs.length - 1;
let _vs;
let value;
if (n === 0) {
return 0;
}
// direct values? compute!
if (derivative === 0) {
value = 0;
for (let k = 0; k <= n; k++) {
value +=
binomialCoefficients[n][k] *
Math.pow(1 - t, n - k) *
Math.pow(t, k) *
vs[k];
}
return value;
} else {
// Still some derivative? go down one order, then try
// for the lower order curve's.
_vs = new Array(n);
for (let k = 0; k < n; k++) {
_vs[k] = n * (vs[k + 1] - vs[k]);
}
return getDerivative(derivative - 1, t, _vs);
}
};
export const t2length = (
length: number,
totalLength: number,
func: (t: number) => number
): number => {
let error = 1;
let t = length / totalLength;
let step = (length - func(t)) / totalLength;
let numIterations = 0;
while (error > 0.001) {
const increasedTLength = func(t + step);
const increasedTError = Math.abs(length - increasedTLength) / totalLength;
if (increasedTError < error) {
error = increasedTError;
t += step;
} else {
const decreasedTLength = func(t - step);
const decreasedTError = Math.abs(length - decreasedTLength) / totalLength;
if (decreasedTError < error) {
error = decreasedTError;
t -= step;
} else {
step /= 2;
}
}
numIterations++;
if (numIterations > 500) {
break;
}
}
return t;
};
================================================
FILE: src/Canvas.ts
================================================
import { Util } from './Util.ts';
import type { Context } from './Context.ts';
import { SceneContext, HitContext } from './Context.ts';
import { Konva } from './Global.ts';
// calculate pixel ratio
let _pixelRatio;
function getDevicePixelRatio() {
if (_pixelRatio) {
return _pixelRatio;
}
const canvas = Util.createCanvasElement();
const context = canvas.getContext('2d') as any;
_pixelRatio = (function () {
const devicePixelRatio = Konva._global.devicePixelRatio || 1,
backingStoreRatio =
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio ||
1;
return devicePixelRatio / backingStoreRatio;
})();
Util.releaseCanvas(canvas);
return _pixelRatio;
}
interface ICanvasConfig {
width?: number;
height?: number;
pixelRatio?: number;
willReadFrequently?: boolean;
}
/**
* Canvas Renderer constructor. It is a wrapper around native canvas element.
* Usually you don't need to use it manually.
* @constructor
* @abstract
* @memberof Konva
* @param {Object} config
* @param {Number} config.width
* @param {Number} config.height
* @param {Number} config.pixelRatio
*/
export class Canvas {
pixelRatio = 1;
_canvas: HTMLCanvasElement;
context: Context;
width = 0;
height = 0;
isCache = false;
constructor(config: ICanvasConfig) {
const conf = config || {};
const pixelRatio =
conf.pixelRatio || Konva.pixelRatio || getDevicePixelRatio();
this.pixelRatio = pixelRatio;
this._canvas = Util.createCanvasElement();
// set inline styles
this._canvas.style.padding = '0';
this._canvas.style.margin = '0';
this._canvas.style.border = '0';
this._canvas.style.background = 'transparent';
this._canvas.style.position = 'absolute';
this._canvas.style.top = '0';
this._canvas.style.left = '0';
}
/**
* get canvas context
* @method
* @name Konva.Canvas#getContext
* @returns {CanvasContext} context
*/
getContext() {
return this.context;
}
/**
* get pixel ratio
* @method
* @name Konva.Canvas#getPixelRatio
* @returns {Number} pixel ratio
* @example
* var pixelRatio = layer.getCanvas.getPixelRatio();
*/
getPixelRatio() {
return this.pixelRatio;
}
/**
* set pixel ratio
* KonvaJS automatically handles pixel ratio adustments in order to render crisp drawings
* on all devices. Most desktops, low end tablets, and low end phones, have device pixel ratios
* of 1. Some high end tablets and phones, like iPhones and iPads have a device pixel ratio
* of 2. Some Macbook Pros, and iMacs also have a device pixel ratio of 2. Some high end Android devices have pixel
* ratios of 2 or 3. Some browsers like Firefox allow you to configure the pixel ratio of the viewport. Unless otherwise
* specificed, the pixel ratio will be defaulted to the actual device pixel ratio. You can override the device pixel
* ratio for special situations, or, if you don't want the pixel ratio to be taken into account, you can set it to 1.
* @method
* @name Konva.Canvas#setPixelRatio
* @param {Number} pixelRatio
* @example
* layer.getCanvas().setPixelRatio(3);
*/
setPixelRatio(pixelRatio) {
const previousRatio = this.pixelRatio;
this.pixelRatio = pixelRatio;
this.setSize(
this.getWidth() / previousRatio,
this.getHeight() / previousRatio
);
}
setWidth(width) {
// take into account pixel ratio
this.width = this._canvas.width = width * this.pixelRatio;
this._canvas.style.width = width + 'px';
const pixelRatio = this.pixelRatio,
_context = this.getContext()._context;
_context.scale(pixelRatio, pixelRatio);
}
setHeight(height) {
// take into account pixel ratio
this.height = this._canvas.height = height * this.pixelRatio;
this._canvas.style.height = height + 'px';
const pixelRatio = this.pixelRatio,
_context = this.getContext()._context;
_context.scale(pixelRatio, pixelRatio);
}
getWidth() {
return this.width;
}
getHeight() {
return this.height;
}
setSize(width, height) {
this.setWidth(width || 0);
this.setHeight(height || 0);
}
/**
* to data url
* @method
* @name Konva.Canvas#toDataURL
* @param {String} mimeType
* @param {Number} quality between 0 and 1 for jpg mime types
* @returns {String} data url string
*/
toDataURL(mimeType, quality) {
try {
// If this call fails (due to browser bug, like in Firefox 3.6),
// then revert to previous no-parameter image/png behavior
return this._canvas.toDataURL(mimeType, quality);
} catch (e) {
try {
return this._canvas.toDataURL();
} catch (err: any) {
Util.error(
'Unable to get data URL. ' +
err.message +
' For more info read https://konvajs.org/docs/posts/Tainted_Canvas.html.'
);
return '';
}
}
}
}
export class SceneCanvas extends Canvas {
constructor(
config: ICanvasConfig = { width: 0, height: 0, willReadFrequently: false }
) {
super(config);
this.context = new SceneContext(this, {
willReadFrequently: config.willReadFrequently,
});
this.setSize(config.width, config.height);
}
}
export class HitCanvas extends Canvas {
hitCanvas = true;
constructor(config: ICanvasConfig = { width: 0, height: 0 }) {
super(config);
this.context = new HitContext(this);
this.setSize(config.width, config.height);
}
}
================================================
FILE: src/Container.ts
================================================
import type { HitCanvas, SceneCanvas } from './Canvas.ts';
import type { SceneContext } from './Context.ts';
import { Factory } from './Factory.ts';
import type { NodeConfig } from './Node.ts';
import { Node } from './Node.ts';
import type { Shape } from './Shape.ts';
import type { GetSet, IRect } from './types.ts';
import { getNumberValidator } from './Validators.ts';
export type ClipFuncOutput =
| void
| [Path2D | CanvasFillRule]
| [Path2D, CanvasFillRule];
export interface ContainerConfig extends NodeConfig {
clearBeforeDraw?: boolean;
clipFunc?: (ctx: SceneContext) => ClipFuncOutput;
clipX?: number;
clipY?: number;
clipWidth?: number;
clipHeight?: number;
}
/**
* Container constructor. Containers are used to contain nodes or other containers
* @constructor
* @memberof Konva
* @augments Konva.Node
* @abstract
* @param {Object} config
* @@nodeParams
* @@containerParams
*/
export abstract class Container<
ChildType extends Node = Node,
Config extends ContainerConfig = ContainerConfig,
> extends Node<Config> {
children: Array<ChildType> = [];
/**
* returns an array of direct descendant nodes
* @method
* @name Konva.Container#getChildren
* @param {Function} [filterFunc] filter function
* @returns {Array}
* @example
* // get all children
* var children = layer.getChildren();
*
* // get only circles
* var circles = layer.getChildren(function(node){
* return node.getClassName() === 'Circle';
* });
*/
getChildren(filterFunc?: (item: Node) => boolean) {
const children = this.children || [];
if (filterFunc) {
return children.filter(filterFunc);
}
return children;
}
/**
* determine if node has children
* @method
* @name Konva.Container#hasChildren
* @returns {Boolean}
*/
hasChildren() {
return this.getChildren().length > 0;
}
/**
* remove all children. Children will be still in memory.
* If you want to completely destroy all children please use "destroyChildren" method instead
* @method
* @name Konva.Container#removeChildren
*/
removeChildren() {
this.getChildren().forEach((child) => {
// reset parent to prevent many _setChildrenIndices calls
child.parent = null;
child.index = 0;
child.remove();
});
this.children = [];
// because all children were detached from parent, request draw via container
this._requestDraw();
return this;
}
/**
* destroy all children nodes.
* @method
* @name Konva.Container#destroyChildren
*/
destroyChildren() {
this.getChildren().forEach((child) => {
// reset parent to prevent many _setChildrenIndices calls
child.parent = null;
child.index = 0;
child.destroy();
});
this.children = [];
// because all children were detached from parent, request draw via container
this._requestDraw();
return this;
}
abstract _validateAdd(node: Node): void;
/**
* add a child and children into container
* @name Konva.Container#add
* @method
* @param {...Konva.Node} children
* @returns {Container}
* @example
* layer.add(rect);
* layer.add(shape1, shape2, shape3);
* // empty arrays are accepted, though each individual child must be defined
* layer.add(...shapes);
*/
add(...children: ChildType[]) {
if (children.length === 0) {
return this;
}
if (children.length > 1) {
for (let i = 0; i < children.length; i++) {
this.add(children[i]);
}
return this;
}
const child = children[0];
if (child.getParent()) {
child.moveTo(this);
return this;
}
this._validateAdd(child);
child.index = this.getChildren().length;
child.parent = this;
child._clearCaches();
this.getChildren().push(child);
this._fire('add', {
child: child,
});
this._requestDraw();
// chainable
return this;
}
destroy() {
if (this.hasChildren()) {
this.destroyChildren();
}
super.destroy();
return this;
}
/**
* return an array of nodes that match the selector.
* You can provide a string with '#' for id selections and '.' for name selections.
* Or a function that will return true/false when a node is passed through. See example below.
* With strings you can also select by type or class name. Pass multiple selectors
* separated by a comma.
* @method
* @name Konva.Container#find
* @param {String | Function} selector
* @returns {Array}
* @example
*
* Passing a string as a selector
* // select node with id foo
* var node = stage.find('#foo');
*
* // select nodes with name bar inside layer
* var nodes = layer.find('.bar');
*
* // select all groups inside layer
* var nodes = layer.find('Group');
*
* // select all rectangles inside layer
* var nodes = layer.find('Rect');
*
* // select node with an id of foo or a name of bar inside layer
* var nodes = layer.find('#foo, .bar');
*
* Passing a function as a selector
*
* // get all groups with a function
* var groups = stage.find(node => {
* return node.getType() === 'Group';
* });
*
* // get only Nodes with partial opacity
* var alphaNodes = layer.find(node => {
* return node.getType() === 'Node' && node.getAbsoluteOpacity() < 1;
* });
*/
find<ChildNode extends Node>(selector): Array<ChildNode> {
// protecting _generalFind to prevent user from accidentally adding
// second argument and getting unexpected `findOne` result
return this._generalFind<ChildNode>(selector, false);
}
/**
* return a first node from `find` method
* @method
* @name Konva.Container#findOne
* @param {String | Function} selector
* @returns {Konva.Node | Undefined}
* @example
* // select node with id foo
* var node = stage.findOne('#foo');
*
* // select node with name bar inside layer
* var nodes = layer.findOne('.bar');
*
* // select the first node to return true in a function
* var node = stage.findOne(node => {
* return node.getType() === 'Shape'
* })
*/
findOne<ChildNode extends Node = Node>(
selector: string | Function
): ChildNode | undefined {
const result = this._generalFind<ChildNode>(selector, true);
return result.length > 0 ? result[0] : undefined;
}
_generalFind<ChildNode extends Node>(
selector: string | Function,
findOne: boolean
) {
const retArr: Array<ChildNode> = [];
this._descendants((node) => {
const valid = node._isMatch(selector);
if (valid) {
retArr.push(node as ChildNode);
}
if (valid && findOne) {
return true;
}
return false;
});
return retArr;
}
private _descendants(fn: (n: Node) => boolean) {
let shouldStop = false;
const children = this.getChildren();
for (const child of children) {
shouldStop = fn(child);
if (shouldStop) {
return true;
}
if (!child.hasChildren()) {
continue;
}
shouldStop = (child as unknown as Container)._descendants(fn);
if (shouldStop) {
return true;
}
}
return false;
}
// extenders
toObject() {
const obj = Node.prototype.toObject.call(this);
obj.children = [];
this.getChildren().forEach((child) => {
obj.children!.push(child.toObject());
});
return obj;
}
/**
* determine if node is an ancestor
* of descendant
* @method
* @name Konva.Container#isAncestorOf
* @param {Konva.Node} node
*/
isAncestorOf(node: Node) {
let parent = node.getParent();
while (parent) {
if (parent._id === this._id) {
return true;
}
parent = parent.getParent();
}
return false;
}
clone(obj?: any) {
// call super method
const node = Node.prototype.clone.call(this, obj);
this.getChildren().forEach(function (no) {
node.add(no.clone());
});
return node as this;
}
/**
* get all shapes that intersect a point. Note: because this method must clear a temporary
* canvas and redraw every shape inside the container, it should only be used for special situations
* because it performs very poorly. Please use the {@link Konva.Stage#getIntersection} method if at all possible
* because it performs much better
* nodes with listening set to false will not be detected
* @method
* @name Konva.Container#getAllIntersections
* @param {Object} pos
* @param {Number} pos.x
* @param {Number} pos.y
* @returns {Array} array of shapes
*/
getAllIntersections(pos) {
const arr: Shape[] = [];
this.find<Shape>('Shape').forEach((shape) => {
if (shape.isVisible() && shape.intersects(pos)) {
arr.push(shape);
}
});
return arr;
}
_clearSelfAndDescendantCache(attr?: string) {
super._clearSelfAndDescendantCache(attr);
// skip clearing if node is cached with canvas
// for performance reasons !!!
if (this.isCached()) {
return;
}
this.children?.forEach(function (node) {
node._clearSelfAndDescendantCache(attr);
});
}
_setChildrenIndices() {
this.children?.forEach(function (child, n) {
child.index = n;
});
this._requestDraw();
}
drawScene(can?: SceneCanvas, top?: Node, bufferCanvas?: SceneCanvas) {
const layer = this.getLayer()!,
canvas = can || (layer && layer.getCanvas()),
context = canvas && canvas.getContext(),
cachedCanvas = this._getCanvasCache(),
cachedSceneCanvas = cachedCanvas && cachedCanvas.scene;
const caching = canvas && canvas.isCache;
if (!this.isVisible() && !caching) {
return this;
}
if (cachedSceneCanvas) {
context.save();
const m = this.getAbsoluteTransform(top).getMatrix();
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
this._drawCachedSceneCanvas(context);
context.restore();
} else {
this._drawChildren('drawScene', canvas, top, bufferCanvas);
}
return this;
}
drawHit(can?: HitCanvas, top?: Node) {
if (!this.shouldDrawHit(top)) {
return this;
}
const layer = this.getLayer()!,
canvas = can || (layer && layer.hitCanvas),
context = canvas && canvas.getContext(),
cachedCanvas = this._getCanvasCache(),
cachedHitCanvas = cachedCanvas && cachedCanvas.hit;
if (cachedHitCanvas) {
context.save();
const m = this.getAbsoluteTransform(top).getMatrix();
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
this._drawCachedHitCanvas(context);
context.restore();
} else {
this._drawChildren('drawHit', canvas, top);
}
return this;
}
_drawChildren(drawMethod, canvas, top, bufferCanvas?) {
const context = canvas && canvas.getContext(),
clipWidth = this.clipWidth(),
clipHeight = this.clipHeight(),
clipFunc = this.clipFunc(),
hasClip =
(typeof clipWidth === 'number' && typeof clipHeight === 'number') ||
clipFunc;
const selfCache = top === this;
if (hasClip) {
context.save();
const transform = this.getAbsoluteTransform(top);
let m = transform.getMatrix();
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
context.beginPath();
let clipArgs;
if (clipFunc) {
clipArgs = clipFunc.call(this, context, this);
} else {
const clipX = this.clipX();
const clipY = this.clipY();
context.rect(clipX || 0, clipY || 0, clipWidth, clipHeight);
}
context.clip.apply(context, clipArgs);
m = transform.copy().invert().getMatrix();
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
}
const hasComposition =
!selfCache &&
this.globalCompositeOperation() !== 'source-over' &&
drawMethod === 'drawScene';
if (hasComposition) {
context.save();
context._applyGlobalCompositeOperation(this);
}
this.children?.forEach(function (child) {
child[drawMethod](canvas, top, bufferCanvas);
});
if (hasComposition) {
context.restore();
}
if (hasClip) {
context.restore();
}
}
getClientRect(
config: {
skipTransform?: boolean;
skipShadow?: boolean;
skipStroke?: boolean;
relativeTo?: Container<Node>;
} = {}
): IRect {
const skipTransform = config.skipTransform;
const relativeTo = config.relativeTo;
let minX, minY, maxX, maxY;
let selfRect = {
x: Infinity,
y: Infinity,
width: 0,
height: 0,
};
const that = this;
this.children?.forEach(function (child) {
// skip invisible children
if (!child.visible()) {
return;
}
const rect = child.getClientRect({
relativeTo: that,
skipShadow: config.skipShadow,
skipStroke: config.skipStroke,
});
// skip invisible children (like empty groups)
if (rect.width === 0 && rect.height === 0) {
return;
}
if (minX === undefined) {
// initial value for first child
minX = rect.x;
minY = rect.y;
maxX = rect.x + rect.width;
maxY = rect.y + rect.height;
} else {
minX = Math.min(minX, rect.x);
minY = Math.min(minY, rect.y);
maxX = Math.max(maxX, rect.x + rect.width);
maxY = Math.max(maxY, rect.y + rect.height);
}
});
// if child is group we need to make sure it has visible shapes inside
const shapes = this.find('Shape');
let hasVisible = false;
for (let i = 0; i < shapes.length; i++) {
const shape = shapes[i];
if (shape._isVisible(this)) {
hasVisible = true;
break;
}
}
if (hasVisible && minX !== undefined) {
selfRect = {
x: minX,
y: minY,
width: maxX - minX,
height: maxY - minY,
};
} else {
selfRect = {
x: 0,
y: 0,
width: 0,
height: 0,
};
}
if (!skipTransform) {
return this._transformedRect(selfRect, relativeTo);
}
return selfRect;
}
clip: GetSet<IRect, this>;
clipX: GetSet<number, this>;
clipY: GetSet<number, this>;
clipWidth: GetSet<number, this>;
clipHeight: GetSet<number, this>;
// there was "this" instead of "Container<ChildType>",
// but it breaks react-konva types: https://github.com/konvajs/react-konva/issues/390
clipFunc: GetSet<
(ctx: CanvasRenderingContext2D, shape: Container) => ClipFuncOutput,
this
>;
}
// add getters setters
Factory.addComponentsGetterSetter(Container, 'clip', [
'x',
'y',
'width',
'height',
]);
/**
* get/set clip
* @method
* @name Konva.Container#clip
* @param {Object} clip
* @param {Number} clip.x
* @param {Number} clip.y
* @param {Number} clip.width
* @param {Number} clip.height
* @returns {Object}
* @example
* // get clip
* var clip = container.clip();
*
* // set clip
* container.clip({
* x: 20,
* y: 20,
* width: 20,
* height: 20
* });
*/
Factory.addGetterSetter(Container, 'clipX', undefined, getNumberValidator());
/**
* get/set clip x
* @name Konva.Container#clipX
* @method
* @param {Number} x
* @returns {Number}
* @example
* // get clip x
* var clipX = container.clipX();
*
* // set clip x
* container.clipX(10);
*/
Factory.addGetterSetter(Container, 'clipY', undefined, getNumberValidator());
/**
* get/set clip y
* @name Konva.Container#clipY
* @method
* @param {Number} y
* @returns {Number}
* @example
* // get clip y
* var clipY = container.clipY();
*
* // set clip y
* container.clipY(10);
*/
Factory.addGetterSetter(
Container,
'clipWidth',
undefined,
getNumberValidator()
);
/**
* get/set clip width
* @name Konva.Container#clipWidth
* @method
* @param {Number} width
* @returns {Number}
* @example
* // get clip width
* var clipWidth = container.clipWidth();
*
* // set clip width
* container.clipWidth(100);
*/
Factory.addGetterSetter(
Container,
'clipHeight',
undefined,
getNumberValidator()
);
/**
* get/set clip height
* @name Konva.Container#clipHeight
* @method
* @param {Number} height
* @returns {Number}
* @example
* // get clip height
* var clipHeight = container.clipHeight();
*
* // set clip height
* container.clipHeight(100);
*/
Factory.addGetterSetter(Container, 'clipFunc');
/**
* get/set clip function
* @name Konva.Container#clipFunc
* @method
* @param {Function} function
* @returns {Function}
* @example
* // get clip function
* var clipFunction = container.clipFunc();
*
* // set clip function
* container.clipFunc(function(ctx) {
* ctx.rect(0, 0, 100, 100);
* });
*
* container.clipFunc(function(ctx) {
* // optionally return a clip Path2D and clip-rule or just the clip-rule
* return [new Path2D('M0 0v50h50Z'), 'evenodd']
* });
*/
================================================
FILE: src/Context.ts
================================================
import { Util } from './Util.ts';
import { Konva } from './Global.ts';
import type { Canvas } from './Canvas.ts';
import type { Shape } from './Shape.ts';
import type { IRect } from './types.ts';
import type { Node } from './Node.ts';
function simplifyArray(arr: Array<any>) {
const retArr: Array<any> = [],
len = arr.length,
util = Util;
for (let n = 0; n < len; n++) {
let val = arr[n];
if (util._isNumber(val)) {
val = Math.round(val * 1000) / 1000;
} else if (!util._isString(val)) {
val = val + '';
}
retArr.push(val);
}
return retArr;
}
const COMMA = ',',
OPEN_PAREN = '(',
CLOSE_PAREN = ')',
OPEN_PAREN_BRACKET = '([',
CLOSE_BRACKET_PAREN = '])',
SEMICOLON = ';',
DOUBLE_PAREN = '()',
// EMPTY_STRING = '',
EQUALS = '=',
// SET = 'set',
CONTEXT_METHODS = [
'arc',
'arcTo',
'beginPath',
'bezierCurveTo',
'clearRect',
'clip',
'closePath',
'createLinearGradient',
'createPattern',
'createRadialGradient',
'drawImage',
'ellipse',
'fill',
'fillText',
'getImageData',
'createImageData',
'lineTo',
'moveTo',
'putImageData',
'quadraticCurveTo',
'rect',
'roundRect',
'restore',
'rotate',
'save',
'scale',
'setLineDash',
'setTransform',
'stroke',
'strokeText',
'transform',
'translate',
];
const CONTEXT_PROPERTIES = [
'fillStyle',
'strokeStyle',
'shadowColor',
'shadowBlur',
'shadowOffsetX',
'shadowOffsetY',
'letterSpacing',
'lineCap',
'lineDashOffset',
'lineJoin',
'lineWidth',
'miterLimit',
'direction',
'font',
'textAlign',
'textBaseline',
'globalAlpha',
'globalCompositeOperation',
'imageSmoothingEnabled',
'filter',
] as const;
const traceArrMax = 100;
// Check if CSS filters are supported in the current browser
let _cssFiltersSupported: boolean | null = null;
export function isCSSFiltersSupported(): boolean {
if (_cssFiltersSupported !== null) {
return _cssFiltersSupported;
}
try {
const canvas = Util.createCanvasElement();
const ctx = canvas.getContext('2d');
if (!ctx) {
_cssFiltersSupported = false;
return false;
}
return !!ctx && 'filter' in ctx;
} catch (e) {
_cssFiltersSupported = false;
return false;
}
}
interface ExtendedCanvasRenderingContext2D extends CanvasRenderingContext2D {
letterSpacing: string;
}
/**
* Konva wrapper around native 2d canvas context. It has almost the same API of 2d context with some additional functions.
* With core Konva shapes you don't need to use this object. But you will use it if you want to create
* a [custom shape](/docs/react/Custom_Shape.html) or a [custom hit regions](/docs/events/Custom_Hit_Region.html).
* For full information about each 2d context API use [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D)
* @constructor
* @memberof Konva
* @example
* const rect = new Konva.Shape({
* fill: 'red',
* width: 100,
* height: 100,
* sceneFunc: (ctx, shape) => {
* // ctx - is context wrapper
* // shape - is instance of Konva.Shape, so it equals to "rect" variable
* ctx.rect(0, 0, shape.getAttr('width'), shape.getAttr('height'));
*
* // automatically fill shape from props and draw hit region
* ctx.fillStrokeShape(shape);
* }
* })
*/
export class Context {
canvas: Canvas;
_context: CanvasRenderingContext2D;
traceArr: Array<string>;
constructor(canvas: Canvas) {
this.canvas = canvas;
if (Konva.enableTrace) {
this.traceArr = [];
this._enableTrace();
}
}
/**
* fill shape
* @method
* @name Konva.Context#fillShape
* @param {Konva.Shape} shape
*/
fillShape(shape: Shape) {
if (shape.fillEnabled()) {
this._fill(shape);
}
}
_fill(shape: Shape) {
// abstract
}
/**
* stroke shape
* @method
* @name Konva.Context#strokeShape
* @param {Konva.Shape} shape
*/
strokeShape(shape: Shape) {
if (shape.hasStroke()) {
this._stroke(shape);
}
}
_stroke(shape: Shape) {
// abstract
}
/**
* fill then stroke
* @method
* @name Konva.Context#fillStrokeShape
* @param {Konva.Shape} shape
*/
fillStrokeShape(shape: Shape) {
if (shape.attrs.fillAfterStrokeEnabled) {
this.strokeShape(shape);
this.fillShape(shape);
} else {
this.fillShape(shape);
this.strokeShape(shape);
}
}
getTrace(relaxed?: boolean, rounded?: boolean) {
let traceArr = this.traceArr,
len = traceArr.length,
str = '',
n,
trace,
method,
args;
for (n = 0; n < len; n++) {
trace = traceArr[n];
method = trace.method;
// methods
if (method) {
args = trace.args;
str += method;
if (relaxed) {
str += DOUBLE_PAREN;
} else {
if (Util._isArray(args[0])) {
str += OPEN_PAREN_BRACKET + args.join(COMMA) + CLOSE_BRACKET_PAREN;
} else {
if (rounded) {
args = args.map((a) =>
typeof a === 'number' ? Math.floor(a) : a
);
}
str += OPEN_PAREN + args.join(COMMA) + CLOSE_PAREN;
}
}
} else {
// properties
str += trace.property;
if (!relaxed) {
str += EQUALS + trace.val;
}
}
str += SEMICOLON;
}
return str;
}
clearTrace() {
this.traceArr = [];
}
_trace(str) {
let traceArr = this.traceArr,
len;
traceArr.push(str);
len = traceArr.length;
if (len >= traceArrMax) {
traceArr.shift();
}
}
/**
* reset canvas context transform
* @method
* @name Konva.Context#reset
*/
reset() {
const pixelRatio = this.getCanvas().getPixelRatio();
this.setTransform(1 * pixelRatio, 0, 0, 1 * pixelRatio, 0, 0);
}
/**
* get canvas wrapper
* @method
* @name Konva.Context#getCanvas
* @returns {Konva.Canvas}
*/
getCanvas() {
return this.canvas;
}
/**
* clear canvas
* @method
* @name Konva.Context#clear
* @param {Object} [bounds]
* @param {Number} [bounds.x]
* @param {Number} [bounds.y]
* @param {Number} [bounds.width]
* @param {Number} [bounds.height]
*/
clear(bounds?: IRect) {
const canvas = this.getCanvas();
if (bounds) {
this.clearRect(
bounds.x || 0,
bounds.y || 0,
bounds.width || 0,
bounds.height || 0
);
} else {
this.clearRect(
0,
0,
canvas.getWidth() / canvas.pixelRatio,
canvas.getHeight() / canvas.pixelRatio
);
}
}
_applyLineCap(shape: Shape) {
const lineCap = shape.attrs.lineCap;
if (lineCap) {
this.setAttr('lineCap', lineCap);
}
}
_applyOpacity(shape: Node) {
const absOpacity = shape.getAbsoluteOpacity();
if (absOpacity !== 1) {
this.setAttr('globalAlpha', absOpacity);
}
}
_applyLineJoin(shape: Shape) {
const lineJoin = shape.attrs.lineJoin;
if (lineJoin) {
this.setAttr('lineJoin', lineJoin);
}
}
_applyMiterLimit(shape: Shape) {
const miterLimit = shape.attrs.miterLimit;
if (miterLimit != null) {
this.setAttr('miterLimit', miterLimit);
}
}
setAttr(attr: string, val) {
this._context[attr] = val;
}
/**
* arc function.
* @method
* @name Konva.Context#arc
*/
arc(
x: number,
y: number,
radius: number,
startAngle: number,
endAngle: number,
counterClockwise?: boolean
) {
this._context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
}
/**
* arcTo function.
* @method
* @name Konva.Context#arcTo
*
*/
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number) {
this._context.arcTo(x1, y1, x2, y2, radius);
}
/**
* beginPath function.
* @method
* @name Konva.Context#beginPath
*/
beginPath() {
this._context.beginPath();
}
/**
* bezierCurveTo function.
* @method
* @name Konva.Context#bezierCurveTo
*/
bezierCurveTo(
cp1x: number,
cp1y: number,
cp2x: number,
cp2y: number,
x: number,
y: number
) {
this._context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
}
/**
* clearRect function.
* @method
* @name Konva.Context#clearRect
*/
clearRect(x: number, y: number, width: number, height: number) {
this._context.clearRect(x, y, width, height);
}
/**
* clip function.
* @method
* @name Konva.Context#clip
*/
clip(fillRule?: CanvasFillRule): void;
clip(path: Path2D, fillRule?: CanvasFillRule): void;
clip(...args: any[]) {
this._context.clip.apply(this._context, args as any);
}
/**
* closePath function.
* @method
* @name Konva.Context#closePath
*/
closePath() {
this._context.closePath();
}
/**
* createImageData function.
* @method
* @name Konva.Context#createImageData
*/
createImageData(width, height) {
const a = arguments;
if (a.length === 2) {
return this._context.createImageData(width, height);
} else if (a.length === 1) {
return this._context.createImageData(width);
}
}
/**
* createLinearGradient function.
* @method
* @name Konva.Context#createLinearGradient
*/
createLinearGradient(x0: number, y0: number, x1: number, y1: number) {
return this._context.createLinearGradient(x0, y0, x1, y1);
}
/**
* createPattern function.
* @method
* @name Konva.Context#createPattern
*/
createPattern(image: CanvasImageSource, repetition: string | null) {
return this._context.createPattern(image, repetition);
}
/**
* createRadialGradient function.
* @method
* @name Konva.Context#createRadialGradient
*/
createRadialGradient(
x0: number,
y0: number,
r0: number,
x1: number,
y1: number,
r1: number
) {
return this._context.createRadialGradient(x0, y0, r0, x1, y1, r1);
}
/**
* drawImage function.
* @method
* @name Konva.Context#drawImage
*/
drawImage(
image: CanvasImageSource,
sx: number,
sy: number,
sWidth?: number,
sHeight?: number,
dx?: number,
dy?: number,
dWidth?: number,
dHeight?: number
) {
// this._context.drawImage(...arguments);
const a = arguments,
_context = this._context;
if (a.length === 3) {
_context.drawImage(image, sx, sy);
} else if (a.length === 5) {
_context.drawImage(image, sx, sy, sWidth as number, sHeight as number);
} else if (a.length === 9) {
_context.drawImage(
image,
sx,
sy,
sWidth as number,
sHeight as number,
dx as number,
dy as number,
dWidth as number,
dHeight as number
);
}
}
/**
* ellipse function.
* @method
* @name Konva.Context#ellipse
*/
ellipse(
x: number,
y: number,
radiusX: number,
radiusY: number,
rotation: number,
startAngle: number,
endAngle: number,
counterclockwise?: boolean
) {
this._context.ellipse(
x,
y,
radiusX,
radiusY,
rotation,
startAngle,
endAngle,
counterclockwise
);
}
/**
* isPointInPath function.
* @method
* @name Konva.Context#isPointInPath
*/
isPointInPath(
x: number,
y: number,
path?: Path2D,
fillRule?: CanvasFillRule
) {
if (path) {
return this._context.isPointInPath(path, x, y, fillRule);
}
return this._context.isPointInPath(x, y, fillRule);
}
/**
* fill function.
* @method
* @name Konva.Context#fill
*/
fill(fillRule?: CanvasFillRule): void;
fill(path: Path2D, fillRule?: CanvasFillRule): void;
fill(...args: any[]) {
// this._context.fill();
this._context.fill.apply(this._context, args as any);
}
/**
* fillRect function.
* @method
* @name Konva.Context#fillRect
*/
fillRect(x: number, y: number, width: number, height: number) {
this._context.fillRect(x, y, width, height);
}
/**
* strokeRect function.
* @method
* @name Konva.Context#strokeRect
*/
strokeRect(x: number, y: number, width: number, height: number) {
this._context.strokeRect(x, y, width, height);
}
/**
* fillText function.
* @method
* @name Konva.Context#fillText
*/
fillText(text: string, x: number, y: number, maxWidth?: number) {
if (maxWidth) {
this._context.fillText(text, x, y, maxWidth);
} else {
this._context.fillText(text, x, y);
}
}
/**
* measureText function.
* @method
* @name Konva.Context#measureText
*/
measureText(text: string) {
return this._context.measureText(text);
}
/**
* getImageData function.
* @method
* @name Konva.Context#getImageData
*/
getImageData(sx: number, sy: number, sw: number, sh: number) {
return this._context.getImageData(sx, sy, sw, sh);
}
/**
* lineTo function.
* @method
* @name Konva.Context#lineTo
*/
lineTo(x: number, y: number) {
this._context.lineTo(x, y);
}
/**
* moveTo function.
* @method
* @name Konva.Context#moveTo
*/
moveTo(x: number, y: number) {
this._context.moveTo(x, y);
}
/**
* rect function.
* @method
* @name Konva.Context#rect
*/
rect(x: number, y: number, width: number, height: number) {
this._context.rect(x, y, width, height);
}
/**
* roundRect function.
* @method
* @name Konva.Context#roundRect
*/
roundRect(
x: number,
y: number,
width: number,
height: number,
radii: number | DOMPointInit | (number | DOMPointInit)[]
) {
this._context.roundRect(x, y, width, height, radii);
}
/**
* putImageData function.
* @method
* @name Konva.Context#putImageData
*/
putImageData(imageData: ImageData, dx: number, dy: number) {
this._context.putImageData(imageData, dx, dy);
}
/**
* quadraticCurveTo function.
* @method
* @name Konva.Context#quadraticCurveTo
*/
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number) {
this._context.quadraticCurveTo(cpx, cpy, x, y);
}
/**
* restore function.
* @method
* @name Konva.Context#restore
*/
restore() {
this._context.restore();
}
/**
* rotate function.
* @method
* @name Konva.Context#rotate
*/
rotate(angle: number) {
this._context.rotate(angle);
}
/**
* save function.
* @method
* @name Konva.Context#save
*/
save() {
this._context.save();
}
/**
* scale function.
* @method
* @name Konva.Context#scale
*/
scale(x: number, y: number) {
this._context.scale(x, y);
}
/**
* setLineDash function.
* @method
* @name Konva.Context#setLineDash
*/
setLineDash(segments: number[]) {
// works for Chrome and IE11
if (this._context.setLineDash) {
this._context.setLineDash(segments);
} else if ('mozDash' in this._context) {
// verified that this works in firefox
(this._context as any)['mozDash'] = segments;
} else if ('webkitLineDash' in this._context) {
// does not currently work for Safari
(this._context as any)['webkitLineDash'] = segments;
}
// no support for IE9 and IE10
}
/**
* getLineDash function.
* @method
* @name Konva.Context#getLineDash
*/
getLineDash() {
return this._context.getLineDash();
}
/**
* setTransform function.
* @method
* @name Konva.Context#setTransform
*/
setTransform(
a: number,
b: number,
c: number,
d: number,
e: number,
f: number
) {
this._context.setTransform(a, b, c, d, e, f);
}
/**
* stroke function.
* @method
* @name Konva.Context#stroke
*/
stroke(path2d?: Path2D) {
if (path2d) {
this._context.stroke(path2d);
} else {
this._context.stroke();
}
}
/**
* strokeText function.
* @method
* @name Konva.Context#strokeText
*/
strokeText(text: string, x: number, y: number, maxWidth?: number) {
this._context.strokeText(text, x, y, maxWidth);
}
/**
* transform function.
* @method
* @name Konva.Context#transform
*/
transform(a: number, b: number, c: number, d: number, e: number, f: number) {
this._context.transform(a, b, c, d, e, f);
}
/**
* translate function.
* @method
* @name Konva.Context#translate
*/
translate(x: number, y: number) {
this._context.translate(x, y);
}
_enableTrace() {
let that = this,
len = CONTEXT_METHODS.length,
origSetter = this.setAttr,
n,
args;
// to prevent creating scope function at each loop
const func = function (methodName) {
let origMethod = that[methodName],
ret;
that[methodName] = function () {
args = simplifyArray(Array.prototype.slice.call(arguments, 0));
ret = origMethod.apply(that, arguments);
that._trace({
method: methodName,
args: args,
});
return ret;
};
};
// methods
for (n = 0; n < len; n++) {
func(CONTEXT_METHODS[n]);
}
// attrs
that.setAttr = function () {
origSetter.apply(that, arguments as any);
const prop = arguments[0];
let val = arguments[1];
if (
prop === 'shadowOffsetX' ||
prop === 'shadowOffsetY' ||
prop === 'shadowBlur'
) {
val = val / this.canvas.getPixelRatio();
}
that._trace({
property: prop,
val: val,
});
};
}
_applyGlobalCompositeOperation(node) {
const op = node.attrs.globalCompositeOperation;
const def = !op || op === 'source-over';
if (!def) {
this.setAttr('globalCompositeOperation', op);
}
}
}
// supported context properties
type CanvasContextProps = Pick<
ExtendedCanvasRenderingContext2D,
(typeof CONTEXT_PROPERTIES)[number]
>;
export interface Context extends CanvasContextProps {}
CONTEXT_PROPERTIES.forEach(function (prop) {
Object.defineProperty(Context.prototype, prop, {
get() {
return this._context[prop];
},
set(val) {
this._context[prop] = val;
},
});
});
export class SceneContext extends Context {
constructor(canvas: Canvas, { willReadFrequently = false } = {}) {
super(canvas);
this._context = canvas._canvas.getContext('2d', {
willReadFrequently,
}) as CanvasRenderingContext2D;
}
_fillColor(shape: Shape) {
const fill = shape.fill();
this.setAttr('fillStyle', fill);
shape._fillFunc(this);
}
_fillPattern(shape: Shape) {
this.setAttr('fillStyle', shape._getFillPattern());
shape._fillFunc(this);
}
_fillLinearGradient(shape: Shape) {
const grd = shape._getLinearGradient();
if (grd) {
this.setAttr('fillStyle', grd);
shape._fillFunc(this);
}
}
_fillRadialGradient(shape: Shape) {
const grd = shape._getRadialGradient();
if (grd) {
this.setAttr('fillStyle', grd);
shape._fillFunc(this);
}
}
_fill(shape) {
const hasColor = shape.fill(),
fillPriority = shape.getFillPriority();
// priority fills
if (hasColor && fillPriority === 'color') {
this._fillColor(shape);
return;
}
const hasPattern = shape.getFillPatternImage();
if (hasPattern && fillPriority === 'pattern') {
this._fillPattern(shape);
return;
}
const hasLinearGradient = shape.getFillLinearGradientColorStops();
if (hasLinearGradient && fillPriority === 'linear-gradient') {
this._fillLinearGradient(shape);
return;
}
const hasRadialGradient = shape.getFillRadialGradientColorStops();
if (hasRadialGradient && fillPriority === 'radial-gradient') {
this._fillRadialGradient(shape);
return;
}
// now just try and fill with whatever is available
if (hasColor) {
this._fillColor(shape);
} else if (hasPattern) {
this._fillPattern(shape);
} else if (hasLinearGradient) {
this._fillLinearGradient(shape);
} else if (hasRadialGradient) {
this._fillRadialGradient(shape);
}
}
_strokeLinearGradient(shape) {
const start = shape.getStrokeLinearGradientStartPoint(),
end = shape.getStrokeLinearGradientEndPoint(),
colorStops = shape.getStrokeLinearGradientColorStops(),
grd = this.createLinearGradient(start.x, start.y, end.x, end.y);
if (colorStops) {
// build color stops
for (let n = 0; n < colorStops.length; n += 2) {
grd.addColorStop(colorStops[n] as number, colorStops[n + 1] as string);
}
this.setAttr('strokeStyle', grd);
}
}
_stroke(shape) {
const dash = shape.dash(),
// ignore strokeScaleEnabled for Text
strokeScaleEnabled = shape.getStrokeScaleEnabled();
if (shape.hasStroke()) {
if (!strokeScaleEnabled) {
this.save();
const pixelRatio = this.getCanvas().getPixelRatio();
this.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
}
this._applyLineCap(shape);
if (dash && shape.dashEnabled()) {
this.setLineDash(dash);
this.setAttr('lineDashOffset', shape.dashOffset());
}
this.setAttr('lineWidth', shape.strokeWidth());
if (!shape.getShadowForStrokeEnabled()) {
this.setAttr('shadowColor', 'rgba(0,0,0,0)');
}
const hasLinearGradient = shape.getStrokeLinearGradientColorStops();
if (hasLinearGradient) {
this._strokeLinearGradient(shape);
} else {
this.setAttr('strokeStyle', shape.stroke());
}
shape._strokeFunc(this);
if (!strokeScaleEnabled) {
this.restore();
}
}
}
_applyShadow(shape) {
const color = shape.getShadowRGBA() ?? 'black',
blur = shape.getShadowBlur() ?? 5,
offset = shape.getShadowOffset() ?? {
x: 0,
y: 0,
},
scale = shape.getAbsoluteScale(),
ratio = this.canvas.getPixelRatio(),
scaleX = scale.x * ratio,
scaleY = scale.y * ratio;
this.setAttr('shadowColor', color);
this.setAttr(
'shadowBlur',
blur * Math.min(Math.abs(scaleX), Math.abs(scaleY))
);
this.setAttr('shadowOffsetX', offset.x * scaleX);
this.setAttr('shadowOffsetY', offset.y * scaleY);
}
}
export class HitContext extends Context {
constructor(canvas: Canvas) {
super(canvas);
this._context = canvas._canvas.getContext('2d', {
willReadFrequently: true,
}) as CanvasRenderingContext2D;
}
_fill(shape: Shape) {
this.save();
this.setAttr('fillStyle', shape.colorKey);
shape._fillFuncHit(this);
this.restore();
}
strokeShape(shape: Shape) {
if (shape.hasHitStroke()) {
this._stroke(shape);
}
}
_stroke(shape) {
if (shape.hasHitStroke()) {
// ignore strokeScaleEnabled for Text
const strokeScaleEnabled = shape.getStrokeScaleEnabled();
if (!strokeScaleEnabled) {
this.save();
const pixelRatio = this.getCanvas().getPixelRatio();
this.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
}
this._applyLineCap(shape);
const hitStrokeWidth = shape.hitStrokeWidth();
const strokeWidth =
hitStrokeWidth === 'auto' ? shape.strokeWidth() : hitStrokeWidth;
this.setAttr('lineWidth', strokeWidth);
this.setAttr('strokeStyle', shape.colorKey);
shape._strokeFuncHit(this);
if (!strokeScaleEnabled) {
this.restore();
}
}
}
}
================================================
FILE: src/Core.ts
================================================
// enter file of limited Konva version with only core functions
export { Konva } from './_CoreInternals.ts';
import { Konva } from './_CoreInternals.ts';
export default Konva;
================================================
FILE: src/DragAndDrop.ts
================================================
import type { Container } from './Container.ts';
import { Konva } from './Global.ts';
import type { Node } from './Node.ts';
import type { Vector2d } from './types.ts';
import { Util } from './Util.ts';
export const DD = {
get isDragging() {
let flag = false;
DD._dragElements.forEach((elem) => {
if (elem.dragStatus === 'dragging') {
flag = true;
}
});
return flag;
},
justDragged: false,
get node() {
// return first dragging node
let node: Node | undefined;
DD._dragElements.forEach((elem) => {
node = elem.node;
});
return node;
},
_dragElements: new Map<
number,
{
node: Node;
startPointerPos: Vector2d;
offset: Vector2d;
pointerId?: number;
startEvent?: any;
// when we just put pointer down on a node
// it will create drag element
dragStatus: 'ready' | 'dragging' | 'stopped';
// dragStarted: boolean;
// isDragging: boolean;
// dragStopped: boolean;
}
>(),
// methods
_drag(evt) {
const nodesToFireEvents: Array<Node> = [];
DD._dragElements.forEach((elem, key) => {
const { node } = elem;
// we need to find pointer relative to that node
const stage = node.getStage()!;
stage.setPointersPositions(evt);
// it is possible that user call startDrag without any event
// it that case we need to detect first movable pointer and attach it into the node
if (elem.pointerId === undefined) {
elem.pointerId = Util._getFirstPointerId(evt);
}
const pos = stage._changedPointerPositions.find(
(pos) => pos.id === elem.pointerId
);
// not related pointer
if (!pos) {
return;
}
if (elem.dragStatus !== 'dragging') {
const dragDistance = node.dragDistance();
const distance = Math.max(
Math.abs(pos.x - elem.startPointerPos.x),
Math.abs(pos.y - elem.startPointerPos.y)
);
if (distance < dragDistance) {
return;
}
node.startDrag({ evt });
// a user can stop dragging inside `dragstart`
if (!node.isDragging()) {
return;
}
}
node._setDragPosition(evt, elem);
nodesToFireEvents.push(node);
});
// call dragmove only after ALL positions are changed
nodesToFireEvents.forEach((node) => {
// node may have been destroyed during a previous dragmove handler
if (!node.getStage()) {
return;
}
node.fire(
'dragmove',
{
type: 'dragmove',
target: node,
evt: evt,
},
true
);
});
},
// dragBefore and dragAfter allows us to set correct order of events
// setup all in dragbefore, and stop dragging only after pointerup triggered.
_endDragBefore(evt?) {
const drawNodes: Array<Container> = [];
DD._dragElements.forEach((elem) => {
const { node } = elem;
// we need to find pointer relative to that node
const stage = node.getStage()!;
if (evt) {
stage.setPointersPositions(evt);
}
const pos = stage._changedPointerPositions.find(
(pos) => pos.id === elem.pointerId
);
// that pointer is not related
if (!pos) {
return;
}
if (elem.dragStatus === 'dragging' || elem.dragStatus === 'stopped') {
// if a node is stopped manually we still need to reset events:
DD.justDragged = true;
Konva._mouseListenClick = false;
Konva._touchListenClick = false;
Konva._pointerListenClick = false;
elem.dragStatus = 'stopped';
}
const drawNode =
elem.node.getLayer() ||
((elem.node instanceof Konva['Stage'] && elem.node) as any);
if (drawNode && drawNodes.indexOf(drawNode) === -1) {
drawNodes.push(drawNode);
}
});
// draw in a sync way
// because mousemove event may trigger BEFORE batch draw is called
// but as we have not hit canvas updated yet, it will trigger incorrect mouseover/mouseout events
drawNodes.forEach((drawNode) => {
drawNode.draw();
});
},
_endDragAfter(evt) {
DD._dragElements.forEach((elem, key) => {
if (elem.dragStatus === 'stopped') {
elem.node.fire(
'dragend',
{
type: 'dragend',
target: elem.node,
evt: evt,
},
true
);
}
if (elem.dragStatus !== 'dragging') {
DD._dragElements.delete(key);
}
});
},
};
if (Konva.isBrowser) {
window.addEventListener('mouseup', DD._endDragBefore, true);
window.addEventListener('touchend', DD._endDragBefore, true);
// add touchcancel to fix this: https://github.com/konvajs/konva/issues/1843
window.addEventListener('touchcancel', DD._endDragBefore, true);
window.addEventListener('mousemove', DD._drag);
window.addEventListener('touchmove', DD._drag);
window.addEventListener('mouseup', DD._endDragAfter, false);
window.addEventListener('touchend', DD._endDragAfter, false);
window.addEventListener('touchcancel', DD._endDragAfter, false);
}
================================================
FILE: src/Factory.ts
================================================
import type { Node } from './Node.ts';
import type { GetSet } from './types.ts';
import { Util } from './Util.ts';
import { getComponentValidator } from './Validators.ts';
const GET = 'get';
const SET = 'set';
/**
* Enforces that a type is a string.
*/
type EnforceString<T> = T extends string ? T : never;
/**
* Represents a class.
*/
type Constructor = abstract new (...args: any) => any;
/**
* An attribute of an instance of the provided class. Attributes names be strings.
*/
type Attr<T extends Constructor> = EnforceString<keyof InstanceType<T>>;
/**
* A function that is called after a setter is called.
*/
type AfterFunc<T extends Constructor> = (this: InstanceType<T>) => void;
/**
* Extracts the type of a GetSet.
*/
type ExtractGetSet<T> = T extends GetSet<infer U, any> ? U : never;
/**
* Extracts the type of a GetSet class attribute.
*/
type Value<T extends Constructor, U extends Attr<T>> = ExtractGetSet<
InstanceType<T>[U]
>;
/**
* A function that validates a value.
*/
type ValidatorFunc<T> = (val: ExtractGetSet<T>, attr: string) => T;
/**
* Extracts the "components" (keys) of a GetSet value. The value must be an object.
*/
type ExtractComponents<T extends Constructor, U extends Attr<T>> =
Value<T, U> extends Record<string, any>
? EnforceString<keyof Value<T, U>>[]
: never;
export const Factory = {
addGetterSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
def?: Value<T, U>,
validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T>
): void {
Factory.addGetter(constructor, attr, def);
Factory.addSetter(constructor, attr, validator, after);
Factory.addOverloadedGetterSetter(constructor, attr);
},
addGetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
def?: Value<T, U>
) {
const method = GET + Util._capitalize(attr);
constructor.prototype[method] =
constructor.prototype[method] ||
function (this: Node) {
const val = this.attrs[attr];
return val === undefined ? def : val;
};
},
addSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T>
) {
const method = SET + Util._capitalize(attr);
if (!constructor.prototype[method]) {
Factory.overWriteSetter(constructor, attr, validator, after);
}
},
overWriteSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T>
) {
const method = SET + Util._capitalize(attr);
constructor.prototype[method] = function (val) {
if (validator && val !== undefined && val !== null) {
val = validator.call(this, val, attr);
}
this._setAttr(attr, val);
if (after) {
after.call(this);
}
return this;
};
},
addComponentsGetterSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
components: ExtractComponents<T, U>,
validator?: ValidatorFunc<Value<T, U>>,
after?: AfterFunc<T>
) {
const len = components.length,
capitalize = Util._capitalize,
getter = GET + capitalize(attr),
setter = SET + capitalize(attr);
// getter
constructor.prototype[getter] = function () {
const ret: Record<string, any> = {};
for (let n = 0; n < len; n++) {
const component = components[n];
ret[component] = this.getAttr(attr + capitalize(component));
}
return ret;
};
const basicValidator = getComponentValidator(components);
// setter
constructor.prototype[setter] = function (val) {
const oldVal = this.attrs[attr];
if (validator) {
val = validator.call(this, val, attr);
}
if (basicValidator) {
basicValidator.call(this, val, attr);
}
for (const key in val) {
if (!val.hasOwnProperty(key)) {
continue;
}
this._setAttr(attr + capitalize(key), val[key]);
}
if (!val) {
components.forEach((component) => {
this._setAttr(attr + capitalize(component), undefined);
});
}
this._fireChangeEvent(attr, oldVal, val);
if (after) {
after.call(this);
}
return this;
};
Factory.addOverloadedGetterSetter(constructor, attr);
},
addOverloadedGetterSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U
) {
const capitalizedAttr = Util._capitalize(attr),
setter = SET + capitalizedAttr,
getter = GET + capitalizedAttr;
constructor.prototype[attr] = function () {
// setting
if (arguments.length) {
this[setter](arguments[0]);
return this;
}
// getting
return this[getter]();
};
},
addDeprecatedGetterSetter<T extends Constructor, U extends Attr<T>>(
constructor: T,
attr: U,
def: Value<T, U>,
validator: ValidatorFunc<Value<T, U>>
) {
Util.error('Adding deprecated ' + attr);
const method = GET + Util._capitalize(attr);
const message =
attr +
' property is deprecated and will be removed soon. Look at Konva change log for more information.';
constructor.prototype[method] = function () {
Util.error(message);
const val = this.attrs[attr];
return val === undefined ? def : val;
};
Factory.addSetter(constructor, attr, validator, function () {
Util.error(message);
});
Factory.addOverloadedGetterSetter(constructor, attr);
},
backCompat<T extends Constructor>(
constructor: T,
methods: Record<string, string>
) {
Util.each(methods, function (oldMethodName, newMethodName) {
const method = constructor.prototype[newMethodName];
const oldGetter = GET + Util._capitalize(oldMethodName);
const oldSetter = SET + Util._capitalize(oldMethodName);
function deprecated(this: Node) {
method.apply(this, arguments);
Util.error(
'"' +
oldMethodName +
'" method is deprecated and will be removed soon. Use ""' +
newMethodName +
'" instead.'
);
}
constructor.prototype[oldMethodName] = deprecated;
constructor.prototype[oldGetter] = deprecated;
constructor.prototype[oldSetter] = deprecated;
});
},
afterSetFilter(this: Node): void {
this._filterUpToDate = false;
},
};
================================================
FILE: src/FastLayer.ts
================================================
import { Util } from './Util.ts';
import { Layer } from './Layer.ts';
import { _registerNode } from './Global.ts';
/**
* FastLayer constructor. **DEPRECATED!** Please use `Konva.Layer({ listening: false})` instead. Layers are tied to their own canvas element and are used
* to contain shapes only. If you don't need node nesting, mouse and touch interactions,
* or event pub/sub, you should use FastLayer instead of Layer to create your layers.
* It renders about 2x faster than normal layers.
*
* @constructor
* @memberof Konva
* @augments Konva.Layer
@@containerParams
* @example
* var layer = new Konva.FastLayer();
*/
export class FastLayer extends Layer {
constructor(attrs) {
super(attrs);
this.listening(false);
Util.warn(
'Konva.Fast layer is deprecated. Please use "new Konva.Layer({ listening: false })" instead.'
);
}
}
FastLayer.prototype.nodeType = 'FastLayer';
_registerNode(FastLayer);
================================================
FILE: src/Global.ts
================================================
/*
* Konva JavaScript Framework v@@version
* http://konvajs.org/
* Licensed under the MIT
* Date: @@date
*
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
*
* @license
*/
const PI_OVER_180 = Math.PI / 180;
/**
* @namespace Konva
*/
function detectBrowser() {
return (
typeof window !== 'undefined' &&
// browser case
({}.toString.call(window) === '[object Window]' ||
// electron case
{}.toString.call(window) === '[object global]')
);
}
declare const WorkerGlobalScope: any;
export const glob: any =
typeof global !== 'undefined'
? global
: typeof window !== 'undefined'
? window
: typeof WorkerGlobalScope !== 'undefined'
? self
: {};
export const Konva = {
_global: glob,
version: '@@version',
isBrowser: detectBrowser(),
isUnminified: /param/.test(function (param: any) {}.toString()),
dblClickWindow: 400,
getAngle(angle: number) {
return Konva.angleDeg ? angle * PI_OVER_180 : angle;
},
enableTrace: false,
pointerEventsEnabled: true,
/**
* Should Konva automatically update canvas on any changes. Default is true.
* @property autoDrawEnabled
* @default true
* @name autoDrawEnabled
* @memberof Konva
* @example
* Konva.autoDrawEnabled = true;
*/
autoDrawEnabled: true,
/**
* Should we enable hit detection while dragging? For performance reasons, by default it is false.
* But on some rare cases you want to see hit graph and check intersections. Just set it to true.
* @property hitOnDragEnabled
* @default false
* @name hitOnDragEnabled
* @memberof Konva
* @example
* Konva.hitOnDragEnabled = true;
*/
hitOnDragEnabled: false,
/**
* Should we capture touch events and bind them to the touchstart target? That is how it works on DOM elements.
* The case: we touchstart on div1, then touchmove out of that element into another element div2.
* DOM will continue trigger touchmove events on div1 (not div2). Because events are "captured" into initial target.
* By default Konva do not do that and will trigger touchmove on another element, while pointer is moving.
* @property capturePointerEventsEnabled
* @default false
* @name capturePointerEventsEnabled
* @memberof Konva
* @example
* Konva.capturePointerEventsEnabled = true;
*/
capturePointerEventsEnabled: false,
_mouseListenClick: false,
_touchListenClick: false,
_pointerListenClick: false,
_mouseInDblClickWindow: false,
_touchInDblClickWindow: false,
_pointerInDblClickWindow: false,
_mouseDblClickPointerId: null,
_touchDblClickPointerId: null,
_pointerDblClickPointerId: null,
_renderBackend: 'web', // web, node-canvas, skia-canvas
/**
* Use legacy text rendering. with "middle" baseline by default.
* @property legacyTextRendering
* @default false
* @name legacyTextRendering
* @memberof Konva
* @example
* Konva.legacyTextRendering = true;
*/
legacyTextRendering: false,
/**
* Global pixel ratio configuration. KonvaJS automatically detect pixel ratio of current device.
* But you may override such property, if you want to use your value. Set this value before any components initializations.
* @property pixelRatio
* @default undefined
* @name pixelRatio
* @memberof Konva
* @example
* // before any Konva code:
* Konva.pixelRatio = 1;
*/
pixelRatio: (typeof window !== 'undefined' && window.devicePixelRatio) || 1,
/**
* Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point,
* only then start dragging. Default is 3px.
* @property dragDistance
* @default 3
* @memberof Konva
* @example
* Konva.dragDistance = 10;
*/
dragDistance: 3,
/**
* Use degree values for angle properties. You may set this property to false if you want to use radian values.
* @property angleDeg
* @default true
* @memberof Konva
* @example
* node.rotation(45); // 45 degrees
* Konva.angleDeg = false;
* node.rotation(Math.PI / 2); // PI/2 radian
*/
angleDeg: true,
/**
* Show different warnings about errors or wrong API usage
* @property showWarnings
* @default true
* @memberof Konva
* @example
* Konva.showWarnings = false;
*/
showWarnings: true,
/**
* Configure what mouse buttons can be used for drag and drop.
* Default value is [0, 1] - left and middle mouse buttons.
* @property dragButtons
* @default [0, 1]
* @memberof Konva
* @example
* // enable left and right mouse buttons
* Konva.dragButtons = [0, 2];
*/
dragButtons: [0, 1],
/**
* returns whether or not drag and drop is currently active
* @method
* @memberof Konva
*/
isDragging(): boolean {
return Konva['DD'].isDragging;
},
isTransforming(): boolean {
return Konva['Transformer']?.isTransforming() ?? false;
},
/**
* returns whether or not a drag and drop operation is ready, but may
* not necessarily have started
* @method
* @memberof Konva
*/
isDragReady() {
return !!Konva['DD'].node;
},
/**
* Should Konva release canvas elements on destroy. Default is true.
* Useful to avoid memory leak issues in Safari on macOS/iOS.
* @property releaseCanvasOnDestroy
* @default true
* @name releaseCanvasOnDestroy
* @memberof Konva
* @example
* Konva.releaseCanvasOnDestroy = true;
*/
releaseCanvasOnDestroy: true,
// user agent
document: glob.document,
// insert Konva into global namespace (window)
// it is required for npm packages
_injectGlobal(Konva) {
if (typeof glob.Konva !== 'undefined') {
console.error(
'Several Konva instances detected. It is not recommended to use multiple Konva instances in the same environment.'
);
}
glob.Konva = Konva;
},
};
export const _registerNode = (NodeClass: any) => {
Konva[NodeClass.prototype.getClassName()] = NodeClass;
};
Konva._injectGlobal(Konva);
================================================
FILE: src/Group.ts
================================================
import { Util } from './Util.ts';
import type { ContainerConfig } from './Container.ts';
import { Container } from './Container.ts';
import { _registerNode } from './Global.ts';
import type { Node } from './Node.ts';
import type { Shape } from './Shape.ts';
export interface GroupConfig extends ContainerConfig {}
/**
* Group constructor. Groups are used to contain shapes or other groups.
* @constructor
* @memberof Konva
* @augments Konva.Container
* @param {Object} config
* @@nodeParams
* @@containerParams
* @example
* var group = new Konva.Group();
*/
export class Group extends Container<Group | Shape> {
_validateAdd(child: Node) {
const type = child.getType();
if (type !== 'Group' && type !== 'Shape') {
Util.throw('You may only add groups and shapes to groups.');
}
}
}
Group.prototype.nodeType = 'Group';
_registerNode(Group);
================================================
FILE: src/Layer.ts
================================================
import { Util } from './Util.ts';
import type { ContainerConfig } from './Container.ts';
import { Container } from './Container.ts';
import { Node } from './Node.ts';
import { Factory } from './Factory.ts';
import { SceneCanvas, HitCanvas } from './Canvas.ts';
import type { Stage } from './Stage.ts';
import { getBooleanValidator } from './Validators.ts';
import type { GetSet, Vector2d } from './types.ts';
import type { Group } from './Group.ts';
import type { Shape } from './Shape.ts';
import { shapes } from './Shape.ts';
import { _registerNode } from './Global.ts';
export interface LayerConfig extends ContainerConfig {
clearBeforeDraw?: boolean;
hitGraphEnabled?: boolean;
imageSmoothingEnabled?: boolean;
}
// constants
const HASH = '#',
BEFORE_DRAW = 'beforeDraw',
DRAW = 'draw',
/*
* 2 - 3 - 4
* | |
* 1 - 0 5
* |
* 8 - 7 - 6
*/
INTERSECTION_OFFSETS = [
{ x: 0, y: 0 }, // 0
{ x: -1, y: -1 }, // 2
{ x: 1, y: -1 }, // 4
{ x: 1, y: 1 }, // 6
{ x: -1, y: 1 }, // 8
],
INTERSECTION_OFFSETS_LEN = INTERSECTION_OFFSETS.length;
/**
* Layer constructor. Layers are tied to their own canvas element and are used
* to contain groups or shapes.
* @constructor
* @memberof Konva
* @augments Konva.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* @@nodeParams
* @@containerParams
* @example
* var layer = new Konva.Layer();
* stage.add(layer);
* // now you can add shapes, groups into the layer
*/
export class Layer extends Container<Group | Shape> {
canvas = new SceneCanvas();
hitCanvas = new HitCanvas({
pixelRatio: 1,
});
_waitingForDraw = false;
constructor(config?: LayerConfig) {
super(config);
this.on('visibleChange.konva', this._checkVisibility);
this._checkVisibility();
this.on('imageSmoothingEnabledChange.konva', this._setSmoothEnabled);
this._setSmoothEnabled();
}
// for nodejs?
createPNGStream() {
const c = this.canvas._canvas as any;
return c.createPNGStream();
}
/**
* get layer canvas wrapper
* @method
* @name Konva.Layer#getCanvas
*/
getCanvas() {
return this.canvas;
}
/**
* get native canvas element
* @method
* @name Konva.Layer#getNativeCanvasElement
*/
getNativeCanvasElement() {
return this.canvas._canvas;
}
/**
* get layer hit canvas
* @method
* @name Konva.Layer#getHitCanvas
*/
getHitCanvas() {
return this.hitCanvas;
}
/**
* get layer canvas context
* @method
* @name Konva.Layer#getContext
*/
getContext() {
return this.getCanvas().getContext();
}
// TODO: deprecate this method
clear(bounds?) {
this.getContext().clear(bounds);
this.getHitCanvas().getContext().clear(bounds);
return this;
}
// extend Node.prototype.setZIndex
setZIndex(index: number) {
super.setZIndex(index);
const stage = this.getStage();
if (stage && stage.content) {
stage.content.removeChild(this.getNativeCanvasElement());
if (index < stage.children.length - 1) {
stage.content.insertBefore(
this.getNativeCanvasElement(),
stage.children[index + 1].getCanvas()._canvas
);
} else {
stage.content.appendChild(this.getNativeCanvasElement());
}
}
return this;
}
moveToTop() {
Node.prototype.moveToTop.call(this);
const stage = this.getStage();
if (stage && stage.content) {
stage.content.removeChild(this.getNativeCanvasElement());
stage.content.appendChild(this.getNativeCanvasElement());
}
return true;
}
moveUp() {
const moved = Node.prototype.moveUp.call(this);
if (!moved) {
return false;
}
const stage = this.getStage();
if (!stage || !stage.content) {
return false;
}
stage.content.removeChild(this.getNativeCanvasElement());
if (this.index < stage.children.length - 1) {
stage.content.insertBefore(
this.getNativeCanvasElement(),
stage.children[this.index + 1].getCanvas()._canvas
);
} else {
stage.content.appendChild(this.getNativeCanvasElement());
}
return true;
}
// extend Node.prototype.moveDown
moveDown() {
if (Node.prototype.moveDown.call(this)) {
const stage = this.getStage();
if (stage) {
const children = stage.children;
if (stage.content) {
stage.content.removeChild(this.getNativeCanvasElement());
stage.content.insertBefore(
this.getNativeCanvasElement(),
children[this.index + 1].getCanvas()._canvas
);
}
}
return true;
}
return false;
}
// extend Node.prototype.moveToBottom
moveToBottom() {
if (Node.prototype.moveToBottom.call(this)) {
const stage = this.getStage();
if (stage) {
const children = stage.children;
if (stage.content) {
stage.content.removeChild(this.getNativeCanvasElement());
stage.content.insertBefore(
this.getNativeCanvasElement(),
children[1].getCanvas()._canvas
);
}
}
return true;
}
return false;
}
getLayer() {
return this;
}
remove() {
const _canvas = this.getNativeCanvasElement();
Node.prototype.remove.call(this);
if (_canvas && _canvas.parentNode && Util._isInDocument(_canvas)) {
_canvas.parentNode.removeChild(_canvas);
}
return this;
}
getStage() {
return this.parent as Stage;
}
setSize({ width, height }) {
this.canvas.setSize(width, height);
this.hitCanvas.setSize(width, height);
this._setSmoothEnabled();
return this;
}
_validateAdd(child) {
const type = child.getType();
if (type !== 'Group' && type !== 'Shape') {
Util.throw('You may only add groups and shapes to a layer.');
}
}
_toKonvaCanvas(config) {
config = { ...config };
config.width = config.width || this.getWidth();
config.height = config.height || this.getHeight();
config.x = config.x !== undefined ? config.x : this.x();
config.y = config.y !== undefined ? config.y : this.y();
return Node.prototype._toKonvaCanvas.call(this, config);
}
_checkVisibility() {
const visible = this.visible();
if (visible) {
this.canvas._canvas.style.display = 'block';
} else {
this.canvas._canvas.style.display = 'none';
}
}
_setSmoothEnabled() {
this.getContext()._context.imageSmoothingEnabled =
this.imageSmoothingEnabled();
}
/**
* get/set width of layer. getter return width of stage. setter doing nothing.
* if you want change width use `stage.width(value);`
* @name Konva.Layer#width
* @method
* @returns {Number}
* @example
* var width = layer.width();
*/
getWidth() {
if (this.parent) {
return this.parent.width();
}
}
setWidth() {
Util.warn(
'Can not change width of layer. Use "stage.width(value)" function instead.'
);
}
/**
* get/set height of layer.getter return height of stage. setter doing nothing.
* if you want change height use `stage.height(value);`
* @name Konva.Layer#height
* @method
* @returns {Number}
* @example
* var height = layer.height();
*/
getHeight() {
if (this.parent) {
return this.parent.height();
}
}
setHeight() {
Util.warn(
'Can not change height of layer. Use "stage.height(value)" function instead.'
);
}
/**
* batch draw. this function will not do immediate draw
* but it will schedule drawing to next tick (requestAnimFrame)
* @method
* @name Konva.Layer#batchDraw
* @return {Konva.Layer} this
*/
batchDraw() {
if (!this._waitingForDraw) {
this._waitingForDraw = true;
Util.requestAnimFrame(() => {
this.draw();
this._waitingForDraw = false;
});
}
return this;
}
/**
* get visible intersection shape. This is the preferred
* method for determining if a point intersects a shape or not
* also you may pass optional selector parameter to return ancestor of intersected shape
* nodes with listening set to false will not be detected
* @method
* @name Konva.Layer#getIntersection
* @param {Object} pos
* @param {Number} pos.x
* @param {Number} pos.y
* @returns {Konva.Node}
* @example
* var shape = layer.getIntersection({x: 50, y: 50});
*/
getIntersection(pos: Vector2d) {
if (!this.isListening() || !this.isVisible()) {
return null;
}
// in some cases antialiased area may be bigger than 1px
// it is possible if we will cache node, then scale it a lot
let spiralSearchDistance = 1;
let continueSearch = false;
while (true) {
for (let i = 0; i < INTERSECTION_OFFSETS_LEN; i++) {
const intersectionOffset = INTERSECTION_OFFSETS[i];
const obj = this._getIntersection({
x: pos.x + intersectionOffset.x * spiralSearchDistance,
y: pos.y + intersectionOffset.y * spiralSearchDistance,
});
const shape = obj.shape;
if (shape) {
return shape;
}
// we should continue search if we found antialiased pixel
// that means our node somewhere very close
continueSearch = !!obj.antialiased;
// stop search if found empty pixel
if (!obj.antialiased) {
break;
}
}
// if no shape, and no antialiased pixel, we should end searching
if (continueSearch) {
spiralSearchDistance += 1;
} else {
return null;
}
}
}
_getIntersection(pos: Vector2d): { shape?: Shape; antialiased?: boolean } {
const ratio = this.hitCanvas.pixelRatio;
const p = this.hitCanvas.context.getImageData(
Math.round(pos.x * ratio),
Math.round(pos.y * ratio),
1,
1
).data;
const p3 = p[3];
// fully opaque pixel
if (p3 === 255) {
const colorKey = Util.getHitColorKey(p[0], p[1], p[2]);
const shape = shapes[colorKey];
if (shape) {
return {
shape: shape,
};
}
return {
antialiased: true,
};
} else if (p3 > 0) {
// antialiased pixel
return {
antialiased: true,
};
}
// empty pixel
return {};
}
drawScene(can?: SceneCanvas, top?: Node, bufferCanvas?: SceneCanvas) {
const layer = this.getLayer(),
canvas = can || (layer && layer.getCanvas());
this._fire(BEFORE_DRAW, {
node: this,
});
if (this.clearBeforeDraw()) {
canvas.getContext().clear();
}
Container.prototype.drawScene.call(this, canvas, top, bufferCanvas);
this._fire(DRAW, {
node: this,
});
return this;
}
drawHit(can?: HitCanvas, top?: Node) {
const layer = this.getLayer(),
canvas = can || (layer && layer.hitCanvas);
if (layer && layer.clearBeforeDraw()) {
layer.getHitCanvas().getContext().clear();
}
Container.prototype.drawHit.call(this, canvas, top);
return this;
}
/**
* enable hit graph. **DEPRECATED!** Use `layer.listening(true)` instead.
* @name Konva.Layer#enableHitGraph
* @method
* @returns {Layer}
*/
enableHitGraph() {
this.hitGraphEnabled(true);
return this;
}
/**
* disable hit graph. **DEPRECATED!** Use `layer.listening(false)` instead.
* @name Konva.Layer#disableHitGraph
* @method
* @returns {Layer}
*/
disableHitGraph() {
this.hitGraphEnabled(false);
return this;
}
setHitGraphEnabled(val) {
Util.warn(
'hitGraphEnabled method is deprecated. Please use layer.listening() instead.'
);
this.listening(val);
}
getHitGraphEnabled(val) {
Util.warn(
'hitGraphEnabled method is deprecated. Please use layer.listening() instead.'
);
return this.listening();
}
/**
* Show or hide hit canvas over the stage. May be useful for debugging custom hitFunc
* @name Konva.Layer#toggleHitCanvas
* @method
*/
toggleHitCanvas() {
if (!this.parent || !this.parent['content']) {
return;
}
const parent = this.parent as any;
const added = !!this.hitCanvas._canvas.parentNode;
if (added) {
parent.content.removeChild(this.hitCanvas._canvas);
} else {
parent.content.appendChild(this.hitCanvas._canvas);
}
}
destroy(): this {
Util.releaseCanvas(
this.getNativeCanvasElement(),
this.getHitCanvas()._canvas
);
return super.destroy();
}
hitGraphEnabled: GetSet<boolean, this>;
clearBeforeDraw: GetSet<boolean, this>;
imageSmoothingEnabled: GetSet<boolean, this>;
}
Layer.prototype.nodeType = 'Layer';
_registerNode(Layer);
/**
* get/set imageSmoothingEnabled flag
* For more info see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled
* @name Konva.Layer#imageSmoothingEnabled
* @method
* @param {Boolean} imageSmoothingEnabled
* @returns {Boolean}
* @example
* // get imageSmoothingEnabled flag
* var imageSmoothingEnabled = layer.imageSmoothingEnabled();
*
* layer.imageSmoothingEnabled(false);
*
* layer.imageSmoothingEnabled(true);
*/
Factory.addGetterSetter(Layer, 'imageSmoothingEnabled', true);
/**
* get/set clearBeforeDraw flag which determines if the layer is cleared or not
* before drawing
* @name Konva.Layer#clearBeforeDraw
* @method
* @param {Boolean} clearBeforeDraw
* @returns {Boolean}
* @example
* // get clearBeforeDraw flag
* var clearBeforeDraw = layer.clearBeforeDraw();
*
* // disable clear before draw
* layer.clearBeforeDraw(false);
*
* // enable clear before draw
* layer.clearBeforeDraw(true);
*/
Factory.addGetterSetter(Layer, 'clearBeforeDraw', true);
Factory.addGetterSetter(Layer, 'hitGraphEnabled', true, getBooleanValidator());
/**
* get/set hitGraphEnabled flag. **DEPRECATED!** Use `layer.listening(false)` instead.
* Disabling the hit graph will greatly increase
* draw performance because the hit graph will not be redrawn each time the layer is
* drawn. This, however, also disables mouse/touch event detection
* @name Konva.Layer#hitGraphEnabled
* @method
* @param {Boolean} enabled
* @returns {Boolean}
* @example
* // get hitGraphEnabled flag
* var hitGraphEnabled = layer.hitGraphEnabled();
*
* // disable hit graph
* layer.hitGraphEnabled(false);
*
* // enable hit graph
* layer.hitGraphEnabled(true);
*/
================================================
FILE: src/Node.ts
================================================
import type { Canvas } from './Canvas.ts';
import { HitCanvas, SceneCanvas } from './Canvas.ts';
import type { Container } from './Container.ts';
import type { Context } from './Context.ts';
import { isCSSFiltersSupported } from './Context.ts';
import { DD } from './DragAndDrop.ts';
import { Factory } from './Factory.ts';
import { Konva } from './Global.ts';
import type { Layer } from './Layer.ts';
import type { Shape } from './Shape.ts';
import type { Stage } from './Stage.ts';
import type { GetSet, IRect, Vector2d } from './types.ts';
import { Transform, Util, type AnyString } from './Util.ts';
import {
getBooleanValidator,
getNumberValidator,
getStringValidator,
} from './Validators.ts';
export type FilterFunction = (this: Node, imageData: ImageData) => void;
export type Filter = FilterFunction | string;
type Filters = Array<FilterFunction | string>;
// CSS filter parser for fallback to function filters
function parseCSSFilters(cssFilter: string): FilterFunction {
// Parse common CSS filter functions and map to Konva filters
const filterRegex = /(\w+)\(([^)]+)\)/g;
let match;
while ((match = filterRegex.exec(cssFilter)) !== null) {
const [, filterName, filterValue] = match;
switch (filterName) {
case 'blur': {
const blurRadius = parseFloat(filterValue.replace('px', ''));
return function (imageData) {
// CSS blur uses standard deviation, Stack Blur uses radius
// Empirical testing shows CSS blur needs ~0.5 scaling for visual match
(this as any).blurRadius(blurRadius * 0.5);
// Access filters through dynamic import to avoid circular dependency
const KonvaFilters = (Konva as any).Filters;
if (KonvaFilters && KonvaFilters.Blur) {
KonvaFilters.Blur.call(this, imageData);
}
};
}
case 'brightness': {
const brightness = filterValue.includes('%')
? parseFloat(filterValue) / 100
: parseFloat(filterValue);
return function (imageData) {
(this as any).brightness(brightness); // CSS uses multiplier
const KonvaFilters = (Konva as any).Filters;
if (KonvaFilters && KonvaFilters.Brightness) {
KonvaFilters.Brightness.call(this, imageData);
}
};
}
case 'contrast': {
const contrast = parseFloat(filterValue);
return function (imageData) {
// Convert CSS contrast to Konva parameter using square root conversion
// to account for Konva's quadratic scaling: Math.pow((param + 100) / 100, 2)
const konvaContrast = 100 * (Math.sqrt(contrast) - 1);
(this as any).contrast(konvaContrast);
const KonvaFilters = (Konva as any).Filters;
if (KonvaFilters && KonvaFilters.Contrast) {
KonvaFilters.Contrast.call(this, imageData);
}
};
}
case 'grayscale': {
return function (imageData) {
const KonvaFilters = (Konva as any).Filters;
if (KonvaFilters && KonvaFilters.Grayscale) {
KonvaFilters.Grayscale.call(this, imageData);
}
};
}
case 'sepia': {
return function (imageData) {
const KonvaFilters = (Konva as any).Filters;
if (KonvaFilters && KonvaFilters.Sepia) {
KonvaFilters.Sepia.call(this, imageData);
}
};
}
case 'invert': {
return function (imageData) {
const KonvaFilters = (Konva as any).Filters;
if (KonvaFilters && KonvaFilters.Invert) {
KonvaFilters.Invert.call(this, imageData);
}
};
}
default:
Util.warn(
`CSS filter "${filterName}" is not supported in fallback mode. Consider using function filters for better compatibility.`
);
break;
}
}
return () => {};
}
type globalCompositeOperationType =
| ''
| 'source-over'
| 'source-in'
| 'source-out'
| 'source-atop'
| 'destination-over'
| 'destination-in'
| 'destination-out'
| 'destination-atop'
| 'lighter'
| 'copy'
| 'xor'
| 'multiply'
| 'screen'
| 'overlay'
| 'darken'
| 'lighten'
| 'color-dodge'
| 'color-burn'
| 'hard-light'
| 'soft-light'
| 'difference'
| 'exclusion'
| 'hue'
| 'saturation'
| 'color'
| 'luminosity';
// allow any custom attribute
export type NodeConfig = {
x?: number;
y?: number;
width?: number;
height?: number;
visible?: boolean;
listening?: boolean;
id?: string;
name?: string;
opacity?: number;
scale?: Vector2d;
scaleX?: number;
skewX?: number;
skewY?: number;
scaleY?: number;
rotation?: num
gitextract_6dbjwh6u/ ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE.md │ └── workflows/ │ ├── build.yml │ ├── prettier.yml │ ├── release.yml │ ├── test-browser.yml │ └── test-node.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── gulpfile.mjs ├── package.json ├── release.sh ├── resources/ │ ├── doc-includes/ │ │ ├── ContainerParams.txt │ │ ├── NodeParams.txt │ │ └── ShapeParams.txt │ └── jsdoc.conf.json ├── rollup.config.mjs ├── src/ │ ├── Animation.ts │ ├── BezierFunctions.ts │ ├── Canvas.ts │ ├── Container.ts │ ├── Context.ts │ ├── Core.ts │ ├── DragAndDrop.ts │ ├── Factory.ts │ ├── FastLayer.ts │ ├── Global.ts │ ├── Group.ts │ ├── Layer.ts │ ├── Node.ts │ ├── PointerEvents.ts │ ├── Shape.ts │ ├── Stage.ts │ ├── Tween.ts │ ├── Util.ts │ ├── Validators.ts │ ├── _CoreInternals.ts │ ├── _FullInternals.ts │ ├── canvas-backend.ts │ ├── filters/ │ │ ├── Blur.ts │ │ ├── Brighten.ts │ │ ├── Brightness.ts │ │ ├── Contrast.ts │ │ ├── Emboss.ts │ │ ├── Enhance.ts │ │ ├── Grayscale.ts │ │ ├── HSL.ts │ │ ├── HSV.ts │ │ ├── Invert.ts │ │ ├── Kaleidoscope.ts │ │ ├── Mask.ts │ │ ├── Noise.ts │ │ ├── Pixelate.ts │ │ ├── Posterize.ts │ │ ├── RGB.ts │ │ ├── RGBA.ts │ │ ├── Sepia.ts │ │ ├── Solarize.ts │ │ └── Threshold.ts │ ├── index.ts │ ├── shapes/ │ │ ├── Arc.ts │ │ ├── Arrow.ts │ │ ├── Circle.ts │ │ ├── Ellipse.ts │ │ ├── Image.ts │ │ ├── Label.ts │ │ ├── Line.ts │ │ ├── Path.ts │ │ ├── Rect.ts │ │ ├── RegularPolygon.ts │ │ ├── Ring.ts │ │ ├── Sprite.ts │ │ ├── Star.ts │ │ ├── Text.ts │ │ ├── TextPath.ts │ │ ├── Transformer.ts │ │ └── Wedge.ts │ ├── skia-backend.ts │ └── types.ts ├── test/ │ ├── assets/ │ │ ├── tiger.ts │ │ └── worldMap.ts │ ├── bunnies.html │ ├── ifame.html │ ├── import-test.cjs │ ├── import-test.mjs │ ├── manual/ │ │ ├── Blur-test.ts │ │ ├── Brighten-test.ts │ │ ├── Contrast-test.ts │ │ ├── Emboss-test.ts │ │ ├── Enhance-test.ts │ │ ├── Grayscale-test.ts │ │ ├── HSL-test.ts │ │ ├── HSV-test.ts │ │ ├── Invert-test.ts │ │ ├── Kaleidoscope-test.ts │ │ ├── Manual-test.ts │ │ ├── Mask-test.ts │ │ ├── Noise-test.ts │ │ ├── Pixelate-test.ts │ │ ├── Posterize-test.ts │ │ ├── RGB-test.ts │ │ ├── RGBA-test.ts │ │ ├── Sepia-test.ts │ │ ├── Solarize-test.ts │ │ └── Threshold-test.ts │ ├── manual-tests.html │ ├── node-canvas-global-setup.mjs │ ├── node-skia-global-setup.mjs │ ├── performance/ │ │ ├── bunnies_native.html │ │ ├── creating_elements.html │ │ └── jump-shape.html │ ├── runner.js │ ├── sandbox.html │ ├── text-paths.html │ ├── typescript/ │ │ └── event-delegation-test.ts │ ├── unit/ │ │ ├── Animation-test.ts │ │ ├── Arc-test.ts │ │ ├── Arrow-test.ts │ │ ├── AutoDraw-test.ts │ │ ├── Blob-test.ts │ │ ├── Canvas-test.ts │ │ ├── Circle-test.ts │ │ ├── Container-test.ts │ │ ├── Context-test.ts │ │ ├── DragAndDrop-test.ts │ │ ├── DragAndDropEvents-test.ts │ │ ├── Ellipse-test.ts │ │ ├── Filter-test.ts │ │ ├── Global-test.ts │ │ ├── Group-test.ts │ │ ├── Image-test.ts │ │ ├── Label-test.ts │ │ ├── Layer-test.ts │ │ ├── Line-test.ts │ │ ├── MouseEvents-test.ts │ │ ├── Node-cache-test.ts │ │ ├── Node-test.ts │ │ ├── Path-test.ts │ │ ├── PointerEvents-test.ts │ │ ├── Polygon-test.ts │ │ ├── Rect-test.ts │ │ ├── RegularPolygon-test.ts │ │ ├── Ring-test.ts │ │ ├── Shape-test.ts │ │ ├── Spline-test.ts │ │ ├── Sprite-test.ts │ │ ├── Stage-test.ts │ │ ├── Star-test.ts │ │ ├── Text-test.ts │ │ ├── TextPath-test.ts │ │ ├── TouchEvents-test.ts │ │ ├── Transformer-test.ts │ │ ├── Tween-test.ts │ │ ├── Util-test.ts │ │ ├── Wedge-test.ts │ │ ├── imagediff.ts │ │ └── test-utils.ts │ └── unit-tests.html ├── tsconfig.json └── tsconfig.test.json
SYMBOL INDEX (1073 symbols across 54 files)
FILE: gulpfile.mjs
function build (line 22) | function build() {
FILE: src/Animation.ts
class Animation (line 40) | class Animation {
method constructor (line 53) | constructor(func: AnimationFn, layers?) {
method setLayers (line 64) | setLayers(layers: null | Layer | Layer[]) {
method getLayers (line 79) | getLayers() {
method addLayer (line 89) | addLayer(layer: Layer) {
method isRunning (line 109) | isRunning() {
method start (line 127) | start() {
method stop (line 140) | stop() {
method _updateFrameObject (line 144) | _updateFrameObject(time: number) {
method _addAnimation (line 155) | static _addAnimation(anim) {
method _removeAnimation (line 159) | static _removeAnimation(anim) {
method _runFrames (line 172) | static _runFrames() {
method _animationLoop (line 222) | static _animationLoop() {
method _handleAnimation (line 231) | static _handleAnimation() {
FILE: src/BezierFunctions.ts
function BFunc (line 750) | function BFunc(xs: number[], ys: number[], t: number) {
FILE: src/Canvas.ts
function getDevicePixelRatio (line 8) | function getDevicePixelRatio() {
type ICanvasConfig (line 29) | interface ICanvasConfig {
class Canvas (line 47) | class Canvas {
method constructor (line 56) | constructor(config: ICanvasConfig) {
method getContext (line 81) | getContext() {
method getPixelRatio (line 92) | getPixelRatio() {
method setPixelRatio (line 110) | setPixelRatio(pixelRatio) {
method setWidth (line 118) | setWidth(width) {
method setHeight (line 127) | setHeight(height) {
method getWidth (line 135) | getWidth() {
method getHeight (line 138) | getHeight() {
method setSize (line 141) | setSize(width, height) {
method toDataURL (line 153) | toDataURL(mimeType, quality) {
class SceneCanvas (line 173) | class SceneCanvas extends Canvas {
method constructor (line 174) | constructor(
class HitCanvas (line 185) | class HitCanvas extends Canvas {
method constructor (line 187) | constructor(config: ICanvasConfig = { width: 0, height: 0 }) {
FILE: src/Container.ts
type ClipFuncOutput (line 10) | type ClipFuncOutput =
type ContainerConfig (line 15) | interface ContainerConfig extends NodeConfig {
method getChildren (line 55) | getChildren(filterFunc?: (item: Node) => boolean) {
method hasChildren (line 68) | hasChildren() {
method removeChildren (line 77) | removeChildren() {
method destroyChildren (line 94) | destroyChildren() {
method add (line 119) | add(...children: ChildType[]) {
method destroy (line 146) | destroy() {
method find (line 193) | find<ChildNode extends Node>(selector): Array<ChildNode> {
method findOne (line 216) | findOne<ChildNode extends Node = Node>(
method _generalFind (line 222) | _generalFind<ChildNode extends Node>(
method _descendants (line 241) | private _descendants(fn: (n: Node) => boolean) {
method toObject (line 260) | toObject() {
method isAncestorOf (line 278) | isAncestorOf(node: Node) {
method clone (line 289) | clone(obj?: any) {
method getAllIntersections (line 311) | getAllIntersections(pos) {
method _clearSelfAndDescendantCache (line 322) | _clearSelfAndDescendantCache(attr?: string) {
method _setChildrenIndices (line 333) | _setChildrenIndices() {
method drawScene (line 339) | drawScene(can?: SceneCanvas, top?: Node, bufferCanvas?: SceneCanvas) {
method drawHit (line 362) | drawHit(can?: HitCanvas, top?: Node) {
method _drawChildren (line 384) | _drawChildren(drawMethod, canvas, top, bufferCanvas?) {
method getClientRect (line 436) | getClientRect(
FILE: src/Context.ts
function simplifyArray (line 8) | function simplifyArray(arr: Array<any>) {
constant COMMA (line 27) | const COMMA = ',',
constant OPEN_PAREN (line 27) | const COMMA = ',',
constant CLOSE_PAREN (line 27) | const COMMA = ',',
constant OPEN_PAREN_BRACKET (line 27) | const COMMA = ',',
constant CLOSE_BRACKET_PAREN (line 27) | const COMMA = ',',
constant SEMICOLON (line 27) | const COMMA = ',',
constant DOUBLE_PAREN (line 27) | const COMMA = ',',
constant EQUALS (line 27) | const COMMA = ',',
constant CONTEXT_METHODS (line 27) | const COMMA = ',',
constant CONTEXT_PROPERTIES (line 72) | const CONTEXT_PROPERTIES = [
function isCSSFiltersSupported (line 99) | function isCSSFiltersSupported(): boolean {
type ExtendedCanvasRenderingContext2D (line 118) | interface ExtendedCanvasRenderingContext2D extends CanvasRenderingContex...
class Context (line 144) | class Context {
method constructor (line 149) | constructor(canvas: Canvas) {
method fillShape (line 164) | fillShape(shape: Shape) {
method _fill (line 170) | _fill(shape: Shape) {
method strokeShape (line 179) | strokeShape(shape: Shape) {
method _stroke (line 185) | _stroke(shape: Shape) {
method fillStrokeShape (line 195) | fillStrokeShape(shape: Shape) {
method getTrace (line 205) | getTrace(relaxed?: boolean, rounded?: boolean) {
method clearTrace (line 250) | clearTrace() {
method _trace (line 253) | _trace(str) {
method reset (line 269) | reset() {
method getCanvas (line 279) | getCanvas() {
method clear (line 292) | clear(bounds?: IRect) {
method _applyLineCap (line 311) | _applyLineCap(shape: Shape) {
method _applyOpacity (line 317) | _applyOpacity(shape: Node) {
method _applyLineJoin (line 323) | _applyLineJoin(shape: Shape) {
method _applyMiterLimit (line 329) | _applyMiterLimit(shape: Shape) {
method setAttr (line 336) | setAttr(attr: string, val) {
method arc (line 345) | arc(
method arcTo (line 361) | arcTo(x1: number, y1: number, x2: number, y2: number, radius: number) {
method beginPath (line 369) | beginPath() {
method bezierCurveTo (line 378) | bezierCurveTo(
method clearRect (line 393) | clearRect(x: number, y: number, width: number, height: number) {
method clip (line 403) | clip(...args: any[]) {
method closePath (line 411) | closePath() {
method createImageData (line 419) | createImageData(width, height) {
method createLinearGradient (line 432) | createLinearGradient(x0: number, y0: number, x1: number, y1: number) {
method createPattern (line 440) | createPattern(image: CanvasImageSource, repetition: string | null) {
method createRadialGradient (line 448) | createRadialGradient(
method drawImage (line 463) | drawImage(
method ellipse (line 500) | ellipse(
method isPointInPath (line 526) | isPointInPath(
method fill (line 544) | fill(...args: any[]) {
method fillRect (line 553) | fillRect(x: number, y: number, width: number, height: number) {
method strokeRect (line 561) | strokeRect(x: number, y: number, width: number, height: number) {
method fillText (line 569) | fillText(text: string, x: number, y: number, maxWidth?: number) {
method measureText (line 581) | measureText(text: string) {
method getImageData (line 589) | getImageData(sx: number, sy: number, sw: number, sh: number) {
method lineTo (line 597) | lineTo(x: number, y: number) {
method moveTo (line 605) | moveTo(x: number, y: number) {
method rect (line 613) | rect(x: number, y: number, width: number, height: number) {
method roundRect (line 621) | roundRect(
method putImageData (line 635) | putImageData(imageData: ImageData, dx: number, dy: number) {
method quadraticCurveTo (line 643) | quadraticCurveTo(cpx: number, cpy: number, x: number, y: number) {
method restore (line 651) | restore() {
method rotate (line 659) | rotate(angle: number) {
method save (line 667) | save() {
method scale (line 675) | scale(x: number, y: number) {
method setLineDash (line 683) | setLineDash(segments: number[]) {
method getLineDash (line 702) | getLineDash() {
method setTransform (line 710) | setTransform(
method stroke (line 725) | stroke(path2d?: Path2D) {
method strokeText (line 737) | strokeText(text: string, x: number, y: number, maxWidth?: number) {
method transform (line 745) | transform(a: number, b: number, c: number, d: number, e: number, f: nu...
method translate (line 753) | translate(x: number, y: number) {
method _enableTrace (line 756) | _enableTrace() {
method _applyGlobalCompositeOperation (line 803) | _applyGlobalCompositeOperation(node) {
type CanvasContextProps (line 813) | type CanvasContextProps = Pick<
type Context (line 818) | interface Context extends CanvasContextProps {}
method constructor (line 149) | constructor(canvas: Canvas) {
method fillShape (line 164) | fillShape(shape: Shape) {
method _fill (line 170) | _fill(shape: Shape) {
method strokeShape (line 179) | strokeShape(shape: Shape) {
method _stroke (line 185) | _stroke(shape: Shape) {
method fillStrokeShape (line 195) | fillStrokeShape(shape: Shape) {
method getTrace (line 205) | getTrace(relaxed?: boolean, rounded?: boolean) {
method clearTrace (line 250) | clearTrace() {
method _trace (line 253) | _trace(str) {
method reset (line 269) | reset() {
method getCanvas (line 279) | getCanvas() {
method clear (line 292) | clear(bounds?: IRect) {
method _applyLineCap (line 311) | _applyLineCap(shape: Shape) {
method _applyOpacity (line 317) | _applyOpacity(shape: Node) {
method _applyLineJoin (line 323) | _applyLineJoin(shape: Shape) {
method _applyMiterLimit (line 329) | _applyMiterLimit(shape: Shape) {
method setAttr (line 336) | setAttr(attr: string, val) {
method arc (line 345) | arc(
method arcTo (line 361) | arcTo(x1: number, y1: number, x2: number, y2: number, radius: number) {
method beginPath (line 369) | beginPath() {
method bezierCurveTo (line 378) | bezierCurveTo(
method clearRect (line 393) | clearRect(x: number, y: number, width: number, height: number) {
method clip (line 403) | clip(...args: any[]) {
method closePath (line 411) | closePath() {
method createImageData (line 419) | createImageData(width, height) {
method createLinearGradient (line 432) | createLinearGradient(x0: number, y0: number, x1: number, y1: number) {
method createPattern (line 440) | createPattern(image: CanvasImageSource, repetition: string | null) {
method createRadialGradient (line 448) | createRadialGradient(
method drawImage (line 463) | drawImage(
method ellipse (line 500) | ellipse(
method isPointInPath (line 526) | isPointInPath(
method fill (line 544) | fill(...args: any[]) {
method fillRect (line 553) | fillRect(x: number, y: number, width: number, height: number) {
method strokeRect (line 561) | strokeRect(x: number, y: number, width: number, height: number) {
method fillText (line 569) | fillText(text: string, x: number, y: number, maxWidth?: number) {
method measureText (line 581) | measureText(text: string) {
method getImageData (line 589) | getImageData(sx: number, sy: number, sw: number, sh: number) {
method lineTo (line 597) | lineTo(x: number, y: number) {
method moveTo (line 605) | moveTo(x: number, y: number) {
method rect (line 613) | rect(x: number, y: number, width: number, height: number) {
method roundRect (line 621) | roundRect(
method putImageData (line 635) | putImageData(imageData: ImageData, dx: number, dy: number) {
method quadraticCurveTo (line 643) | quadraticCurveTo(cpx: number, cpy: number, x: number, y: number) {
method restore (line 651) | restore() {
method rotate (line 659) | rotate(angle: number) {
method save (line 667) | save() {
method scale (line 675) | scale(x: number, y: number) {
method setLineDash (line 683) | setLineDash(segments: number[]) {
method getLineDash (line 702) | getLineDash() {
method setTransform (line 710) | setTransform(
method stroke (line 725) | stroke(path2d?: Path2D) {
method strokeText (line 737) | strokeText(text: string, x: number, y: number, maxWidth?: number) {
method transform (line 745) | transform(a: number, b: number, c: number, d: number, e: number, f: nu...
method translate (line 753) | translate(x: number, y: number) {
method _enableTrace (line 756) | _enableTrace() {
method _applyGlobalCompositeOperation (line 803) | _applyGlobalCompositeOperation(node) {
method get (line 822) | get() {
method set (line 825) | set(val) {
class SceneContext (line 831) | class SceneContext extends Context {
method constructor (line 832) | constructor(canvas: Canvas, { willReadFrequently = false } = {}) {
method _fillColor (line 838) | _fillColor(shape: Shape) {
method _fillPattern (line 844) | _fillPattern(shape: Shape) {
method _fillLinearGradient (line 848) | _fillLinearGradient(shape: Shape) {
method _fillRadialGradient (line 856) | _fillRadialGradient(shape: Shape) {
method _fill (line 863) | _fill(shape) {
method _strokeLinearGradient (line 902) | _strokeLinearGradient(shape) {
method _stroke (line 916) | _stroke(shape) {
method _applyShadow (line 954) | _applyShadow(shape) {
class HitContext (line 976) | class HitContext extends Context {
method constructor (line 977) | constructor(canvas: Canvas) {
method _fill (line 983) | _fill(shape: Shape) {
method strokeShape (line 989) | strokeShape(shape: Shape) {
method _stroke (line 994) | _stroke(shape) {
FILE: src/DragAndDrop.ts
method isDragging (line 8) | get isDragging() {
method node (line 18) | get node() {
method _drag (line 44) | _drag(evt) {
method _endDragBefore (line 103) | _endDragBefore(evt?) {
method _endDragAfter (line 146) | _endDragAfter(evt) {
FILE: src/Factory.ts
constant GET (line 6) | const GET = 'get';
constant SET (line 7) | const SET = 'set';
type EnforceString (line 12) | type EnforceString<T> = T extends string ? T : never;
type Constructor (line 17) | type Constructor = abstract new (...args: any) => any;
type Attr (line 22) | type Attr<T extends Constructor> = EnforceString<keyof InstanceType<T>>;
type AfterFunc (line 27) | type AfterFunc<T extends Constructor> = (this: InstanceType<T>) => void;
type ExtractGetSet (line 32) | type ExtractGetSet<T> = T extends GetSet<infer U, any> ? U : never;
type Value (line 37) | type Value<T extends Constructor, U extends Attr<T>> = ExtractGetSet<
type ValidatorFunc (line 44) | type ValidatorFunc<T> = (val: ExtractGetSet<T>, attr: string) => T;
type ExtractComponents (line 49) | type ExtractComponents<T extends Constructor, U extends Attr<T>> =
method addGetterSetter (line 55) | addGetterSetter<T extends Constructor, U extends Attr<T>>(
method addGetter (line 66) | addGetter<T extends Constructor, U extends Attr<T>>(
method addSetter (line 81) | addSetter<T extends Constructor, U extends Attr<T>>(
method overWriteSetter (line 94) | overWriteSetter<T extends Constructor, U extends Attr<T>>(
method addComponentsGetterSetter (line 116) | addComponentsGetterSetter<T extends Constructor, U extends Attr<T>>(
method addOverloadedGetterSetter (line 177) | addOverloadedGetterSetter<T extends Constructor, U extends Attr<T>>(
method addDeprecatedGetterSetter (line 195) | addDeprecatedGetterSetter<T extends Constructor, U extends Attr<T>>(
method backCompat (line 218) | backCompat<T extends Constructor>(
method afterSetFilter (line 243) | afterSetFilter(this: Node): void {
FILE: src/FastLayer.ts
class FastLayer (line 18) | class FastLayer extends Layer {
method constructor (line 19) | constructor(attrs) {
FILE: src/Global.ts
constant PI_OVER_180 (line 12) | const PI_OVER_180 = Math.PI / 180;
function detectBrowser (line 17) | function detectBrowser() {
method getAngle (line 44) | getAngle(angle: number) {
method isDragging (line 166) | isDragging(): boolean {
method isTransforming (line 169) | isTransforming(): boolean {
method isDragReady (line 178) | isDragReady() {
method _injectGlobal (line 196) | _injectGlobal(Konva) {
FILE: src/Group.ts
type GroupConfig (line 8) | interface GroupConfig extends ContainerConfig {}
class Group (line 21) | class Group extends Container<Group | Shape> {
method _validateAdd (line 22) | _validateAdd(child: Node) {
FILE: src/Layer.ts
type LayerConfig (line 16) | interface LayerConfig extends ContainerConfig {
constant HASH (line 23) | const HASH = '#',
constant BEFORE_DRAW (line 23) | const HASH = '#',
constant DRAW (line 23) | const HASH = '#',
constant INTERSECTION_OFFSETS (line 23) | const HASH = '#',
constant INTERSECTION_OFFSETS_LEN (line 23) | const HASH = '#',
class Layer (line 59) | class Layer extends Container<Group | Shape> {
method constructor (line 67) | constructor(config?: LayerConfig) {
method createPNGStream (line 76) | createPNGStream() {
method getCanvas (line 85) | getCanvas() {
method getNativeCanvasElement (line 93) | getNativeCanvasElement() {
method getHitCanvas (line 101) | getHitCanvas() {
method getContext (line 109) | getContext() {
method clear (line 113) | clear(bounds?) {
method setZIndex (line 119) | setZIndex(index: number) {
method moveToTop (line 136) | moveToTop() {
method moveUp (line 145) | moveUp() {
method moveDown (line 167) | moveDown() {
method moveToBottom (line 185) | moveToBottom() {
method getLayer (line 202) | getLayer() {
method remove (line 205) | remove() {
method getStage (line 215) | getStage() {
method setSize (line 218) | setSize({ width, height }) {
method _validateAdd (line 224) | _validateAdd(child) {
method _toKonvaCanvas (line 230) | _toKonvaCanvas(config) {
method _checkVisibility (line 240) | _checkVisibility() {
method _setSmoothEnabled (line 249) | _setSmoothEnabled() {
method getWidth (line 262) | getWidth() {
method setWidth (line 267) | setWidth() {
method getHeight (line 281) | getHeight() {
method setHeight (line 286) | setHeight() {
method batchDraw (line 299) | batchDraw() {
method getIntersection (line 324) | getIntersection(pos: Vector2d) {
method _getIntersection (line 359) | _getIntersection(pos: Vector2d): { shape?: Shape; antialiased?: boolea...
method drawScene (line 391) | drawScene(can?: SceneCanvas, top?: Node, bufferCanvas?: SceneCanvas) {
method drawHit (line 411) | drawHit(can?: HitCanvas, top?: Node) {
method enableHitGraph (line 428) | enableHitGraph() {
method disableHitGraph (line 438) | disableHitGraph() {
method setHitGraphEnabled (line 443) | setHitGraphEnabled(val) {
method getHitGraphEnabled (line 450) | getHitGraphEnabled(val) {
method toggleHitCanvas (line 462) | toggleHitCanvas() {
method destroy (line 475) | destroy(): this {
FILE: src/Node.ts
type FilterFunction (line 20) | type FilterFunction = (this: Node, imageData: ImageData) => void;
type Filter (line 21) | type Filter = FilterFunction | string;
type Filters (line 22) | type Filters = Array<FilterFunction | string>;
function parseCSSFilters (line 25) | function parseCSSFilters(cssFilter: string): FilterFunction {
type globalCompositeOperationType (line 108) | type globalCompositeOperationType =
type NodeConfig (line 138) | type NodeConfig = {
constant ABSOLUTE_OPACITY (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant ALL_LISTENERS (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant ABSOLUTE_TRANSFORM (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant ABSOLUTE_SCALE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant CANVAS (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant CHANGE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant CHILDREN (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant KONVA (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant LISTENING (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant MOUSEENTER (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant MOUSELEAVE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant POINTERENTER (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant POINTERLEAVE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant TOUCHENTER (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant TOUCHLEAVE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant NAME (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant SET (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant SHAPE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant SPACE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant STAGE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant TRANSFORM (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant UPPER_STAGE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant VISIBLE (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
constant TRANSFORM_CHANGE_STR (line 168) | const ABSOLUTE_OPACITY = 'absoluteOpacity',
type NodeEventMap (line 207) | type NodeEventMap = GlobalEventHandlersEventMap & {
type KonvaEventObject (line 211) | interface KonvaEventObject<EventType, This = Node> {
type KonvaEventListener (line 221) | type KonvaEventListener<This, EventType> = (
type CanvasConfig (line 226) | type CanvasConfig = {
type ImageConfig (line 235) | type ImageConfig = CanvasConfig & {
method constructor (line 272) | constructor(config?: Config) {
method hasChildren (line 281) | hasChildren() {
method _clearCache (line 285) | _clearCache(attr?: string) {
method _getCache (line 301) | _getCache(attr: string, privateGetter: Function) {
method _calculate (line 319) | _calculate(name: string, deps: Array<string>, getter: Function) {
method _getCanvasCache (line 333) | _getCanvasCache() {
method _clearSelfAndDescendantCache (line 340) | _clearSelfAndDescendantCache(attr?: string) {
method clearCache (line 355) | clearCache() {
method cache (line 410) | cache(
method isCached (line 574) | isCached() {
method getClientRect (line 616) | getClientRect(config?: {
method _transformedRect (line 626) | _transformedRect(rect: IRect, top?: Node | null) {
method _drawCachedSceneCanvas (line 656) | _drawCachedSceneCanvas(context: Context) {
method _drawCachedHitCanvas (line 676) | _drawCachedHitCanvas(context: Context) {
method _getCachedSceneCanvas (line 690) | _getCachedSceneCanvas() {
method on (line 855) | on(...args: any[]): this {
method off (line 911) | off(evtStr?: string, callback?: Function) {
method dispatchEvent (line 948) | dispatchEvent(evt: any) {
method addEventListener (line 957) | addEventListener(type: string, handler: (e: Event) => void) {
method removeEventListener (line 964) | removeEventListener(type: string) {
method _delegate (line 969) | _delegate(event: string, selector: string, handler: (e: Event) => void) {
method remove (line 989) | remove() {
method _clearCaches (line 1006) | _clearCaches() {
method _remove (line 1014) | _remove() {
method destroy (line 1035) | destroy() {
method getAttr (line 1049) | getAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(
method getAncestors (line 1069) | getAncestors() {
method getAttrs (line 1086) | getAttrs(): Config {
method setAttrs (line 1101) | setAttrs(config?: Config) {
method isListening (line 1139) | isListening() {
method _isListening (line 1142) | _isListening(relativeTo?: Node): boolean {
method isVisible (line 1168) | isVisible() {
method _isVisible (line 1171) | _isVisible(relativeTo?: Node): boolean {
method shouldDrawHit (line 1183) | shouldDrawHit(top?: Node, skipDragCheck = false) {
method show (line 1213) | show() {
method hide (line 1223) | hide() {
method getZIndex (line 1227) | getZIndex() {
method getAbsoluteZIndex (line 1237) | getAbsoluteZIndex() {
method getDepth (line 1281) | getDepth() {
method _batchTransformChanges (line 1296) | _batchTransformChanges(func) {
method setPosition (line 1307) | setPosition(pos: Vector2d) {
method getPosition (line 1314) | getPosition() {
method getRelativePointerPosition (line 1332) | getRelativePointerPosition() {
method getAbsolutePosition (line 1363) | getAbsolutePosition(top?: Node) {
method setAbsolutePosition (line 1388) | setAbsolutePosition(pos: Vector2d) {
method _setTransform (line 1412) | _setTransform(trans) {
method _clearTransform (line 1421) | _clearTransform() {
method move (line 1462) | move(change: Vector2d) {
method _eachAncestorReverse (line 1479) | _eachAncestorReverse(func, top) {
method rotate (line 1512) | rotate(theta: number) {
method moveToTop (line 1522) | moveToTop() {
method moveUp (line 1543) | moveUp() {
method moveDown (line 1564) | moveDown() {
method moveToBottom (line 1584) | moveToBottom() {
method setZIndex (line 1598) | setZIndex(zIndex) {
method getAbsoluteOpacity (line 1624) | getAbsoluteOpacity() {
method _getAbsoluteOpacity (line 1627) | _getAbsoluteOpacity() {
method moveTo (line 1645) | moveTo(newContainer: any) {
method toObject (line 1659) | toObject() {
method toJSON (line 1704) | toJSON() {
method getParent (line 1713) | getParent() {
method findAncestors (line 1728) | findAncestors(
method isAncestorOf (line 1750) | isAncestorOf(node: Node) {
method findAncestor (line 1765) | findAncestor(
method _isMatch (line 1773) | _isMatch(selector: string | Function) {
method getLayer (line 1820) | getLayer(): Layer | null {
method getStage (line 1830) | getStage(): Stage | null {
method _getStage (line 1834) | _getStage() {
method fire (line 1866) | fire(eventType: string, evt: any = {}, bubble?: boolean) {
method getAbsoluteTransform (line 1884) | getAbsoluteTransform(top?: Node | null) {
method _getAbsoluteTransform (line 1896) | _getAbsoluteTransform(top?: Node) {
method getAbsoluteScale (line 1947) | getAbsoluteScale(top?: Node) {
method getAbsoluteRotation (line 1977) | getAbsoluteRotation() {
method getTransform (line 1994) | getTransform() {
method _getTransform (line 1997) | _getTransform(): Transform {
method clone (line 2051) | clone(obj?: any) {
method _toKonvaCanvas (line 2086) | _toKonvaCanvas(config) {
method toCanvas (line 2147) | toCanvas(config?: CanvasConfig) {
method toDataURL (line 2173) | toDataURL(
method toImage (line 2218) | toImage(
method toBlob (line 2257) | toBlob(
method setSize (line 2279) | setSize(size) {
method getSize (line 2284) | getSize() {
method getClassName (line 2296) | getClassName() {
method getType (line 2305) | getType() {
method getDragDistance (line 2308) | getDragDistance(): number {
method _off (line 2318) | _off(type, name?, callback?) {
method _fireChangeEvent (line 2346) | _fireChangeEvent(attr, oldVal, newVal) {
method addName (line 2363) | addName(name: string) {
method hasName (line 2383) | hasName(name) {
method removeName (line 2407) | removeName(name) {
method setAttr (line 2426) | setAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(
method _requestDraw (line 2440) | _requestDraw() {
method _setAttr (line 2446) | _setAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(
method _setComponentAttr (line 2464) | _setComponentAttr(key, component, val) {
method _fireAndBubble (line 2478) | _fireAndBubble(eventType, evt, compareShape?) {
method _getProtoListeners (line 2526) | _getProtoListeners(eventType) {
method _fire (line 2546) | _fire(eventType, evt) {
method draw (line 2573) | draw() {
method _createDragElement (line 2580) | _createDragElement(evt) {
method startDrag (line 2609) | startDrag(evt?: any, bubbleEvent = true) {
method _setDragPosition (line 2629) | _setDragPosition(evt, elem) {
method stopDrag (line 2671) | stopDrag(evt?) {
method setDraggable (line 2680) | setDraggable(draggable) {
method isDragging (line 2690) | isDragging() {
method _listenDrag (line 2695) | _listenDrag() {
method _dragChange (line 2723) | _dragChange() {
method _dragCleanup (line 2751) | _dragCleanup() {
method isClientRectOnScreen (line 2771) | isClientRectOnScreen(
method create (line 2869) | static create(data, container?) {
method _createNode (line 2876) | static _createNode(obj, container?) {
type AnimTo (line 2911) | interface AnimTo extends NodeConfig {
FILE: src/PointerEvents.ts
constant SUPPORT_POINTER_EVENTS (line 11) | const SUPPORT_POINTER_EVENTS = Konva._global['PointerEvent'] !== undefined;
type KonvaPointerEvent (line 13) | interface KonvaPointerEvent extends KonvaEventObject<PointerEvent> {
function getCapturedShape (line 17) | function getCapturedShape(pointerId: number) {
function createEvent (line 21) | function createEvent(evt: PointerEvent): KonvaPointerEvent {
function hasPointerCapture (line 28) | function hasPointerCapture(pointerId: number, shape: Shape | Stage) {
function setPointerCapture (line 32) | function setPointerCapture(pointerId: number, shape: Shape | Stage) {
function releaseCapture (line 48) | function releaseCapture(pointerId: number, target?: Shape | Stage) {
FILE: src/Shape.ts
type ShapeConfigHandler (line 22) | type ShapeConfigHandler<TTarget> = {
type LineJoin (line 26) | type LineJoin = 'round' | 'bevel' | 'miter';
type LineCap (line 27) | type LineCap = 'butt' | 'round' | 'square';
type ShapeConfig (line 29) | type ShapeConfig = NodeConfig & {
type ShapeGetClientRectConfig (line 87) | interface ShapeGetClientRectConfig {
type FillFuncOutput (line 94) | type FillFuncOutput =
constant HAS_SHADOW (line 99) | const HAS_SHADOW = 'hasShadow';
constant SHADOW_RGBA (line 100) | const SHADOW_RGBA = 'shadowRGBA';
function getDummyContext (line 106) | function getDummyContext(): CanvasRenderingContext2D {
function _fillFunc (line 122) | function _fillFunc(this: Node, context) {
function _strokeFunc (line 130) | function _strokeFunc(context) {
function _fillFuncHit (line 133) | function _fillFuncHit(this: Node, context) {
function _strokeFuncHit (line 141) | function _strokeFuncHit(context) {
function _clearHasShadowCache (line 145) | function _clearHasShadowCache(this: Node) {
function _clearGetShadowRGBACache (line 149) | function _clearGetShadowRGBACache(this: Node) {
function _clearFillPatternCache (line 153) | function _clearFillPatternCache(this: Node) {
function _clearLinearGradientCache (line 157) | function _clearLinearGradientCache(this: Node) {
function _clearRadialGradientCache (line 161) | function _clearRadialGradientCache(this: Node) {
class Shape (line 191) | class Shape<
method constructor (line 202) | constructor(config?: Config) {
method getContext (line 230) | getContext() {
method getCanvas (line 237) | getCanvas() {
method getSceneFunc (line 242) | getSceneFunc() {
method getHitFunc (line 246) | getHitFunc() {
method hasShadow (line 255) | hasShadow() {
method _hasShadow (line 258) | _hasShadow() {
method _getFillPattern (line 270) | _getFillPattern() {
method __getFillPattern (line 273) | __getFillPattern() {
method _getLinearGradient (line 310) | _getLinearGradient() {
method __getLinearGradient (line 313) | __getLinearGradient() {
method _getRadialGradient (line 330) | _getRadialGradient() {
method __getRadialGradient (line 333) | __getRadialGradient() {
method getShadowRGBA (line 356) | getShadowRGBA() {
method _getShadowRGBA (line 359) | _getShadowRGBA() {
method hasFill (line 384) | hasFill() {
method hasStroke (line 413) | hasStroke() {
method hasHitStroke (line 438) | hasHitStroke() {
method intersects (line 462) | intersects(point: Vector2d) {
method destroy (line 480) | destroy() {
method _useBufferCanvas (line 489) | _useBufferCanvas(forceFill?: boolean): boolean {
method setStrokeHitEnabled (line 514) | setStrokeHitEnabled(val: number) {
method getStrokeHitEnabled (line 524) | getStrokeHitEnabled() {
method getSelfRect (line 543) | getSelfRect() {
method getClientRect (line 552) | getClientRect(config: ShapeGetClientRectConfig = {}) {
method drawScene (line 607) | drawScene(can?: SceneCanvas, top?: Node, bufferCanvas?: SceneCanvas) {
method drawHit (line 718) | drawHit(can?: HitCanvas, top?: Node, skipDragCheck = false) {
method drawHitFromCache (line 774) | drawHitFromCache(alphaThreshold = 0) {
method hasPointerCapture (line 813) | hasPointerCapture(pointerId: number): boolean {
method setPointerCapture (line 817) | setPointerCapture(pointerId: number) {
method releaseCapture (line 821) | releaseCapture(pointerId: number) {
FILE: src/Stage.ts
type StageConfig (line 14) | interface StageConfig extends ContainerConfig {
constant STAGE (line 19) | const STAGE = 'Stage',
constant STRING (line 19) | const STAGE = 'Stage',
constant MOUSEOUT (line 19) | const STAGE = 'Stage',
constant MOUSELEAVE (line 19) | const STAGE = 'Stage',
constant MOUSEOVER (line 19) | const STAGE = 'Stage',
constant MOUSEENTER (line 19) | const STAGE = 'Stage',
constant MOUSEMOVE (line 19) | const STAGE = 'Stage',
constant MOUSEDOWN (line 19) | const STAGE = 'Stage',
constant MOUSEUP (line 19) | const STAGE = 'Stage',
constant POINTERMOVE (line 19) | const STAGE = 'Stage',
constant POINTERDOWN (line 19) | const STAGE = 'Stage',
constant POINTERUP (line 19) | const STAGE = 'Stage',
constant POINTERCANCEL (line 19) | const STAGE = 'Stage',
constant LOSTPOINTERCAPTURE (line 19) | const STAGE = 'Stage',
constant POINTEROUT (line 19) | const STAGE = 'Stage',
constant POINTERLEAVE (line 19) | const STAGE = 'Stage',
constant POINTEROVER (line 19) | const STAGE = 'Stage',
constant POINTERENTER (line 19) | const STAGE = 'Stage',
constant CONTEXTMENU (line 19) | const STAGE = 'Stage',
constant TOUCHSTART (line 19) | const STAGE = 'Stage',
constant TOUCHEND (line 19) | const STAGE = 'Stage',
constant TOUCHMOVE (line 19) | const STAGE = 'Stage',
constant TOUCHCANCEL (line 19) | const STAGE = 'Stage',
constant WHEEL (line 19) | const STAGE = 'Stage',
constant MAX_LAYERS_NUMBER (line 19) | const STAGE = 'Stage',
constant EVENTS (line 19) | const STAGE = 'Stage',
constant EVENTS_MAP (line 66) | const EVENTS_MAP = {
function checkNoClip (line 128) | function checkNoClip(attrs: any = {}) {
constant NO_POINTERS_MESSAGE (line 137) | const NO_POINTERS_MESSAGE = `Pointer position is missing and not registe...
class Stage (line 157) | class Stage extends Container<Layer, StageConfig> {
method constructor (line 179) | constructor(config: StageConfig) {
method _validateAdd (line 195) | _validateAdd(child) {
method _checkVisibility (line 204) | _checkVisibility() {
method setContainer (line 217) | setContainer(container) {
method shouldDrawHit (line 244) | shouldDrawHit() {
method clear (line 253) | clear() {
method clone (line 262) | clone(obj?) {
method destroy (line 271) | destroy() {
method getPointerPosition (line 295) | getPointerPosition(): Vector2d | null {
method _getPointerById (line 306) | _getPointerById(id?: number) {
method getPointersPositions (line 309) | getPointersPositions() {
method getStage (line 312) | getStage() {
method getContent (line 315) | getContent() {
method _toKonvaCanvas (line 318) | _toKonvaCanvas(config) {
method getIntersection (line 367) | getIntersection(pos: Vector2d) {
method _resizeDOM (line 384) | _resizeDOM() {
method add (line 402) | add(layer: Layer, ...rest) {
method getParent (line 431) | getParent() {
method getLayer (line 434) | getLayer() {
method hasPointerCapture (line 438) | hasPointerCapture(pointerId: number): boolean {
method setPointerCapture (line 442) | setPointerCapture(pointerId: number) {
method releaseCapture (line 446) | releaseCapture(pointerId: number) {
method getLayers (line 455) | getLayers() {
method _bindContentEvents (line 458) | _bindContentEvents() {
method _pointerenter (line 472) | _pointerenter(evt: PointerEvent) {
method _pointerover (line 483) | _pointerover(evt) {
method _getTargetShape (line 494) | _getTargetShape(evenType) {
method _pointerleave (line 501) | _pointerleave(evt) {
method _pointerdown (line 537) | _pointerdown(evt: TouchEvent | MouseEvent | PointerEvent) {
method _pointermove (line 590) | _pointermove(evt: TouchEvent | MouseEvent | PointerEvent) {
method _pointerup (line 670) | _pointerup(evt) {
method _contextmenu (line 781) | _contextmenu(evt) {
method _wheel (line 796) | _wheel(evt) {
method _pointercancel (line 811) | _pointercancel(evt: PointerEvent) {
method _lostpointercapture (line 824) | _lostpointercapture(evt: PointerEvent) {
method setPointersPositions (line 842) | setPointersPositions(evt) {
method _setPointerPosition (line 886) | _setPointerPosition(evt) {
method _getContentPosition (line 892) | _getContentPosition() {
method _buildDOM (line 913) | _buildDOM() {
method cache (line 947) | cache() {
method clearCache (line 953) | clearCache() {
method batchDraw (line 962) | batchDraw() {
FILE: src/Tween.ts
constant PAUSED (line 8) | const blacklist = {
constant PLAYING (line 8) | const blacklist = {
constant REVERSING (line 8) | const blacklist = {
class TweenEngine (line 21) | class TweenEngine {
method constructor (line 44) | constructor(prop, propFunc, func, begin, finish, duration, yoyo) {
method fire (line 61) | fire(str) {
method setTime (line 67) | setTime(t) {
method getTime (line 87) | getTime() {
method setPosition (line 90) | setPosition(p) {
method getPosition (line 95) | getPosition(t) {
method play (line 101) | play() {
method reverse (line 107) | reverse() {
method seek (line 114) | seek(t) {
method reset (line 120) | reset() {
method finish (line 126) | finish() {
method update (line 132) | update() {
method onEnterFrame (line 136) | onEnterFrame() {
method pause (line 144) | pause() {
method getTimer (line 148) | getTimer() {
type TweenConfig (line 153) | interface TweenConfig extends NodeConfig {
class Tween (line 189) | class Tween {
method constructor (line 201) | constructor(config: TweenConfig) {
method _addAttr (line 271) | _addAttr(key, end) {
method _tweenFunc (line 351) | _tweenFunc(i) {
method _addListeners (line 406) | _addListeners() {
method play (line 456) | play() {
method reverse (line 466) | reverse() {
method reset (line 476) | reset() {
method seek (line 487) | seek(t) {
method pause (line 497) | pause() {
method finish (line 507) | finish() {
method destroy (line 516) | destroy() {
method BackEaseIn (line 590) | BackEaseIn(t, b, c, d) {
method BackEaseOut (line 599) | BackEaseOut(t, b, c, d) {
method BackEaseInOut (line 608) | BackEaseInOut(t, b, c, d) {
method ElasticEaseIn (line 620) | ElasticEaseIn(t, b, c, d, a, p) {
method ElasticEaseOut (line 651) | ElasticEaseOut(t, b, c, d, a, p) {
method ElasticEaseInOut (line 680) | ElasticEaseInOut(t, b, c, d, a, p) {
method BounceEaseOut (line 721) | BounceEaseOut(t, b, c, d) {
method BounceEaseIn (line 737) | BounceEaseIn(t, b, c, d) {
method BounceEaseInOut (line 745) | BounceEaseInOut(t, b, c, d) {
method EaseIn (line 757) | EaseIn(t, b, c, d) {
method EaseOut (line 765) | EaseOut(t, b, c, d) {
method EaseInOut (line 773) | EaseInOut(t, b, c, d) {
method StrongEaseIn (line 784) | StrongEaseIn(t, b, c, d) {
method StrongEaseOut (line 792) | StrongEaseOut(t, b, c, d) {
method StrongEaseInOut (line 800) | StrongEaseInOut(t, b, c, d) {
method Linear (line 811) | Linear(t, b, c, d) {
FILE: src/Util.ts
constant NODE_ERROR (line 5) | const NODE_ERROR = `Konva.js unsupported environment.
class Transform (line 49) | class Transform {
method constructor (line 52) | constructor(m = [1, 0, 0, 1, 0, 0]) {
method reset (line 55) | reset() {
method copy (line 71) | copy() {
method copyInto (line 74) | copyInto(tr: Transform) {
method point (line 89) | point(point: Vector2d) {
method translate (line 104) | translate(x: number, y: number) {
method scale (line 117) | scale(sx: number, sy: number) {
method rotate (line 131) | rotate(rad: number) {
method getTranslation (line 150) | getTranslation() {
method skew (line 164) | skew(sx: number, sy: number) {
method multiply (line 182) | multiply(matrix: Transform) {
method invert (line 206) | invert() {
method getMatrix (line 227) | getMatrix() {
method decompose (line 236) | decompose() {
constant OBJECT_ARRAY (line 283) | const OBJECT_ARRAY = '[object Array]',
constant OBJECT_NUMBER (line 283) | const OBJECT_ARRAY = '[object Array]',
constant OBJECT_STRING (line 283) | const OBJECT_ARRAY = '[object Array]',
constant OBJECT_BOOLEAN (line 283) | const OBJECT_ARRAY = '[object Array]',
constant PI_OVER_DEG180 (line 283) | const OBJECT_ARRAY = '[object Array]',
constant DEG180_OVER_PI (line 283) | const OBJECT_ARRAY = '[object Array]',
constant HASH (line 283) | const OBJECT_ARRAY = '[object Array]',
constant EMPTY_STRING (line 283) | const OBJECT_ARRAY = '[object Array]',
constant ZERO (line 283) | const OBJECT_ARRAY = '[object Array]',
constant KONVA_WARNING (line 283) | const OBJECT_ARRAY = '[object Array]',
constant KONVA_ERROR (line 283) | const OBJECT_ARRAY = '[object Array]',
constant RGB_PAREN (line 283) | const OBJECT_ARRAY = '[object Array]',
constant COLORS (line 283) | const OBJECT_ARRAY = '[object Array]',
constant RGB_REGEX (line 283) | const OBJECT_ARRAY = '[object Array]',
method _isElement (line 465) | _isElement(obj: any): obj is Element {
method _isFunction (line 468) | _isFunction(obj: any) {
method _isPlainObject (line 471) | _isPlainObject(obj: any) {
method _isArray (line 474) | _isArray(obj: any): obj is Array<any> {
method _isNumber (line 477) | _isNumber(obj: any): obj is number {
method _isString (line 484) | _isString(obj: any): obj is string {
method _isBoolean (line 487) | _isBoolean(obj: any): obj is boolean {
method isObject (line 491) | isObject(val: any): val is object {
method isValidSelector (line 494) | isValidSelector(selector: any) {
method _sign (line 505) | _sign(number: number) {
method requestAnimFrame (line 518) | requestAnimFrame(callback: Function) {
method createCanvasElement (line 530) | createCanvasElement() {
method createImageElement (line 539) | createImageElement() {
method _isInDocument (line 543) | _isInDocument(el: any) {
method _urlToImage (line 555) | _urlToImage(url: string, callback: Function) {
method _rgbToHex (line 563) | _rgbToHex(r: number, g: number, b: number) {
method _hexToRgb (line 566) | _hexToRgb(hex: string): RGB {
method getRandomColor (line 582) | getRandomColor() {
method isCanvasFarblingActive (line 595) | isCanvasFarblingActive() {
method getHitColor (line 640) | getHitColor(): string {
method getHitColorKey (line 655) | getHitColorKey(r: number, g: number, b: number): string {
method getSnappedHexColor (line 670) | getSnappedHexColor(hex: string): string {
method getRGB (line 693) | getRGB(color: string): RGB {
method colorToRGBA (line 725) | colorToRGBA(str: string) {
method _namedColorToRBA (line 739) | _namedColorToRBA(str: string) {
method _rgbColorToRGBA (line 752) | _rgbColorToRGBA(str: string) {
method _rgbaColorToRGBA (line 765) | _rgbaColorToRGBA(str: string) {
method _hex8ColorToRGBA (line 783) | _hex8ColorToRGBA(str: string) {
method _hex6ColorToRGBA (line 794) | _hex6ColorToRGBA(str: string) {
method _hex4ColorToRGBA (line 805) | _hex4ColorToRGBA(str: string) {
method _hex3ColorToRGBA (line 816) | _hex3ColorToRGBA(str: string) {
method _hslColorToRGBA (line 827) | _hslColorToRGBA(str: string) {
method haveIntersection (line 900) | haveIntersection(r1: IRect, r2: IRect) {
method cloneObject (line 908) | cloneObject<Any>(obj: Any): Any {
method cloneArray (line 921) | cloneArray(arr: Array<any>) {
method degToRad (line 924) | degToRad(deg: number) {
method radToDeg (line 927) | radToDeg(rad: number) {
method _degToRad (line 930) | _degToRad(deg: number) {
method _radToDeg (line 936) | _radToDeg(rad: number) {
method _getRotation (line 942) | _getRotation(radians: number) {
method _capitalize (line 945) | _capitalize(str: string) {
method throw (line 948) | throw(str: string) {
method error (line 951) | error(str: string) {
method warn (line 954) | warn(str: string) {
method each (line 960) | each(obj: object, func: Function) {
method _inRange (line 965) | _inRange(val: number, left: number, right: number) {
method _getProjectionToSegment (line 968) | _getProjectionToSegment(x1, y1, x2, y2, x3, y3) {
method _getProjectionToLine (line 996) | _getProjectionToLine(pt: Vector2d, line: Array<Vector2d>, isClosed: bool...
method _prepareArrayForTween (line 1023) | _prepareArrayForTween(startArray, endArray, isClosed) {
method _prepareToStringify (line 1052) | _prepareToStringify<T>(obj: any): T | null {
method _assign (line 1087) | _assign<T, U>(target: T, source: U) {
method _getFirstPointerId (line 1093) | _getFirstPointerId(evt) {
method releaseCanvas (line 1101) | releaseCanvas(...canvases: HTMLCanvasElement[]) {
method drawRoundedRectPath (line 1109) | drawRoundedRectPath(
method drawRoundedPolygonPath (line 1174) | drawRoundedPolygonPath(
type AnyString (line 1220) | type AnyString<T> = T | (string & {});
FILE: src/Validators.ts
function _formatValue (line 4) | function _formatValue(val: any) {
function RGBComponent (line 17) | function RGBComponent(val: number) {
function alphaComponent (line 25) | function alphaComponent(val: number) {
function getNumberValidator (line 36) | function getNumberValidator<T>() {
function getNumberOrArrayOfNumbersValidator (line 52) | function getNumberOrArrayOfNumbersValidator<T>(noOfElements: number) {
function getNumberOrAutoValidator (line 72) | function getNumberOrAutoValidator<T>() {
function getStringValidator (line 91) | function getStringValidator<T>() {
function getStringOrGradientValidator (line 107) | function getStringOrGradientValidator<T>() {
function getFunctionValidator (line 127) | function getFunctionValidator<T>() {
function getNumberArrayValidator (line 142) | function getNumberArrayValidator<T>() {
function getBooleanValidator (line 175) | function getBooleanValidator<T>() {
function getComponentValidator (line 191) | function getComponentValidator<T>(components: string[]) {
FILE: src/_CoreInternals.ts
type Vector2d (line 46) | type Vector2d = import('./types.ts').Vector2d;
type Node (line 47) | type Node = import('./Node.ts').Node;
type NodeConfig (line 48) | type NodeConfig = import('./Node.ts').NodeConfig;
type KonvaEventObject (line 49) | type KonvaEventObject<EventType> =
type KonvaPointerEvent (line 52) | type KonvaPointerEvent =
type KonvaEventListener (line 55) | type KonvaEventListener<This, EventType> =
type Container (line 58) | type Container = import('./Container.ts').Container
type ContainerConfig (line 59) | type ContainerConfig = import('./Container.ts').ContainerConfig;
type Transform (line 61) | type Transform = import('./Util.ts').Transform;
type Context (line 63) | type Context = import('./Context.ts').Context;
type Stage (line 65) | type Stage = import('./Stage.ts').Stage;
type StageConfig (line 66) | type StageConfig = import('./Stage.ts').StageConfig;
type Layer (line 68) | type Layer = import('./Layer.ts').Layer;
type LayerConfig (line 69) | type LayerConfig = import('./Layer.ts').LayerConfig;
type FastLayer (line 71) | type FastLayer = import('./FastLayer.ts').FastLayer;
type Group (line 73) | type Group = import('./Group.ts').Group;
type GroupConfig (line 74) | type GroupConfig = import('./Group.ts').GroupConfig;
type Shape (line 76) | type Shape = import('./Shape.ts').Shape;
type ShapeConfig (line 77) | type ShapeConfig = import('./Shape.ts').ShapeConfig;
type Animation (line 79) | type Animation = import('./Animation.ts').Animation;
type Tween (line 81) | type Tween = import('./Tween.ts').Tween;
type TweenConfig (line 82) | type TweenConfig = import('./Tween.ts').TweenConfig;
FILE: src/_FullInternals.ts
type Vector2d (line 94) | type Vector2d = Core.Vector2d;
type Node (line 95) | type Node = Core.Node;
type NodeConfig (line 96) | type NodeConfig = Core.NodeConfig;
type KonvaEventObject (line 97) | type KonvaEventObject<EventType> = Core.KonvaEventObject<EventType>;
type KonvaPointerEvent (line 99) | type KonvaPointerEvent = Core.KonvaPointerEvent;
type KonvaEventListener (line 101) | type KonvaEventListener<This, EventType> = Core.KonvaEventListener<
type Container (line 106) | type Container = Core.Container;
type ContainerConfig (line 107) | type ContainerConfig = Core.ContainerConfig;
type Transform (line 109) | type Transform = Core.Transform;
type Context (line 111) | type Context = Core.Context;
type Stage (line 113) | type Stage = Core.Stage;
type StageConfig (line 114) | type StageConfig = Core.StageConfig;
type Layer (line 116) | type Layer = Core.Layer;
type LayerConfig (line 117) | type LayerConfig = Core.LayerConfig;
type FastLayer (line 119) | type FastLayer = Core.FastLayer;
type Group (line 121) | type Group = Core.Group;
type GroupConfig (line 122) | type GroupConfig = Core.GroupConfig;
type Shape (line 124) | type Shape = Core.Shape;
type ShapeConfig (line 125) | type ShapeConfig = Core.ShapeConfig;
type Animation (line 127) | type Animation = Core.Animation;
type Tween (line 129) | type Tween = Core.Tween;
type TweenConfig (line 130) | type TweenConfig = Core.TweenConfig;
type Arc (line 132) | type Arc = import('./shapes/Arc.ts').Arc;
type ArcConfig (line 133) | type ArcConfig = import('./shapes/Arc.ts').ArcConfig;
type Arrow (line 134) | type Arrow = import('./shapes/Arrow.ts').Arrow;
type ArrowConfig (line 135) | type ArrowConfig = import('./shapes/Arrow.ts').ArrowConfig;
type Circle (line 136) | type Circle = import('./shapes/Circle.ts').Circle;
type CircleConfig (line 137) | type CircleConfig = import('./shapes/Circle.ts').CircleConfig;
type Ellipse (line 138) | type Ellipse = import('./shapes/Ellipse.ts').Ellipse;
type EllipseConfig (line 139) | type EllipseConfig = import('./shapes/Ellipse.ts').EllipseConfig;
type Image (line 140) | type Image = import('./shapes/Image.ts').Image;
type ImageConfig (line 141) | type ImageConfig = import('./shapes/Image.ts').ImageConfig;
type Label (line 142) | type Label = import('./shapes/Label.ts').Label;
type LabelConfig (line 143) | type LabelConfig = import('./shapes/Label.ts').LabelConfig;
type Tag (line 144) | type Tag = import('./shapes/Label.ts').Tag;
type TagConfig (line 145) | type TagConfig = import('./shapes/Label.ts').TagConfig;
type Line (line 146) | type Line = import('./shapes/Line.ts').Line;
type LineConfig (line 147) | type LineConfig = import('./shapes/Line.ts').LineConfig;
type Path (line 148) | type Path = import('./shapes/Path.ts').Path;
type PathConfig (line 149) | type PathConfig = import('./shapes/Path.ts').PathConfig;
type Rect (line 150) | type Rect = import('./shapes/Rect.ts').Rect;
type RectConfig (line 151) | type RectConfig = import('./shapes/Rect.ts').RectConfig;
type RegularPolygon (line 152) | type RegularPolygon =
type RegularPolygonConfig (line 154) | type RegularPolygonConfig =
type Ring (line 156) | type Ring = import('./shapes/Ring.ts').Ring;
type RingConfig (line 157) | type RingConfig = import('./shapes/Ring.ts').RingConfig;
type Sprite (line 158) | type Sprite = import('./shapes/Sprite.ts').Sprite;
type SpriteConfig (line 159) | type SpriteConfig = import('./shapes/Sprite.ts').SpriteConfig;
type Star (line 160) | type Star = import('./shapes/Star.ts').Star;
type StarConfig (line 161) | type StarConfig = import('./shapes/Star.ts').StarConfig;
type Text (line 162) | type Text = import('./shapes/Text.ts').Text;
type TextConfig (line 163) | type TextConfig = import('./shapes/Text.ts').TextConfig;
type TextPath (line 164) | type TextPath = import('./shapes/TextPath.ts').TextPath;
type TextPathConfig (line 165) | type TextPathConfig = import('./shapes/TextPath.ts').TextPathConfig;
type Transformer (line 166) | type Transformer = import('./shapes/Transformer.ts').Transformer;
type TransformerConfig (line 167) | type TransformerConfig =
type Wedge (line 169) | type Wedge = import('./shapes/Wedge.ts').Wedge;
type WedgeConfig (line 170) | type WedgeConfig = import('./shapes/Wedge.ts').WedgeConfig;
FILE: src/canvas-backend.ts
method constructor (line 12) | constructor(path: any) {
method [Symbol.toStringTag] (line 16) | get [Symbol.toStringTag]() {
FILE: src/filters/Blur.ts
function BlurStack (line 51) | function BlurStack(this: any) {
function filterGaussBlurRGBA (line 96) | function filterGaussBlurRGBA(imageData, radius) {
FILE: src/filters/Enhance.ts
function remap (line 6) | function remap(
FILE: src/filters/Mask.ts
function pixelAt (line 6) | function pixelAt(idata, x: number, y: number) {
function rgbDistance (line 18) | function rgbDistance(p1, p2) {
function rgbMean (line 26) | function rgbMean(pTab) {
function backgroundMask (line 42) | function backgroundMask(idata, threshold) {
function applyMask (line 73) | function applyMask(idata, mask) {
function erodeMask (line 79) | function erodeMask(mask, sw, sh) {
function dilateMask (line 110) | function dilateMask(mask, sw, sh) {
function smoothEdgeMask (line 141) | function smoothEdgeMask(mask, sw: number, sh: number) {
FILE: src/shapes/Arc.ts
type ArcConfig (line 10) | interface ArcConfig extends ShapeConfig {
class Arc (line 41) | class Arc extends Shape<ArcConfig> {
method _sceneFunc (line 42) | _sceneFunc(context: Context) {
method getWidth (line 52) | getWidth() {
method getHeight (line 55) | getHeight() {
method setWidth (line 58) | setWidth(width: number) {
method setHeight (line 61) | setHeight(height: number) {
method getSelfRect (line 65) | getSelfRect() {
FILE: src/shapes/Arrow.ts
type ArrowConfig (line 10) | interface ArrowConfig extends LineConfig {
class Arrow (line 44) | class Arrow extends Line<ArrowConfig> {
method _sceneFunc (line 45) | _sceneFunc(ctx: Context) {
method __fillStroke (line 131) | __fillStroke(ctx: Context) {
method getSelfRect (line 151) | getSelfRect() {
FILE: src/shapes/Circle.ts
type CircleConfig (line 9) | interface CircleConfig extends ShapeConfig {
class Circle (line 31) | class Circle extends Shape<CircleConfig> {
method _sceneFunc (line 32) | _sceneFunc(context: Context) {
method getWidth (line 38) | getWidth() {
method getHeight (line 41) | getHeight() {
method setWidth (line 44) | setWidth(width: number) {
method setHeight (line 49) | setHeight(height: number) {
FILE: src/shapes/Ellipse.ts
type EllipseConfig (line 10) | interface EllipseConfig extends ShapeConfig {
class Ellipse (line 33) | class Ellipse extends Shape<EllipseConfig> {
method _sceneFunc (line 34) | _sceneFunc(context: Context) {
method getWidth (line 48) | getWidth() {
method getHeight (line 51) | getHeight() {
method setWidth (line 54) | setWidth(width: number) {
method setHeight (line 57) | setHeight(height: number) {
FILE: src/shapes/Image.ts
type ImageConfig (line 14) | interface ImageConfig extends ShapeConfig {
class Image (line 43) | class Image extends Shape<ImageConfig> {
method constructor (line 46) | constructor(attrs?: ImageConfig) {
method _setImageLoad (line 59) | _setImageLoad() {
method _removeImageLoad (line 73) | _removeImageLoad(image: any) {
method destroy (line 78) | destroy() {
method _useBufferCanvas (line 83) | _useBufferCanvas() {
method _sceneFunc (line 91) | _sceneFunc(context: Context) {
method _hitFunc (line 135) | _hitFunc(context: Context) {
method getWidth (line 149) | getWidth() {
method getHeight (line 152) | getHeight() {
method fromURL (line 169) | static fromURL(
FILE: src/shapes/Label.ts
type LabelConfig (line 16) | interface LabelConfig extends ContainerConfig {}
constant ATTR_CHANGE_LIST (line 19) | const ATTR_CHANGE_LIST = [
constant CHANGE_KONVA (line 19) | const ATTR_CHANGE_LIST = [
constant NONE (line 19) | const ATTR_CHANGE_LIST = [
constant RIGHT (line 19) | const ATTR_CHANGE_LIST = [
constant DOWN (line 19) | const ATTR_CHANGE_LIST = [
constant LEFT (line 19) | const ATTR_CHANGE_LIST = [
class Label (line 79) | class Label extends Group {
method constructor (line 80) | constructor(config?: LabelConfig) {
method getText (line 96) | getText() {
method getTag (line 105) | getTag() {
method _addListeners (line 108) | _addListeners(text) {
method getWidth (line 120) | getWidth() {
method getHeight (line 123) | getHeight() {
method _sync (line 126) | _sync() {
type TagConfig (line 183) | interface TagConfig extends ShapeConfig {
class Tag (line 202) | class Tag extends Shape<TagConfig> {
method _sceneFunc (line 203) | _sceneFunc(context: Context) {
method getSelfRect (line 292) | getSelfRect() {
FILE: src/shapes/Line.ts
function getControlPoints (line 10) | function getControlPoints(
function expandPoints (line 31) | function expandPoints(p, tension) {
function getBezierExtremaPoints (line 59) | function getBezierExtremaPoints(points) {
type LineConfig (line 96) | interface LineConfig extends ShapeConfig {
class Line (line 137) | class Line<
method constructor (line 140) | constructor(config?: Config) {
method _sceneFunc (line 150) | _sceneFunc(context: Context) {
method getTensionPoints (line 224) | getTensionPoints() {
method _getTensionPoints (line 227) | _getTensionPoints() {
method _getTensionPointsClosed (line 234) | _getTensionPointsClosed() {
method getWidth (line 274) | getWidth() {
method getHeight (line 277) | getHeight() {
method getSelfRect (line 281) | getSelfRect() {
FILE: src/shapes/Path.ts
type PathConfig (line 13) | interface PathConfig extends ShapeConfig {
class Path (line 36) | class Path extends Shape<PathConfig> {
method constructor (line 40) | constructor(config?: PathConfig) {
method _readDataAttribute (line 49) | _readDataAttribute() {
method _sceneFunc (line 54) | _sceneFunc(context) {
method getSelfRect (line 112) | getSelfRect() {
method getLength (line 209) | getLength() {
method getPointAtLength (line 221) | getPointAtLength(length: number) {
method getLineLength (line 227) | static getLineLength(x1, y1, x2, y2) {
method getPathLength (line 231) | static getPathLength(dataArray: PathSegment[]) {
method getPointAtLengthOfDataArray (line 239) | static getPointAtLengthOfDataArray(length: number, dataArray: PathSegm...
method getPointOnLine (line 331) | static getPointOnLine(
method getPointOnCubicBezier (line 374) | static getPointOnCubicBezier(
method getPointOnQuadraticBezier (line 402) | static getPointOnQuadraticBezier(pct, P1x, P1y, P2x, P2y, P3x, P3y) {
method getPointOnEllipticalArc (line 417) | static getPointOnEllipticalArc(
method parsePathData (line 442) | static parsePathData(data): PathSegment[] {
method calcLength (line 834) | static calcLength(x, y, cmd, points) {
method convertEndpointToCenterParameterization (line 919) | static convertEndpointToCenterParameterization(
FILE: src/shapes/Rect.ts
type RectConfig (line 11) | type RectConfig = ShapeConfig & {
class Rect (line 33) | class Rect extends Shape<RectConfig> {
method _sceneFunc (line 34) | _sceneFunc(context: Context) {
FILE: src/shapes/RegularPolygon.ts
type RegularPolygonConfig (line 13) | interface RegularPolygonConfig extends ShapeConfig {
class RegularPolygon (line 40) | class RegularPolygon extends Shape<RegularPolygonConfig> {
method _sceneFunc (line 41) | _sceneFunc(context: Context) {
method _getPoints (line 61) | _getPoints() {
method getSelfRect (line 73) | getSelfRect() {
method getWidth (line 93) | getWidth() {
method getHeight (line 96) | getHeight() {
method setWidth (line 99) | setWidth(width: number) {
method setHeight (line 102) | setHeight(height: number) {
FILE: src/shapes/Ring.ts
type RingConfig (line 9) | interface RingConfig extends ShapeConfig {
class Ring (line 34) | class Ring extends Shape<RingConfig> {
method _sceneFunc (line 35) | _sceneFunc(context: Context) {
method getWidth (line 43) | getWidth() {
method getHeight (line 46) | getHeight() {
method setWidth (line 49) | setWidth(width: number) {
method setHeight (line 52) | setHeight(height: number) {
FILE: src/shapes/Sprite.ts
type SpriteConfig (line 11) | interface SpriteConfig extends ShapeConfig {
class Sprite (line 66) | class Sprite extends Shape<SpriteConfig> {
method constructor (line 70) | constructor(config: SpriteConfig) {
method _sceneFunc (line 95) | _sceneFunc(context: Context) {
method _hitFunc (line 134) | _hitFunc(context: Context) {
method _useBufferCanvas (line 155) | _useBufferCanvas() {
method _setInterval (line 159) | _setInterval() {
method start (line 170) | start() {
method stop (line 191) | stop() {
method isRunning (line 201) | isRunning() {
method _updateIndex (line 204) | _updateIndex() {
FILE: src/shapes/Star.ts
type StarConfig (line 10) | interface StarConfig extends ShapeConfig {
class Star (line 39) | class Star extends Shape<StarConfig> {
method _sceneFunc (line 40) | _sceneFunc(context: Context) {
method getWidth (line 58) | getWidth() {
method getHeight (line 61) | getHeight() {
method setWidth (line 64) | setWidth(width: number) {
method setHeight (line 67) | setHeight(height: number) {
FILE: src/shapes/Text.ts
type CharRenderProps (line 17) | interface CharRenderProps {
function stringToArray (line 29) | function stringToArray(string: string): string[] {
type TextConfig (line 65) | interface TextConfig extends ShapeConfig {
constant AUTO (line 84) | const AUTO = 'auto',
constant CENTER (line 84) | const AUTO = 'auto',
constant INHERIT (line 84) | const AUTO = 'auto',
constant JUSTIFY (line 84) | const AUTO = 'auto',
constant CHANGE_KONVA (line 84) | const AUTO = 'auto',
constant CONTEXT_2D (line 84) | const AUTO = 'auto',
constant DASH (line 84) | const AUTO = 'auto',
constant LEFT (line 84) | const AUTO = 'auto',
constant TEXT (line 84) | const AUTO = 'auto',
constant TEXT_UPPER (line 84) | const AUTO = 'auto',
constant TOP (line 84) | const AUTO = 'auto',
constant BOTTOM (line 84) | const AUTO = 'auto',
constant MIDDLE (line 84) | const AUTO = 'auto',
constant NORMAL (line 84) | const AUTO = 'auto',
constant PX_SPACE (line 84) | const AUTO = 'auto',
constant SPACE (line 84) | const AUTO = 'auto',
constant RIGHT (line 84) | const AUTO = 'auto',
constant RTL (line 84) | const AUTO = 'auto',
constant WORD (line 84) | const AUTO = 'auto',
constant CHAR (line 84) | const AUTO = 'auto',
constant NONE (line 84) | const AUTO = 'auto',
constant ELLIPSIS (line 84) | const AUTO = 'auto',
constant ATTR_CHANGE_LIST (line 84) | const AUTO = 'auto',
function normalizeFontFamily (line 127) | function normalizeFontFamily(fontFamily: string) {
function getDummyContext (line 143) | function getDummyContext() {
function _fillFunc (line 153) | function _fillFunc(this: Text, context: Context) {
function _strokeFunc (line 156) | function _strokeFunc(this: Text, context: Context) {
function checkDefaultFill (line 161) | function checkDefaultFill(config?: TextConfig) {
class Text (line 207) | class Text extends Shape<TextConfig> {
method constructor (line 215) | constructor(config?: TextConfig) {
method _sceneFunc (line 224) | _sceneFunc(context: Context) {
method _hitFunc (line 420) | _hitFunc(context: Context) {
method setText (line 429) | setText(text: string) {
method getWidth (line 438) | getWidth() {
method getHeight (line 442) | getHeight() {
method getTextWidth (line 456) | getTextWidth() {
method getTextHeight (line 459) | getTextHeight() {
method measureSize (line 474) | measureSize(text: string) {
method _getContextFont (line 510) | _getContextFont() {
method _addTextLine (line 521) | _addTextLine(line: string) {
method _getTextWidth (line 533) | _getTextWidth(text: string) {
method _setTextData (line 540) | _setTextData() {
method _shouldHandleEllipsis (line 706) | _shouldHandleEllipsis(currentHeightPx: number): boolean {
method _tryToAddEllipsisToLastLine (line 722) | _tryToAddEllipsisToLastLine(): void {
method getStrokeScaleEnabled (line 747) | getStrokeScaleEnabled() {
method _useBufferCanvas (line 751) | _useBufferCanvas() {
FILE: src/shapes/TextPath.ts
type TextPathConfig (line 13) | interface TextPathConfig extends ShapeConfig {
constant EMPTY_STRING (line 28) | const EMPTY_STRING = '',
constant NORMAL (line 28) | const EMPTY_STRING = '',
function _fillFunc (line 31) | function _fillFunc(this: TextPath, context) {
function _strokeFunc (line 34) | function _strokeFunc(this: TextPath, context) {
class TextPath (line 82) | class TextPath extends Shape<TextPathConfig> {
method constructor (line 99) | constructor(config?: TextPathConfig) {
method _getTextPathLength (line 119) | _getTextPathLength() {
method _getPointAtLength (line 122) | _getPointAtLength(length: number) {
method _readDataAttribute (line 137) | _readDataAttribute() {
method _sceneFunc (line 142) | _sceneFunc(context: Context) {
method _hitFunc (line 216) | _hitFunc(context: Context) {
method getTextWidth (line 237) | getTextWidth() {
method getTextHeight (line 240) | getTextHeight() {
method setText (line 246) | setText(text: string) {
method _getContextFont (line 250) | _getContextFont() {
method _getTextSize (line 254) | _getTextSize(text: string) {
method _setTextData (line 270) | _setTextData() {
method getSelfRect (line 393) | getSelfRect() {
method destroy (line 431) | destroy(): this {
FILE: src/shapes/Transformer.ts
type Box (line 14) | interface Box extends IRect {
type TransformerConfig (line 18) | interface TransformerConfig extends ContainerConfig {
constant EVENTS_NAME (line 54) | const EVENTS_NAME = 'tr-konva';
constant ATTR_CHANGE_LIST (line 56) | const ATTR_CHANGE_LIST = [
constant NODES_RECT (line 77) | const NODES_RECT = 'nodesRect';
constant TRANSFORM_CHANGE_STR (line 79) | const TRANSFORM_CHANGE_STR = [
constant ANGLES (line 94) | const ANGLES = {
constant TOUCH_DEVICE (line 105) | const TOUCH_DEVICE = 'ontouchstart' in Konva._global;
function getCursor (line 107) | function getCursor(anchorName, rad, rotateCursor) {
constant ANCHORS_NAMES (line 146) | const ANCHORS_NAMES = [
constant MAX_SAFE_INTEGER (line 157) | const MAX_SAFE_INTEGER = 100000000;
function getCenter (line 159) | function getCenter(shape: Box) {
function rotateAroundPoint (line 172) | function rotateAroundPoint(shape: Box, angleRad: number, point: Vector2d) {
function rotateAroundCenter (line 189) | function rotateAroundCenter(shape: Box, deltaRad: number) {
function getSnap (line 194) | function getSnap(snaps: Array<number>, newRotationRad: number, tol: numb...
class Transformer (line 251) | class Transformer extends Group {
method constructor (line 265) | constructor(config?: TransformerConfig) {
method attachTo (line 290) | attachTo(node: Node) {
method setNode (line 294) | setNode(node: Node) {
method getNode (line 300) | getNode() {
method _getEventNamespace (line 304) | _getEventNamespace() {
method setNodes (line 308) | setNodes(nodes: Array<Node> = []) {
method _proxyDrag (line 367) | _proxyDrag(node: Node) {
method getNodes (line 402) | getNodes() {
method getActiveAnchor (line 413) | getActiveAnchor() {
method detach (line 424) | detach() {
method _resetTransformCache (line 447) | _resetTransformCache() {
method _getNodeRect (line 452) | _getNodeRect() {
method __getNodeShape (line 457) | __getNodeShape(node: Node, rot = this.rotation(), relative?: Node) {
method __getNodeRect (line 487) | __getNodeRect() {
method getX (line 557) | getX() {
method getY (line 560) | getY() {
method getWidth (line 563) | getWidth() {
method getHeight (line 566) | getHeight() {
method _createElements (line 569) | _createElements() {
method _createAnchor (line 579) | _createAnchor(name) {
method _createBack (line 619) | _createBack() {
method _handleMouseDown (line 708) | _handleMouseDown(e) {
method _handleMouseMove (line 744) | _handleMouseMove(e) {
method _handleMouseUp (line 992) | _handleMouseUp(e) {
method getAbsoluteTransform (line 995) | getAbsoluteTransform() {
method _removeEvents (line 998) | _removeEvents(e?) {
method _fitNodesInto (line 1023) | _fitNodesInto(newAttrs, evt?) {
method forceUpdate (line 1195) | forceUpdate() {
method _batchChangeChild (line 1200) | _batchChangeChild(selector: string, attrs: any) {
method update (line 1205) | update() {
method isTransforming (line 1353) | isTransforming() {
method stopTransform (line 1362) | stopTransform() {
method destroy (line 1371) | destroy() {
method add (line 1384) | add(...children: any[]) {
method toObject (line 1395) | toObject() {
method clone (line 1400) | clone(obj?: any) {
method getClientRect (line 1404) | getClientRect() {
function validateAnchors (line 1449) | function validateAnchors(val) {
FILE: src/shapes/Wedge.ts
type WedgeConfig (line 11) | interface WedgeConfig extends ShapeConfig {
class Wedge (line 39) | class Wedge extends Shape<WedgeConfig> {
method _sceneFunc (line 40) | _sceneFunc(context: Context) {
method getWidth (line 54) | getWidth() {
method getHeight (line 57) | getHeight() {
method setWidth (line 60) | setWidth(width: number) {
method setHeight (line 63) | setHeight(height: number) {
FILE: src/types.ts
type GetSet (line 1) | interface GetSet<Type, This> {
type Vector2d (line 6) | interface Vector2d {
type PathSegment (line 11) | interface PathSegment {
type IRect (line 38) | interface IRect {
type IFrame (line 45) | interface IFrame {
type AnimationFn (line 52) | type AnimationFn = (frame: IFrame) => boolean | void;
type RGB (line 76) | interface RGB {
type RGBA (line 82) | interface RGBA extends RGB {
FILE: test/import-test.mjs
function equal (line 1) | function equal(val1, val2, message) {
FILE: test/node-canvas-global-setup.mjs
function mochaGlobalSetup (line 1) | async function mochaGlobalSetup() {
FILE: test/node-skia-global-setup.mjs
function mochaGlobalSetup (line 1) | async function mochaGlobalSetup() {
FILE: test/runner.js
function init (line 25) | function init() {
function addStats (line 70) | function addStats() {
function addStage (line 90) | function addStage(attrs) {
function createCanvas (line 107) | function createCanvas() {
function get (line 117) | function get(element, content) {
function compareCanvases (line 124) | function compareCanvases(canvas1, canvas2, tol) {
function compareLayerAndCanvas (line 167) | function compareLayerAndCanvas(layer, canvas, tol) {
function compareLayers (line 171) | function compareLayers(layer1, layer2, tol) {
function cloneAndCompareLayer (line 175) | function cloneAndCompareLayer(layer, tol) {
function cloneAndCompareLayerWithHit (line 182) | function cloneAndCompareLayerWithHit(layer, tol) {
function compareSceneAndHit (line 194) | function compareSceneAndHit(layer) {
function addContainer (line 198) | function addContainer() {
function showCanvas (line 206) | function showCanvas(canvas) {
function showHit (line 211) | function showHit(layer) {
FILE: test/unit/MouseEvents-test.ts
function remove (line 35) | function remove() {
FILE: test/unit/Node-cache-test.ts
function getColor (line 1236) | function getColor(pos) {
FILE: test/unit/Shape-test.ts
class CustomShape (line 1667) | class CustomShape extends Konva.Shape {
method foo (line 1668) | foo() {}
FILE: test/unit/Text-test.ts
function getOffsetY (line 14) | function getOffsetY(
FILE: test/unit/Transformer-test.ts
function simulateMouseDown (line 16) | function simulateMouseDown(
function simulateMouseMove (line 23) | function simulateMouseMove(
function simulateMouseUp (line 43) | function simulateMouseUp(tr: Transformer, pos = { x: 0, y: 0 }) {
FILE: test/unit/imagediff.ts
function getCanvas (line 13) | function getCanvas(width?, height?) {
function getSingleCanvas (line 18) | function getSingleCanvas() {
function getImageData (line 25) | function getImageData(width, height) {
function isImage (line 35) | function isImage(object) {
function isCanvas (line 38) | function isCanvas(object) {
function isContext (line 41) | function isContext(object) {
function isImageData (line 44) | function isImageData(object) {
function isImageType (line 53) | function isImageType(object) {
function isType (line 61) | function isType(object, type) {
function copyImageData (line 66) | function copyImageData(imageData) {
function toImageData (line 84) | function toImageData(object) {
function toImageDataFromImage (line 98) | function toImageDataFromImage(image) {
function toImageDataFromCanvas (line 109) | function toImageDataFromCanvas(canvas) {
function toImageDataFromContext (line 119) | function toImageDataFromContext(context) {
function toCanvas (line 125) | function toCanvas(object) {
function equalWidth (line 135) | function equalWidth(a, b) {
function equalHeight (line 138) | function equalHeight(a, b) {
function equalDimensions (line 141) | function equalDimensions(a, b) {
function equal (line 145) | function equal(a, b, tolerance, secondTol) {
function diff (line 174) | function diff(a, b, options) {
function diffEqual (line 177) | function diffEqual(a, b, options) {
function diffUnequal (line 195) | function diffUnequal(a, b, options) {
function checkType (line 249) | function checkType(...args) {
FILE: test/unit/test-utils.ts
function getContainer (line 46) | function getContainer() {
function addContainer (line 50) | function addContainer() {
function addStage (line 60) | function addStage(attrs?) {
function loadImage (line 78) | function loadImage(url, callback) {
function getPixelRatio (line 96) | function getPixelRatio() {
function get (line 100) | function get(element, content?) {
function compareCanvases (line 108) | function compareCanvases(canvas1, canvas2, tol = 1, secondTol?) {
function compareLayerAndCanvas (line 152) | function compareLayerAndCanvas(layer: Layer, canvas, tol?, secondTol?) {
function cloneAndCompareLayer (line 156) | function cloneAndCompareLayer(layer: Layer, tol?, secondTol?) {
function compareLayers (line 163) | function compareLayers(layer1: Layer, layer2: Layer, tol?, secondTol?) {
function createCanvasAndContext (line 172) | function createCanvasAndContext() {
function showHit (line 181) | function showHit(layer) {
function simulateMouseDown (line 191) | function simulateMouseDown(
function simulateMouseMove (line 206) | function simulateMouseMove(
function simulateMouseUp (line 223) | function simulateMouseUp(stage, pos) {
function simulateTouchStart (line 238) | function simulateTouchStart(stage, pos, changed?) {
function simulateTouchMove (line 275) | function simulateTouchMove(stage, pos, changed?) {
function simulateTouchEnd (line 313) | function simulateTouchEnd(stage, pos, changed?) {
type SimulatedPointerEvent (line 352) | type SimulatedPointerEvent = {
function simulatePointerDown (line 358) | function simulatePointerDown(stage: Stage, pos: SimulatedPointerEvent) {
function simulatePointerMove (line 369) | function simulatePointerMove(stage: Stage, pos: SimulatedPointerEvent) {
function simulatePointerUp (line 383) | function simulatePointerUp(stage: Stage, pos: SimulatedPointerEvent) {
function isClose (line 398) | function isClose(a, b, tol = 0.000001) {
Condensed preview — 162 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,048K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 567,
"preview": "# These are supported funding model platforms\n\ngithub: [lavrton]\npatreon: lavrton\nopen_collective: konva\nko_fi: # Replac"
},
{
"path": ".github/ISSUE_TEMPLATE.md",
"chars": 497,
"preview": "Thank you for submitting an issue!\n\nPlease make sure to check current open and closed issues to see if your question has"
},
{
"path": ".github/workflows/build.yml",
"chars": 440,
"preview": "name: Build\n\non:\n push:\n branches: [master]\n pull_request:\n branches: [master]\n\njobs:\n build:\n runs-on: ubun"
},
{
"path": ".github/workflows/prettier.yml",
"chars": 273,
"preview": "name: check formatting\non:\n pull_request:\njobs:\n fmt-check:\n runs-on: ubuntu-latest\n steps:\n - uses: action"
},
{
"path": ".github/workflows/release.yml",
"chars": 390,
"preview": "---\nname: 'tagged-release'\n\non:\n push:\n tags:\n - '*'\n\njobs:\n tagged-release:\n name: 'Tagged Release'\n ru"
},
{
"path": ".github/workflows/test-browser.yml",
"chars": 454,
"preview": "name: Test Browser\n\non:\n push:\n branches: [master]\n pull_request:\n branches: [master]\n\njobs:\n build:\n runs-o"
},
{
"path": ".github/workflows/test-node.yml",
"chars": 450,
"preview": "name: Test NodeJS\n\non:\n push:\n branches: [master]\n pull_request:\n branches: [master]\n\njobs:\n build:\n runs-on"
},
{
"path": ".gitignore",
"chars": 646,
"preview": "dist\nes\n.parcel-cache\ntest-build\ndocumentation\nanalysis\nnode_modules\nbower_components\nphantomjs.exe\ndocs\nhomedocs\njsdoc-"
},
{
"path": "CHANGELOG.md",
"chars": 43330,
"preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nThis project adheres to [Semantic Ver"
},
{
"path": "LICENSE",
"chars": 1172,
"preview": "MIT License\n\nOriginal work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)\nModified work Copyright (C) 2014 - prese"
},
{
"path": "README.md",
"chars": 8355,
"preview": "<p align=\"center\">\n <img src=\"https://konvajs.org/img/icon.png\" alt=\"Konva logo\" height=\"60\" />\n</p>\n\n<h1 align=\"center"
},
{
"path": "gulpfile.mjs",
"chars": 2827,
"preview": "import gulp from 'gulp';\nimport rename from 'gulp-rename';\nimport uglify from 'gulp-uglify-es';\nimport replace from 'gul"
},
{
"path": "package.json",
"chars": 4096,
"preview": "{\n \"name\": \"konva\",\n \"version\": \"10.2.3\",\n \"description\": \"HTML5 2d canvas library.\",\n \"author\": \"Anton Lavrenov\",\n "
},
{
"path": "release.sh",
"chars": 1388,
"preview": "#!/usr/bin/env bash\n\nset -e\nold_version=\"$(git describe --abbrev=0 --tags)\"\nnew_version=$1\n\n\nold_cdn_min=\"https://unpkg."
},
{
"path": "resources/doc-includes/ContainerParams.txt",
"chars": 312,
"preview": "* @param {Object} [config.clip] set clip\n * @param {Number} [config.clipX] set clip x\n * @param {Number} [config"
},
{
"path": "resources/doc-includes/NodeParams.txt",
"chars": 1141,
"preview": "@param {Number} [config.x]\n * @param {Number} [config.y]\n * @param {Number} [config.width]\n * @param {Number"
},
{
"path": "resources/doc-includes/ShapeParams.txt",
"chars": 4325,
"preview": "@param {String} [config.fill] fill color\n * @param {Image} [config.fillPatternImage] fill pattern image\n * @para"
},
{
"path": "resources/jsdoc.conf.json",
"chars": 635,
"preview": "{\n \"path\": \"ink-docstrap\",\n \"tags\": {\n \"allowUnknownTags\": true\n },\n \"plugins\": [\"plugins/markdown\"],\n\n \"templat"
},
{
"path": "rollup.config.mjs",
"chars": 618,
"preview": "// import resolve from 'rollup-plugin-node-resolve';\nimport typescript from 'rollup-plugin-typescript2';\n\nexport default"
},
{
"path": "src/Animation.ts",
"chars": 6448,
"preview": "import { glob } from './Global.ts';\nimport type { Layer } from './Layer.ts';\nimport type { IFrame, AnimationFn } from '."
},
{
"path": "src/BezierFunctions.ts",
"chars": 32254,
"preview": "// Credits: rveciana/svg-path-properties\n\n// Legendre-Gauss abscissae (xi values, defined at i=n as the roots of the nth"
},
{
"path": "src/Canvas.ts",
"chars": 5658,
"preview": "import { Util } from './Util.ts';\nimport type { Context } from './Context.ts';\nimport { SceneContext, HitContext } from "
},
{
"path": "src/Container.ts",
"chars": 16951,
"preview": "import type { HitCanvas, SceneCanvas } from './Canvas.ts';\nimport type { SceneContext } from './Context.ts';\nimport { Fa"
},
{
"path": "src/Context.ts",
"chars": 23615,
"preview": "import { Util } from './Util.ts';\nimport { Konva } from './Global.ts';\nimport type { Canvas } from './Canvas.ts';\nimport"
},
{
"path": "src/Core.ts",
"chars": 177,
"preview": "// enter file of limited Konva version with only core functions\nexport { Konva } from './_CoreInternals.ts';\nimport { Ko"
},
{
"path": "src/DragAndDrop.ts",
"chars": 5187,
"preview": "import type { Container } from './Container.ts';\nimport { Konva } from './Global.ts';\nimport type { Node } from './Node."
},
{
"path": "src/Factory.ts",
"chars": 6528,
"preview": "import type { Node } from './Node.ts';\nimport type { GetSet } from './types.ts';\nimport { Util } from './Util.ts';\nimpor"
},
{
"path": "src/FastLayer.ts",
"chars": 942,
"preview": "import { Util } from './Util.ts';\nimport { Layer } from './Layer.ts';\nimport { _registerNode } from './Global.ts';\n\n/**\n"
},
{
"path": "src/Global.ts",
"chars": 6114,
"preview": "/*\n * Konva JavaScript Framework v@@version\n * http://konvajs.org/\n * Licensed under the MIT\n * Date: @@date\n *\n * Origi"
},
{
"path": "src/Group.ts",
"chars": 875,
"preview": "import { Util } from './Util.ts';\nimport type { ContainerConfig } from './Container.ts';\nimport { Container } from './Co"
},
{
"path": "src/Layer.ts",
"chars": 14595,
"preview": "import { Util } from './Util.ts';\nimport type { ContainerConfig } from './Container.ts';\nimport { Container } from './Co"
},
{
"path": "src/Node.ts",
"chars": 96882,
"preview": "import type { Canvas } from './Canvas.ts';\nimport { HitCanvas, SceneCanvas } from './Canvas.ts';\nimport type { Container"
},
{
"path": "src/PointerEvents.ts",
"chars": 1663,
"preview": "import type { KonvaEventObject } from './Node.ts';\nimport { Konva } from './Global.ts';\n\nimport type { Shape } from './S"
},
{
"path": "src/Shape.ts",
"chars": 57642,
"preview": "import { Konva } from './Global.ts';\nimport { Transform, Util } from './Util.ts';\nimport { Factory } from './Factory.ts'"
},
{
"path": "src/Stage.ts",
"chars": 27801,
"preview": "import { Util } from './Util.ts';\nimport { Factory } from './Factory.ts';\nimport type { ContainerConfig } from './Contai"
},
{
"path": "src/Tween.ts",
"chars": 18168,
"preview": "import { Util } from './Util.ts';\nimport { Animation } from './Animation.ts';\nimport type { NodeConfig } from './Node.ts"
},
{
"path": "src/Util.ts",
"chars": 32287,
"preview": "import { Konva } from './Global.ts';\nimport type { Context } from './Context.ts';\nimport type { IRect, RGB, Vector2d } f"
},
{
"path": "src/Validators.ts",
"chars": 5560,
"preview": "import { Konva } from './Global.ts';\nimport { Util } from './Util.ts';\n\nfunction _formatValue(val: any) {\n if (Util._is"
},
{
"path": "src/_CoreInternals.ts",
"chars": 2300,
"preview": "// what is core parts of Konva?\nimport { Konva as Global } from './Global.ts';\n\nimport { Util, Transform } from './Util."
},
{
"path": "src/_FullInternals.ts",
"chars": 5836,
"preview": "// we need to import core of the Konva and then extend it with all additional objects\n\nimport { Konva as Core } from './"
},
{
"path": "src/canvas-backend.ts",
"chars": 728,
"preview": "import { Konva } from './_CoreInternals.ts';\n// @ts-ignore\nimport * as Canvas from 'canvas';\n\nconst canvas = Canvas['def"
},
{
"path": "src/filters/Blur.ts",
"chars": 11167,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Brighten.ts",
"chars": 1305,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Brightness.ts",
"chars": 894,
"preview": "import type { Filter } from '../Node.ts';\n\n/**\n * Brightness Filter.\n * CSS-compatible brightness filter that uses multi"
},
{
"path": "src/filters/Contrast.ts",
"chars": 1610,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Emboss.ts",
"chars": 6008,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Enhance.ts",
"chars": 3936,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Grayscale.ts",
"chars": 570,
"preview": "import type { Filter } from '../Node.ts';\n\n/**\n * Grayscale Filter\n * @function\n * @memberof Konva.Filters\n * @param {Ob"
},
{
"path": "src/filters/HSL.ts",
"chars": 3190,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/HSV.ts",
"chars": 3166,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Invert.ts",
"chars": 497,
"preview": "import type { Filter } from '../Node.ts';\n/**\n * Invert Filter\n * @function\n * @memberof Konva.Filters\n * @param {Object"
},
{
"path": "src/filters/Kaleidoscope.ts",
"chars": 8458,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Mask.ts",
"chars": 5181,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Noise.ts",
"chars": 1111,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Pixelate.ts",
"chars": 2794,
"preview": "import { Factory } from '../Factory.ts';\nimport { Util } from '../Util.ts';\nimport type { Filter } from '../Node.ts';\nim"
},
{
"path": "src/filters/Posterize.ts",
"chars": 1200,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/RGB.ts",
"chars": 2042,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/RGBA.ts",
"chars": 2451,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/filters/Sepia.ts",
"chars": 734,
"preview": "import type { Filter } from '../Node.ts';\n\n// based on https://stackoverflow.com/questions/1061093/how-is-a-sepia-tone-c"
},
{
"path": "src/filters/Solarize.ts",
"chars": 641,
"preview": "import type { Filter } from '../Node.ts';\n/**\n * Solarize Filter\n * @function\n * @name Solarize\n * @memberof Konva.Filte"
},
{
"path": "src/filters/Threshold.ts",
"chars": 1138,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Filter } from '../Node.ts';\nimport { Node } from '../Node.ts';\nim"
},
{
"path": "src/index.ts",
"chars": 68,
"preview": "import { Konva } from './_FullInternals.ts';\n\nexport default Konva;\n"
},
{
"path": "src/shapes/Arc.ts",
"chars": 4387,
"preview": "import { Factory } from '../Factory.ts';\nimport type { ShapeConfig } from '../Shape.ts';\nimport { Shape } from '../Shape"
},
{
"path": "src/shapes/Arrow.ts",
"chars": 6178,
"preview": "import { Factory } from '../Factory.ts';\nimport type { LineConfig } from './Line.ts';\nimport { Line } from './Line.ts';\n"
},
{
"path": "src/shapes/Circle.ts",
"chars": 1753,
"preview": "import { Factory } from '../Factory.ts';\nimport type { ShapeConfig } from '../Shape.ts';\nimport { Shape } from '../Shape"
},
{
"path": "src/shapes/Ellipse.ts",
"chars": 2625,
"preview": "import { Factory } from '../Factory.ts';\nimport type { ShapeConfig } from '../Shape.ts';\nimport { Shape } from '../Shape"
},
{
"path": "src/shapes/Image.ts",
"chars": 7520,
"preview": "import { Util } from '../Util.ts';\nimport { Factory } from '../Factory.ts';\nimport type { ShapeConfig } from '../Shape.t"
},
{
"path": "src/shapes/Label.ts",
"chars": 9351,
"preview": "import { Factory } from '../Factory.ts';\nimport type { ShapeConfig } from '../Shape.ts';\nimport { Shape } from '../Shape"
},
{
"path": "src/shapes/Line.ts",
"chars": 9690,
"preview": "import { Factory } from '../Factory.ts';\nimport { _registerNode } from '../Global.ts';\nimport type { ShapeConfig } from "
},
{
"path": "src/shapes/Path.ts",
"chars": 28053,
"preview": "import { Factory } from '../Factory.ts';\nimport { _registerNode } from '../Global.ts';\nimport type { ShapeConfig } from "
},
{
"path": "src/shapes/Rect.ts",
"chars": 1894,
"preview": "import { Factory } from '../Factory.ts';\nimport type { ShapeConfig } from '../Shape.ts';\nimport { Shape } from '../Shape"
},
{
"path": "src/shapes/RegularPolygon.ts",
"chars": 4074,
"preview": "import { Factory } from '../Factory.ts';\nimport type { ShapeConfig } from '../Shape.ts';\nimport { Shape } from '../Shape"
},
{
"path": "src/shapes/Ring.ts",
"chars": 2276,
"preview": "import { Factory } from '../Factory.ts';\nimport type { ShapeConfig } from '../Shape.ts';\nimport { Shape } from '../Shape"
},
{
"path": "src/shapes/Sprite.ts",
"chars": 8586,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Context } from '../Context.ts';\nimport type { ShapeConfig } from "
},
{
"path": "src/shapes/Star.ts",
"chars": 2981,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Context } from '../Context.ts';\nimport type { ShapeConfig } from "
},
{
"path": "src/shapes/Text.ts",
"chars": 32679,
"preview": "import { Util } from '../Util.ts';\nimport type { Context } from '../Context.ts';\nimport { Factory } from '../Factory.ts'"
},
{
"path": "src/shapes/TextPath.ts",
"chars": 17519,
"preview": "import { Util } from '../Util.ts';\nimport { Factory } from '../Factory.ts';\nimport type { Context } from '../Context.ts'"
},
{
"path": "src/shapes/Transformer.ts",
"chars": 58388,
"preview": "import { Util, Transform } from '../Util.ts';\nimport { Factory } from '../Factory.ts';\nimport { Node } from '../Node.ts'"
},
{
"path": "src/shapes/Wedge.ts",
"chars": 2791,
"preview": "import { Factory } from '../Factory.ts';\nimport type { Context } from '../Context.ts';\nimport type { ShapeConfig } from "
},
{
"path": "src/skia-backend.ts",
"chars": 1024,
"preview": "import { Konva } from './_CoreInternals.ts';\n// @ts-ignore\nimport { Canvas, DOMMatrix, Image, Path2D } from 'skia-canvas"
},
{
"path": "src/types.ts",
"chars": 1327,
"preview": "export interface GetSet<Type, This> {\n (): Type;\n (v: Type | null | undefined): This;\n}\n\nexport interface Vector2d {\n "
},
{
"path": "test/assets/tiger.ts",
"chars": 96162,
"preview": "export default [\n {\n fill: '#ffffff',\n stroke: '#000000',\n strokeWidth: 0.172,\n data: 'M-122.304 84.285C-12"
},
{
"path": "test/assets/worldMap.ts",
"chars": 123389,
"preview": "export default {\n shapes: {\n AE: 'M604.196,161.643l0.514-0.129l0,0.772l2.188-0.386l2.189,0l1.672,0.129l1.803-1.802l2"
},
{
"path": "test/bunnies.html",
"chars": 5224,
"preview": "<!doctype html>\n<html>\n <head>\n <style>\n body {\n margin: 0px;\n padding: 0px;\n }\n </style>"
},
{
"path": "test/ifame.html",
"chars": 368,
"preview": "<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <title>KonvaJS Sandbox</title>\n <meta\n name=\"vi"
},
{
"path": "test/import-test.cjs",
"chars": 179,
"preview": "// try to import only core\nconst Konva = require('../').default;\nrequire('../lib/canvas-backend');\n\n// just do a simple "
},
{
"path": "test/import-test.mjs",
"chars": 453,
"preview": "function equal(val1, val2, message) {\n if (val1 !== val2) {\n throw new Error('Not passed: ' + message);\n }\n}\n\n// tr"
},
{
"path": "test/manual/Blur-test.ts",
"chars": 5811,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Blur', fu"
},
{
"path": "test/manual/Brighten-test.ts",
"chars": 3041,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Brighten'"
},
{
"path": "test/manual/Contrast-test.ts",
"chars": 2177,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Filter Co"
},
{
"path": "test/manual/Emboss-test.ts",
"chars": 2068,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Emboss', "
},
{
"path": "test/manual/Enhance-test.ts",
"chars": 1660,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Enhance',"
},
{
"path": "test/manual/Grayscale-test.ts",
"chars": 1714,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Grayscale"
},
{
"path": "test/manual/HSL-test.ts",
"chars": 2690,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('HSL', fun"
},
{
"path": "test/manual/HSV-test.ts",
"chars": 3529,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('HSV', fun"
},
{
"path": "test/manual/Invert-test.ts",
"chars": 1704,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Invert', "
},
{
"path": "test/manual/Kaleidoscope-test.ts",
"chars": 2836,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Kaleidosc"
},
{
"path": "test/manual/Manual-test.ts",
"chars": 9286,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage, showHit } from '../unit/test-utils.ts';\n\ndescribe('"
},
{
"path": "test/manual/Mask-test.ts",
"chars": 843,
"preview": "import { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Mask', function () {\n // ==============="
},
{
"path": "test/manual/Noise-test.ts",
"chars": 966,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Noise', f"
},
{
"path": "test/manual/Pixelate-test.ts",
"chars": 2059,
"preview": "import { addStage, Konva, loadImage } from '../unit/test-utils.ts';\nimport { cloneAndCompareLayer } from '../unit/test-u"
},
{
"path": "test/manual/Posterize-test.ts",
"chars": 978,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Posterize"
},
{
"path": "test/manual/RGB-test.ts",
"chars": 2631,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('RGB', fun"
},
{
"path": "test/manual/RGBA-test.ts",
"chars": 1566,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('RGBA', fu"
},
{
"path": "test/manual/Sepia-test.ts",
"chars": 1712,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Filter Se"
},
{
"path": "test/manual/Solarize-test.ts",
"chars": 685,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Solarize'"
},
{
"path": "test/manual/Threshold-test.ts",
"chars": 982,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from '../unit/test-utils.ts';\n\ndescribe('Threshold"
},
{
"path": "test/manual-tests.html",
"chars": 2044,
"preview": "<html>\n <body>\n <div id=\"mocha\"></div>\n <!-- use mocha from CDN instead of local node_modules -->\n <!-- becaus"
},
{
"path": "test/node-canvas-global-setup.mjs",
"chars": 89,
"preview": "export async function mochaGlobalSetup() {\n await import('../src/canvas-backend.ts');\n}\n"
},
{
"path": "test/node-skia-global-setup.mjs",
"chars": 87,
"preview": "export async function mochaGlobalSetup() {\n await import('../src/skia-backend.ts');\n}\n"
},
{
"path": "test/performance/bunnies_native.html",
"chars": 3905,
"preview": "<!doctype html>\n<html>\n <head>\n <style>\n body {\n margin: 0px;\n padding: 0px;\n }\n </style>"
},
{
"path": "test/performance/creating_elements.html",
"chars": 2612,
"preview": "<!doctype html>\n<html>\n <head>\n <style>\n body {\n margin: 0px;\n padding: 0px;\n }\n </style>"
},
{
"path": "test/performance/jump-shape.html",
"chars": 4087,
"preview": "<!doctype html>\n<html>\n <head>\n <style>\n body {\n margin: 0px;\n padding: 0px;\n }\n </style>"
},
{
"path": "test/runner.js",
"chars": 11900,
"preview": "mocha.ui('tdd');\nmocha.setup('bdd');\nvar assert = chai.assert,\n konvaContainer = document.getElementById('konva-contain"
},
{
"path": "test/sandbox.html",
"chars": 1293,
"preview": "<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <title>KonvaJS Blur Comparison Sandbox</title>\n <met"
},
{
"path": "test/text-paths.html",
"chars": 11618,
"preview": "<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <title>KonvaJS text paths</title>\n <meta\n name="
},
{
"path": "test/typescript/event-delegation-test.ts",
"chars": 1261,
"preview": "// TypeScript type test for event delegation\n// This file tests that the new event delegation overload works correctly\n\n"
},
{
"path": "test/unit/Animation-test.ts",
"chars": 2947,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva } from './test-utils.ts';\n\ndescribe('Animation', function () {\n"
},
{
"path": "test/unit/Arc-test.ts",
"chars": 4457,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n createCanvasAndContext,\n compareLayerAndCanvas,\n asser"
},
{
"path": "test/unit/Arrow-test.ts",
"chars": 8604,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, cloneAndCompareLayer } from './test-utils.ts';\n\ndescribe('Arro"
},
{
"path": "test/unit/AutoDraw-test.ts",
"chars": 3969,
"preview": "import { assert } from 'chai';\nimport { addStage, isNode, Konva } from './test-utils.ts';\n\ndescribe('AutoDraw', function"
},
{
"path": "test/unit/Blob-test.ts",
"chars": 3374,
"preview": "import { assert } from 'chai';\nimport type { Line } from '../../src/shapes/Line.ts';\n\nimport { addStage, Konva, cloneAnd"
},
{
"path": "test/unit/Canvas-test.ts",
"chars": 1055,
"preview": "import { assert } from 'chai';\nimport { addStage, Konva } from './test-utils.ts';\n\ndescribe('Canvas', function () {\n //"
},
{
"path": "test/unit/Circle-test.ts",
"chars": 9089,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n createCanvasAndContext,\n compareLayerAndCanvas,\n loadI"
},
{
"path": "test/unit/Container-test.ts",
"chars": 64570,
"preview": "import { assert } from 'chai';\nimport type { Shape } from '../../src/Shape.js';\nimport { addStage, Konva, compareLayers,"
},
{
"path": "test/unit/Context-test.ts",
"chars": 2449,
"preview": "import { assert } from 'chai';\nimport { addStage, Konva } from './test-utils.ts';\n\ndescribe('Context', function () {\n /"
},
{
"path": "test/unit/DragAndDrop-test.ts",
"chars": 29984,
"preview": "import { assert } from 'chai';\nimport {\n addStage,\n Konva,\n simulateMouseDown,\n simulateMouseMove,\n simulateMouseUp"
},
{
"path": "test/unit/DragAndDropEvents-test.ts",
"chars": 14751,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n simulateMouseDown,\n simulateMouseMove,\n simulateMouseU"
},
{
"path": "test/unit/Ellipse-test.ts",
"chars": 2930,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n createCanvasAndContext,\n compareLayerAndCanvas,\n} from "
},
{
"path": "test/unit/Filter-test.ts",
"chars": 9110,
"preview": "import {\n addStage,\n Konva,\n cloneAndCompareLayer,\n loadImage,\n compareLayers,\n} from '../unit/test-utils';\n\ndescri"
},
{
"path": "test/unit/Global-test.ts",
"chars": 642,
"preview": "import { assert } from 'chai';\nimport { Konva } from './test-utils.ts';\n\ndescribe('Global', function () {\n // ========="
},
{
"path": "test/unit/Group-test.ts",
"chars": 2523,
"preview": "import { addStage, cloneAndCompareLayer, Konva } from './test-utils.ts';\nimport { assert } from 'chai';\n\ndescribe('Group"
},
{
"path": "test/unit/Image-test.ts",
"chars": 11687,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n compareLayerAndCanvas,\n loadImage,\n isNode,\n isBrowse"
},
{
"path": "test/unit/Label-test.ts",
"chars": 10095,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n cloneAndCompareLayer,\n isBrowser,\n} from './test-utils."
},
{
"path": "test/unit/Layer-test.ts",
"chars": 12418,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n simulateMouseDown,\n simulateMouseMove,\n simulateMouseUp,\n show"
},
{
"path": "test/unit/Line-test.ts",
"chars": 18000,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n createCanvasAndContext,\n compareLayerAndCanvas,\n compa"
},
{
"path": "test/unit/MouseEvents-test.ts",
"chars": 57190,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n simulateMouseDown,\n simulateMouseMove,\n simulateMouseU"
},
{
"path": "test/unit/Node-cache-test.ts",
"chars": 35400,
"preview": "import { assert } from 'chai';\nimport {\n addStage,\n Konva,\n compareLayerAndCanvas,\n cloneAndCompareLayer,\n compareL"
},
{
"path": "test/unit/Node-test.ts",
"chars": 96035,
"preview": "import { assert } from 'chai';\nimport type { Shape } from '../../src/Shape.ts';\n\nimport {\n addStage,\n simulateMouseDow"
},
{
"path": "test/unit/Path-test.ts",
"chars": 98495,
"preview": "import { assert } from 'chai';\n\nimport worldMap from '../assets/worldMap.ts';\nimport tiger from '../assets/tiger.ts';\n\ni"
},
{
"path": "test/unit/PointerEvents-test.ts",
"chars": 5576,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n simulatePointerDown,\n simulatePointerMove,\n simulatePo"
},
{
"path": "test/unit/Polygon-test.ts",
"chars": 541,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva } from './test-utils.ts';\n\ndescribe('Polygon', function () {\n "
},
{
"path": "test/unit/Rect-test.ts",
"chars": 7362,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n createCanvasAndContext,\n compareLayerAndCanvas,\n} from "
},
{
"path": "test/unit/RegularPolygon-test.ts",
"chars": 7136,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n cloneAndCompareLayer,\n assertAlmostEqual,\n createCanva"
},
{
"path": "test/unit/Ring-test.ts",
"chars": 2195,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, compareLayers } from './test-utils.ts';\n\ndescribe('Ring', func"
},
{
"path": "test/unit/Shape-test.ts",
"chars": 61726,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n simulateMouseDown,\n simulateMouseMove,\n simulateMouseUp,\n crea"
},
{
"path": "test/unit/Spline-test.ts",
"chars": 3164,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva } from './test-utils.ts';\n\ndescribe('Spline', function () {\n /"
},
{
"path": "test/unit/Sprite-test.ts",
"chars": 7510,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, loadImage } from './test-utils.ts';\n\ndescribe('Sprite', functi"
},
{
"path": "test/unit/Stage-test.ts",
"chars": 37235,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n simulateMouseDown,\n simulateMouseMove,\n simulateMouseUp,\n simu"
},
{
"path": "test/unit/Star-test.ts",
"chars": 3235,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva, cloneAndCompareLayer } from './test-utils.ts';\n\ndescribe('Star"
},
{
"path": "test/unit/Text-test.ts",
"chars": 78368,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n createCanvasAndContext,\n compareLayerAndCanvas,\n compa"
},
{
"path": "test/unit/TextPath-test.ts",
"chars": 69798,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n cloneAndCompareLayer,\n assertAlmostEqual,\n} from './tes"
},
{
"path": "test/unit/TouchEvents-test.ts",
"chars": 19526,
"preview": "import { assert } from 'chai';\n\nimport {\n addStage,\n Konva,\n simulateTouchStart,\n simulateTouchEnd,\n simulateTouchM"
},
{
"path": "test/unit/Transformer-test.ts",
"chars": 118366,
"preview": "import { assert } from 'chai';\nimport type { Transformer } from '../../src/shapes/Transformer.ts';\nimport type { Rect } "
},
{
"path": "test/unit/Tween-test.ts",
"chars": 9543,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva } from './test-utils.ts';\n\ndescribe('Tween', function () {\n //"
},
{
"path": "test/unit/Util-test.ts",
"chars": 2407,
"preview": "import { assert } from 'chai';\nimport { Konva } from './test-utils.ts';\n\ndescribe('Util', function () {\n it('test _prep"
},
{
"path": "test/unit/Wedge-test.ts",
"chars": 2039,
"preview": "import { assert } from 'chai';\n\nimport { addStage, Konva } from './test-utils.ts';\n\ndescribe('Wedge', function () {\n //"
},
{
"path": "test/unit/imagediff.ts",
"chars": 8284,
"preview": "import KonvaModule from '../../src/index.ts';\nexport const Konva = KonvaModule;\n\nvar TYPE_ARRAY = /\\[object Array\\]/i,\n "
},
{
"path": "test/unit/test-utils.ts",
"chars": 10048,
"preview": "import { assert } from 'chai';\nimport KonvaModule from '../../src/index.ts';\n\nexport const Konva = KonvaModule;\n\n// impo"
},
{
"path": "test/unit-tests.html",
"chars": 2505,
"preview": "<html>\n <body>\n <div id=\"mocha\"></div>\n <!-- use mocha from CDN instead of local node_modules -->\n <!-- becaus"
},
{
"path": "tsconfig.json",
"chars": 1118,
"preview": "{\n \"compilerOptions\": {\n \"outDir\": \"lib\",\n \"target\": \"ES2018\",\n \"lib\": [\"ES2019\", \"dom\"],\n \"module\": \"noden"
},
{
"path": "tsconfig.test.json",
"chars": 112,
"preview": "{\n \"extends\": \"./tsconfig.json\",\n \"compilerOptions\": {\n \"noEmit\": true\n },\n \"include\": [\"src\", \"test\"]\n}\n"
}
]
About this extraction
This page contains the full source code of the konvajs/konva GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 162 files (1.9 MB), approximately 645.0k tokens, and a symbol index with 1073 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.