Giter Club home page Giter Club logo

siriwave's Introduction

SiriWave

The "Apple Siri" wave replicated in pure Javascript using the Canvas API. To learn more about the project, read the blog post here, check the demo or codepen.

npm version

iOS (classic) style

The classic, pre-iOS9 style.

iOS9 style

The new fluorescent wave introduced in iOS9.

iOS13 style

work in progress

The wave reinvented as a bubble.

Usage

Browser (via CDN) usage

Import the UMD package via the unpkg CDN and it's ready to use.

<script src="https://unpkg.com/siriwave/dist/siriwave.umd.min.js"></script>

ES module

Install it through npm install siriwave or npm add siriwave first:

import SiriWave from "siriwave";

Initialize

Create a div container and instantiate a new SiriWave object:

<div id="siri-container"></div>
<script>
  var siriWave = new SiriWave({
    container: document.getElementById("siri-container"),
    width: 640,
    height: 200,
  });
</script>

Constructor options

Key Type Description Default Required
container DOMElement The DOM container where the DOM canvas element will be added. null yes
style "ios", "ios9" The style of the wave. "ios" no
ratio Number Ratio of the display to use. Calculated by default. calculated no
speed Number The speed of the animation. 0.2 no
amplitude Number The amplitude of the complete wave-form. 1 no
frequency Number The frequency of the complete wave-form. Only available in style "ios" 6 no
color String Color of the wave. Only available in style "ios" "#fff" no
cover Bool The canvas covers the entire width or height of the container false no
autostart Bool Decide wether start the animation on boot. false no
pixelDepth Number Number of step (in pixels) used when drawed on canvas. 0.02 no
lerpSpeed Number Lerp speed to interpolate properties. 0.01 no
curveDefinition ICurveDefinition[] Override definition of the curves, check above for more details. null no
ranges IiOS9Ranges Override the default random ranges of the curves. null no
globalCompositeOperation GlobalCompositeOperation globalCompositeOperation of the canvas, controls wave overlap design. "lighter" no

Ranges

Each wave chooses a random parameter for each of these ranges that factors into their creation. You can override these ranges by passing a ranges object to the constructor.

Here is the type of the ranges object:

export type IiOS9Ranges = {
  noOfCurves?: [number, number];
  amplitude?: [number, number];
  offset?: [number, number];
  width?: [number, number];
  speed?: [number, number];
  despawnTimeout?: [number, number];
};

API

new SiriWave

curveDefinition

By passing this argument, you're overriding the default curve definition resulting in a completely different style.

The default definition for the ios classic style is:

[
  { attenuation: -2, lineWidth: 1, opacity: 0.1 },
  { attenuation: -6, lineWidth: 1, opacity: 0.2 },
  { attenuation: 4, lineWidth: 1, opacity: 0.4 },
  { attenuation: 2, lineWidth: 1, opacity: 0.6 },
  { attenuation: 1, lineWidth: 1.5, opacity: 1 },
];

and it results in 5 different sin-waves with different parameters and amplitude.

You can set 4 attributes for each curve:

  • attenuation: the power factor determining the attenuation
  • lineWidth: the line width
  • opacity: the opacity
  • color: the color, default to SiriWave.color; optional

The ios9 style definition is instead:

[
  { color: "255,255,255", supportLine: true },
  { color: "15, 82, 169" }, // blue
  { color: "173, 57, 76" }, // red
  { color: "48, 220, 155" }, // green
];

and it results in 3 different colored waves + 1 support wave that needs to be there.

Here you set:

  • supportLine: only one of these curves must have this to true, it will be used to draw the support line
  • color: the color of the wave

start()

Start the animation

stop()

Stop the animation.

setSpeed(newValue)

Set the new value of speed (animated)

setAmplitude(value)

Set the new value of amplitude (animated)

dispose()

Stop the animation and destroy the canvas, by removing it from the DOM. Subsequent start() calls on this SiriWave instance will fail with an exception.

