Code Monkey home page Code Monkey logo

mojs-curve-editor's Introduction

@mojs/curve-editor – npm

GUI for live easing/property curves editing.

mojs-curve-editor

MojsCurveEditor is a GUI plugin for interactive custom easings and property curves editing while crafting your animations. It is part of mojs tools.

Installation

The MojsCurveEditor depends on mojs >= 0.225.2, tween autoupdates available for mojs >= 0.276.2. Please make sure you've linked mojs library first.

# npm
npm install @mojs/curve-editor

# cdn
<script src="https://cdn.jsdelivr.net/npm/@mojs/curve-editor"></script>

Import MojsCurveEditor constructor inside your code, depending on your environment:

const MojsCurveEditor = require('mojs-curve-editor').default;

// or
import MojsCurveEditor from '@mojs/curve-editor';

If you installed it with script link - you should have MojsCurveEditor global

Usage

Construct MojsCurveEditor with the next options:

  const mojsCurve = new MojsCurveEditor({

    // name of the Curve you are working on. The name is used to
    // identify record in `localStorage` to restore the state from
    // when page gets reloaded, so please specify unique names if
    // you use more than one editor on the same page.
    name: 'bounce curve'
  });

After that you can "connect" the curve with your mojs modules by passing a "sample" of the curve to the easing property of the module, like this:

  const mojsCurve = new MojsCurveEditor();

  const tween = new mojs.Tween({
    easing: mojsCurve.getEasing()
  });

  // or

  const shape = new mojs.Shape({
    easing: mojsCurve.getEasing()
  });

  // or as `property curve`

  const html = new mojs.Html({
    el: '#js-el',
    x: {
      0: 100,
      curve: mojsCurve.getEasing()
    }
  });

Each tween/module should have it's out sample of the curve, this means you need to call mojsCurve.getEasing() send the sample of the curve to the easing property of modules.

If you use mojs>0.276.5 the state of the modules with the curve sample will be updated automatically.

The getEasing function receives options hash:

  easing: mojsCurve.getEasing({

    // `transform` function that pipes through the current value
    // of the curve so you can transform it
    transform: (k) => { return k; }
  });

After you are happy with the curve you made, you need to change the sample, mojsCurve.getEasing() calls, with the actual path data that you can get by clicking on the code button code button:

  const html = new mojs.Html({
    el: '#js-el',
    x: {
      0: 100,
      easing: 'M0, 100 L100, 0'
    }
  });

Options

Constructor accepts the next options:

const curveEditor = new MojsCurveEditor({

  // name of the curve editor
  name: 'bounce curve'

  // if should preserve state on page reloads
  isSaveState: true,

  // start path - will be loaded on initialization of the curve,
  // e.g. before any user modifications were made. Path of 'M0, 100 L100, 0' is set by default.
  startPath: 'M0, 100 L100, 0',

  // callback on path change, accepts path string
  onChange: function (path) {},

  // if should hide when minimized - useful when you try to embed
  isHiddenOnMin: false
});

Public Methods

curveEditor

  // get `easing function` of the curve
  .getEasing()

  // maximize the curve editor
  .maximize()

  // minimize the curve editor
  .minimize()

  // toggle `maximize/minimize` methods regarding editor's state
  .toggleSize();

Shortcuts

  • alt + z - undo curve action
  • alt + x - redo curve action
  • alt + d - delete selected point(s)
  • [3 times] alt + \ - reset curve

All shortcuts work only for active editor - it should have orange mojs logo indicator at bottom left.

Development

Install webpack globally:

[sudo] npm install webpack -g

Install dependencies with npm:

[sudo] npm install

Run webpack:

webpack

Please make sure you started a feature branch with the feature name (better from the dev branch) before making changes.

mojs-curve-editor's People

Contributors

dependabot[bot] avatar dev99problems avatar legomushroom avatar nemerovchenko avatar sandstedt avatar tomsapps avatar xavierfoucrier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mojs-curve-editor's Issues

Code not updated on NPM

I've installed the latest version (1.5.0) with Yarn but it doesn't contain any of the startPath code.

Add `.destroy` method on API class

The .destroy() method should unrender main component and make sure everything including event listeners initialised with hammerjs are removed in componentWillUnmount method.

We can unrender the main component like this:

let root = render(
  <YourApp />,
  document.body
);

// to destroy it:
const Empty = () => null;
render(
  <Empty />,     // component that returns nothing
  document.body,
  root           // tell preact to replace the app root
);

Curve disappears when Codepen refreshes

Hi there,
This tool is so awesome, thanks for taking the time to make it.

I'm trying to use the isSaveState property on the curve editor inside a Codepen.
When I make a change to the source and the page refreshes, the curve I drew disappears.
My guess is this is a limitation of using Codepen. Is this intentional, or am I making a mistake in how I'm using it?

An example pen is here: https://codepen.io/lifeinchords/pen/vgGbrr

Thanks Oleg!

Editor goes crazy when using a lambda curve

