2016-12-12 20 views
9

私は、SVGグラフィックスをレンダリングするためにd3 v4を使用しています。私はいくつか<path>要素にclipPathを使用しています。私はrect要素の動作をパンしており、clipPathはいくつかのパス要素を隠すのに役立っています。アンドロイドでパンニングするとき。 clipPathは必要に応じて機能しますが、iOSでパンすると描画が不安定になります。以下を参照してください:iOSアプリのWebViewのSVGクリップ経路問題

BEFORE

私は次のコードでSVGクリップを実装しました AFTER PANNING

AFTER BEFORE:

this.line = d3.line() 
    .curve(d3.curveMonotoneX) 
    .x((d) => this.xScale(this.getDate(d))) 
    .y((d) => this.yScale(d.kWh)); 

this.area = d3.area() 
    .curve(d3.curveMonotoneX) 
    .x((d) => { 
     return this.xScale(this.getDate(d)) 
    }) 
    .y0(this.height) 
    .y1((d) => this.yScale(d.kWh)); 

// Definition for clipPath 
this.svg.append("defs").append("clipPath") 
    .attr("id", "clip") 
    .append("rect") 
    .attr("width", this.width) 
    .attr('transform', 'translate(0,-20)') 
    .attr("height", this.height + 20); 
// clipPath added to area 
var areaPath = this.focus.append("path") 
    .datum(this.data) 
    .attr("class", "area") 
    .attr('height', this.height) 
    .attr('fill-opacity', .2) 
    .attr('clip-path', 'url(#clip)') 
    .attr("d", this.area) 
    .attr("transform", "translate(0," + 80 + ")") 
    .style("fill", "url(#gradient)"); 
// clipPath added to the line 
var linePath = this.focus.append('path') 
    .datum(this.data) 
    .attr('class', 'line') 
    .attr('fill', 'none') 
    .attr('clip-path', 'url(#clip)') 
    .attr('stroke', '#31B5BB') 
    .attr('stroke-width', '2px') 
    .attr("transform", "translate(0," + 80 + ")") 
    .attr('d', this.line); 

彼はexceですズームから呼び出されるズームからのrpts。

private zoomed =() => { 

     if (this.isMinZooming) return; 

     let diff, 
      domain, 
      minBuffer, 
      maxBuffer, 
      t; 

     t = d3.event.transform; 
     // loose mobile events 
     if (isNaN(t.k)) return; 

     this.xScale.domain(t.rescaleX(this.x2Scale).domain()); 
     diff = this.daydiff(this.xScale.domain()[0], this.xScale.domain()[1]); 

     // Redraw Axis 
     this.xAxis = d3.axisBottom(this.xScale).tickSize(0).tickFormat(d3.timeFormat('%b')); 
     this.focus.select(".axis--x").call(this.xAxis); 

     // Redraw Paths. This is where the redraw function gets messy in the iOS webview. 
     this.focus.select(".area").attr("d", this.area); 
     this.focus.select('.line').attr('d', this.line); 

     ... 
} 

clipPathを使用すると誰も同じ問題が発生しましたか?

+0

これは、clipPathとクリッピングしている要素が同じ座標系で定義されておらず、同じ変換を受けていないためです。http://stackoverflow.com/a/38088473/1160916 – Ashitaka

+0

@Ashitaka IOS以外のすべてのブラウザでこの機能が動作するのはなぜですか?それはサファリでも働く。理由は何ですか? – inspired

答えて

0

私は問題を把握しました。そのようなサドルバグです。

.area{ 
    clip-path: url(#clip); 
} 

すべてのブラウザでは、これは<rect><path>のために働くだろうが、iOS webviewのためには、上記の表示エラーをレンダリングします:私は私のcssファイルのどこかで定義されました。代わりに別のCSSファイルでこれを定める

、私はそのようにそれを適用したいものすべてSVG Objectためにインラインで定義された:

var areaPath = this.focus.append("path") 
     ... 
     .attr('clip-path', 'url(#clip)') //defining it inline 

このバグは狂気私を運転したが、私は「うれしいです解決策を見つけました。