Grapher plots

Build and development

If you wanna make some modifications in your local environment, use:

npm dev

this will create a watchable build with RollupJS and automatically create a server to see your changes in the browser.

To finally build all targets:

npm build

QA

How do I integrate this library with a microphone user input?

You can find an excellent demo here by @semmel

siriwave's People

Contributors

andrenguyener avatar charliegerard avatar dependabot[bot] avatar gitter-badger avatar kopiro avatar krishkrosh avatar lastguest avatar mikemaccana avatar semmel avatar yujiaaoyujia avatar yulon 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  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

siriwave's Issues

In style "ios", setting color in curve definition doesn't affect the curve.

I want to have different colors for the curves, I am using the following curve definition
[ { attenuation: -2, lineWidth: 1, opacity: 0.6, color: "229,231,233", }, { attenuation: 2, lineWidth: 1, opacity: 0.8, color: "255,159,148", }, { attenuation: 1, lineWidth: 1.5, opacity: 1, color: "109,111,189", }, ]

But the wave is shown in default white color only.

NPM

Can we add this library to npm? 💃

Issue with getting it to work with IOS

Hi,
I am facing an issue getting this to work with microphone input on some versions of IOS but it doesn't seem to be consistent in terms of which versions it works on. Works fine in the browser(chrome) on both pc and android but does not work on ios chrome for some versions. If I talk about the versions I managed to get my hands on and test then an iphone 14 with IOS 17 worked whereas an iphone 13 with ios 16.x did not work.

Even opening the demo website for siriwave with micrphone (https://jsitor.com/PPQtOp9Yp) didn't work so it isn't something I did differently.
Any ideas what might be the problem? I suspect it might have to do with that specific ios version's handling of the DOM with the canvas object. Not sure.

Any help of suggestions would be much appreciated. I can try to get more information if requried.

Module import does not work with Typescript

Hi @kopiro Thank you for creating an amazing library. I was trying to use it my Typescript application with import SiriWave from 'siriwave'; but I get Cannot find module 'siriwave ts(2307)'. literally with any compilerOptions.module variants in tsconfig.ts.

Typescript module resolution gives me the following:

======== Resolving module 'siriwave' from 'c:/Projects/tstest/app.ts'. ========
Explicitly specified module resolution kind: 'NodeJs'.
Loading module 'siriwave' from 'node_modules' folder, target file type 'TypeScript'.
Found 'package.json' at 'c:/Projects/tstest/node_modules/siriwave/package.json'.
'package.json' does not have a 'typesVersions' field.
File 'c:/Projects/tstest/node_modules/siriwave.ts' does not exist.
File 'c:/Projects/tstest/node_modules/siriwave.tsx' does not exist.
File 'c:/Projects/tstest/node_modules/siriwave.d.ts' does not exist.
'package.json' does not have a 'typings' field.
'package.json' does not have a 'types' field.
'package.json' does not have a 'main' field.
File 'c:/Projects/tstest/node_modules/siriwave/index.ts' does not exist.
File 'c:/Projects/tstest/node_modules/siriwave/index.tsx' does not exist.
File 'c:/Projects/tstest/node_modules/siriwave/index.d.ts' does not exist.
Directory 'c:/Projects/tstest/node_modules/@types' does not exist, skipping all lookups in it.
Directory 'c:/Projects/node_modules' does not exist, skipping all lookups in it.    
Directory 'c:/node_modules' does not exist, skipping all lookups in it.
Loading module 'siriwave' from 'node_modules' folder, target file type 'JavaScript'.
Found 'package.json' at 'c:/Projects/tstest/node_modules/siriwave/package.json'.
'package.json' does not have a 'typesVersions' field.
File 'c:/Projects/tstest/node_modules/siriwave.js' does not exist.
File 'c:/Projects/tstest/node_modules/siriwave.jsx' does not exist.
'package.json' does not have a 'main' field.
File 'c:/Projects/tstest/node_modules/siriwave/index.js' does not exist.
File 'c:/Projects/tstest/node_modules/siriwave/index.jsx' does not exist.
Directory 'c:/Projects/node_modules' does not exist, skipping all lookups in it.
Directory 'c:/node_modules' does not exist, skipping all lookups in it.
======== Module name 'siriwave' was not resolved. ========

As a workaround I have added "main": "dist/siriwave.js" to package.json but I'm not sure that this is the way to go with rollup.js compilation. Meaning I do not know if rollup.js js generates package.json for you or not. Any suggestions on how to make the library usable in Typescript in the sane way?

Wave is not visible on iOS

Hello kopiro and team,

First of all, i would like to say thank you for setting up such a great project.

Good work. I'm already looking forward to the new version.

Unfortunately, I have the problem that on iOS devices (no matter which browser is used) the siri wave is not displayed. The div is rendered, but the line does not move.

I also don't get any errors in the developer console.

Any idea what this could be?

Unable to work from a webpack

I use Quasar/Vuejs,

The earlier version used to work well but it failed with this version.

import SiriWave from 'siriwave'

 methods: {
    initialized () {
      this.siriWave = new SiriWave({
        container: this.$refs['siri'],
        width: window.innerWidth,
        height: window.innerHeight * 0.12
      })
    }
  },
  mounted () {
    this.initialized()
  }
}