image

    this.square1 = new mojs.Shape({
        parent: this.parentShape.el,
        duration: 3000,
        radius: 100,
        y: { 150: 150, curve: this.yCurve.getEasing() },
        scaleX: { 1: 1, curve: p => 1 - this.scaleCurve.getEasing()(p) },
        scaleY: { 1: 1, curve: p => 1 + this.scaleCurve.getEasing()(p) },
        angle: { [5]: 5, curve: this.angleCurve.getEasing() }
    });

With just scaleX: { 1: 1, curve: this.scaleCurve.getEasing() }, this seems to work fine, but the example above caused the screenshot above.

Bezier curves support appears broken

Upon activating a bezier curve on a point, an "Expected number" error is thrown.

the startPath throws this on load.
Clearing the path with shift + option + pressing \ 3 times, then creating a new control point, then activating the bezier curve also throws the error.

Mar-10-2021 22-17-53

Curve hiding when used with normalise.css

screen shot 2016-11-21 at 11 48 58

Had issues with the curve hiding above 1 and below 0 (see attached) so dug into the code and found a conflict with normalise.css. Normalise is adding overflow: hidden to svg:not(:root) which is hiding the curve.

Mojs curve editor issue : hidden curve beyond boundaries

Hi,

I encounter an issue when editing the curve when it goes beyond the boundaries (below 0, and above 1 axis) as showed in the attached screen : it's hidden.

I imported it using the cdn method. Thanks if you have a workaround to deal with this.
curve_editor

Reset button

It would be very helpfull to add a reset/clear/trash button below the left tools to allow the user to manually reset the curve. Shortcuts are usefull, but adding a button on the interface would be convenient as we use the mouse to draw the curve.

Improve the way anchor points are removed

  1. In the README it says alt + d to remove an anchor point. Working on Windows in Chrome this isn't working here. After selecting an editor and an anchor point on the curve the point is not deleted with alt + d. Neither with ctrl + d or shift + d. Am I missing something, or is this an issue?

  2. In most graphical software I use deleting anchor points happens with the DEL-key. Could this shortcut be added as an additional keyboard shortcut? To me that would be a lot more descriptive and intuitive then a double keystroke for something we use a lot.

  3. It would be nice to have a delete-button in the curve-editor interface too. Working with a lot of different software it's hard to remember all different shortcuts and keys aren't always the prefered way to me. Having a key to remove an anchor point would not only be convenient for graphical use, but could also show the shortcut key on the tooltip, so you get to know the shortcut after use more often. Instead of having to go to the github readme.

That said, very impressive workflow like this and beautiful layout of both the curve editor as the player. Thanks a lot for all the effort you obviously put into all of this! It's a lot of fun using mo.js! I like it a lot. Keep up the great work! :)

Error when adding startPath

When I specify a value that I previously copied from the editor

const mojsCurve = new MojsCurveEditor({
  startPath: 'M0, 100 C0, 100 100, 0 100, 0',
});

I get the following error

mojs-curve-editor.js:13544 Error: <path> attribute d: Expected number, "M0, 100 C0, 100 N aN, N aN 100, …".

I'm using the latest version of Chrome (61.0.3163.100) and I've pulled directly from Github rather than using NPM where the code seems to say it's version 1.5.0 but it's not the same as it is here on Github

error on initialize

Hi, i have an error in initiating curve editor:

in console i have:

Uncaught Error: MojsPlayer expects Tween/Timeline/Module as add option in constructor call. [ new MojsPlayer({ add: new mojs.Tween }); ]

this is my code:

import MojsPlayer from 'mojs-player';
import MojsCurveEditor from 'mojs-player';

const mojsCurve = new MojsCurveEditor({
    name:         'bounce curve',
    isSaveState:  true
  });

and here is my gulp compile task:


gulp.task('js', ()=> {
  return gulp
  .src('src/fx.js')
  .pipe(webpack({
    module: {
      loaders: [
      {
        test: /\.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ["stage-0" , "es2015"]
        }
      }
      ],
    },
    output: {
      filename: 'fx.js',
    },
  }))
  .on('error', handleError)
  .pipe(gulp.dest('dist/js/'))
  .pipe(browserSync.reload({
    stream: true
  }));
});

can you help me out? appreciate any help. thank you...

Add `startPath` option

Right now you can get curve's code by clicking the code button and copying the path coordinates from there.

Something like this: M0, 100 C0, 100 28.155286227103208, 95.35825418399047 30, 52.42857142857143 C31.844713772896824, 9.498888673152383 75.15078407720145, 24.857142857142858 75.15078407720145, 24.857142857142858 C75.15078407720145, 24.857142857142858 100, 0 100, 0

We need to do the opposite - parse this path coordinates data back to js objects:

// an array of points, where each point has the next structure:
point: {
     x: 30,
     y: 52.42,
     handle1: {x:28.15, y: 95.35},
     handle2: {x:31.84, y: 9.49}
}

There is how the SVG path data maps to js objects:

