GithubHelp home page GithubHelp logo

ng-rive's Introduction

Angular Rive

A repository for Angular built around the rive canvas runtime.

GitHub npm npm

Compatibility

Animations built before version 0.7.0 rive-canvas will not work with new versions of ng-rive.

Angular ng-rive @rive-app/canvas-advanced
>=15 0.3.* 2..
14-15 0.2.6 1.1.6
12-13 0.1.* 0.7.* (rive-canvas)
<12 0.0.* 0.6.* (rive-canvas)

Note: Version 0.3.0 and above use standalone component.

Get started

  1. Install :
npm install ng-rive

Note: since version 0.3.0 we install @rive-app/canvas-advanced with ng-rive to avoid mismatching version.

  1. Module vs standalone RiveModule:

  2. Module RiveModule

import { RiveModule } from 'ng-rive';

@NgModule({
  declarations: [MyComponent],
  imports: [
    CommonModule,
    RiveModule,
  ],
})
export class MyModule { }
  1. Standalone:
import { RiveCanvas, RiveLinearAnimation } from 'ng-rive';
@Component({
  ...
  standalone: true,
  imports: [
    RiveCanvas,
    RiveLinearAnimation,
    ...
  ],
})
export class MyComponent {}
  1. Add your .riv file in your assets
|-- assets
|   |--rive
|      |-- knight.riv

If you want to change the path you can specify it with the RIVE_FOLDER provider:

import { RiveModule, RIVE_FOLDER } from 'ng-rive';
@NgModule({
  declarations: [MyComponent],
  imports: [
    CommonModule,
    RiveModule,
  ],
  providers: [{
    provide: RIVE_FOLDER,
    useValue: 'assets/animations',
  }]
})
export class MyModule { }
  1. Use in template :
<canvas riv="knight" width="500" height="500">
  <riv-animation name="idle" play></riv-animation>
</canvas>
  1. Debug: If you see the error Error: Can't resolve 'fs', add this in your package.json:
"browser": {
  "fs": false,
  "path": false
}
  1. (Bonus) Rive wasm runtime custom location:

If you want to host the rive wasm (WebAssembly runtime environment) yourself or use a cdn other than unpkg, you can do so with the RIVE_WASM provider:

import { RiveModule, RIVE_WASM } from 'ng-rive';
@NgModule({
  declarations: [MyComponent],
  imports: [
    CommonModule,
    RiveModule,
  ],
  providers: [{
    provide: RIVE_WASM,
    useValue: 'assets/rive/rive.wasm',
  }]
})
export class MyModule { }

to build the rive wasm runtime with the angular project it must be added into your angular.json config file. the rive.wasm runtime is provided with the @rive-app/canvas-advanced package. This package is already part of @ng-rive. This can be configured as follows:

...
  "architect": {
    "build": {
      ...
      "options": {
        ...
        "assets": {
          ...,
          {
            "glob": "*.wasm",
            "input": "node_modules/@rive-app/canvas-advanced/",
            "output": "assets/rive/"
          },
          ...
        },
        ...
      },
      ...
    },
    ...
  },
...
  1. (Bonus) Rive version If you want to set a specific version for your wasm file you can use the RIVE_VERSION injection token.
  providers: [{
    provide: RIVE_VERSION,
    useValue: 'latest',
  }]

ng-rive used to default to "latest", but it created some issue in production app. Now it defaults to the latest version used when the library is publish. You can see the current default version here.

API

Canvas

The RiveCanvas loads a .riv animation file into it's canvas tag :

Input

  • [riv]: The .riv file or it's name if in the asset. Full path is managed by the RIVE_FOLDER token.
  • [artboard]: The name of the artboard to used. If not specified, the default one is used.
  • [width]: The width of the canvas in pixel.
  • [height]: The height of the canvas in pixel.
  • [fit]: How the animation should fit inside the canvas.
  • [alignment]: Where the animation should be positioned inside the canvas.
  • [lazy]: If provided, the file will only be loaded when canvas is visible in the viewport.
  • [viewbox]: Enable zoom in the canvas. Expect a string minX minY maxX maxY. Default 0 0 100% 100%.

⚠️ The lazy input use the IntersectionObserver API which will not work in all browser.

Output

  • (artboardChange): Emit the new Artboard

Examples

