JavaScript library for object-based canvas drawing

Overview

oCanvas - Object-based canvas drawing

FOSSA Status

oCanvas makes canvas development easier to understand and do, by creating a bridge between the native pixel drawing approach and objects that are created and added to canvas. It is now possible to very easily create objects, change properties of these objects and add events to them — and everything just works because oCanvas handles the background stuff for you.

Building your own oCanvas

The git repo contains a build directory with a build script. That will combine all modules specified in the config file and output one file with the full source and one file with the minified source.

The script uses Node, so you need to install that first. The minification is done by UglifyJS which is included in the repo.

First you need to get your own copy of the source files, by running the following in the terminal: git clone git://github.com/koggdal/ocanvas.git

Then navigate to the build directory by running: cd ocanvas/build

Finally run the build command: node build.js

You will now have two source files in the build/dev/ directory: ocanvas-x.x.x.js and ocanvas-x.x.x.min.js

Documentation

All the documentation can be found at the website, http://ocanvas.org/

Issue reporting

Issues should be reported on GitHub, and every good issue should contain a good description, details about oCanvas version, operating system and browser. A test case of some sorts is also very much appreciated.

Contributing

oCanvas is an open source project created and maintained by me (Johannes Koggdal). It would be great to get some more developers working on it, since I can't possibly make everything on my spare time. If you want to help out—reach out to me, so we can sync up to avoid double work. Then just send a pull request to get it in.

I have two main branches, master and develop, where develop is the branch where everything happens. When a new version is about to be released, it gets merged to master, where the version number is updated. So if you want to help out, make sure you're working on top of develop.

License

FOSSA Status