This throws an error telling SiriWave is not a constructor:

[Vue warn]: Error in mounted hook: "TypeError: siriwave__WEBPACK_IMPORTED_MODULE_1___default.a is not a constructor"

and

TypeError: siriwave__WEBPACK_IMPORTED_MODULE_1___default.a is not a constructor

Wave reuse problem

Hello
I use your library and encountered a problem. I use to draw the waves when talking (using a microphone)
After I stopped recording and started recording it again, the waves start to twitch
Can you tell me how to fix this?

On this demo page you can see it. Just press the “Record” button and the “Stop” button several times.

https://siriwavejs.herokuapp.com/

I’m really looking forward to the answer, as I use this library for my university project, which will be in two weeks

nice~ I just got a question

how do you analysis the animation. I mean from see it and coded it out, how to do it. What skill (or math knowledge) should I know to achieve this. Thanks.

a question, agin

sorry for bother you, agin...
I see through your code, change variable and play around. My final question is how do you come about the _globalAttenuationFn. I know this function is for reduce the y position from strongly > softly > strongly. where to find some good learning material to learn make this attenuation function. Thanks.

btw. like this animation very much, and your codepen demo was broken.

Issues when using with sveltekit

I found some issues when trying to use siriwave with sveltekit.

It always throw this error.

export { SiriWave as default };
^^^^^^

SyntaxError: Unexpected token 'export'
    at Object.compileFunction (node:vm:360:18)
    at wrapSafe (node:internal/modules/cjs/loader:1055:15)
    at Module._compile (node:internal/modules/cjs/loader:1090:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
    at Module.load (node:internal/modules/cjs/loader:1004:32)
    at Function.Module._load (node:internal/modules/cjs/loader:839:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:533:24)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I manage to get around this by changing the siriwave package.json adding this line

 type: 'modules' 
{
  "name": "siriwave",
  "version": "2.3.0",
  "description": "The Siri wave replicated in a JS library.",
  "module": "./dist/siriwave.esm.js",
  "main": "./dist/siriwave.esm.js",
  "browser": "./dist/siriwave.umd.js",
  "types": "./dist/types",
  "type": "module", // <------- this line
  "umdName": "SiriWave",
  "files": [
    "/dist",
    "/src"
  ],
  "scripts": {
    "gh-pages": "git checkout master && git pull && git checkout gh-pages && git reset --hard master && git push -f origin gh-pages && git checkout master",
    "build:declaration": "rm -rf ./dist/types && tsc --outDir ./dist/types --declaration && rm -rf ./dist/types/*.js",
    "build": "yarn build:declaration && NODE_ENV=production rollup -c",
    "dev": "BUILD=watch rollup -c -w"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/kopiro/siriwave.git"
  },
  "keywords": [
    "siri",
    "siriwave",
    "ios"
  ],
  "author": "Flavio De Stefano",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/kopiro/siriwave/issues"
  },
  "homepage": "https://github.com/kopiro/siriwave#readme",
  "devDependencies": {
    "@rollup/plugin-typescript": "^6.1.0",
    "eslint": "^7.14.0",
    "eslint-plugin-prettier": "^3.1.3",
    "prettier": "^2.0.5",
    "rollup": "^2.7.6",
    "rollup-plugin-livereload": "^2.0.0",
    "rollup-plugin-serve": "^1.1.0",
    "rollup-plugin-terser": "^7.0.2",
    "tslib": "^2.0.0",
    "typescript": "^4.1.2"
  }
}

