All files / entities/base Line.js

0% Statements 0/29
0% Branches 0/20
0% Functions 0/10
0% Lines 0/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84                                                                                                                                                                       
import Element from "../Element";
import { ENTITY_TYPES } from "../constants";
 
import {
    LineBasicMaterial,
    LineDashedMaterial,
    BufferGeometry,
    Line as THREELine,
    Vector3,
} from "three";
 
const DEFAULT_LINE_COLOR = 0xffffff;
const DEFAULT_LINE_THICKNESS = 2;
 
export default class Line extends Element {
    constructor(points = [], options = {}) {
        super({
            points,
            ...options,
        });
 
        this.points = points;
 
        const material = this.buildMaterial();
        const geometry = this.getGeometryFromPoints();
        const body = new THREELine(geometry, material);
 
        this.setBody({ body });
        this.setEntityType(ENTITY_TYPES.MESH.TYPE);
        this.setEntitySubType(ENTITY_TYPES.MESH.SUBTYPES.LINE);
    }
 
    postBodyCreation() {
        super.postBodyCreation();
        const { dashed = false } = this.options;
 
        if (dashed) {
            this.body.computeLineDistances();
        }
    }
 
    buildMaterial() {
        const {
            color = DEFAULT_LINE_COLOR,
            dashed = false,
            thickness = DEFAULT_LINE_THICKNESS,
        } = this.options;
 
        return dashed
            ? new LineDashedMaterial({ color, linewidth: thickness })
            : new LineBasicMaterial({ color, linewidth: thickness });
    }
 
    getGeometryFromPoints() {
        const vectors = this.points.map(({ x = 0, y = 0, z = 0 }) => new Vector3(x, y, z));
 
        return new BufferGeometry().setFromPoints(vectors);
    }
 
    updatePoints = points => {
        const vectors = points.map(({ x, y, z }) => new Vector3(x, y, z));
        this.body.geometry.vertices = vectors;
        this.body.geometry.verticesNeedUpdate = true;
    };
 
    setThickness(thickness = DEFAULT_LINE_THICKNESS) {
        const numericThickness = Number(thickness) || DEFAULT_LINE_THICKNESS;
        this.body.material.linewidth = numericThickness;
    }
 
    toJSON(parseJSON = false) {
        if (this.isSerializable()) {
            return {
                ...super.toJSON(parseJSON),
                points: this.points,
            };
        }
    }
 
    static create(data = {}) {
        return new Line(data.points, data.options);
    }
}