Coder Social home page Coder Social logo

api-discussion's People

Contributors

asturur avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

samkenxstream

api-discussion's Issues

CLIPPING API

Clipping API

Current in fabric 2.2.3

Fabricjs as of now has a deprecated (canvas/object).clipTo = function(ctx) {} that allows you to write a custom function that will be run before rendering in order to define a clipping path for the next object.

Why is drepacted

The current method is depreacted because

  • Is hard to serialize/restore because of possible dependencies from external variables
  • requires the dev to use the plain canvas api and requires too much understanding of the fabricJS render pipeline to be used with confidence
  • Canvas support one clip path at time, so for example a group and an inner object cannot both have a clipTo function
  • storing functions and eval them back make some people concerned
  • is not possible to evaluate when a clipping function change and so the caching should be disable automatically.
  • Is not enough to build an SVG clipPath support
  • A free function will not allow an easy ( or just possible ) SVG export
  • Most of the example of people using it, they try to use the render method of existing shapes as clipping function

What we will have next

Currently there is an implementation in a PR here:
fabricjs/fabric.js#4786
This implementation was in my head since caching and works in this way

  • A clippath is define by a fabricObject, a rect, a circle, a group with many object
  • An Object that has a clipPath will be drawn like if it is cached, even if caching is disabled
  • The clipPath object uses top,left,scale.... to position itself starting from the center of the object that is clipping
  • A property can be provided, to be decided and understood, that allow the clipPath to scale positioning to the parent ( clip object A with a Rect that is fixed on the canvas, or to the group in which A is )
  • The clipPath object gets painted on a separate canvas with BLACK fill and no stroke.
  • The clipPath canvas gets painted over the cached object with a global composite operation that will remove the pixels outside the clipPath
  • The clipPath canvas gets trashed after the paint operation, while the cached one is mantained as always. ( this must be decided i m not sure what is best )

This provide the following benefits over the clipTo approach:

  • serialization is and restore is like normal fabric objects
  • should be easier to use, everyone understand rect and circle or a path.
  • transformations from object to canvas are handled by fabricJS.

Three Layer System for objects.

The problem to solve

  • When attempting to add in more advanced features on top of fabric's stock featureset (A goal preferred to adding advanced editor functionality to the core fabric product), object layering frequently becomes an issue.
  • Overlays are currently limited to images and fabric.Patterns.
  • Overlays and backgrounds have kind of odd APIs whose names don't reflect their capabilities (canvas.setOverlayColor takes a pattern, for example)

Current situation

  1. I would like to render a control object above my fabric objects. I don't want to have to worry about shuffling objects around to make sure it is always on top. My control is neither an image or a color/pattern (all that is supported via overlay), so I have difficulty writing it.

  2. I would like to render a control under my fabric objects. The same issues apply, and the only consistent recourse is canvas.setBackgroundColor/setBackgroundImage

  3. Some of these issues can be solved via after:render, but not all. after:render paints over fabric's stock controls and doesn't give you the object caching properties of fabric.

Proposal

Convert the current fabric system, which contains a single array of objects, a single background, and a single overlay, into a three array system.

Instead of just canvas.getObjects(), there would be canvas.getBackgroundObjects() and canvas.getOverlayObjects() as well, as well as functions to add, reorder, and remove objects from those arrays.

There would be more powerful options available to those who want to write their own canvas based controls (literally) on top of fabric, and we could simplify some mild confusion in the API. If the arrays are empty, we could simply not render them, making it not a huge performance hit.

Breaking changes

  1. canvas.setOverlayColor/Image and canvas.setBackgroundColor/Image would enter a deprecation cycle. This would probably be a big break for a lot of applications, and we might want to maintain utility functions canvas.setBackground() and canvas.setOverlay() to facilitate the learning curve and migration of existing applications.
  2. Examples would need to be updated.

Patterns api improvements

The problem to solve

Pattern API can be improved.

Current situation

