GithubHelp home page GithubHelp logo

kaliedarik / scrawl-canvas Goto Github PK

View Code? Open in Web Editor NEW
314.0 8.0 25.0 221.64 MB

Responsive, interactive and more accessible HTML5 canvas elements. Scrawl-canvas is a JavaScript library designed to make using the HTML5 canvas element easier, and more fun

Home Page: https://scrawl-v8.rikweb.org.uk

License: MIT License

HTML 0.09% JavaScript 99.91%
html5 canvas javascript html5-canvas-element graphical-displays animations accessibility responsive-web-design html5-canvas

scrawl-canvas's Introduction

Welcome to the Scrawl-canvas Library

Version: 8.13.1 - 3 May 2024

Scrawl-canvas website: scrawl-v8.rikweb.org.uk.

Scrawl-canvas on CodePen: codepen.io/collection/RzzMjw.

Scrawl-canvas on Discord: discord.com/channels/...

Do you want to contribute? Don't be afraid - reach out and let's see what website magic we can create together!

CII Best Practices Rate on Openbase

What?

Scrawl-canvas is a Javascript library for working with the HTML5 <canvas> element. The library:

  • Defines a set of factory functions for creating a wide range of graphic artefacts and effects, which can be drawn on a canvas.
  • Includes an adaptable - yet easy to use - protocol for positioning, displaying and animating artefacts and effects across the canvas.
  • Adds functionality to make <canvas> elements responsive, adapting their size to their surrounding environment while remaining fully interactive.
  • Helps make canvas elements more accessible for both keyboard and AT users.
github-promo-2.mp4

Why?

Working with the native Canvas API is hard work - particularly when the desired result is more complex than a couple of coloured boxes in a static display.

But the benefits of using canvases for graphical displays and animations are also great:

  • Canvases are part of the DOM (unlike Flash);
  • They are natively wired for events and user interactions;
  • They use immediate mode redering (which makes them very quick); and
  • The canvas-related APIs are designed to be used with Javascript.

Sadly these advantages are also significant barriers:

  • Working directly with the canvas-related APIs means writing significant amounts of Javascript boilerplate code.
  • <canvas> elements can be resized and styled using CSS, but changing the CSS size does not affect the element's drawing dimensions - leading to ugly results.
  • Events work on the canvas, not on the graphical objects within the canvas - we cannot use those objects as links or hot-spots (click/tap events), we cannot give them the equivalent of a CSS hover state (focus/blur events), we cannot drag-and-drop them around the display (move events).
  • Tracking a user's interaction with the various parts of a canvas display, for analytics and research on web page performance, is particularly difficult.
  • We cannot easily save and share displays, effects and animations; each <canvas> element's output is tightly coupled to the code that defines that output.
  • Of most concern, canvases are entirely graphical - visual - by nature; they come with significant accessibility issues. Given the ever-stricter requirements for websites to be accessible to all users, this makes using a canvas to present important information a dangerous proposition.

Scrawl-canvas overcomes these barriers

Scrawl-canvas is fast, and developer-friendly. It's suitable for building infographics, games, interactive videos - whatever we can imagine for a 2D graphical presentation. And it is modular - we can break the code for a particular effect into its own module file which can be reused in other projects.

Scrawl-canvas offers all of this while never losing its hard focus on making the <canvas> element accessible, responsive and fully interactive while at the same time offering a pleasant developer experience.

Also, Scrawl-canvas supports developers coding in TypeScript by means of a TS definitions file included in the repository.

Installation and use

There are three main ways to include Scrawl-canvas in your project:

Download, unpack, use

  1. Download the zipped file from GitHub
  2. Unzip the file to a folder in your project.
  3. Import the library into the script code where you will be using it.

Alternatively, a zip package of the v8.13.1 files can be downloaded from this link: scrawl.rikweb.org.uk/downloads/scrawl-canvas_8-13-1.zip - that package only includes the minified file.

<!-- Hello world -->
<!DOCTYPE html>
<html>
<head>
    <title>Scrawl-canvas Hello World</title>
