在 Angular 中使用 D3 缩放 SVG。

3

我想要在一个svg上进行平移/缩放。

我试图使用d3,就像这个教程中提到的那样。

以下是我的代码:

import { Component,AfterViewInit,OnInit } from '@angular/core';
import * as d3 from "d3";
@Component({
  selector: 'my-app',
  templateUrl: './app.component.svg',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit,OnInit  {
  name = 'Angular';
  ngOnInit() {

  }
  ngAfterViewInit() {
    var svg = d3.select("svg")
      .call(d3.zoom().on("zoom", function () {
       svg.attr("transform", d3.event.transform)
      }))
    .append("g")
  }
}

实际上没有任何事情发生,滚动svg不会缩放。

演示


真的需要使用 d3.js 吗?使用普通的 cssAngular 鼠标事件就可以实现缩放和平移,无需使用 d3.js - Chaitanya
不需要使用d3,你能给我更多细节吗? - infodev
你是在使用 <svg> 标签还是作为 <img> 的源吗? - Chaitanya
SVG标签,如演示。 - infodev
3个回答

2
有一个合适的解决方案:最初的回答。
var svg = d3.select("svg");
var zoomFn = d3.zoom().on('zoom', function() {
    svg.attr("transform", d3.event.transform)
});    
svg.call(zoomFn);

我要能够缩放,我需要添加另一段代码吗?因为我试图向下滚动以缩放,但什么也没有发生。 - infodev
@infodev,是的。添加我的代码,缩放功能将按预期工作。 - Ihor Yanovchyk
@IhorYanovchyk 现在 d3.event 已经被移除了,我们该如何重写它? - Muhy

1
对于我的情况,Ihor Yanovchyk的解决方案还有缺陷。svg以一种奇怪的方式缩放,将整个svg移出视图。我不得不添加一个selectAll('g')并改变它们的transform属性。
对于我的情况有效的方法是:
const svg1 = select(this.svg1.nativeElement).call(zoom().on('zoom',function(){
    svg1.selectAll('g').attr("transform", event.transform)
}));

现在d3.event已被移除,我们该如何重写它? - Muhy
2
@Muhy,可以这样写:const svg1 = select(this.svg1.nativeElement).call(zoom().on('zoom',function handleZoom(event){ svg1.selectAll('g').attr("transform", event.transform) })); - khadeeja

0

<img> 标签中使用 svg 作为源的示例

在您的 app 模块 中导入 hammerjs

<!-- app.module.ts -->
import 'hammerjs'

以下是用于img HTML的代码。
<img [src]="imageSrc" alt="de-ethynizer" (pan)="onPan($event)" [ngStyle]="imageStyle()"
    (wheel)="onScroll($event)" style="cursor: grab">

以下是组件文件。
export class SomeComponent implements OnInit{
 scale: number;
  pan: any = { x: 0, y: 0 };

  constructor() {
    this.scale = 1;
  }

  ngOnInit() {}

/* Method which adds style to the image */
  imageStyle() {
    return {
      transform: `translate(${this.pan['x']}px,${
        this.pan['y']
      }px) rotate(0deg) scale(${this.scale})`
    };
  }

  /* Method will be called on pan image */
  onPan(e) {
    this.pan = { x: e['deltaX'], y: e['deltaY'] };
  }

  /* Method will be called when user zooms image */
  onZoomP() {
    this.scale = this.scale + 0.1;
  }

  /* Method will be called when user zooms out image */
  onZoomM() {
// below you can check zoom out level from 0 to 1

    if (this.scale < 1) {
      return;
    } else {
      this.scale = this.scale - 0.1;
    }
  }

  /* Method will be called on mouse wheel scroll */
  onScroll(e) {
    if (e['deltaY'] < 0) {
      this.onZoomP();
    }
    if (e['deltaY'] > 0) {
      this.onZoomM();
    }
  }
}

给出了<img>的示例。您也可以在<svg>上使用相同的鼠标事件和css,并使用[ngStyle]。否则,您可以将SVG作为<img>的源传递,并可以使用整个解决方案。 - Chaitanya
我正在尝试实现这个功能,但似乎只有在图像与容器大小相同时才能正常工作,否则无法超出容器的大小进行平移。有什么建议吗? - Supamiu
没事了,我通过分别存储原始pan和编辑后的pan来完成它。 - Supamiu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接