SVG中的曲线+路径动画+响应

时间:2017-03-03 22:03:20

标签: javascript jquery css svg snap.svg

我使用snap.svg,并试图实现这样的行为。 svg应该是缩放的,并且在移动设备上居中,就像在图像上一样。当悬停在点上时也是可能的 - 国家名称应该出现&是可点击的链接。在任何情况下都可以优化代码?如何将svg集中在移动设备上? Codepen update

enter image description here

var s = Snap("#svg");
var startPoint, endPoint;
var path;
var circleProps = {
  fill: 'white',
  strokeWidth: 3,
  opacity: 0,
  class: "cicles"
};
circleProps.stroke = 'white';
startPoint = s.circle(770,415,5);
startPoint.attr(circleProps);

endPoint = s.circle(795,386,5);
endPoint.attr(circleProps);


endPoint1 = s.circle(820,445,5);
endPoint1.attr(circleProps);


endPoint2 = s.circle(900,500,5);
endPoint2.attr(circleProps);


endPoint3 = s.circle(1050,630,5);
endPoint3.attr(circleProps);

endPoint4 = s.circle(1170,540,5);
endPoint4.attr(circleProps);

endPoint5 = s.circle(810,600,5);
endPoint5.attr(circleProps);

endPoint6 = s.circle(750,460,5);
endPoint6.attr(circleProps);

text = s.text(735,350, ["LATVIA"]);
text.attr({
  fill: "white",
  "font-size": "20px",
  "font-family": "Verdana",
  "background": "black",


});

p1 = text.selectAll("tspan:nth-child(2)");

p3 = text.selectAll("tspan:nth-child(4)");


path = s.path("M770,415,Q790,360,795,386").attr({
  fill: "none",
  stroke: "white",
  strokeWidth: 4
});

path1 = s.path("M770,415,Q800,410,820,445").attr({
  fill: "none",
  stroke: "white",
  strokeWidth: 4
});

path2 = s.path("M770,415,Q880,410,900,500").attr({
  fill: "none",
  stroke: "white",
  strokeWidth: 4
});

path3 = s.path("M770,415,Q1060,410,1050,630").attr({
  fill: "none",
  stroke: "white",
  strokeWidth: 4
});

path4 = s.path("M770,415,Q1060,410,1170,540").attr({
  fill: "none",
  stroke: "white",
  strokeWidth: 4
});

path5 = s.path("M770,415,Q810,410,810,600").attr({
  fill: "none",
  stroke: "white",
  strokeWidth: 4
});

path6 = s.path("M770,415,Q810,410,750,460").attr({
  fill: "none",
  stroke: "white",
  strokeWidth: 4
});

var pathLength = Snap.path.getTotalLength( path );

path.node.style.strokeDasharray = pathLength + ' ' + pathLength;
path.node.style.strokeDashoffset = pathLength;

var pathLength1 = Snap.path.getTotalLength( path1 );

path1.node.style.strokeDasharray = pathLength1 + ' ' + pathLength1;
path1.node.style.strokeDashoffset = pathLength1;

var pathLength2 = Snap.path.getTotalLength( path2 );

path2.node.style.strokeDasharray = pathLength2 + ' ' + pathLength2;
path2.node.style.strokeDashoffset = pathLength2;

var pathLength3 = Snap.path.getTotalLength( path3 );

path3.node.style.strokeDasharray = pathLength3 + ' ' + pathLength3;
path3.node.style.strokeDashoffset = pathLength3;

var pathLength4 = Snap.path.getTotalLength( path4 );

path4.node.style.strokeDasharray = pathLength4 + ' ' + pathLength4;
path4.node.style.strokeDashoffset = pathLength4;

var pathLength5 = Snap.path.getTotalLength( path5 );

path5.node.style.strokeDasharray = pathLength5 + ' ' + pathLength5;
path5.node.style.strokeDashoffset = pathLength5;

var pathLength6 = Snap.path.getTotalLength( path6 );

path6.node.style.strokeDasharray = pathLength6 + ' ' + pathLength6;
path6.node.style.strokeDashoffset = pathLength6;