</head>
<body>
    
    <canvas id="my-canvas"></canvas>

    <!-- The library is entirely modular and needs to be imported into a module script -->
    <script type="module">

        import * as scrawl from './relative-or-absolute/path/to/scrawl-canvas/min/scrawl.js';

        // Get a handle to the canvas element
        let canvas = scrawl.findCanvas('my-canvas');

        // Setup the scene to be displayed in the canvas
        scrawl.makeLabel({

            name: 'hello',
            start: [20, 20],

            text: 'Hello, World!',
            fontString: 'bold 40px Garamond, serif',
        });

        // Render the canvas scene once
        canvas.render();

    </script>

</body>
</html>

CDN - unpkg.com

This will pull the requested npm package directly into your web page:

<script type="module">
    import * as scrawl from 'https://unpkg.com/[email protected]';
    [...]
</script>

NPM/Yarn

  1. Add the library to your project using NPM or Yarn
  2. Import the library into the script code where you will be using it.
// either
$> npm install scrawl-canvas

// or
$> yarn add scrawl-canvas

// then in your script file
import * as scrawl from 'scrawl-canvas';

// Scrawl-canvas has no dependencies
// - it can be used as-is, with no further installation steps required

Local development and testing

After forking this repo down to your local machine, cd into the scrawl-canvas folder, run yarn install or npm install (for the local build toolchain - the library itself has no external dependencies) and start a local server.

$> cd ./path/to/Scrawl-canvas/folder
$> yarn install
$> yarn dev

Testing

The code base does not include any unit testing frameworks. Instead, we rely on a set of Demo tests which allow us to perform integration testing and user interface testing.

Why this approach? Because most of the Scrawl-canvas functionality revolves around various forms of user interaction and animation, which requires visual inspection of the Demo tests to check that the canvas display - and thus, by inference, the underlying code - performs as expected.

Demos that include user interaction allow us to test specific aspects of the code base.

Linting

The tool chain includes the ESLint package to impose some basic checks on code. We use the default checks supplied by the package (as indicated in the rules documentation page). To run the linter:

$> yarn lint

The tool chain also includes the Knip package to check for unused files and exports in the source Javascript. To run Knip:

$> yarn knip

TypeScript support

Scrawl-canvas supports TypeScript through a TypeScript Definitions (d.ts) file. The definitions file aims to be as accurate, comprehensive and informative as possible, but specifically excludes support for internal (private) SC object attributes and functions.

To view the library's API types, try the tsdocs.dev website.

To aid development, we test the definitions file against the entire suite of Demo code .js files supplied as part of the library. From the root of the project, run the following command:

$> yarn test

Documentation

The source code has been extensively commented. We generate documentation from that code using Docco. Documentation is regenerated each time the library is rebuilt.

Minification

We minify the source code using rollup and its terser plugin.

Building the library

Running the following command on the command line will recreate the minified file, and regenerate the documentation:

$> yarn build

Star History

Star History Chart

Development team

Developed by Rik Roots: [email protected]

scrawl-canvas's People

Contributors

dependabot[bot] avatar goodnovember avatar kaliedarik 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  avatar  avatar  avatar

scrawl-canvas's Issues

anchors of pictures are in the default nav

hi
thanks for your work on this library! i'm not sure if i'm missing something or if i've found a bug:
when i put a block with an anchor on my canvas, the anchor tag is added to the canvas nav.
when I put an image with an anchor on my canvas, the anchor tag is added to the default nav.
is this a bug or the intended behavior? how could i get the anchor tag of the image in the canvas nav?

Chrome UI fund request

As described in this repository's README.md[1] file, Scrawl-canvas exists to help make the HTML5 canvas element more responsive, interactive and accessible for end users. I have designed this Javascript library to make developing more responsive, accessible canvas outputs easier for web developers.

As things stand, I have been the sole developer and maintainer of Scrawl-canvas for over 8 years, and I have no plans to stop this work in the known future. My key failure over this time has been my inability to build a community of developers and users to help with this (what I consider to be important) work. As clever as I may think I am, I'm not very good at promoting the library, or the issues that the library is designed to tackle.

