【问题标题】:How to draw a dashed line across a rectangle in PixiJS and Angular?如何在 PixiJS 和 Angular 中的矩形上绘制虚线?
【发布时间】:2018-10-03 06:55:24
【问题描述】:

下面的 sn-p 在它自己的 PixiJS 应用程序中绘制一个填充的实线矩形。 PIXI.Graphics 没有提供绘制虚线的内置方法。

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);
    }
}

【问题讨论】:

    标签: angular pixi.js


    【解决方案1】:

    我建议您将任何试图操纵 html 的代码移至 ngAfterViewInit 方法。

    此外,您可以使用 @ViewChild 装饰器获取对 html 模板中任何元素的引用。这样您就不必使用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 
      }
    }
    

    【讨论】:

      【解决方案2】:

      你试过看https://github.com/pixijs/pixi.js/issues/1333 吗? 这是多边形代码。

      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();
      

      【讨论】:

        【解决方案3】:

        另一个简单的解决方案是使用虚线。我也回复了https://github.com/pixijs/pixi.js/issues/1333

        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);
        &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.7.1/pixi.min.js"&gt;&lt;/script&gt;

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-01-24
          • 2019-06-15
          • 2020-06-26
          • 2013-04-01
          • 1970-01-01
          • 2019-03-11
          • 1970-01-01
          相关资源
          最近更新 更多