Canvas zoomed from "25% 25%" (top left), to "75% 75%" (bottom right).

<canvas riv="knight" viewbox="25% 25% 75% 75%" width="500" height="500"></canvas>

Animation

Run an animation inside a canvas based on name or index:

<canvas riv="knight" width="500" height="500">
  <riv-animation name="idle" play speed="0.5"></riv-animation>
</canvas>

Input

  • [name]: The name of the animation in the file loaded by the canvas.
  • [index] The index of the animation in the file loaded by the canvas (used if name is not provided).
  • [play]: Bind the player to a boolean (playing: true, paused: false).
  • [speed]: The speed at which the animation should play. Negative values cause the animation to play backward.
  • [mix]: The weight of this application over another in the same Artboard.

Output

  • (load): Emitted the loaded LinearAnimation.

Player

Provide more control over the animation

<canvas riv="poison-loader" width="500" height="500">
  <riv-player #player="rivPlayer" name="idle" [time]="time" mode="one-shot"></riv-player>
</canvas>
<input type="range" step="0.1" (input)="time = $event.target.value" [min]="player.startTime" [max]="player.endTime" />

Input / Output

  • [(time)]: Bind the animation to a specific time
  • [(play)]: Bind the player to a boolean (playing: true, paused: false).
  • [(speed)]: The speed at which the animation should play. Negative values cause the animation to play backward.

Based on the mode, the play, time & speed might change automatically.

Input

  • [name]: The name of the animation in the file loaded by the canvas.
  • [index] The index of the animation in the file loaded by the canvas (used if name is not provided).
  • [mix]: The weight of this application over another in the same Artboard.

⚠️ Deprecated: These input will be remove in the next version

  • [mode]: Force a mode: "one-shot", "loop" or "ping-pong" (if undefined, default mode is used).
  • [autoreset]: If true, will reset the animation to start when done (only for one-shot mode).

Output

  • (load): Emitted the loaded LinearAnimation.
  • (timeChange): Emitted just before refreshing the canvas when play is true. This output will be triggered for every frame if listened to. As every output create a rendering cycle, use it with care.

Node

The RiveNode directive give you access to one node :

<canvas riv="knight">
  <riv-animation name="idle" play></riv-animation>
  <riv-node name="cloud" x="300"></riv-node>
</canvas>

This example will set the position of the cloud to 300px of its origin.

Important: You need to have at least one animation playing to modify a node.

Input

  • [x] The x position of the node.
  • [y] The y position of the node.
  • [scaleX] The scaleX of the node.
  • [scaleY] The scaleX of the node.
  • [scale] Apply scaleX & scaleY.
  • [rotation] Apply rotation on the node. If value is below 2*PI use radians, else degrees.

⚠️ If the property of the node is updated by the animation, the animation wins.


State Machine

You can manipulate the state of a state machine animation though inputs:

<canvas riv="skills">
  <riv-state-machine name="move" play>
    <riv-input name="Level" [value]="level.value"><riv-input>
  </riv-state-machine>
</canvas>
<input type="radio" formControl="level" value="0" > Beginner
<input type="radio" formControl="level" value="1"> Intermediate
<input type="radio" formControl="level" value="2"> Expert

Input

  • [name] The name of the state machine in the file loaded by the canvas.
  • [index] The index of the state machine in the file loaded by the canvas (used if name is not provided).
  • [play]: Bind the player to a boolean (playing: true, paused: false).
  • [speed]: The speed at which the animation should play. Negative values cause the animation to play backward.

Output

  • (load): Emitted the loaded StateMachine.
  • (stateChange): Emitted the names of the states that have changed.

State Machine Input

The riv-input enables you to manipulated the state machine:

<canvas riv="skills">
  <riv-state-machine name="move" play>
    <riv-input #trigger="rivInput" name="Level"><riv-input>
  </riv-state-machine>
</canvas>
<button (click)="tigger.fire()">Trigger change</button>

Input

  • [name] The name of the input
  • [value] The value of the input, only if the type of the input is Boolean or Number

Ouput

  • (load) Emit the State Machine Input object when it's loaded from the rive file.
  • (change) Emit when the input value is changed or if fired.

Method

  • fire() Trigger a change, only if the type of the input is Trigger

Technics

Play if canvas is visible

To save ressources you can play the animation only when the canvas is visible in the viewport :