/*
  Input: M0, 100 C0, 100 28.155286227103208, 95.35825418399047 30, 52.42857142857143 C31.844713772896824, 9.498888673152383 75.15078407720145, 24.857142857142858 75.15078407720145, 24.857142857142858 C75.15078407720145, 24.857142857142858 100, 0 100, 0

  Sudo: [point1] [point1.handle2] [point2.handle1] [point2] [point2.handle2] [point3.handle1] [point3] [point3.handle2] [point4.handle1] [point4]
  
  Output:
    point1:
     x: 0, y: 100,
     handle2: x:0, y: 100
     
    point2:
     x: 30, y: 52.42857142857143,
     handle1: x:28.155286227103208, y: 95.35825418399047
     handle2: x:31.844713772896824, y: 9.498888673152383
    
    point3:
     x: 75.15078407720145, y: 24.857142857142858,
     handle1: x:75.15078407720145, y: 24.857142857142858
     handle2: x:75.15078407720145, y: 24.857142857142858

    point4:
     x: 100, y: 0
     handle1: x: 100, y: 0
*/

We can use getPathData polyfill that will make the parsing of theSVG coordinates data simple. After this, we need to fire few redux actions to send this data to redux store which will update components automatically. With this functionality, we can easily add startPath option to the curve editor which will allow launching(loading) the plugin with a predefined path - import the path back.

If you have any question, please feel free to ask, would love to help!

Cheers!

If the start point is a curve, then it will be converted to a line

Problem

If you star with this path in the curve editor:

M0, 100 C26, 100 30, 0 30, 0 C30, 0 37, 50 50, 50 C63, 50 75, 0 75, 0 C75, 0 83, 100 100, 100

bild

save it, and then reload the page, it will be converted to:

M0, 100 C0, 100 30, 0 30, 0 C30, 0 37, 50 50, 50 C63, 50 75, 0 75, 0 C75, 0 83, 100 100, 100

bild

So the first point M0, 100 C26, gets converted to M0, 100 C0

You can work around it by adding an extra point in the beginning, like this:

M0, 100 C0, 100 0, 100 0, 100 C26, 100 30, 0 30, 0 C30, 0 37, 50 50, 50 C63, 50 75, 0 75, 0 C75, 0 83, 100 100, 100 

Not sure it it's related to the curve-editor or how mojs interpret SVG paths. Will need to investigate further.

Use case

If you wanna create a seamless loop you often need to start and end with a curved point.

Reproduction codepen

https://codepen.io/sandstedt/pen/OJWKXmO?editors=1010

MoJS curve editor fails on getEasing

I've bene trying to debug this for the last hour, and I can't seem to find out why this parent object is null. My setup is pretty basic, but it is running inside an angular service.

mojs-curve-editor.js:280 Uncaught TypeError: Cannot read property '_o' of undefined_updateParent @ mojs-curve-editor.js:280_fireOnChange @ mojs-curve-editor.js:270(anonymous function) @ mojs-> curve-editor.js:319
mojs-curve-editor.js:280 Uncaught TypeError: Cannot read property '_o' of undefined_updateParent @ mojs-curve-editor.js:280_fireOnChange @ mojs-curve-editor.js:270(anonymous function) @ mojs-curve-editor.js:255

Exception location:

else if (parent._o.callbacksContext){
key: '_updateParent',
        value: function _updateParent(easing) {
          var parent = easing._parent;

          if (parent && parent.setProgress) {
            this._triggerParent(parent);
          } else if (parent._o.callbacksContext){
            this._triggerParent(parent._o.callbacksContext.timeline);
          } else if (parent.timeline) {
            this._triggerParent(parent.timeline);
          } else if (parent.tween) {
            this._triggerParent(parent.tween);
          }
        }

Offending calling code:

const parentElement = document.getElementById("js-el");
  const mojsCurve = new MojsCurveEditor({
    name:         'b curve'
  });

  const rect = new mojs.Shape({
    shape:        'rect',

    left:         {'0%':'100%'},
    top:          0,
    fill:         'none',
    radius:       20,
    stroke:       { 'rgba(0,255,255, 1)' : 'magenta',  easing: mojsCurve.getEasing() },
    strokeWidth:  { 10: 0 },
    strokeDasharray: '100%',
    strokeDashoffset: { '-100%' : '100%' },
    angle:        { 0: 180 },

    duration:     1500,
  });

 $scope.mainTimeline.add( rect );
  const mojsPlayer = new MojsPlayer({ add: $scope.mainTimeline });

I only get the exception when mojsCurve.getEasing() is used - otherwise there are no exceptions thrown on initialization.

Using
mojs - 0.288.1
mojs-curve-editor - 1.4.3
mojs-player - 0.43.15

FWIW
angular 1.4.3

localStorage access is unguarded

Even with isSaveState: false, it gets "DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document" when storage is disabled in the browser settings.

All usage of localStorage should be wrapped in a try-catch.

Joint Creation on line click

Hello!

I tested out the curve editor on the newest IE, Chrome, and FireFox. It works great in FireFox, but the other two browsers seem to have an issue that when you highlight and click on the initial line itself, it will create a new line and jump out of the bounds of the grid and onto the page.
I was testing it here:

http://codepen.io/zfrisch/pen/KgybAj

image

image

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.