after that I run yarn again, and its working just fine, no problem at all.

but every time I install new packages in my project, the siriwave package.json
get override to the old one, and every time I need to re add the line to it.

 type: 'modules' 

I am not sure the implication of adding this line in pakcage.json to current siriwave project. but if there's no significant effect, then maybe you can consider adding this line ? (just my suggestions)

sveltekit:doesn't appear to be written in CJS

Hi Kopiro,
after installing it on my project it throws this error:
siriwave doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix.

If you have encountered this problem before please let me know how you fixed it...

there is a noise

If write the code, there is a noise
analyser.connect(ctx.destination);
in mac(10.13 )chrome browser,why?

What effect does it have to get rid of it?

var ctx = new (window.AudioContext || window.webkitAudioContext)();
var analyser = ctx.createAnalyser();
//analyser.connect(ctx.destination);
analyser.fftSize = 2048;

API (speed,amplitude)

When we update speed or amplitude during runtime the animation is not smooth and change brutally, so it's not very nice looking.
Any chance to have this feature ?

By way nice work here..

Frequency and color don't update.

I try to update frequency and color using siriwave object, but it doesn't work. any idea? amplitude works correctly, but the frequency and color...

NPM version

I saw that SiriWave is still version 1.2.4 on NPM.
Can you update to version 1.3.0?

Thanks!

60fps support?

This is bring my 60fps existing animation down to ~24fps. Is there an option or plan to improve the rendering?

Not the same rendering between browsers

Hi there,
first thank you very much for this outstanding plugin.
Here's my issue : I don't have the same render between two browsers, the wave look thinner on Chrome then on Firefox.

On Firefox :
capture d ecran 2015-09-11 a 15 32 57

On Chrome :
capture d ecran 2015-09-11 a 15 33 08

Is there any way to obtain a 1px thickness on the both cases ?
Thank you very much.

Idea: dispose() method

In it's constructor SiriWave mutates the DOM by appending a <canvas> child to the target container DOM element.
Would it not be nice to have some dispose() method (i.e. something like a destructor) which reverses the effects of the constructor?

Basically such a method just would have to

dispose() {
   this.stop();
   this.canvas.remove();
   // But also: what if this instance is (wrongly) called again by the user?
   // ... throw on next start() ?
}

My use case:
I find myself destroying and creating new SiriWaves when my app's layout (i.e. the container element size) changes. So that width and height of the canvas are properly reset for the line animation. However unused canvas elements (owned by probably already garbage-collected SiriWaves) break my layout.

How to draw a straight line before and after a wave using siriwave.js

I've an issue using siriwave.js, I would like to have a line then the canvas which contains the wave but my problem is that the begin (at the left) and the end (at the right) of the wave both move. It result that I can't give a sense of continuity between my line and the canvas.

Here's a link to illustrate my problem :
http://stackoverflow.com/questions/31235493/how-to-draw-a-straight-line-before-and-after-a-wave-using-siriwave-js

Does anyone knows how to fix that ? Many thanks

amplitudes remain zero when too much time elapses between new SiriWave() and start()