Pattern source as of now accept a URL, an drawable ( canvas or img ... or video ) or a function.
This i confusing.

Pattern by function with a custom canvas is hardly serializable
Dynamic patterns do not invalidate cache and are hard to handle
People ask for functionalities that can't be obtained if not with the custom canvas

Proposal

A pattern source could accept as source a fabricObject,
Image or a Group compose by more objects.
The Object could use the dirty property and the cache system to understand when is changed and so it needs a repaint. The repaint would happen with the cache logic, and a custom canvas would be generated under the hood for the pattern.

Serialization in this case would be straight forward.

Patterns could use at least some new props:

  • scaleX
  • scaleY
  • angle
  • skewX
  • skewY

To transform the pattern before using it
This would probably NOT work for text out of the box and would require some extra code to normalize the situation.

Patterns could also use a property, to be named to counter the effect of object scaling, so when an object is scaled, the pattern would repeat itself to fill the new space ( again won't work with text )

Breaking changes

This would be a breaking change, to handle it probably we could create a Pattern2 object, deprecate Pattern, and then keep patterns called Pattern2 forever.

Alternatively add the code to Pattern to handle the new source and deprecate the old sources types

Callback methods for finer control on object changes in the canvas

I've been trying to implement undo functionality for objects and needed some robust way to know when user changes the canvas object on canvas.

What I had in mind:

Right now, Canvas.onBeforeScaleRotate exists already. We can add Canvas.onBeforeMove and probably even Canvas.onBeforeSkew.

Once these methods are there, it should be pretty easy to provide implementations of these callbacks to trigger custom object methods.

For example:

fabric.StaticCanvas.prototype.onBeforeScaleRotate = function (target) {
	if (target.__corner === 'mtr') {
		this.trigger('object:before:rotate', { target: target });
		target.trigger('before:rotate');
	} else {
		this.trigger('object:before:scale', { target: target });
		target.trigger('before:scale');
	}
};

And we can then put state variables in the object's event listeners to know if an object is being moved/scaled/rotated or skewed. Once the state variables are set, we'll be able to predict what change happened on the object exactly by listening on the modified event. We'll be able to have event handlers for moved, scaled, rotated, skewered along with moving, scaling, rotating, skewing, before:rotate, before:scale, before:move, before:skew.

My pull request here adds Canvas.onBeforeMove callback.

I am unsure if these custom functions that give control belong in the library or can be implemented by everyone for themselves as needed. But, your thoughts on this are welcome.

Thanks.

Easier and more intuitive scaling for simple shapes.

The problem to solve

Presently, if you use drag handles to 'scale' a Rect, polygon, etc, its internal height and width stay the same. This is fine, except in situations where you want to say, add a stroke. It will be added incongruently and inconsistently if the shape is non-uniformly scaled. As well, setting a stroke of '5' on a object with a scale of 3x is actually setting a stroke of 15.

Current situation

We are implementing post modification edits to resize objects based on the scale provided. This works fine, but is a lot of boilerplate code, especially for complex objects like Poly{things}.

Proposal

This kind of functionality feels like it should be the default, or at least a toggleable option.

Breaking changes

A lot. I would estimate a lot of projects include this boilerplate code, and it would potentially malfunction and double or triple scale the object. Could be avoided by making it a toggle on instead of a toggle off.

More events callback and hooks, api normalization

What are we trying to address

FabricJS offers a range of events for objects and canvas

   * Root object class from which all 2d shape classes inherit from
   * @class fabric.Object
   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}
   * @see {@link fabric.Object#initialize} for constructor definition
   *
   * @fires added
   * @fires removed
   *
   * @fires selected
   * @fires deselected
   * @fires modified
   * @fires rotating
   * @fires scaling
   * @fires moving
   * @fires skewing
   *
   * @fires mousedown
   * @fires mouseup
   * @fires mouseover
   * @fires mouseout
   * @fires mousewheel
   * @fires mousedblclick
   *
   * @fires dragover
   * @fires dragenter
   * @fires dragleave
   * @fires drop

Those events are of course not javascript events even if they get fired as a consequence of JS events with mouse and mousewheel and from particular situations.

Other than that some other events are implemented via callbacks ( like onBeforeScaleRotate ).

Now those events let you react to user interaction, and are meant exclusively to let you run your code on user actions you can't control beforehand ( so just to be clear, using a modified event with statefull true to catch a color change from a UI button is sort of wrong, even if you are free to do what you want, if you have button on the UI, put the code you need in the onclick handler ).

There is long standing problem that is that those events are fired in a particular moment, mostly after all the fabricJS logic has already happened and if you want to change it you have to revert it in some way.

When developing professionally with FabricJS i sometimes feel like more events and more detials inside the event would be useful.

What a user can do without a dev controls is usually:

  • Initiating a transform
  • mouse events

What i would like to know is often when those things are about to happen.

A possible change

onBeforeScaleRotate is a really little usefull thing, i believe that an event like
'object:beforeTransform' and maybe a 'beforeTransform' that let you know what object is about to start a transform and what kind of transform is about to fire may be useful and solve a variety of situations.

Also adding events like 'before:mousedown' and 'before:mouseup' ( uncertain about mousemove ) to fire before all the fabric logic is going to happen can help to control your canvas situation an particular features better.

Breaking changes

OnBeforeScaleRotate would be deprecated, in the JSDOC of the function i would add a snippet to call it with the new event code, in fabricJS 3.0 the function would be removed and just the information left.

Introducing automated visual testing in fabricJS

To trust more the changes that happens in the library we need at least some automated visual testing.

I would like to have a test stack that execute some code on a canvas ( node-canvas or browser canvas ) and then compare with a reference screenshot.

I would avoid using puppet and taking browser screenshots, i would rather using something that can compare images by pixels.

On fabricJS website kangax setup this long ago:

http://fabricjs.com/test/automated_visual/stroke.html

Also our tests suite for now runs on qunit that allows us to work on node and on browser, using testem to craft a simple indexhtml page with tests, and run on node, chrome and firefox ( and potentially other headless browsers if something for ie11/safari would ever come out).

Someone here has suggestion or is willing to take on the tast to translate that automated visual testing in some script that can blend with our current setup, or expand our current setup?

Improving Touch Gestures

The problem to solve

Touch interactivity is broken/non working mostly currently. (as discussed in #8)

Current situation

Current touch is implemented using eventjs and some code magic, this was not improved for a long time.

Proposal

Using Hammerjs and a just a little code would make it work again.

Breaking changes

Removing eventjs and introducing Hammerjs might break some user implementations.

See my fiddle in userland for what I have done so far:

https://jsfiddle.net/7dk28mza/1/

This allows smooth scaling/rotating no matter if you really perfectly hit the object. Also it prevents unwanted rotation (currently only rotates above 10 degrees).

Node Canvas 2, fabric major bump, trimming chances

The problem to solve

Node canvas 2 is getting out, will require latest jsdom, that requires node 6.
Node canvas 2 improvements are nice and i would like to upgrade, we need to remove node 4 support and so we should bump fabric to 3.x

This thread is to ask what you think of those changes and if there is a part of the api you think is bad and that ypu would like to fix at the next breaking occasion.

Current situation

We could bump to 3 with the only change being node 4 and move on. Or we could introduce some other breaking changes.

Proposal

Things i would like to kill:
setBackgroundImage api, setGradient api.
I would prefer people to learn to create a gradient, and assign to the right property, no need to have a special api for that.

Adding promise support (without embedding a promise polyfill ).
Leaving callback support.in
If a callback is not provided, the method would return a promise.( maybe this can be done anyway no major bump required )

Breaking changes

node 4 removal
removing a couple of methods from canvas
removal of setPatternFill and setGradientFill from objects

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.