<canvas #canvas="rivCanvas" riv="knight" width="500" height="500">
  <riv-animation name="idle" [name]="canvas.isVisible | async"></riv-animation>
</canvas>

Multiple Animations

You can run multiple animations within the same canvas :

<canvas riv="knight">
  <riv-player name="idle" play></riv-player>
  <riv-player name="day_night" play mode="ping-pong" speed="0.5"></riv-player>
</canvas>

ng-rive's People

Contributors

grandschtroumpf avatar kaisoellch 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

Watchers

 avatar  avatar  avatar

ng-rive's Issues

Change color

I would like to know how I can change the color of a fill, is it possible?

Rendering multiple rive assets together causes "BindingError" and One Shot animation doesn't reset properly

Hi, first of all thanks for the package, I recently used this extensively in a demo Ionic + Angular app, you can see the demo for that here, overall the package works just fine, but there were some issues I faced, which I'm detailing below.

1. Loading multiple rive assets together causes "BindingError"

The app uses many rive assets in a single screen, which as they are all rendered together cause many to fail and only few are successfully rendered, as you can see below.

image

for others, the package throws "BindingError: Expected null or instance of StateMachine, got an instance of Animation"

image

Though luckily, I was able to find a workaround for this, the trick was to load them all with some delay, as you can see here

image

and only render after value is true, like here

image

So this fixed the issue, only that this workaround is needed to be applied on almost every rive asset used on the page like here and here and few more.

Though this particular issue is also reported on #26.

2 One Shot animations keeps on repeating

It's better to explain it through a video.
it's just a simple button, with mode one-shot and autoreset true, the code for this can be found here, as you can see in the video it doesn't reset properly, sometimes it plays for once, sometimes for 2, 4, 7, 8 etc. times.
Maybe I didn't use this asset properly, so feel free to correct me. The detail about the button asset can be found here.

ng-rive_animation_reset_issue.mp4

These 2 were the main issues that I encountered, let me know if more info is needed.

This demo can also be used as a good case study for possible improvements.

Thanks!

Angular + Rive Text

Issue request after this conversation on the rive discord group:

I was asking how to implement rive text with angular:

Me:
this works for me to set input and stuff

<canvas #riveCanvas id="canvas" [ngClass]="{'up': !focus, 'down': focus}" riv="edenaut_moon" width="1920" height="1080" >

<riv-input name="aura" [value]="this.playerData.pot_active">
<riv-input name="solar-robot-on-init" [value]="this.playerData.solar_robot">
<riv-input name="adam" [value]="this.playerData.adam">
<riv-input name="piaget-visible" [value]="this.playerData.piaget_visible" >
<riv-input name="tech-lab-visible" [value]="this.playerData.tech_lab_visible" >
<riv-input #trigger="rivInput" name="trigger-eden">

BUT

how to set text? tutorials didn't fit for me

i tried something like this but the canvas never showed up...

<canvas id="canvas" [ngClass]="{'up': !focus, 'down': focus}" width="1920" height="882">

with

import {Rive} from '@rive-app/canvas'
ngOnInit(): void {
this.r = new rive.Rive({
src: "edenaut_moon.riv",
canvas: document.getElementById("canvas"),
autoplay: true,
artboard:"Edenauts" ,
stateMachines: ["State Machine 1"],
onLoad: () => {
// then setting the text
}
}});

can anybody help me achieve that?

m_andrasch
Mh just an educated guess:

Seems like onLoad is not yet implemented in ng-rive API, at least it is not documented: https://github.com/dappsnation/ng-rive?tab=readme-ov-file#api

You could open an issue here
https://github.com/dappsnation/ng-rive/issues

Much success!

Cannot have multiple artboard on the same page

I'm using Angular 16.2.3, standalone way.

Each time I add more than one <canvas> in a component, I got an error...

main.ts

bootstrapApplication(AppComponent, {
  providers: [
    {provide: RIVE_FOLDER, useValue: 'assets/animations'},
    {provide: RIVE_WASM, useValue: 'assets/rive/rive.wasm'},
    {provide: RIVE_VERSION, useValue: '2.1.0'},
    {provide: RouteReuseStrategy, useClass: IonicRouteStrategy},
    importProvidersFrom(IonicModule.forRoot({}), RiveModule),
    provideRouter(routes),
  ],
});

