Warpvas is inspired by the combination of "warped" and "canvas", meaning a distorted canvas.
This JavaScript library helps you efficiently implement 3D-like image distortion effects on Canvas 2D
. Using specific strategies, you can achieve various effects such as perspective, convex/concave lens effects.
npm install warpvas
# or
pnpm add warpvas
- Grid Split Strategy: Supports custom grid splitting algorithms to achieve perspective/wave/curved surface distortion effects through different strategies.
- Boundary Curve Control: Fine-tune boundary distortion effects through Bezier curve control points.
- Auxiliary Display Effects: Provides options to add split lines and split points on the distorted image to assist in observing the distortion effects.
- Input/Output Limitations: Provides options to control the input and output dimensions of distorted images for better quality and efficiency control, also preventing performance issues from oversized images.
- Multiple Rendering Engines: Switch freely between WebGL (high performance) and Canvas2D (high compatibility) rendering modes.
- Safe Rendering Mode: Automatically falls back to Canvas2D rendering when WebGL rendering fails, ensuring basic functionality.
- State Serialization: Supports serializing distortion states to base64 strings for easy saving/restoring of complex distortion states.
// Create using an image
const img = new Image();
img.src = 'example.jpg';
img.onload = () => new Warpvas(img);
// Create using canvas with a 2x2 grid
const canvas = document.createElement('canvas');
const warpvas = new Warpvas(canvas, 2, 2);
// Move the top-left vertex of region (0,0) to (50,50)
const warpvas = new Warpvas(canvas);
warpvas.updateVertexCoord(
0, // row index
0, // column index
'tl', // vertex position (top-left)
{ x: 50, y: 50 }, // new position
true // recalculate curve
);
// Create an arc-shaped bottom boundary
const warpvas = new Warpvas(canvas);
warpvas.updateRegionBoundCoords(
0, // row index
0, // column index
'bottom', // direction
[
{ x: 0, y: canvas.height }, // start point
{ x: canvas.width / 3, y: canvas.height / 2 }, // control point 1
{ x: (canvas.width / 3) * 2, y: canvas.height / 2 }, // control point 2
{ x: canvas.width, y: canvas.height }, // end point
]
);
// Add a split point at the center of the first region (0,0) with 10% tolerance
const warpvas = new Warpvas(canvas);
const region = warpvas.originalRegions[0][0];
warpvas.splitRegionByPoint(
0, // row index
0, // column index
{
x: (region.tl.x + region.br.x) / 2, // region center X coordinate
y: (region.tl.y + region.br.y) / 2, // region center Y coordinate
},
0.1 // 10% tolerance
);
// Remove the region at row 1, column 1
const warpvas = new Warpvas(canvas);
warpvas.removeRegion({
row: 1,
column: 1
});
// Control rendering effects and debug view display
const warpvas = new Warpvas(canvas);
warpvas.setRenderingConfig({
// padding: 10, // Set 10px padding
// enableAntialias: true, // Enable anti-aliasing
// enableSafeRendering: true, // Enable safe rendering mode
// enableContentDisplay: true, // Show distorted content
enableGridDisplay: true, // Show distortion grid
enableGridVertexDisplay: true, // Show grid vertices
gridColor: { r: 206, g: 102, b: 91, a: 1 } // Use coral red grid
});
// Set sparse grid to improve performance
const warpvas = new Warpvas(canvas);
warpvas
.setSplitUnit(0.2)
.setRenderingConfig({
enableGridDisplay: true,
gridColor: { r: 206, g: 102, b: 91, a: 1 }
});
To apply perspective mode, you need to install the warpvas-perspective package separately.
import WarpvasPerspective from 'warpvas-perspective';
const warpvas = new Warpvas(canvas);
warpvas.setSplitStrategy({
name: 'custom',
execute: (warpvas) => {
// Use default strategy calculation result
// return Warpvas.strategy(warpvas);
// Use perspective strategy calculation result
return WarpvasPerspective.strategy(warpvas);
}
});
When processing large images, you can use this method to limit the maximum size of the input canvas. The system will automatically scale the image proportionally within the limits to improve performance and reduce memory usage.
const warpvas = new Warpvas(canvas);
// Limit input height to 100px, width scales proportionally
warpvas.setInputLimitSize({
height: 100
});
Limit the maximum size of the distorted output canvas. When distortion results in an oversized canvas, the system will automatically scale the result proportionally within limits to prevent rendering failures due to memory constraints.
const warpvas = new Warpvas(canvas);
// Limit output height to 100px, width scales proportionally
warpvas.setOutputLimitSize({
height: 100
});
const warpvas = new Warpvas(canvas);
// Enable Canvas2D rendering
warpvas.setRenderingContext('2d');
// Enable WebGL rendering
warpvas.setRenderingContext('webgl');
const canvas = document.createElement('canvas');
const warpvas = new Warpvas(canvas);
await warpvas.renderWithWorker();
Check out the project's online demo or directly view the project API documentation.
This project is licensed under the MIT License - see the LICENSE file for details.
huanjinliu - huanjin.liu@foxmail.com