Comments
  • Use of getters/setters removes any chance of compatibility with IE

    Use of getters/setters removes any chance of compatibility with IE

    First off, great job on this library. Next time I need a scene graph, I may put this thing through the ringer with some game dev.

    I was evaluating using oCanvas in a project for work, where, unfortunately, the requirements are >= IE6. I hoped that with a canvas shim everything would be ok (I'm using FlashCanvas)...

    GAH! Getters and setters! Foiled!

    I know it's a long shot that you'd even consider removing them, but I figured I'd at least report this in the event that others are wondering... and to save them some time.

    I realize it's non-trivial and would break the current API. Also, I suppose it's sort of trivial in difficulty to remove getters/setters and replace them with function calls, but would still take time (which I don't believe I have enough for this work project).

    Let's say I got really motivated, and replaced all the getters/setters... what would you think of that?

    opened by kirbysayshi 13
  • Added clipping feature to Arc, Ellipse, Image, Polygon, Rectangle and Sprite

    Added clipping feature to Arc, Ellipse, Image, Polygon, Rectangle and Sprite

    I deleted last commits from develop-patch-clipping then the previous pull request was automatically closed.

    My branch is in a good state now. I think you can do the merge! :grinning:

    Thanks for teaching me something more about using git :smiley:

    opened by nestorrente 12
  • Event problem when associating 2 oCanvas objects on same <canvas>

    Event problem when associating 2 oCanvas objects on same

    Hi,

    I have special use case, when I want to define 2 or more oCanvas objects on single (same) html canvas element. Then I get events mixed. I think that problem occurs because 2 or more oCanvas objects mix object events because of children object ID-s which are same in both oCanvas objects.

    For example:

    1. define 2 oCanvas objects on single canvas
    2. add rectangle children on both oCanvas objects
    3. add dragDrop events on those 2 rectangles
    4. show only one oCanvas object, events work
    5. show second oCanvas, events don't work
    6. Switch back to first oCanvas object, events work

    Here is code example. You'll notice that second black rectangle events don't work.

    <html>
    <head>
        <meta charset="UTF-8" />
        <title>oCanvas Example</title>
    
        <script type="text/javascript" src="http://localhost:88/ocanvas-2.1.1.js"></script>
        <script type="text/javascript" >
    
        var canvas;
        var canvas2;
        var rectangle;
        var rectangle2;
        var p1,p2;
    
        function load()
        {   
            //1st oCanvas
            canvas = oCanvas.create({
                canvas: "#canvas"
                ,background: "#ccc"
            });
    
            rectangle = canvas.display.rectangle({
                x: 277,
                y: 100,
                width: 100,
                height: 100,
                fill: "#000"
            });
    
            canvas.addChild(rectangle);
            rectangle.dragAndDrop();       
    
            //2nd oCanvas
            canvas2 = oCanvas.create({
                canvas: "#canvas"
                ,background: "#ccf"
            });
    
            rectangle2 = canvas2.display.rectangle({
                x: 77,
                y: 100,
                width: 100,
                height: 100,
                fill: "#00f"
            });
    
            canvas2.addChild(rectangle2);
            rectangle2.dragAndDrop();
    
        }
    
    
        function klik()
        {
            canvas.clear();    
            canvas.events.enabled = false;
    
            canvas2.draw.redraw(); 
            canvas2.events.enabled = true;        
    
        }
    
        function klik2()
        {
            canvas2.clear();    
            canvas2.events.enabled = false;
    
            canvas.draw.redraw();
            canvas.events.enabled = true;
    
    
        }
    
        </script>
    
    </head>
    <body onload="load()">
    
        <input type=button value="Klik" onclick="klik()" />
        <input type=button value="Klik2" onclick="klik2()" />
    
        <canvas id="canvas" width="500" height="500"></canvas>
    
    
    </body>
    </html>
    
    
    
    opened by jongo 11
  • Preloading Image

    Preloading Image

    I need the ability to preload images before drawing them to the canvas. I have done this before in javascript but the framework does not currently allow for this.

    opened by josh-oiknine 7
  • Google chrome

    Google chrome

    Hi,

    Sorry for my bad english.

    Since few times oCanvas not working in Google chrome.

    Events (mousedown, mouseup) are not recognize.

    What is the problem ?

    Thank you for your help.

    opened by Aleski17 7
  • Object events aren't triggered properly when the page is scrolled

    Object events aren't triggered properly when the page is scrolled

    I'm getting fairly consistent bugs when a canvas is further down the page. I've tried re-drawing it on window.scroll, just in case that was the issue, but still no luck.

    Events are triggered properly when applied to the base; it's just on display objects, such as Arcs or Ellipsis.

    I've had a look at the transformPointerPosition and isObjectInside methods, and can't see anything to do with a window.scrollY offset?

    Any ideas?

    opened by joecritch 7
  • Rectangle: new borderRadius property

    Rectangle: new borderRadius property

    This PR adds the feature discussed in issue #158.

    @koggdal if you want me to rearrange the code in another way, let me know :) I didn't know where could be the best place to put the "private methods".

    I had to set strokePosition to "black". The reason for doing that is because black is the default color when invoking stroke() method, but when the stroke is simulated using a path (as in rectangles with a borderRadius) a default strokeColor is needed. Otherwise, the stroke is painted with the same color as the fill.

    opened by nestorrente 6
  • core not finding canvas

    core not finding canvas

    I had to modify this code to find the canvas element: // Set canvas to the element specified using a selector else if (typeof this.settings.canvas === "string") { this.canvasElement = document.querySelector(this.settings.canvas); } if (this.canvasElement == undefined) this.canvasElement = document.getElementById(this.settings.canvas)

    document.querySelector didn't work.

    Is this library still active and supported/

    opened by QuinDennis 6
  • Added clipping feature

    Added clipping feature

    Now an object can "clip" its childs into its shape.

    Before this change, the drawObject function restored the canvas before draw object's children. In that way, clipping feature was not possible.

    Instead of restoring canvas and making again all parent's transformations, now the canvas is restored after children were drawn. This allows us to use the clip() function before draw the object's children.

    I realized that the fillRect() function doesn't work fine with clip() -it paints the object above its children. That's the reason why I wrote the function fillRectClipping. This function executes a rect() then a fill() instead of a fillRect(). Using rect()+fill(), the object is painted below its children as expected.

    Now the trick begins: when an object has a "clipChildren" property with a truthly value, the following happens:

    1. canvas.fillRect() function is replaced by fillRectClipping function (line 159).
    2. object's draw() function is invoked (line 160).
    3. canvas.fillRect() function is restored (line 161).
    4. canvas.clip() function is invoked (line 162).

    When "clipChildren" property is not defined or it has a falsy value, only "obj.draw()" is invoked.

    Here its an example of this clipping feature:

    clipping_example

    opened by nestorrente 6
  • Custom easing function error

    Custom easing function error

    When I define a custom easing function, oCanvas breaks. The error is "Uncaught TypeError: Cannot read property 'length' of undefined".

    I think that the error comes from the function "parseEasingOption". The code of the function is:

    parseEasingOption: function (easing) { if (typeof easing === "string") { // The cubic-bezier() syntax is now deprecated (though it was never really public) if (~easing.indexOf("cubic-bezier")) { return this.getCustomCubicBezier(easing) || this.easing[this.defaults.easing]; } else { return this.easing[easing] || this.easing[this.defaults.easing]; } } else if (typeof easing !== "function") { return this.easing[this.defaults.easing]; } },

    I think that the error is because an "else" statement is missing. Adding an "else return easing;" solves the problem.

    opened by nestorrente 6
  • Background does not redraw properly on resized canvases

    Background does not redraw properly on resized canvases

    If I resize my canvas after initializing the Core module, and then call redraw() on either the Core module or the Draw module, the background doesn't redraw to fill the canvas. Calling reset() on the Core module doesn't work either, nor does using the set() method on the Background module. If I were to guess, I think it's due to the drawing function not checking for canvas size changes after the initialization.

    opened by elldritch 6
  • transformPointerPosition gives incorrect coordinates when the context is scaled

    transformPointerPosition gives incorrect coordinates when the context is scaled

    When the 2D rendering context is scaled, (here is a reason for scaling) things like .dragAndDrop() fails. Example setup:

    let ratio = 0.8 // some value other than 1
    let canvas = document.createElement('CANVAS')
    let context = cnv.getContext('2d')
    document.body.appendChild(canvas)
    context.scale(ratio, ratio)
    
    let oc = oCanvas.create({
    	canvas: canvas
    })
    

    Since the ratio is different from 1, mouse position in terms of document pixels and mouse position in terms of canvas pixels becomes two separate things, x and y values that transformPointerPosition should be multiplied accordingly, to the context scaling ratio.

    opened by onurkerimov 1
  • rounded rectangle

    rounded rectangle

    What you think about add a rounded rectangle?

    I suggest a property radius, e.g.

    const rectangle = ocanvas.display.rectangle({
      width: 200,
      height: 100,
      x: 0,
      y: 0,
      stroke: '1px black',
      radius: 10,
    }
    

    Maybe a radiusTopLeft, radiusTopRight, etc... can be useful

    opened by darlanmendonca 8
  • I think performance is the biggest problem of ocanvas

    I think performance is the biggest problem of ocanvas

    I tried oCanvas a few days and found its so beautiful and elegant, and have a very small size. But when I run some tests, the FPS makes me so disappointed(already set the fps to 60), especially on android phone.

    Then I forked the project and checked the main loop in source code and found some setTimeout functions may slow down the fps, so I removed the fps setting and did some modification in main loop, sprite and animation, and then the fps looks improved a lot , I add some examples to compare the fps(https://github.com/keel/ocanvas/tree/develop/examples).

    Also, I add loop and update paras to animate(), so I can make some special effect (examples/animation.html)

    I really like oCanvas and hope it used widely, I don't think my work is good enough, so I suggest @koggdal can make some performance improvement , and add unit tests to make it more stable.

    opened by keel 1
  • Request for a new display object

    Request for a new display object "freeform"

    Hi Johannes, I have a request for a new display object "freeform". Freeform is a display object, which wiil be drawn by a an array of points. The point array is drawn with lines, which connects the points. See the image:

    grafik

    This element isn't neither a rectangle nor a radial element.

    I add some code to give you an idea: var viewportPoints = [{x: 10, y: 20}, {x: 11, y: 22}, ....]; // array of points this.pathLines = this.createPathLines(viewportPoints);

    createPathLines: function(viewportPoints) { var my = this; var pathLines = []; var prev = null; viewportPoints.forEach(function(p){ if (prev) { var pathLine = my.ocanvas.display.line({ start: {x: p.x, y: p.y}, end: {x: prev.x, y: prev.y} }); pathLines.push(pathLine); } prev = p; }); return pathLines; },

    The freeform object should be draggable, scalable and should have the behaviour of all the other display objects.

    E. g. I add my own isPointerInside(x, y) Method, which checks, if a pointer position is inside this shape.

    isPointerInside: function(x, y) { // Example, retrieve canvas context with jQuery var $canvas = $(this.ocanvas.settings.canvas); var canvas = $canvas.get(0); var ctx = canvas.getContext("2d");

    var first = true;
    ctx.beginPath();
    this.pathPoints.forEach(function(pathPoint){
    	if (true === first) {
    		ctx.moveTo(pathPoint.x, pathPoint.y);
    		first = false;
    	} else {
    		ctx.lineTo(pathPoint.x, pathPoint.y);
    	}
    });
    ctx.closePath();
    var inside = ctx.isPointInPath(x, y);
    return inside;
    

    },

    But this method only works, if I add an outerBox to my freeform. The outerBox ist light blue, the selected freeform widget has a wider selection stroke in the next image.

    grafik

    The outerBox is drawn around my freeform. Here is how I create it: this.outerBox = this.createOuterBox(x, y, w, h); // x, y, w, h outerBox geometrie

    createOuterBox: function(x, y, w, h) { var my = this; var box = this.ocanvas.display.rectangle({ x: x, y: y, width: w, height: h, fill: "transparent" }); box.setOrigin("left", "top"); box.bind("mousemove", function(){ if (my.isPointerInside(my.ocanvas.pointer.x, mu.ocanvas.pointer.y)) { my.ocanvas.mouse.cursor("move"); } else { my.ocanvas.mouse.cursor("default"); } }); return box; },

    I'd like to use this new element to select an arbitray region in an image, where someone can leave a comment to this region.

    It would be very fine, if you can add this new display object to your wonderful library.

    Thank you very much.

    opened by lionstorke 0
Owner
Johannes Koggdal
Web developer focusing mostly on UI in application development.
Johannes Koggdal
jQuery plugin based on raphael.js that allows you to display dynamic vector maps

jQuery Mapael - Dynamic vector maps The complete documentation is available on Mapael website (repository: 'neveldo/mapael-documentation'). Additional

Vincent Brouté 1k Jan 5, 2023
🌅 Content-aware image resizer based on Seam Carving algorithm

Content-aware image resizing might be applied when it comes to changing the image proportions (i.e. reducing the width while keeping the height) and when losing some parts of the image is not desirable.

Oleksii Trekhleb 1.4k Dec 30, 2022
:woman: Library for image processing

Lena.js Tiny library for image processing. Install via NPM npm install lena.js --save Install via yarn yarn add lena.js Run demo yarn demo Demo htt

Davidson Fellipe 558 Dec 28, 2022
Simple library to custom waveforms🎶

waveform-path LIVE DEMO WITH EXAMPLES Simple library to custom waveforms. Install NPM npm install waveform-path -s Download Download the last realease

Jero Soler 22 Jan 4, 2023
An image post-processing code library

WebGPU image filter Preview online 这是一个用来展示 webgpu 在图片处理方面应用的 demo,但由于 webgpu API 还不稳定,本地都需要经常修改 API 才能跟上金丝雀的脚步,所以本项目的效果目前也还不稳定,目前仅供学习交流。

kuake 4 Mar 8, 2022
A light wight javascript image viewing plugin with smooth animation and 0 dependence

A light wight javascript image viewing plugin with smooth animation and 0 dependence

null 50 Nov 12, 2022
Picdit - Photo Editor is a web application created using HTML, CSS, PHP and JavaScript

Picdit - Photo Editor is a web application created using HTML, CSS, PHP and JavaScript with the help VS Code and Microsoft Azure to develop the final project application outcome.

Darin Joshua D 3 Mar 31, 2022
taichi.js - a modern GPU computing framework for Javascript

taichi.js is a modern GPU computing framework for Javascript. It transforms Javascript functions into WebGPU Compute Shaders for massive parallelization. It is a Javascript version of the Python library Taichi.

Dunfan Lu 129 Dec 16, 2022
React + Canvas = Love. JavaScript library for drawing complex canvas graphics using React.

React Konva React Konva is a JavaScript library for drawing complex canvas graphics using React. It provides declarative and reactive bindings to the

konva 4.9k Jan 9, 2023
Responsive, interactive and more accessible HTML5 canvas elements. Scrawl-canvas is a JavaScript library designed to make using the HTML5 canvas element a bit easier, and a bit more fun!

Scrawl-canvas Library Version: 8.5.2 - 11 Mar 2021 Scrawl-canvas website: scrawl-v8.rikweb.org.uk. Do you want to contribute? I've been developing thi

Rik Roots 227 Dec 31, 2022
Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Fabric.js Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element. I

Fabric.js 23.6k Jan 3, 2023
Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Fabric.js Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element. I

Fabric.js 23.6k Jan 3, 2023
Node.js object hash library with properties/arrays sorting to provide constant hashes. It also provides a method that returns sorted object strings that can be used for object comparison without hashes.

node-object-hash Tiny and fast node.js object hash library with properties/arrays sorting to provide constant hashes. It also provides a method that r

Alexander 73 Oct 7, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
JustGage is a handy JavaScript plugin for generating and animating nice & clean dashboard gauges. It is based on Raphaël library for vector drawing.

JustGage JustGage is a handy JavaScript plugin for generating and animating nice & clean dashboard gauges. It is based on Raphaël library for vector d

Bojan Djuricic 1.8k Jan 3, 2023
Canvas rendering library, Sprite manipulation of canvas

el-canvas Canvas rendering library, Sprite manipulation of canvas hello world <div id="app"><div></div></div> yarn add elem-canvas or npm i

null 15 Apr 13, 2022
HTML5 Canvas Gauge. Tiny implementation of highly configurable gauge using pure JavaScript and HTML5 canvas. No dependencies. Suitable for IoT devices because of minimum code base.

HTML Canvas Gauges v2.1 Installation Documentation Add-Ons Special Thanks License This is tiny implementation of highly configurable gauge using pure

Mykhailo Stadnyk 1.5k Dec 30, 2022
Konva.js is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.

Konva Konva is an HTML5 Canvas JavaScript framework that enables high performance animations, transitions, node nesting, layering, filtering, caching,

konva 8.7k Jan 8, 2023