curtains.component.ts

import {Component, OnInit} from '@angular/core';
import {RiveCanvas, RiveLinearAnimation} from 'ng-rive';

@Component({
  selector: 'app-curtains',
  templateUrl: './curtains.component.html',
  styleUrls: ['./curtains.component.scss'],
  standalone: true,
  imports: [RiveCanvas, RiveLinearAnimation],
})
export class CurtainsComponent implements OnInit {
  constructor() {
  }

  ngOnInit() {
  }
}

curtains.component.html

<canvas
  riv="magic_ball"
  [artboard]="'CurtainsTopArtBoard'"
  width="1500"
  height="375"
  style="position: absolute;top: 0;left: 0;width: 100%;height: auto;aspect-ratio: 4"
  fit="fill">
  <riv-animation name="CurtainsTopOpening" play></riv-animation>
</canvas>

<canvas
  riv="magic_ball"
  [artboard]="'CurtainsSidesArtBoard'"
  width="1500"
  height="2250"
  style="position: absolute;top: 0;left: 0;width: 100%;height: 100%;"
  fit="fill">
  <riv-animation name="CurtainsSidesOpening" play></riv-animation>
</canvas>

Error thrown

zone.js:177 Uncaught BindingError: Expected null or instance of LinearAnimation, got an instance of Animation
    at Q (canvas_advanced.mjs:39:301)
    at Mb (canvas_advanced.mjs:50:38)
    at Rb.Pb [as toWireType] (canvas_advanced.mjs:51:399)
    at Wa.<anonymous> (canvas_advanced.mjs:58:8)
    at Wa.<anonymous> (canvas_advanced.mjs:80:10)
    at new LinearAnimationInstance (canvas_advanced.mjs:39:189)
    at RiveLinearAnimation.initAnimation (ng-rive.mjs:829:25)
    at ng-rive.mjs:838:62
    at map.js:7:37
    at OperatorSubscriber._next (OperatorSubscriber.js:13:21)

StackBlitz reproduction

https://stackblitz.com/edit/stackblitz-starters-nwmvhu?file=src%2Fcomponents%2Fcurtains%2Fcurtains.component.html

You can remove one canvas on the curtains.component.html file and check that it works again...

module vs standalone setup errors

I'm using v0.3.0 with a standalone component and getting errors while navigating.

If I set up my component with RiveCanvas and RiveLinearAnimation in the imports, it doesn't run the animation and I get the following error:

main.ts:6 ERROR NullInjectorError: R3InjectorError(AppModule)[RiveService -> RiveService]: 
  NullInjectorError: No provider for RiveService!
    at NullInjector.get (core.mjs:8771:27)
    at R3Injector.get (core.mjs:9200:33)
    at R3Injector.get (core.mjs:9200:33)
    at ChainedInjector.get (core.mjs:13007:36)
    at lookupTokenUsingModuleInjector (core.mjs:4436:39)
    at getOrCreateInjectable (core.mjs:4484:12)
    at Module.ɵɵdirectiveInject (core.mjs:10778:12)
    at NodeInjectorFactory._class2_Factory [as factory] (ng-rive.mjs:80:84)
    at getNodeInjectable (core.mjs:4669:44)
    at instantiateAllDirectives (core.mjs:11598:27)

If I use RiveModule instead, the animation runs but I also get this error:

ERROR BindingError: LinearAnimationInstance instance already deleted
    at Q (canvas_advanced.mjs:39:301)
    at Hb (canvas_advanced.mjs:47:153)
    at Ib.delete (canvas_advanced.mjs:71:45)
    at ng-rive.mjs:806:47
    at timer (zone.js:2367:41)
    at _ZoneDelegate.invokeTask (zone.js:402:31)
    at core.mjs:25990:55
    at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:25990:36)
    at _ZoneDelegate.invokeTask (zone.js:401:60)
    at Object.onInvokeTask (core.mjs:26300:33)

Not sure what I'm doing wrong, it's not that complex of a setup. Here's some of the code, I'm just intercepting HTTP requests and using a service to display the animation component:

loader.interceptor.ts:

@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
  constructor(private loader: FullScreenLoaderService) {}
  public intercept(
    req: HttpRequest<any>,
    next: HttpHandler,
  ): Observable<HttpEvent<any>> {
    this.loader.showLoader()
    return next.handle(req).pipe(finalize(() => this.loader.hideLoader()))
  }
}

full-screen-loader.service.ts:

@Injectable({
  providedIn: 'root',
})
export class FullScreenLoaderService {
  private apiCount = 0
  private isLoadingSubject = new BehaviorSubject<boolean>(false)
  public isLoading$ = this.isLoadingSubject.asObservable()

  public showLoader(): void {
    if (this.apiCount === 0) {
      this.isLoadingSubject.next(true)
    }
    this.apiCount++
  }

  public hideLoader(): void {
    this.apiCount--
    if (this.apiCount === 0) {
      this.isLoadingSubject.next(false)
    }
  }
}

full-screen-loader.component.ts:

@Component({
  selector: 'app-full-screen-loader',
  standalone: true,
  imports: [CommonModule, RiveModule], // OR  [CommonModule, RiveCanvas, RiveLinearAnimation],
  templateUrl: './full-screen-loader.component.html',
  styleUrls: ['./full-screen-loader.component.scss'],
})
export class FullScreenLoaderComponent {
  constructor(public loader: FullScreenLoaderService) {}
}

full-screen-loader.component.html:

<div
  *ngIf="loader.isLoading$ | async"
  class="w-full h-full fixed block top-0 left-0 bg-white opacity-90 z-50"
>
  <div
    class="w-full h-full bg-white opacity-75 z-50 flex justify-center items-center"
  >
    <app-loader-animation></app-loader-animation>
  </div>
</div>

Any ideas?

Missing declaration files.

When installing and importing Rive as a Module in a Module, following error appears:

node_modules/ng-rive/lib/component/node.d.ts:4:22 - error TS7016: Could not find a declaration file for module 'rive-canvas'. '/xxxxx/node_modules/rive-canvas/rive.min.js' implicitly has an 'any' type.
Try npm install @types/rive-canvas if it exists or add a new declaration (.d.ts) file containing declare module 'rive-canvas';

Installting those types, including new declaration files, or ts-ignoring don't do anything.

2-way bindings deprecated ?

When we use the <riv-player>, the documentation states that we can use the [(play)] binding.
But, in the code, it seems to be deprecated :

/** @deprecated will be removed */
@Output() playChange = new EventEmitter<boolean>();

How can we know if the animation is playing / is finished, without using this ?
Is there any other event we can use ?

Thanks !

v 0.2.6 LinearAnimationInstance instance already deleted

We use <riv-animation> tag to display a custom loader instead of <mat-spinner> from materials.
When page is loaded, <riv-animation> is not displayed anymore and we have a message LinearAnimationInstance instance already deleted .

This was not the case with 0.2.3

Listeners not working?

Thanks for an interesting library!

We have an Angular 15 app (using OnPush change detection if it matters).
When we try using Rive animations none of the Listeners specified by the designer appear to have any effect.

For example, onmousemove or onpointerdown don't appear to have any effect and the animation is completely non-interactive in Angular, despite being interactive in the play/demo mode.

Is this to be expected or are we doing something incorrectly in our Angular code?

Best regards!
/Magnus

"shouldFire" fails

Hi !

I use the fire() method, but instead of using a (click)="...", I use the reference in the component :

  @ViewChild('triggerElt') triggerElt!: RiveSMInput;

  ngAfterViewInit() {
    this.triggerElt.fire();
  }

It fails with this error :

Uncaught TypeError: input.fire is not a function

After some investigations, this comes from the "shouldFire" mechanism.

On the init method, input is used instead of this.input. I don't know how the getInput() function works, but it seems that the input object is not complete before going through :

    init(input) {
        if (!input || input.name === this.input?.name)
            return;
        this.input = getInput(input);
        this.load.emit(input);
        if (typeof this._value !== 'undefined') {
            this.input.value = this._value;
            this.change.emit(this.input);
        }
        if (this.shouldFire) {
            this.shouldFire(input); // <---- this line should be "this.shouldFire(this.input);"
            delete this.shouldFire;
        }
    }

Am I wrong ? This solves my problem...

Thanks !

State machine binding error

Hello! I tried to use state machine in my code but I get bindingError: 'function StateMachineInstance.advance called with 1 arguments, expected 2 args!' when the play is true.