p1.animate({
    fill: "white",
}, 600, mina.easeout);
startPoint.animate({
    r: 5,
    opacity: 1
}, 600, mina.easeout);

setTimeout(function() {
  endPoint.animate({
      r: 5,
      opacity: 1
  }, 600, mina.easeout);
  endPoint1.animate({
      r: 5,
      opacity: 1
  }, 600, mina.easeout);
  endPoint2.animate({
      r: 5,
      opacity: 1
  }, 600, mina.easeout);
  endPoint3.animate({
      r: 5,
      opacity: 1
  }, 600, mina.easeout);
  endPoint4.animate({
      r: 5,
      opacity: 1
  }, 600, mina.easeout);
  endPoint5.animate({
      r: 5,
      opacity: 1
  }, 600, mina.easeout);
  endPoint6.animate({
      r: 5,
      opacity: 1
  }, 600, mina.easeout);
}, 1800);


setTimeout(function() {
  Snap.animate(pathLength, 0, function( value ) {
  path.node.style.strokeDashoffset = value;
                       }, 1600);
}, 2700);

setTimeout(function() {
  Snap.animate(pathLength1, 0, function( value ) {
  path1.node.style.strokeDashoffset = value;
                       }, 1600);

}, 2700);

setTimeout(function() {
  Snap.animate(pathLength2, 0, function( value ) {
  path2.node.style.strokeDashoffset = value;
                       }, 1600);

}, 2700);

setTimeout(function() {
  Snap.animate(pathLength3, 0, function( value ) {
  path3.node.style.strokeDashoffset = value;
                       }, 1600);

}, 2700);

setTimeout(function() {
  Snap.animate(pathLength4, 0, function( value ) {
  path4.node.style.strokeDashoffset = value;
                       }, 1600);

}, 2700);

setTimeout(function() {
  Snap.animate(pathLength5, 0, function( value ) {
  path5.node.style.strokeDashoffset = value;
                       }, 1600);

}, 2700);

setTimeout(function() {
  Snap.animate(pathLength6, 0, function( value ) {
  path6.node.style.strokeDashoffset = value;
                       }, 1600);

}, 2700);

// get cordiante 

function svgPoint(element, x, y) {

  var pt = svg.createSVGPoint();
  pt.x = x;
  pt.y = y;
  return pt.matrixTransform(element.getScreenCTM().inverse());

}


var svg = document.getElementById('svg');
var NS = svg.getAttribute('xmlns');
 var local = svg.getElementById('Markets');
var coords = document.getElementById('coords');

svg.addEventListener('mousemove', function(e) {

  var
    x = e.clientX,
    y = e.clientY,
    svgP = svgPoint(svg, x, y),
    svgL = svgPoint(local, x, y);

  // output co-ordinates
  coords.textContent =
    '[page: ' + x + ',' + y +
    '] => [svg space: ' + Math.round(svgP.x) + ',' + Math.round(svgP.y) +
    '] [local transformed space: ' + Math.round(svgL.x) + ',' + Math.round(svgL.y) + ']'
    ;

}, false);

1 个答案:

答案 0 :(得分:0)

此处的解决方案CODEPEN Snap SVG是强大的库,我使用它的API。我不太喜欢我的响应式解决方案。

我使用这种语法将text标签附加到link标签,然后使用链接为每个链接集属性添加,并且在悬停时使用CSS不透明度可以单击SVG中的城市名称。

a.add(s.text(715,375, " LATVIA ").attr(linkStyle));
a.node.setAttributeNS('http://www.w3.org/1999/xlink', 'href', 'https://uk.wikipedia.org/wiki/%D0%9B%D0%B0%D1%82%D0%B2%D1%96%D1%8F');



.map {
height:450px;
max-height: 450px; 
position: relative;
left: calc(100vw/2 - 100vh/2);

}

@media screen and (min-width: 640px){
  .map {
    height: 553px;
    max-height: 553px;
    left: 0;
    left: calc(80vw/2 - 100vh/2);
  }
}
@media screen and (min-width: 1200px){
  .map {
    height: 838px;
    max-height: 838px;
    left: 0;
  }
}