4

Shape

The following snippet draws a filled, solid-stroked rectangle in its own PixiJS application. PIXI.Graphics provides no built-in way to draw dashed strokes.

import {
    Component,
    OnInit
} from '@angular/core';

import * as PIXI from 'pixi.js';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
    ngOnInit(): void {
        // Autodetect, create and append the renderer to the body element
        let renderer = PIXI.autoDetectRenderer(400, 400, {
            backgroundColor: 0xffffff,
            antialias: true
        });
        document.getElementById('demo').appendChild(renderer.view);
        // Create the main stage for your display objects
        let stage = new PIXI.Container();
        // Initialize the pixi Graphics class
        let graphics = new PIXI.Graphics();
        // Set the fill color
        graphics.beginFill(0x222222); // Red
        graphics.lineStyle(2, 0xff0000);
        // Draw a circle
        graphics.drawRoundedRect(240, 150, 100, 100, 10); // drawCircle(x, y, radius)
        // Applies fill to lines and shapes since the last call to beginFill.
        graphics.endFill();
        // Append child to Stage
        stage.addChild(graphics);
        // Rendering 
        renderer.render(stage);
    }
}
Shukant Pal
  • 706
  • 6
  • 19
Arun
  • 71
  • 1
  • 11

3 Answers3

1

Another simple solution is just use dashed lines. I answered https://github.com/pixijs/pixi.js/issues/1333 as well.

PIXI.Graphics.prototype.drawDashLine = function(toX, toY, dash = 16, gap = 8) {
  const lastPosition = this.currentPath.shape.points;

  const currentPosition = {
    x: lastPosition[lastPosition.length - 2] || 0,
    y: lastPosition[lastPosition.length - 1] || 0
  };

  const absValues = {
    toX: Math.abs(toX),
    toY: Math.abs(toY)
  };

  for (
    ;
    Math.abs(currentPosition.x) < absValues.toX ||
    Math.abs(currentPosition.y) < absValues.toY;
  ) {
    currentPosition.x =
      Math.abs(currentPosition.x + dash) < absValues.toX
        ? currentPosition.x + dash
        : toX;
    currentPosition.y =
      Math.abs(currentPosition.y + dash) < absValues.toY
        ? currentPosition.y + dash
        : toY;

    this.lineTo(currentPosition.x, currentPosition.y);

    currentPosition.x =
      Math.abs(currentPosition.x + gap) < absValues.toX
        ? currentPosition.x + gap
        : toX;
    currentPosition.y =
      Math.abs(currentPosition.y + gap) < absValues.toY
        ? currentPosition.y + gap
        : toY;

    this.moveTo(currentPosition.x, currentPosition.y);
  }
};

const app = new PIXI.Application();
document.body.appendChild(app.view);

const line = new PIXI.Graphics();
line.lineStyle(1, 0xffffff); 
line.moveTo(0,0);
line.drawDashLine(200, 200, 10, 3);

line.moveTo(150,0);
line.drawDashLine(150, 100, 20, 10);

line.moveTo(300,20);
line.drawDashLine(600, 20, 1, 3);

app.stage.addChild(line);
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.7.1/pixi.min.js"></script>
Martin Bokša
  • 188
  • 1
  • 1
  • 11
0

I'd advise you to move any code that tries to manipulate the html to the ngAfterViewInit method.

Also, you can get the reference to any element in your html template by using the @ViewChild decorator. That way you do not have to use document.getElementById('demo').

import {
  Component,
  AfterViewInit,
  ElementRef,
} from '@angular/core';
import * as PIXI from 'pixi.js';

@Component({
  selector: 'app-root',
  template: '<div #demo></div>',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  @ViewChild('demo') el: ElementRef;

  ngAfterViewInit(): void {
    let renderer = PIXI.autoDetectRenderer(400, 400, {
      backgroundColor: 0xffffff,
      antialias: true
    });

    this.demo.nativeElement.appendChild(renderer.view);
    // ... rest of the code 
  }
}
Tomasz Kula
  • 16,199
  • 2
  • 68
  • 79
0

Have you tried to look at https://github.com/pixijs/pixi.js/issues/1333 ? Here is polygon code.

PIXI.Graphics.prototype.drawDashedPolygon = function(polygons, x, y, rotation, dash, gap, offsetPercentage){
        var i;
        var p1;
        var p2;
        var dashLeft = 0;
        var gapLeft = 0;
        if(offsetPercentage>0){
            var progressOffset = (dash+gap)*offsetPercentage;
            if(progressOffset < dash) dashLeft = dash-progressOffset;
            else gapLeft = gap-(progressOffset-dash);
        }
        var rotatedPolygons = [];
        for(i = 0; i<polygons.length; i++){
            var p = {x:polygons[i].x, y:polygons[i].y};
            var cosAngle = Math.cos(rotation);
            var sinAngle = Math.sin(rotation);
            var dx = p.x;
            var dy = p.y;
            p.x = (dx*cosAngle-dy*sinAngle);
            p.y = (dx*sinAngle+dy*cosAngle);
            rotatedPolygons.push(p);
        }
        for(i = 0; i<rotatedPolygons.length; i++){
            p1 = rotatedPolygons[i];
            if(i == rotatedPolygons.length-1) p2 = rotatedPolygons[0];
            else p2 = rotatedPolygons[i+1];
            var dx = p2.x-p1.x;
            var dy = p2.y-p1.y;
            var len = Math.sqrt(dx*dx+dy*dy);
            var normal = {x:dx/len, y:dy/len};
            var progressOnLine = 0;
            this.moveTo(x+p1.x+gapLeft*normal.x, y+p1.y+gapLeft*normal.y);
            while(progressOnLine<=len){
        progressOnLine+=gapLeft;
                if(dashLeft > 0) progressOnLine += dashLeft;
                else progressOnLine+= dash;
                if(progressOnLine>len){
                    dashLeft = progressOnLine-len;
                    progressOnLine = len;
                }else{
                    dashLeft = 0;
                }
                this.lineTo(x+p1.x+progressOnLine*normal.x, y+p1.y+progressOnLine*normal.y);
                progressOnLine+= gap;
                if(progressOnLine>len && dashLeft == 0){
                    gapLeft = progressOnLine-len;
          console.log(progressOnLine, len, gap);
                }else{
                    gapLeft = 0;
                    this.moveTo(x+p1.x+progressOnLine*normal.x, y+p1.y+progressOnLine*normal.y);
                }
            }
        }
    }


// create app
var app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    antialias: true,
    backgroundColor: 0x808080
});
document.body.appendChild(app.view);


var polygons = [];
polygons.push({x:-50, y:-50});
polygons.push({x:-50, y:50});
polygons.push({x:50, y:50});
polygons.push({x:75, y:0});
polygons.push({x:50, y:-50});


var body = new PIXI.Graphics();
body.x = 200;
body.y = 100;
app.stage.addChild(body);

function animate(time) {
    body.rotation += 0.005;
    body.clear();
    body.lineStyle(1, 0x00FF00, 0.7);
    var offsetInterval = 750;
    body.drawDashedPolygon(polygons, 0, 0, 0, 10, 5, (Date.now()%offsetInterval+1)/offsetInterval);
    requestAnimationFrame(animate);
}
animate();
Martin Bokša
  • 188
  • 1
  • 1
  • 11