Could you help me why?

<canvas riv="rocketWithText"> <riv-state-machine name="State Machine 1" play> <riv-input name="Text" [value]="100"></riv-input> <riv-input name="Fire" [value]="100"></riv-input> <riv-input name="Move" [value]="100"></riv-input> </riv-state-machine> </canvas>

Cannot read property 'apply' of undefined

Greetings, I am implementing Rive for animations in an angular app and I get the following error, I already followed the documentation and exported my animation for version 6, but I always get this error.

Captura

Update to use newer Rive app npm package? @rive-app/canvas is recommended

Looks like Rive has been fairly busy and updated the WASM runtimes significantly, and now have new npm packages they recommend instead of the rive-js / rive-canvas they previously used (and that this uses currently). Are there plans for this plugin to update to use the newer packages?

The migration guide indicates it should be compatible with the same API. The runtime docs recommend the @rive-app/canvas barring any specific needs, but I haven't looked into the specifics of whether that would just work with the existing Angular wrapper components here or if other updates would be needed, so I don't have a good sense of how big a task this is.

Could potentially allow closing #24 as their upstream recommendation is to use the newer runtime. And similarly for a JS error when WebAssembly isn't available I reported on their repo.

Cannot access 'RiveStateMachine' before initialization

Hi, I just created a fresh Angular 14 project, and this is the error I see :

Error in /turbo_modules/[email protected]/fesm2015/ng-rive.mjs (910:134) Cannot access 'RiveStateMachine' before initialization

AppModule.ts

import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { RiveModule } from 'ng-rive';
import { CommonModule } from '@angular/common';

