2016-12-12 3 views
9

Я использую d3 v4 для рендеринга графики SVG. Я использую clipPath на нескольких элементах <path>. У меня есть поведение панорамирования на элементе rect, и clipPath помогает скрыть некоторые элементы пути. При панорамировании в андроиде. ClipPath работает по мере необходимости, но при панорамировании в iOS рисунок рендерится. Смотрите ниже:IOS app webview SVG ClipPath Issue

ПЕРЕД

BEFORE

ПОСЛЕ AFTER PANNING

Я реализовал SVG клип со следующим кодом:

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

Я понял вопрос. Это такая ошибка. Я определял где-то в файле CSS:

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

Во всех браузерах это будет работать для <rect> и <path>, но для iOS webview это сделало бы выше ошибки отображения.

Вместо определения этого в отдельном файле CSS, я определил его рядный для всех SVG Object, что я хотел, чтобы применить его как таковой:

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

Эта ошибка сводили меня с ума, но я рад, что я ve нашел решение.