如何使用FabricJS绘制1/16英寸×1/16英寸网格

时间:2018-02-08 03:44:06

标签: javascript css html5 canvas fabricjs

我正在将FabricJS集成到我的角度应用程序中。我已经设法将画布缩小并自动将图形添加到画布中。

我的目标是通过8英寸使图形8英寸并添加具有动态网格高度和宽度的网格(比如说1/16英寸x 1/16英寸)。

以下是我的问题: 1.添加图形时,我无法以英寸为单位设置图形高度和宽度。我只能使用一个数字。我怎样才能使用不同的单位呢?我使用了cssOnly:true用于画布,但我似乎无法弄清楚这个数字。

 addFigure(figure) {
    let add: any;
    switch (figure) {
      case 'rectangle':
        add = new fabric.Rect({
          width: 500, height: 500, left: 150, top: 10, angle: 0, opacity: .3,
          fill: '#3f51b5'
        });
        break;
      case 'square':
        add = new fabric.Rect({
          width: 200, height: 200, left: 0, top: 0, angle: 0, opacity: .15,
          fill: '#4caf50'
        });
        break;
      case 'triangle':
        add = new fabric.Triangle({
          width: 100, height: 100, left: 10, top: 10, fill: '#2196f3'
        });
        break;
      case 'circle':
        add = new fabric.Circle({
          radius: 50, left: 10, top: 10, fill: '#ff5722'
        });
        break;
    }
    this.extend(add, this.randomId());
    console.log(add);
    this.canvas.add(add);
    // this.selectItemAfterAdded(add);
  }
  1. 图形高度显示200但看起来不正确。以下是上图作为正方形的示例。请注意,200宽度是正确的,但高度看起来不正确,因为画布是6英寸乘6英寸。高度延伸通过画布的底部。
  2. enter image description here

    1. 注意上面的网格。我有同样的问题。这是我从Adding grid over Fabric.js canvas提取的网格代码。我遇到的问题是我不知道如何将这个网格均匀地分成1/16英寸1/16英寸,因为这是一个8英寸乘8英寸的画布。

      onst gridGroup = new fabric.Group([],{left:0,top:0});

      const gridSize = 16;
      const gridWidth = 400;
      const gridHeight = 400;
      const lineOption = {stroke: 'rgba(0,0,0,.4)', strokeWidth: 1, selectable: false, strokeDashArray: [3, 3]};
      
      for (let i = Math.ceil(gridWidth / gridSize); i--;) {
        this.canvas.add( new fabric.Line([gridSize * i, 0, gridSize * i, gridHeight], lineOption) );
      }
      
      for (let i = Math.ceil(gridHeight / gridSize); i--;) {
        this.canvas.add( new fabric.Line([0, gridSize * i, gridWidth, gridSize * i], lineOption) );
      }
      
      this.canvas.add(gridGroup);
      
    2. 以下是供审核的整个组件。在设置中有什么我做错了吗?

       // private canvas: any;
        uploading = false;
        uploaded = false;
        pdfUrl = '';
        canvas: any;
        props: any = {
          canvasFill: '#ffffff',
          canvasImage: '',
          id: null,
          opacity: null,
          fill: null,
          fontSize: null,
          lineHeight: null,
          charSpacing: null,
          fontWeight: null,
          fontStyle: null,
          textAlign: null,
          fontFamily: null,
          TextDecoration: ''
        };
      
        textString: string;
        url = '';
        size: any = {
          width: '6in',
          height: '6in'
        };
      
        json: any;
        globalEditor = false;
        textEditor = false;
        imageEditor = false;
        figureEditor = false;
        selected: any;
      
        constructor(
          private router: Router,
          private userService: UserService,
          private fileService: FileService
        ) { }
      
        ngOnInit() {
          this.getActive();
          // this.activateCanvas();
      
          //setup front side canvas
          this.canvas = new fabric.Canvas('canvas', {
            hoverCursor: 'pointer',
            selection: true,
            selectionBorderColor: 'blue'
          });
      
          this.canvas.on({
            'object:moving': (e) => { },
            'object:modified': (e) => { },
            'object:selected': (e) => {
      
              const selectedObject = e.target;
              this.selected = selectedObject
              selectedObject.hasRotatingPoint = true;
              selectedObject.transparentCorners = false;
              // selectedObject.cornerColor = 'rgba(255, 87, 34, 0.7)';
              this.resetPanels();
      
              if (selectedObject.type !== 'group' && selectedObject) {
      
                this.getId();
                this.getOpacity();
      
                switch (selectedObject.type) {
                  case 'rect':
                  case 'circle':
                  case 'triangle':
                    this.figureEditor = true;
                    this.getFill();
                    break;
                  case 'i-text':
                    this.textEditor = true;
                    this.getLineHeight();
                    this.getCharSpacing();
                    this.getBold();
                    this.getFontStyle();
                    this.getFill();
                    this.getTextDecoration();
                    this.getTextAlign();
                    this.getFontFamily();
                    break;
                  case 'image':
                    break;
                }
              }
            },
            'selection:cleared': (e) => {
              this.selected = null;
              this.resetPanels();
            }
          });
      
          this.canvas.setWidth(this.size.width, {cssOnly: true});
          this.canvas.setHeight(this.size.height, {cssOnly: true});
      
          this.addFigure('square');
      
          const gridGroup = new fabric.Group([], {left: 0, top: 0});
      
          const gridSize = 16;
          const gridWidth = 400;
          const gridHeight = 400;
          const lineOption = {stroke: 'rgba(0,0,0,.4)', strokeWidth: 1, selectable: false, strokeDashArray: [3, 3]};
      
          for (let i = Math.ceil(gridWidth / gridSize); i--;) {
            this.canvas.add( new fabric.Line([gridSize * i, 0, gridSize * i, gridHeight], lineOption) );
          }
      
          for (let i = Math.ceil(gridHeight / gridSize); i--;) {
            this.canvas.add( new fabric.Line([0, gridSize * i, gridWidth, gridSize * i], lineOption) );
          }
      
          this.canvas.add(gridGroup);
      
          // for ( let x = 1; x < ( this.canvas.width / gridsize); x++) {
          //   this.canvas.add(new fabric.Line([cellWidth * x, 0, cellWidth * x, 800],
          //     { stroke: '#000000', strokeWidth: 1, selectable: false}));
      
          //   this.canvas.add(new fabric.Line([0, cellWidth * x, 800, cellWidth * x],
          //     { stroke: '#000000', strokeWidth: 1, selectable: false}));
          // }
      
          // get references to the html canvas element & its context
          // this.canvas.on('mouse:down', (e) => {
          // let canvasElement: any = document.getElementById('canvas');
          // console.log(canvasElement)
          // });
        }
      
      
        /*------------------------Block elements------------------------*/
      
        //Block "Size"
        changeSize(event: any) {
          this.canvas.setWidth(this.size.width);
          this.canvas.setHeight(this.size.height);
        }
      
        //Block "Add text"
        addText() {
          let textString = this.textString;
          let text = new fabric.IText(textString, {
            left: 10,
            top: 10,
            fontFamily: 'helvetica',
            angle: 0,
            fill: '#000000',
            scaleX: 0.5,
            scaleY: 0.5,
            fontWeight: '',
            hasRotatingPoint: true
          });
          this.extend(text, this.randomId());
          this.canvas.add(text);
          this.selectItemAfterAdded(text);
          this.textString = '';
        }
      
        //Block "Add images"
        getImgPolaroid(event: any) {
          let el = event.target;
          fabric.Image.fromURL(el.src, (image) => {
            image.set({
              left: 10,
              top: 10,
              angle: 0,
              padding: 10,
              cornersize: 10,
              hasRotatingPoint: true,
              peloas: 12
            });
            // image.setWidth(150);
            // image.setHeight(150);
            this.extend(image, this.randomId());
            this.canvas.add(image);
            this.selectItemAfterAdded(image);
          });
        }
      
        //Block "Upload Image"
        addImageOnCanvas(url) {
          if (url) {
            fabric.Image.fromURL(url, (image) => {
              image.set({
                left: 10,
                top: 10,
                angle: 0,
                // scaleX: 200,
                // scaleY: 200,
                padding: 10,
                cornersize: 10,
                hasRotatingPoint: true
              });
              image.scale(0.2);
              // image.setWidth(200);
              // image.height = 200;
              // image.width = 200;
              this.extend(image, this.randomId());
              this.canvas.add(image);
              this.selectItemAfterAdded(image);
            });
          }
        }
      
        readUrl(event) {
          if (event.target.files && event.target.files[0]) {
            const reader = new FileReader();
            reader.onload = (e) => {
              this.url = e.target['result'];
            };
            reader.readAsDataURL(event.target.files[0]);
          }
        }
      
        removeWhite(url) {
          this.url = '';
        }
      
      
        //Block "Add figure"
        addFigure(figure) {
          let add: any;
          switch (figure) {
            case 'rectangle':
              add = new fabric.Rect({
                width: 500, height: 500, left: 150, top: 10, angle: 0, opacity: .3,
                fill: '#3f51b5'
              });
              break;
            case 'square':
              add = new fabric.Rect({
                width: 200, height: 200, left: 0, top: 0, angle: 0, opacity: .4,
                fill: '#4caf50'
              });
              break;
            case 'triangle':
              add = new fabric.Triangle({
                width: 100, height: 100, left: 10, top: 10, fill: '#2196f3'
              });
              break;
            case 'circle':
              add = new fabric.Circle({
                radius: 50, left: 10, top: 10, fill: '#ff5722'
              });
              break;
          }
          this.extend(add, this.randomId());
          console.log(add);
          this.canvas.add(add);
          // this.selectItemAfterAdded(add);
        }
      
        /*Canvas*/
      
        cleanSelect() {
          this.canvas.discardActiveObject();
        }
      
        selectItemAfterAdded(obj) {
          this.canvas.discardActiveObject();
          this.canvas.setActiveObject(obj);
        }
      
        setCanvasFill() {
          if (!this.props.canvasImage) {
            this.canvas.backgroundColor = this.props.canvasFill;
            this.canvas.renderAll();
          }
        }
      
        extend(obj, id) {
          obj.toObject = (function (toObject) {
            return function () {
              return fabric.util.object.extend(toObject.call(this), {
                id: id
              });
            };
          })(obj.toObject);
        }
      
        setCanvasImage() {
          let self = this;
          if (this.props.canvasImage) {
            this.canvas.setBackgroundColor({ source: this.props.canvasImage, repeat: 'repeat' }, function () {
              // self.props.canvasFill = '';
              self.canvas.renderAll();
            });
          }
        }
      
        randomId() {
          return Math.floor(Math.random() * 999999) + 1;
        }
      
        /*------------------------Global actions for element------------------------*/
      
        getActiveStyle(styleName, object) {
          object = object || this.canvas.getActiveObject();
          if (!object) {return '';}
      
          return (object.getSelectionStyles && object.isEditing)
            ? (object.getSelectionStyles()[styleName] || '')
            : (object[styleName] || '');
        }
      
      
        setActiveStyle(styleName, value, object) {
          object = object || this.canvas.getActiveObject();
          if (!object) {return '';}
      
          if (object.setSelectionStyles && object.isEditing) {
            let style = {};
            style[styleName] = value;
            object.setSelectionStyles(style);
            object.setCoords();
          } else {
            object.set(styleName, value);
          }
      
          object.setCoords();
          this.canvas.renderAll();
        }
      
      
        getActiveProp(name) {
          let object = this.canvas.getActiveObject();
          if (!object) {return '';}
      
          return object[name] || '';
        }
      
        setActiveProp(name, value) {
          const object = this.canvas.getActiveObject();
          if (!object) {return ''};
          object.set(name, value).setCoords();
          this.canvas.renderAll();
        }
      
        clone() {
          const activeObject = this.canvas.getActiveObject(),
            activeGroup = this.canvas.getActiveGroup();
      
          if (activeObject) {
            let clone;
            switch (activeObject.type) {
              case 'rect':
                clone = new fabric.Rect(activeObject.toObject());
                break;
              case 'circle':
                clone = new fabric.Circle(activeObject.toObject());
                break;
              case 'triangle':
                clone = new fabric.Triangle(activeObject.toObject());
                break;
              case 'i-text':
                clone = new fabric.IText('', activeObject.toObject());
                break;
              case 'image':
                clone = fabric.util.object.clone(activeObject);
                break;
            }
            if (clone) {
              clone.set({ left: 10, top: 10 });
              this.canvas.add(clone);
              this.selectItemAfterAdded(clone);
            }
          }
        }
      
        getId() {
          this.props.id = this.canvas.getActiveObject().toObject().id;
        }
      
        setId() {
          const val = this.props.id;
          const complete = this.canvas.getActiveObject().toObject();
          console.log(complete);
          this.canvas.getActiveObject().toObject = () => {
            complete.id = val;
            return complete;
          };
        }
      
        getOpacity() {
          this.props.opacity = this.getActiveStyle('opacity', null) * 100;
        }
      
        setOpacity() {
          this.setActiveStyle('opacity', +this.props.opacity / 100, null);
        }
      
        getFill() {
          this.props.fill = this.getActiveStyle('fill', null);
        }
      
        setFill() {
          this.setActiveStyle('fill', this.props.fill, null);
        }
      
        getLineHeight() {
          this.props.lineHeight = this.getActiveStyle('lineHeight', null);
        }
      
        setLineHeight() {
          this.setActiveStyle('lineHeight', parseFloat(this.props.lineHeight), null);
        }
      
        getCharSpacing() {
          this.props.charSpacing = this.getActiveStyle('charSpacing', null);
        }
      
        setCharSpacing() {
          this.setActiveStyle('charSpacing', this.props.charSpacing, null);
        }
      
        getFontSize() {
          this.props.fontSize = this.getActiveStyle('fontSize', null);
        }
      
        setFontSize() {
          this.setActiveStyle('fontSize', +this.props.fontSize, null);
        }
      
        getBold() {
          this.props.fontWeight = this.getActiveStyle('fontWeight', null);
        }
      
        setBold() {
          this.props.fontWeight = !this.props.fontWeight;
          this.setActiveStyle('fontWeight', this.props.fontWeight ? 'bold' : '', null);
        }
      
        getFontStyle() {
          this.props.fontStyle = this.getActiveStyle('fontStyle', null);
        }
      
        setFontStyle() {
          this.props.fontStyle = !this.props.fontStyle;
          this.setActiveStyle('fontStyle', this.props.fontStyle ? 'italic' : '', null);
        }
      
      
        getTextDecoration() {
          this.props.TextDecoration = this.getActiveStyle('textDecoration', null);
        }
      
        setTextDecoration(value) {
          let iclass = this.props.TextDecoration;
          if (iclass.includes(value)) {
            iclass = iclass.replace(RegExp(value, 'g'), '');
          } else {
            iclass += ` ${value}`
          }
          this.props.TextDecoration = iclass;
          this.setActiveStyle('textDecoration', this.props.TextDecoration, null);
        }
      
        hasTextDecoration(value) {
          return this.props.TextDecoration.includes(value);
        }
      
      
        getTextAlign() {
          this.props.textAlign = this.getActiveProp('textAlign');
        }
      
        setTextAlign(value) {
          this.props.textAlign = value;
          this.setActiveProp('textAlign', this.props.textAlign);
        }
      
        getFontFamily() {
          this.props.fontFamily = this.getActiveProp('fontFamily');
        }
      
        setFontFamily() {
          this.setActiveProp('fontFamily', this.props.fontFamily);
        }
      
        /*System*/
      
      
        removeSelected() {
          let activeObject = this.canvas.getActiveObject(),
            activeGroup = this.canvas.getActiveGroup();
      
          if (activeObject) {
            this.canvas.remove(activeObject);
            // this.textString = '';
          } else if (activeGroup) {
            let objectsInGroup = activeGroup.getObjects();
            this.canvas.discardActiveGroup();
            let self = this;
            objectsInGroup.forEach(function (object) {
              self.canvas.remove(object);
            });
          }
        }
      
        bringToFront() {
          let activeObject = this.canvas.getActiveObject(),
            activeGroup = this.canvas.getActiveGroup();
      
          if (activeObject) {
            activeObject.bringToFront();
            // activeObject.opacity = 1;
          }
          else if (activeGroup) {
            let objectsInGroup = activeGroup.getObjects();
            this.canvas.discardActiveGroup();
            objectsInGroup.forEach((object) => {
              object.bringToFront();
            });
          }
        }
      
        sendToBack() {
          const activeObject = this.canvas.getActiveObject(),
            activeGroup = this.canvas.getActiveGroup();
      
          if (activeObject) {
            activeObject.sendToBack();
            // activeObject.opacity = 1;
          } else if (activeGroup) {
            const objectsInGroup = activeGroup.getObjects();
            this.canvas.discardActiveGroup();
            objectsInGroup.forEach((object) => {
              object.sendToBack();
            });
          }
        }
      
        confirmClear() {
          if (confirm('Are you sure?')) {
            this.canvas.clear();
          }
        }
      
        rasterize() {
          if (!fabric.Canvas.supports('toDataURL')) {
            alert('This browser doesn\'t provide means to serialize canvas to an image');
          } else {
            console.log(this.canvas.toDataURL('png'))
            //window.open(this.canvas.toDataURL('png'));
            let image = new Image();
            image.src = this.canvas.toDataURL('png')
            let w = window.open('');
            w.document.write(image.outerHTML);
          }
        }
      
        rasterizeSVG() {
          console.log(this.canvas.toSVG())
          // window.open(
          //   'data:image/svg+xml;utf8,' +
          //   encodeURIComponent(this.canvas.toSVG()));
          // console.log(this.canvas.toSVG())
          // let image = new Image();
          // image.src = this.canvas.toSVG()
          const w = window.open('');
          w.document.write(this.canvas.toSVG());
        }
      
      
        saveCanvasToJSON() {
          const json = JSON.stringify(this.canvas);
          localStorage.setItem('Kanvas', json);
          console.log('json');
          console.log(json);
      
        }
      
        loadCanvasFromJSON() {
          const CANVAS = localStorage.getItem('Kanvas');
          console.log('CANVAS');
          console.log(CANVAS);
      
          // and load everything from the same json
          this.canvas.loadFromJSON(CANVAS, () => {
            console.log('CANVAS untar');
            console.log(CANVAS);
      
            // making sure to render canvas at the end
            this.canvas.renderAll();
      
            // and checking if object's "name" is preserved
            console.log('this.canvas.item(0).name');
            console.log(this.canvas);
          });
      
        }
      
        rasterizeJSON() {
          this.json = JSON.stringify(this.canvas, null, 2);
        }
      
        resetPanels() {
          this.textEditor = false;
          this.imageEditor = false;
          this.figureEditor = false;
        }
      

      总之,我希望在8英寸乘8英寸的画布上使用1/16英寸x 1/16英寸(可能是动态的)网格,并在此画布中添加一个偶数正方形的图形。

1 个答案:

答案 0 :(得分:1)

对于有同样问题的人。似乎cssOnly boolean param选项Im传递不是实际将画布缩放到英寸的解决方案。

以下是我的解决方法。

1)我现在有一个输入,允许用户手动输入他们的PPI,给出关于此网址的信息 - http://dpi.lv/

2)我保存PPI

3)我创建了一个方法calcPixels(inches:number),它使用pixels = inches * ppi来计算所需的像素数

4)我在整个应用程序中使用该方法获取所有宽度,高度,网格线等。

这给了我一个7英寸乘7英寸网格线。它的自动化程度稍低,但如果您保存PPI,用户只需输入一次!

新结果

enter image description here