The initial aim for this (small) funding request is, initially, to help cover the hosting and development costs for the library's dedicated website[2][3]. That site includes extensive documentation on learning and using the code, as well as a wide range of demonstrations, which makes it an integral part of the product. These uncertain times (and my age) have made me realise that not being able to cover those costs - for whatever reason - would cripple the entire project. Additionally, I have a CodePen[4] Pro account which I use to create the CodePen examples embedded into the 'Learn' sections of the library website.

While this funding request may address the initial aim, it does not address the biggest problem facing the Scrawl-canvas project: the lack of a viable community surrounding it. Without a community, I can't raise awareness of the project among developers, project managers and other key players. And without that awareness, the project will fail to deliver on its keystone purpose: to give end users a better experience of a webpage through the use of properly responsive, interactive and - most importantly -accessible canvas-based graphics and animations. I don't know how to solve this problem - maybe others can advise?

[1] - README.md link: https://github.com/KaliedaRik/Scrawl-canvas/blob/master/README.md
[2] - Library website: https://scrawl-v8.rikweb.org.uk/
[3] - Library website's code on GitHub - https://github.com/KaliedaRik/scrawl-canvas-website
[4] - CodePen link: https://codepen.io/collection/RzzMjw

Scrawl-canvas v9 roadmap

If people have suggestions for big, possibly breaking, changes to Scrawl-canvas, please leave them in a comment below.

Discussion on suggested changes is welcome!

Empty scrawl.library.canvas (canvas could not be found?) in Vue2

I am new to scrawl-canvas (like 10-minutes in kind of new), so my first goal is to get the hello world to work within my Vue2 project (soon to be Vue3), with the end goal of generating a downloadable 256x256 avatar based on a transparent png + circular mask + another image (seems within the realm of Scrawl-canvas possibilities, right?).

I'm trying the hello world example from the front page. But this being Vue, this happens within a component:

<template>
    <div>
        <canvas id="mycanvas"></canvas>
        <v-btn @click="helloworld()">go!</v-btn>
    </div>
</template>
import * as scrawl from 'scrawl-canvas'
export default {
    methods: {
        helloworld() {
            let canvas = scrawl.library.canvas.mycanvas
            console.log(scrawl.library.canvas) // empty object!

            // Setup the scene to be displayed in the canvas
            scrawl.makePhrase({
                name: 'hello',
                text: 'Hello, World!',
                width: '100%',
                startX: 20,
                startY: 20,
                font: 'bold 40px Garamond, serif',
            });

            // Render the canvas scene once
            canvas.render(); // Error, canvas is undefined.
        }
    },
}

However, the canvas object remains empty.

Dynamicly resize mycanvas with Javascript

Hello, as a beginner of scrawl-canvas, I wonder if it's possible to resize mycanvas according to the size of img which is dynamicly changing.
I tried to cover a canvas on an img, always fitting in the img size, and then I can make notes on different imgs. The problem is, once imported scrawl module and set that canvas tag as "data-scrawl-canvas", there seems an initial setting for that with {width:0;height:0;display:block;} in inline styles, which makes it hard to override by further javascripts.
Besides, each time when the makeRender() calls, such initial setting will guarantee above settings being reset again, which means if I want to do something with scrawl, I have to abandon the idea of dynamicly resizing mycanvas with Javascript.
Am I use it a wrong way? Thanks!
Here is the basic Html to show the relation of "note" canvas and the dynamicly-changing "background" img
<div class="img_wrapper" > <img src="" alt="" > <canvas id="mycanvas" data-scrawl-canvas ></canvas> </div>

Phrase element - letter spacing issue

When adding letter spacing to a multiline Phrase entity, the spacing applies itself in front of the first letter of the text, both when left-justified and full-justified.

To view the issue, go to demo Canvas 017 and apply letter spacing to the entity.
Screenshot 2021-01-05 at 20 40 37