@NgModule({
  imports: [CommonModule, RiveModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule {}

package.json

{
  "name": "angular",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "dependencies": {
    "@angular/animations": "^14.0.0",
    "@angular/common": "^14.0.0",
    "@angular/compiler": "^14.0.0",
    "@angular/core": "^14.0.0",
    "@angular/forms": "^14.0.0",
    "@angular/platform-browser": "^14.0.0",
    "@angular/platform-browser-dynamic": "^14.0.0",
    "@angular/router": "^14.0.0",
    "ng-rive": "^0.1.3",
    "rxjs": "~7.5.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^14.0.0",
    "@angular/cli": "~14.0.0",
    "@angular/compiler-cli": "^14.0.0",
    "@types/jasmine": "~4.0.0",
    "jasmine-core": "~4.1.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "typescript": "~4.7.2"
  },
  "browser": {
    "fs": false,
    "path": false
  }
}

Error with "OffscreenCanvas"

Getting errors in canvas.d.ts and types.d.ts regarding OffscreenCanvas and OffscreenCanvasRenderingContext2D.

Console output:
Compiled with problems:X

ERROR

node_modules/ng-rive/lib/canvas.d.ts:18:33 - error TS2304: Cannot find name 'OffscreenCanvas'.

18 canvas: HTMLCanvasElement | OffscreenCanvas;
~~~~~~~~~~~~~~~

ERROR

node_modules/ng-rive/lib/canvas.d.ts:38:43 - error TS2304: Cannot find name 'OffscreenCanvasRenderingContext2D'.

38 get ctx(): CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ERROR

node_modules/ng-rive/lib/types.d.ts:52:49 - error TS2304: Cannot find name 'OffscreenCanvasRenderingContext2D'.

52 constructor(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ERROR

node_modules/rive-canvas/types.d.ts:77:47 - error TS2304: Cannot find name 'OffscreenCanvasRenderingContext2D'.

77 constructor(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ERROR

node_modules/rive-canvas/types.d.ts:81:40 - error TS2304: Cannot find name 'OffscreenCanvasRenderingContext2D'.

81 draw(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, path: RenderPath): void;

Uncaught Error: Could not load animation before running it

Followed all the steps but, getting this log

zone.js:182 Uncaught Error: Could not load animation before running it at RiveAnimationDirective.moveFrame (ng-rive.js:624) at MapSubscriber.project (ng-rive.js:618) at MapSubscriber._next (map.js:29) at MapSubscriber.next (Subscriber.js:49) at FilterSubscriber._next (filter.js:33) at FilterSubscriber.next (Subscriber.js:49) at SwitchMapSubscriber.notifyNext (switchMap.js:66) at SimpleInnerSubscriber._next (innerSubscribe.js:10) at SimpleInnerSubscriber.next (Subscriber.js:49) at MapSubscriber._next (map.js:35)

Play when visible is not working

Quote from readme:

Play if canvas is visible

<canvas #canvas="rivCanvas" riv="knight" width="500" height="500">
  <riv-animation name="idle" [name]="canvas.isVisible | async"></riv-animation>
</canvas>

First: I believe, it should be something like

<riv-animation name="idle" [play]="canvas.whenVisible | async"></riv-animation>

Second the playback control over [play] input is not working at all.
I have a component which has play = false; and template:

<canvas [riv]="animation" width="640" height="325">
    <riv-animation [name]="animationName" [play]="play"></riv-animation>
</canvas>

<button (click)="play = !play">Play</button> {{play}}

Clicking button changes the play property, but animation does not start.

Using Angular 16.2.12, ng-rive 0.3.1

How to use custom WASM location in standalone component ?

Hi !

I'm creating a standalone component in an Angular project, and trying to add Rive following the documentation.

On the standalone component, I imports "RiveCanvas" and "RiveLinearAnimations".
To get <rive-*> DOM elements working, I add schema: [CUSTOM_ELEMENTS_SCHEMA] too (not in the documentation)

I want to avoid HTTP calls, and build the WASM file to use it.
Updating angular.json configuration file works great, the file is built.

To have the local WASM file used, I had to modify the main.ts file (changing the providers on the standalone component itself does not work) :

bootstrapApplication(AppComponent, {
  providers: [
    // [...]
    { provide: RIVE_WASM, useValue: 'assets/rive/rive.wasm' },
    { provide: RIVE_VERSION, useValue: '2.1.0' },
  ],
});

But now, when I load the component, I got this error :

R3InjectorError(Standalone[MyComponent])[RiveService -> RiveService -> RiveService -> RiveService]: NullInjectorError: No provider for RiveService!

So, when working on a standalone component, if we want to change the WASM file location, we have to load the entire module (+ update the main.ts file) on the component itself ?

Thanks !

Improve error message with suggestions & links

Error messages are quite generic and difficult to debug for developer that don't have a deep understanding of Rive.

Errors should :

  • Provide suggestions of what when wrong.
  • Provide a link to the documentation, or better, a "known issues" markdown file on Github that could be updated by the developers who experiences this issue.

Undefined is not an object.

Hello there,
I am new to rive and angular.
I am trying to follow the documentation provided, But having the following error [attached in screenshot].
I tried to change the rive files and tried to debug to the best of my ability. But still couldn't figure out the solution. I think the error is originating from the source files.
Can you please check the following error and help me out.
Thank you.

Screen Shot 2021-05-05 at 8 30 49 PM

documentation error

<button (click)="tigger.fire()">Trigger change

=>

<button (click)="trigger.fire()">Trigger change

Yo tigger! :)

"Expected null or instance of LinearAnimation, got an instance of Animation" error when used inside a lazy-module.

Setup

I have a generic angular applications with 3 modules - the app rootModule, a home featureModule and an about featureModule.
The Home and About featureModules are loaded lazily.
I have multiple animations playing in a page declared in the Home featureModule.
localhost.log

Procedure

  1. Navigate to the about page which is declared in the lazy-loaded aboutFeatureModule.
  2. Navigate back to the home page which is declared in the lazy-loaded homeFeatureModule.

Expectation

The animations declared in the home page should be loaded and played as soon as the user navigates to the page.

Observation / Issue

The animations are not loaded.
The following errors are printed to the console:

Uncaught BindingError {name: 'BindingError', message: 'Expected null or instance of LinearAnimation, got an instance of Animation', stack: 'BindingError: Expected null or instance of LinearA…) 

*the complete log file is viewable in the attached localhost.log

Notes

There are a total of 4 animations playing at the same time on four different canvases. occasionaly the last one loads perfectly without errors.

Gaps on the left and right side of Rive file in canvas

Problem

When I set the canvas size to the exact same size as the artboard in my Rive file, there are gaps on the left and right side that don't exist in the Rive file. The canvas size is rendered correctly when I inspect it in the browser. I didn't set a Fit style, so this is using the default "Contain" Fit:
image

How the Rive file looks on the artboard:

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.