pikasojs / pikaso Goto Github PK
View Code? Open in Web Editor NEWSeamless, headless and fully tested HTML5 Canvas library
Home Page: https://pikaso.app
License: MIT License
Seamless, headless and fully tested HTML5 Canvas library
Home Page: https://pikaso.app
License: MIT License
I think this is important to be able save the current state to json to be able save that and restore that later by importing the exported json
Sir I want to show the height width of a shape while I am drawing it on x and y axis of the shape, and it should vary when I increase or decrease height width while drawing, also it should vanish after I have completed drawing the shape.
Hello
I'm trying to get started using Pikaso with Svelte.
This is what I'm trying:
<script lang="ts">
import Pikaso from 'pikaso'
import { onMount } from 'svelte';
let editor;
onMount(async () => {
editor = new Pikaso({
container: editor,
});
editor.shapes.polygon.insert({
x: 250,
y: 250,
radius: 90,
sides: 6,
fill: "tomato",
});
});
</script>
<div bind:this={editor}>
</div>
However, I'm getting this error:
global is not defined
@http://localhost:3000/node_modules/.vite/pikaso.js?v=3f3cda72:9974:1
Any help is appreciated.
I know this is a must need for designers. But just a nice to have, so, low priority.
As seen in this Konva.js demo, the ability to precisely snap to other shapes, helps designers create pixel perfect designs in a shorter cycles.
We can add following functionalities as part of this:
I am not sure where the code goes, will leave that to your judgement.
Clicking text will not be selected
It would be lovely if Layer
s had a name or id to uniquely identify it. This would be handy when naming the layer inside the Canvas Editor.
Maybe create a LayerModel
or something...
Lines 28 to 297 in 48d0abd
Having the ability to group is a necessity. Konva suggests having fewer layers, whereas Pikaso offers only one. This means managing shapes through Groups is required.
I have drafted an API in my mind (it might change)
Board class will offer a groups
field that is probably created from GroupManager
so editor.board.groups.list
will provide list of the created groups, for example.
editor.board.groups.create('<name>')
or editor.board.groups.remove('<name>')
will create and remove groups.
ShapeModel#setGroup
has to manage it for created shapes. Probably, it will have to create the group automatically if it doesn't exist and move it to another group if necessary.
When the users moves a label on top of an existing shape, mouse events seems to be propagating to the underlying shape. Backspace keystroke used to edit the inline text will cause the shape beneath it to be deleted accidentally.
In the demo, https://pikaso.netlify.app/
e.cancelBubble = true
in the inlineEdit
function that's triggered on a dblclick
. This does prevent the double click event from propagating.Describe the bug
When rotating the shape, MeasurementTag's position is messed up
How To Reproduce
Rotate the shape while MeasurementTag is active
Screenshots
https://user-images.githubusercontent.com/334716/173230955-126ebdb9-a384-4664-8ad1-371b483a58d7.mp4
Version
2.7.1
i am creating a rect. of full with and height according to window/document.
now i have no space outside that rect. to draw an other one.
basically it will be like room and i will create multiple object like a new rect. or a line over it.
so in this case i want to know how could that be possible.
or
or
or there should be a way that a when you hover over an object selection cursor appears so it can be edited.
but cursor should only come when you click on any object not hovering over it.
when you click on object then you can resize that object.
As explained in title, when i try to load an image from external URL i receive an error (CORS)
In FabricJS it's possible by using the crossOrigin: "annonymous" option.
I am implementing a complex drawing solution using Pikaso. Unfortunately, there doesn't seem to be anyway to reflect the drawn elements in state outside of Pikaso's internal state.
I need to keep the newly drawn items' information in my own component's state, however, it seems that there is no way to currently do it except doing editor.export.toJSON() and picking the latest item from there.
In the product I'm building, something you have drawn right now can be deleted by someone else sharing your session in the next second (just like any collaborative editing apps). For this reason, I must always keep a "clone" of Pikaso state in memory.
One way to do this is to constantly do editor.export.toJSON() on each and every event that the user is doing like adding/editing/removing/showing/hiding any node.
Do you think that that's the "right" way to do it? I wonder if it's good for performance when it comes to a board that has too many items rendered.
Describe the solution you'd like
I'm not sure if this is a good solution but maybe it would be a good idea to make private nodeToObject
property of JsonExport class to be available as a standalone function, so that one can use it to mutate their state on each board event (by making sure that every "create" results in adding nodeToObject(currentItem)
to custom state.
react-konva makes it really easy to have React state representing the shapes and mapping over them to draw Canvas items. This ensures that if some outside event or service deletes an object from the react state list, the canvas automatically makes that Konva node disappear. Of course, I will develop the reconciling (adding/removing specific nodes based on outside events) myself in the product's business logic for Pikaso, but I only need your insight on what's the best way to maintain that state to begin with. That if exporting the whole board as JSON at every event is alright or should I be doing something else.
If there is a solution that you recommend which needs changes to Pikaso itself I would be happy to work on it.
Is your feature request related to a problem? Please describe.
I am trying to use certain method for setting zIndex of shape.
Currently this feature is not available on pikaso, however Konva has that ability to set zIndex.
https://konvajs.org/docs/groups_and_layers/zIndex.html
Problem started when I created one editor with Image and Text on top of that. Later I exported JSON and when I import that JSON back into editor then sequence or zindex is lost, image always comes on top and text on bottom hiding behind it. Having an option to set specific z index will solve the issue.
Describe the solution you'd like
If there is a way to access the native Konva shape method then it could solve lot of issues.
Describe alternatives you've considered
If it is not possible then there should be specific way to set index of object.
Currently shape.node has index property however there is no way to change the index of objects if we want to move one on top of other.
I'm trying to use Pikaso with Sveltekit. I've tried several variations of the following but all generally result in the same error.
Any direction is greatly appreciated.
<script lang="ts">
import Pikaso from 'pikaso'
import { onMount } from 'svelte';
let editor;
onMount(async () => {
let pikaso = new Pikaso({
container: editor,
});
pikaso.shapes.polygon.insert({
x: 250,
y: 250,
radius: 900,
sides: 6,
fill: "tomato",
});
});
</script>
<div bind:this={editor}>
</div>
Uncaught (in promise) TypeError: canvas.createCanvas is not a function
createCanvasElement index.all.js:10383
Canvas$1 index.all.js:1614
SceneCanvas index.all.js:1676
_buildDOM index.all.js:4161
Stage index.all.js:3615
Board2 index.all.js:12137
init index.all.js:14282
Pikaso2 index.all.js:14219
instance Canvas.svelte:8
run index.mjs:18
mount_component index.mjs:1802
flush index.mjs:1067
init index.mjs:1894
Root root.svelte:920
createProxiedComponent svelte-hooks.js:341
ProxyComponent proxy.js:242
Proxy<Root> proxy.js:349
initialize start.js:702
_hydrate start.js:1602
start start.js:1639
<anonymous> (index):230
Is your feature request related to a problem? Please describe.
I would like to implement NodeJS Environment support so that something like this can be implemented
https://github.com/konvajs/konva#4-nodejs-env
We are looking to generate the image dynamically by replacing certain tokens in JSON.
We would be generating canvas and drawings that would be exported as JSON later on.
Later on we could replace some placeholder texts in JSON file to generate the fully dynamic image using node js environment.
Describe the solution you'd like
Konva supports the stage creation in nodejs environment. It would be really nice to have something like that in Pikaso.
https://github.com/konvajs/konva#4-nodejs-env
Example code in Konva
const Konva = require('konva/cmj').default;
let fs = require('fs');
let jsonContent = fs.readFileSync(process.cwd() + "/stage.json").toString();
jsonContent = jsonContent.replace("{{first_name}}", "Hussain");
var stage = Konva.Node.create(jsonContent);
let base64Data = stage.toDataURL();
base64Data = base64Data.replace(/^data:image\/png;base64,/, "");
fs.writeFileSync(process.cwd() + "/stage.png", base64Data, 'base64');
Can the zoom function of the canvas be realized? When the mouse rolls over the canvas, the canvas can be enlarged or shrunk, and the user can see more clearly. I tried to control the canvas size using the wheel event on the listening stage, but the mouse shifted when the box was selected
This is a feature request to allow users to resize "label" similar to "text". If possible allow to edit "text" as it is already resizable.
More details I have posted in this discussion
this.image = new ImageModel(board, image, {
selectable: false,
history: false
})
this.overlay = new RectModel(board, overlay, {
selectable: false,
history: false
})
The background constructor has no way of passing a flag for setting the background as selectable, incase of the need to fill/change background.
Check discussion
I think this is mandatory to provide a global config to be able config every minor detail like transformer shape, selection behavior, default colors and etc
This is just an accessibility feature, though, low priority, it goes well with #28, so, I will add it for discussion.
We might need a formal keyboard api, that will help access all core functionalities via the Keyboard. Especially features like zoom in/out.
Currently, we can focus on generic keyboard shortcuts; avoiding mac shortcuts, and implementing
SHORTCUTS
Undo
Redo
Canvas
Zoom in
Zoom out
Zoom to actual size
Zoom to fit canvas
Layers
Duplicate layer
Constrain proportions
RESIZE LAYER
Delete Layer
Nudge position by 1px
Nudge position by 10px
Bring forward
Send backward
Text Label and Shapes seem to behave differently when created and when imported from JSON.
They cant be resized/transformed as the handles/transformers are missing.
Check in this demo: https://bnbear.bubbleapps.io/version-test/edit_template/temp1?project_id=1624555421210x555044648605350200 (Click on 'New Layer' to add a shape or text, and compare to shapes that exist on the canvas, loaded from JSON)
We may need an accessible way to switch this on/off, depending on use-case.
When I was using Pikaso, I found a canvas leak problem on webbiew/safari of iOS and Safari of Mac and Windows. It's not a bug of Pikaso or Konva-JS, it may be an bad implementaion of iOS webview.
But using pikaso in some way will cause the canvas leak ,and reach the limi of 384M memory of iOS,then no canvas can be operated on the web page.
Let me describe the detail of the problem.
(2) The setImageFromUrl function. It will create a history state with a konva stage and a snapshot will be clone from the stage. The snapshot is a local variable, so the canvas of the snapshot will cause a leak.
Description:
Both Vertical and Horizontal Flip breaking when the Background Image or other shapes are rotated
Always Reproducible:
Yes
Version
1.0.0-beta.13
Browser
All browsers
Currently as it is, the app developer is in-charge of the zooming functionality. Without the snap to grid/shape functionality, using the keyboard becomes the only option, while keeping track of the x
and y
variables.
I am not sure if we have a keyboard shortcut map, but that can also be added later.
As seen in this Konva.js demo.
In this functionality, we want the area around the canvas to be part of the <canvas/>
, instead of the current <div>
.
shape
/board
, or background image
/overlay
should lose focus/selection when i click outside the stage.We can break down this to smaller issues, if we get to that point, or if this feature is within Pikaso's focus.
If we can have this feature, it would be easy to create a feature such as:
Can't import classes SvgModel & SvgDrawer
import { SvgDrawer, SvgModel } from 'pikaso';
My IDE automatically add these imports:
import { SvgDrawer } from 'pikaso/esm/shape/drawers/SvgDrawer'; import { SvgModel } from 'pikaso/esm/shape/models/SvgModel';
I got this error on compiling:
Module not found: Error: Can't resolve 'pikaso/esm/shape/drawers/SvgDrawer'
Maybe the SgvDrawer and SvgModel exports are missing in index.all.ts ?
Additional context
Use in Angular
Version
"pikaso": "^2.7.5"
Currently, there is no way for persons new to the TypeScript/Node.js/React.js ecosystem to setup/contribute.
We may need a policy on the following:
Describe the bug
Create Image shape in NodeJs is not working
Reference Error: File is not defined
How To Reproduce
const { Pikaso } = require('pikaso')
const editor = new Pikaso({
width: 500,
height: 500
})
editor.shapes.image.insert('<url>')
Version
2.7.1
I know we have discussed this is #24. But I feel that we should have default names for each shape created.
In #24 you had suggested that we should pass the name such as:
const rect = editor.shapes.rect.insert({
name: '<name>',
// rest config
})
and access that through console.log(rect.node.name())
, or change the name through rect.node.name('<new name>')
I feel that this leaves room for bugs, due to missing this in Pikaso's documentation.
I suggest we add a method renameShape()
and add
public insert(config: Konva.ArrowConfig): ArrowModel {
return super.insert({
name: `${type}`
...config
})
}
and duplicate take the name of the original, and postfix -copy
, e.g, triangle
to triangle-copy
.
Two shapes can have the same name however...
I plan to change the way in which Pikaso creates the container, to give the possibility to center the image anything natively with an algorithm instead of using a css trick to center the background image to the stage, and additionally the function of zoomIn and zoomOut
Background.ts:125
if (options.size === 'resize') {
this.board.centerAndFitShape(this.image.node)
}
/**
* Centers the stage and fit especific shape
* @param {Konva.Shape} shape
* @param {number} padding = 2
* @example
* ```ts
* editor.board.centerAndFitShape(Konva.Shape)
* ```
*/
centerAndFitShape(shape, padding = 2) {
padding = padding || 0
const rawShapeRect = shape.getClientRect({ relativeTo: this.stage }), // Note: getClientRect gives size based on scaling - we want unscaled size so use 'relativeTo: stage' param to ensure consistent measurements.
paddedShapeRect = {
x: rawShapeRect.x - padding,
y: rawShapeRect.y - padding,
width: rawShapeRect.width + (2 * padding),
height: rawShapeRect.height + (2 * padding)
},
viewRect = {
width: Math.min(this.stage.width(), this.container.offsetWidth),
height: Math.min(this.stage.height(), this.container.offsetHeight)
},
widthRatio = viewRect.width / paddedShapeRect.width, heightRatio = viewRect.height / paddedShapeRect.height,
scale = widthRatio > heightRatio ? heightRatio : widthRatio,
centeringAjustment = {
x: (viewRect.width - paddedShapeRect.width * scale) / 2,
y: (viewRect.height - paddedShapeRect.height * scale) / 2
},
finalPosition = {
x: centeringAjustment.x + (-paddedShapeRect.x * scale),
y: centeringAjustment.y + (-paddedShapeRect.y * scale)
}
this.stage.to({
x: finalPosition.x,
y: finalPosition.y,
scaleX: scale,
scaleY: scale,
duration: 0.1
})
}
/**
* Zoom the stage
* @param {number} scaleBy
* @see zoomIn = 1.2, zoomOut = 0.8
*/
zoom (scaleBy) {
const oldScale = this.stage.scaleX()
// Calculate the center of the stage
const pos = {
x: this.stage.width() / 2,
y: this.stage.height() / 2
}
// Calculate the position of the mouse relative to the stage
const mousePointTo = {
x: pos.x / oldScale - this.stage.x() / oldScale,
y: pos.y / oldScale - this.stage.y() / oldScale
}
// Calculate the new scale of the stage
const newScale = Math.max(0.05, oldScale * scaleBy)
// Calculate the new position of the stage to keep it centered
const newPos = {
x: -(mousePointTo.x - pos.x / newScale) * newScale,
y: -(mousePointTo.y - pos.y / newScale) * newScale
}
// Update the stage with the new position and scale
this.stage.to({
x: newPos.x,
y: newPos.y,
scaleX: newScale,
scaleY: newScale,
duration: 0.1
})
}
Is your feature request related to a problem? Please describe.
Currently, when you load from an Image from a URL, the size of the image overrides all other settings of width and height. This breaks the UI, as the developer is forced to resize the image before importing it into Pikaso.
Describe the solution you'd like
If we can have the loadFromUrl
or setImageFromUrl
to accept a resize
value, which can be a percentage of its aspect ratio, or actual width
and height
values that can be respected.
Describe alternatives you've considered
The image imported should not be larger than scene area, unless explicitly zoomed.
Is your feature request related to a problem? Please describe.
Need a way to destroy the Pikaso instance so that it no longer listens for events or any adjacent code
Describe the solution you'd like
In the main instance add a method called destroy similar to the one in KonvaJS
class Pikaso {
constructor(config) {
// constructor implementation
}
// other methods implementation
destroy() {
// stop listening to events
this.off();
// other cleanup operations
// ...
// set instance properties to null to aid garbage collection
for (let prop in this) {
if (this.hasOwnProperty(prop)) {
this[prop] = null;
}
}
}
}
There is no copy/paste functionality, but a duplicate shape
feature would be nice to have.
x
and y
value of the duplicate, by a small offset (5px or 10px)Board
.Is your feature request related to a problem? Please describe.
Currently, once you have set the background items to be selectable;
editor.board.background.image.isSelectable = true;
editor.board.background.overlay.isSelectable = true;
There is no way of setting if the image is resizable
or draggable
on creation.
Describe the solution you'd like
selectable
and not draggable
at the same time.Describe alternatives you've considered
Additional context
https://codesandbox.io/s/59-ability-to-resize-imported-image-forked-idxry0
It seems Flexible Rectangle and Circular cropper become laggy after code compilation on Production
Browsers: Chrome, Firefox and Brave
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.