Demo:

In the demo in the left and right containers two otherwise identical SiriWave instances are created at startup time. The left is run (with random data) right away, while the right gets run but on a click of the button below.

If more than a couple of seconds elapse before the right SiriWave instance is started, it's y amplitudes remain zero and just a white zero line is drawn. On the other hand if you click the button quickly after loading, both visualisations behave similar.

I have not found this to be the case for the "ios" visualisation.

Analysis

I guess it's the this.spawnAt timestamp in ios9curve.ts which is set once at construction time and then becomes relatively small compared to the timestamp at the later point when start() and subsequently draw() is called. Thus in the draw() method the time comparison in the for loop always decreases this.amplitudes[ci] which in turn causes the _ypos() method to always compute 0.

Quick fix

Respawn all curves in start() by adding a line in index.ts:

start() {
        this.phase = 0;
        // Ensure we don't re-launch the draw cycle
        if (!this.run) {
            this.run = true;
            this.curves.map(curve => curve.respawn());  // <--- Added this line
            this.startDrawCycle();
        }
    }

Note that with this fix for autostart: true, respawn is called twice in a row:

  • from the curve constructor and
  • from SiriWave constructor again via SiriWave.start()

Screenshot 2020-12-17 at 19 47 44

sound wave with siriwave

I'm making sound player that lets you play heartbeats. The problem is that I don't know how to load that sound, also I need to get top peaks in sound and based on volume/noise of that peaks I need to create amplitude with that heigth.

I don't understand your graph because I'm not that good in math, and I didn't learn that in school yet.

Android WebView

Hi, I'm using the Siriwave in an application and i need it to look still like no one is speaking. I tried doing changing the amplitude and the speed to .01 but the speed didn't change. Any ideas? The speed attribute seems to be unresponsive.

Demo

This demo is a modernised version of the old demo.

It does not use the deprecated ScriptProcessorNode API. Also I attempted to explain in the comments how speed and frequency can be calculated from an audio source signal.

Would be great that could be integrated into this project.

Edit:
Does not run in Safari, because I did not polyfill requestIdleCallback, which however would be easy.

Build TypeScript target version does not match Rollup output type

Just nitpicking, but setting the TypeScript compile target to es5 and then bundling to an ES6 module with rollup does not make sense.

It may not hurt bad, except for readability and debugability for all who import dist/*.esm.js.

The options for the TypeScript rollup plugin permit setting the target dynamically overriding those in tsconfig.json.

E.g. plugins:[typescript({target: "es6"})]

Edit:
I managed to quickly hack a proof of concept.

// just the edited lines in rollup.config.js
import typescript from "@rollup/plugin-typescript";
// ...
const plugins = [
  typescript({
    target: "es6",
    lib: ["es5", "es6", "ESNext", "dom"]
  }),
];

Unfortunately the upgraded TypeScript rollup plugin has a nasty bug which required some editing in tsconfig.json too:

{
  "compilerOptions": {
    "module": "es6",
    "noImplicitAny": true,
    "target": "es5",
    "moduleResolution": "node"
  },
  "include": ["src/*.ts"],
  "exclude": ["node_modules"]
}

It was also necessary for me to npm install tslib. Being not interested in TypeScript, I have not investigated further.

Btw.

  1. I did not find any license for siriwave. We're a very small company and would perhaps use it in one of our products.
  2. We really like your work, it's a really artistic visualisation.

Update colors to match?

Great plugin. I'd like all waves to match the same RGB code, but when I try this, they still create a blend filter lightening most of them. Is this avoidable or is there a section (even in the min code) that I can update to change this?

Integrated in angular/typescript

hey sir, thank you for the beatiful animation. I would like to add it to my chatbot written in Angular.
I added this code to ngOnInit():
this.siriWave = new SiriWave({
container: document.querySelector("#myWave"),
cover: true,
height: 100,
style: "ios9"
});

But somehow i am getting the error: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'. Can you please help me out ?

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.