Code Monkey home page Code Monkey logo

pixi-dashed-line's Introduction

pixi-dashed-line

A pixi.js implementation to support dashed lines in PIXI.Graphics.

  • Two implementations of a dashed line for pixi.js: lineTo/moveTo w/gaps (preferred), and texture-based (using a dashed-line texture when drawing the line)
  • Dashed support for lineTo, drawCircle, drawEllipse, drawPolygon
  • Dashed lines can be scaled (allows for dashed lines to remain the same size regardless of zoom level)

Live Demo

https://davidfig.github.io/pixi-dashed-line (source code)

Documentation

class DashLine

constructor(graphics: PIXI.Graphics, options?.DashLineOptions)

DashLine.DashLineOptions = {
    useTexture?=false - whether to use a texture or moveTo/lineTo (see notes below in README.md)
    dashes?=[10, 5] - an array holding one or more [dash, gap] entries, eg, [10, 5, 20, 10, ...])
    width?=1 - width of the dashed line
    color?=0xffffff - color of the dashed line
    alpha?=1 - alpha of the dashed line
    options.cap? - add a PIXI.LINE_CAP style to dashed lines (only works for useTexture: false)
    options.join? - add a PIXI.LINE_JOIN style to the dashed lines (only works for useTexture: false)
    options.alignment? - change alignment of lines drawn (0.5 = middle, 1 = outer, 0 = inner)
}

moveTo(x: number, y: number)

Moves cursor to location

lineTo(x: number, y: number, closePath?: boolean)

Draws a dashed line. If closePath = true, then lineTo will leave a proper gap if its destination is the first point (ie, if this line closes the shape)

drawCircle(x: number, y: number, radius: number, points=80, matrix?: PIXI.Matrix)

where x,y is the center of circle, and points are the number of points used to draw the circle; matrix is applied before the draw (this adds a shape-specific transform to pixi's DisplayObject transforms)

drawEllipse(x: number, y: number, radiusX: number, radiusY: number, points=80, matrix?: PIXI.Matrix)

where x,y is the center of ellipse, and points are the number of points used to draw the ellipse; matrix is applied before the draw (this adds a shape-specific transform to pixi's DisplayObject transforms)

drawRect(x: number, y: number, width: number, height: number, matrix?: PIXI.Matrix)

draws a dashed rectangle; matrix is applied before the draw (this adds a shape-specific transform to pixi's DisplayObject transforms)

drawPolygon(PIXI.Point[] | number[], matrix?: PIXI.Matrix)

draws a dashed polygon; matrix is applied before the draw (this adds a shape-specific transform to pixi's DisplayObject transforms)

setLineStyle()

changes line style to the proper dashed line style -- this is useful if the graphics element's lineStyle was changed

Simple Example

import { DashLine } from 'pixi-dashed-lines'

...
const g = stage.addChild(new PIXI.Graphics())

const dash = new DashLine(g, {
    dash: [20, 10],
    width: 5,
    color: 0xff0000,
})

// draws a dashed triangle
dash.moveTo(0, 0)
    .lineTo(100, 100)
    .lineTo(0, 100)
    .lineTo(0, 0)

When to use options.useTexture = true

For most use-cases, the lineTo/moveTo (options.useTexture = false) is better because it provides a more accurate implementation and supports cap and join styles.

The texture-based approach (options.useTexture = true) is useful when the geometry is very large or very small as PIXI.Graphics does not handle those cases well (see https://www.html5gamedevs.com/topic/24876-weird-lines-when-using-extreme-coordinate-values/). You'll know you need this if zooming in and out on the dashed line causes out of memory errors :)

Technical Notes on options.useTexture = true

options.useTexture=true does not use pixi.js's line joins and caps for connecting lines (see https://mattdesl.svbtle.com/drawing-lines-is-hard): instead it uses Graphics.lineTextureStyle to supply a texture to draw the dashed lines. The texture needs a custom matrix to properly rotate the dash based on the angle of the next line (and to translate the texture so it starts properly (see https://www.html5gamedevs.com/topic/45698-begintexturefill/)). Without the matrix, the dash's length will change as the line's angle changes.

Regrettably, pixi.js does not provide a mechanism to change the matrix of a texture without breaking the current line with a moveTo command. (This was my key insight that finally got this working. I banged my head many hours trying to figure out why the texture did not rotate properly. The answer was that you have to moveTo before changing the matrix.)

Future work

Ideally, the dashed line functionality should be built directly into pixi.js's Graphics line drawing module w/logic that separates the triangles of the dashed line to take into account changes in the angle of the line. I thought about adding it, but decided the amount of work was not worth it. (Especially since the use case for useTexture is limited to strange PIXI.Graphics geometries.) Maybe someone does a different calculus and adds this feature directly into pixi.js and makes this library obsolete.

License

MIT License (c) 2021 David Figatner

pixi-dashed-line's People

Contributors

davidfig 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

Watchers

 avatar  avatar  avatar

pixi-dashed-line's Issues

Support alignment lineStyle option

It would be nice if the DashLineOptions would support the alignment property of PIXI.Graphics similar to the cap and join options as described in #2.
I also did a quick test by editing the pixi-dashed-line/index.js and it also worked for me (with useTexture: false).

Support cap and join lineStyle options

PIXI.Graphics supports different line cap and join styles and it would be great to have these supported when drawing dashed lines.

I did a quick test by editing my pixi-dashed-line/index.js to add cap: PIXI.LINE_CAP.ROUND and join: PIXI.LINE_JOIN.ROUND in the DashLine constructor where lineStyle is called. It appears to work perfectly when not using textures.

image

With textures enabled, the caps do not work:
image

I don't know whether this is easily fixed, but I think having cap and join style options exposed in the DashLineOptions would be a nice addition even if it did require useTexture: false.

Dashed Curved Lines

Would it be possible to add support for the bezierTo function so that we could create dashed curved lines? Are there any fundamental limitations to doing this?

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.