Scrawl-canvas v8 improvements

If people have suggestions for improvements we can make to the library, then please leave them in a comment below.

The scope of an improvement is that it should not compromise or break existing functionality. Adding to the library's API is fine.

Discussion about suggested improvements is welcome!

How to apply a clipping artefact to a specific image artefact only? (Question)

The demo's do sometimes a bit too much, which makes it a little more difficult to disect the information you're trying to learn form them. However, after working with it for a few hours and reading through the tutorials I came very close to my goals, and must say that it's a very capable library, although I have no experience with other similar ones, I am absolutely very happy choosing this one for my little project.

There is however one thing that I have so far not been able to figure out, and that is how to apply clipping to only certain artefacts (and probably by extension, grouping, as I have a feeling it might be accomplished through groups). This screenshot shows the issue, there are two images, a background (the person in the suit) and a foreground (the ring which is a transparent png, with some shading on the inside of the ring. Then there is a third artefact, a wheel-clip, which I want to ONLY apply to the background image.

image

I have been playing around with order and groups, but have been so far unsuccesful.

At the end of the 'struggle', this was the code producing the screenshot above (as you may notice there are is a variable scale and postioning, which I took from the Pan&Zoom example ;-) ):

            this.canvas = scrawl.getCanvas('#mycanvas')
            let base = this.canvas.base,
                baseGroup = scrawl.library.group[base.name];

            let naturalWidth = document.getElementById("subjectImg").naturalWidth
            let naturalHeight = document.getElementById("subjectImg").naturalHeight
            let maxScale = (naturalHeight / this.frameDimension)
            if (!this.currentScale) {
                this.currentScale = maxScale
            }
            let minScale = 1
            let fromLeft = 0
            let fromTop = 0

            this.canvas.set({
                width: this.frameDimension,
                height: this.frameDimension,
                checkForResize: true,               // ?
                baseMatchesCanvasDimensions: true,  // ?
                isComponent: true,                  // ??
            }).setAsCurrentCanvas();

            // Ring
            this.tokenRing = scrawl.makePicture({
                name: `token-image`,
                imageSource: `/../img/ring.png`,
                width: '100%',
                height: '100%',
                copyWidth: '100%',
                copyHeight: '100%',
                order:2,
            });

            // Subject
            let tokenSubject = scrawl.makePicture({
                name: 'token-subject',
                imageSource: `/../img/background.png`,
                width: '100%',
                height: '100%',
                copyWidth: this.currentScale * this.frameDimension,
                copyHeight: this.currentScale * this.frameDimension,
                copyStartX: fromLeft,
                copyStartY: fromTop,
                filter: 'drop-shadow(2px 2px 2px #000000)',
                order: 1,
            });

            scrawl.makeWheel({
                name: 'wheel-clip',
                //radius: 257,
                radius: 270,
                startAngle: 0,
                endAngle: 360,
                includeCenter: true,
                startX: 279,
                startY: 279,
                handle: ['center', 'center'],
                method: 'clip',
                order: 3,
            })

            scrawl.makeRender({
                name: "demo-animation",
                target: this.canvas,
            });

Respond to prefers-reduced-motion OS user preferences

The prefers-reduced-motion media query detects whether the user has requested the operating system to minimise the amount of animation or motion it uses - see web.dev article here https://web.dev/prefers-reduced-motion/

We can add functionality to the library to detect, and act on, user preferences (as set in the user's device OS) to reduce the amount of animation they are exposed to. To do this, we need to:

  1. Detect the initial setting - if the motion setting is set to 'reduced' then we can enforce all animations to halt after a maximum of 5 seconds

  2. Detect changes in the setting - which in turns runs/halts the animations

See MDN links for detecting media queries in Javascript - https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia and https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries

For testing, we need to simulate user settings in the browser - see https://umaar.com/dev-tips/211-media-query-simulation/

The scope of this ticket excludes subsequent user behaviour eg to start an animation running by clicking on a canvas/stack 'run' button

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.