SVG viewbox显示显示屏幕项目 [英] SVG viewbox showing showing off-screen items

查看:188
本文介绍了SVG viewbox显示显示屏幕项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在HTML5中使用 svg 标签制作游戏,以提供多分辨率显示。大多数游戏是完整的,但在测试中,我刚刚遇到一个涉及SVG对象可见的重大错误,尽管在非本机分辨率的viewbox外。我不知道这是一个缺陷在我的代码,或与浏览器本身(谷歌Chrome 54.0.2840.99米(64位)和57.0.2950.0(官方编译)金丝雀(64位))。我必须使用谷歌浏览器,因为我在项目中使用WebSQL(它不是在许多主要的浏览器)。



这个项目是一个自上而下的滚动迷宫游戏,其中阴影通过从形状顶点经由raycast填充的多边形绘制。阴影只有当它们附着到的一个或多个顶点在屏幕上时才被绘制。问题是,当我降低我的分辨率(我的默认值是1366×768),那么他们不会像往常一样画到屏幕的顶部/底部。它应该看起来像这样。



下面是我的代码的主要缩减版本。我假设如果有一个错误,在我的代码,它将在 shadowrays()函数内。通常,程序将以全屏模式(F11)运行,以确保它与窗口的大小相同。要移动屏幕,请使用w,a,s和d键。



  window.setInterval(function(){if(draw){if(keystate [controls [2]]){xvelocity  -  = 2;} if(keystate [controls [3]]){xvelocity + = 2;} xvelocity = xvelocity * 0.93; xscroll + = xvelocity; svg.setAttribute(viewBox,(xscroll ++ yscroll ++ dimensions.width ++ dimensions.height)); centerplayer(); if(checkcollision {xscroll  -  = xvelocity; xvelocity = xvelocity * -0.8;} if(keystate [controls [0]]){yvelocity + = 2;} if(keystate [controls [1]]){yvelocity  -  = 2;} yvelocity = yvelocity * 0.93; yscroll  -  = yvelocity; svg.setAttribute(viewBox,(xscroll ++ yscroll ++ dimensions.width ++ dimensions.height)); centerplayer(); if(checkcollision ){yscroll + = yvelocity; yvelocity = yvelocity * -0.8; } shadowrays(); }},16.666666666666667); var keystate = {}; window.addEventListener(keydown,function(e){if(!((e.keycode || e.which)> 111)& e.keyCode || e.which)<124))){keystate [e.keycode || e.which] = true;}},true); window.addEventListener(keyup,function(e){keystate [e.keycode || e.which] = false;},true); function shadowrays(){var kill = document.getElementsByClassName(shadowray); while(kill [0]){kill [0] .parentNode.removeChild(kill [0]); } var len = level.length,shape = {},points = [],poly = [],p1x,p2x,p1y,p2y,p3x,p3y,p4x,p4y,p5x,p5y,p6x,p6y,cx = player .cx.animVal.value,cy = player.cy.animVal.value,m,i,n; for(i = 1; i  = 0; i- = 1){if(collisions [i] .id ==renclosure|| collisions [i] .id ==cplayer|| collision [i] .id ==rpain|| collisions [i] .id ==rhb|| collisions [i] .className.animVal ==shadowray){collisions.splice(i,1) } else if(collisions [i] .id ==rexit){// winner // DO STUFF}} if(collisions.length> 0){return true; } else {return false; }} level = [{id:l0,name:pretty,// level namedescription:oooooo shadows,// desciptionxspawn:0, yspawn:0,xexit:2200,//其中退出它yexit:2200,bits:50 //级别中的qbits数},{id:enclosure type:rect,// shape type x:0,// top left xy:0,// top left y class:obstacle_box,// style for style width:5760,// width height:2160 // height},{id:1,type:rect,x:150,y:200,class:obstacle_box,width:100,height:100},{id:2 ,x:350,y:200,class:obstacle_box,width:100,height:100},{id:3,type:rect,x:550,y:200,class: ,width:100,height:100},{id:4,type:rect,x:750,y:200,class:obstacle_box,width:100,height:100} 5,类型:rect,x:950,y:200,class:obstacle_box,width:100,height:100},{id:6​​,type:rect,x: y:200,class:obstacle_box,width:100,height:100},{id:7,type:rect,x:1350,y:200,class: height:100},{id:8,type:rect,x:1550,y:200,class:obstacle_box,width:100,height:100} rect,x:1750,y:200,class:obstacle_box,width:100,height:100},{id:10,type:rect,x:1950,y: obstacle_box,width:100,height:100},{id:11,type:rect,x:2150,y:200,class:obstacle_box,width:100,height:100} id:12,type:rect,x:2350,y:200,class:obstacle_box,width:100,height:100},{id:13 2550,y:200,类:obstacle_box,width:100,height:100},{id:14,type:rect,x:2750,y:200,class: 100,height:100},{id:15,type:rect,x:2950,y:200,class:obstacle_box,width:100,height:100}类型:rect,x:3150,y:200,class:obstacle_box,width:100,height:100},{id:17,type:rect,x:3350,y: class:obstacle_box,width:100,height:100},{id:18,type:rect,x:3550,y:200,class:obstacle_box,width:100,height:100} ,{id:19,type:rect,x:3750,y:200,class:obstacle_box,width:100,height:100},{id:20 x:3950,y:200,class:obstacle_box,width:100,height:100}]; draw(level); player = document.getElementById(cplayer); svg.setAttribute(viewBox, ++ yscroll ++ dimensions.width ++ dimensions.height)); centerplayer(); shadowrays();    html,body {/ *所有元素的默认字体* / font-family:Calibri; / *确保页面flush * / margin:0px; width:100%;高度:100%; / *文本的默认位置* / text-align:center; / *摆脱滚动条* / overflow:hidden; / *游标总是正常的指针* / cursor:default;}#canvas {/ *让它与页面齐平* / height:100%; width:100%; padding:0; / * black background * / background-color:#000; / *更多冲洗* /位置:固定; left:0px; top:0px; border:none;}#border {height:100%; width:100%; padding:0; / * black background * / background:none; / *更多冲洗* /位置:固定; left:0px; top:0px; border:1px solid#000;} / *当前播放器* /。st1 {/ *它是黑色的,没有轮廓* / fill:black; stroke:none;} / *可以collidable的级别的主要黑色比特* /。obstacle_box {/ * black fill * / fill:#000; / *黑色轮廓* / stroke:#000; stroke-width:1; / *防止边角卷曲* / stroke-miterlimit:10;} / * hitbox thingy * /。st2 {/ *无填充,但是暗轮廓* / fill:none; stroke:#999; stroke-width:1; stroke-miterlimit:10;} / * exit * /。exit {/ * greenish fill * / fill:#0C3; / *绿色轮廓* / stroke:#00FF40; stroke-width:5; / *让行结束圆* / stroke-linecap:round; / *让它们虚线* / stroke-dasharray:10,10; / *动画:循环中的轮廓* / animation:exit 0.5s linear infinite;} / *退出的轮廓效果* / @ keyframes exit {0%{/ * outline break offset * / stroke-dashoffset:0} {stroke-dashoffset:20}}。shadowray {/ * black * / fill:#000; / * black * / stroke:#000; stroke-width:1; stroke-miterlimit:10; / * visible * / opacity:1;} / * level的边缘* /#renclosure {/ *你实际看到的背景* / fill:#EEE;}  

 < svg id =canvasviewBox =0 0 1920 1080> <! - 用于向 - >添加SVG过滤器< defs id =filters>< / defs>< / svg>< div id =border>< / div>   

解决方案

结果是有一个非常简单的解决方案, code> preserveAspectRatio =none插入 svg 标记,这将使它伸展以填充所有窗口。



  window.setInterval(function(){if(draw){if(keystate [controls [ (xscroll +x);xbox=xml;}}){xvelocity  -  = 2;} if(keystate [controls [3]]){xvelocity + = 2;} xvelocity = xvelocity * 0.93; xscroll + = xvelocity; svg.setAttribute + yscroll ++ dimensions.width ++ dimensions.height); centerplayer(); if(checkcollision()){xscroll  -  = xvelocity; xvelocity = xvelocity * -0.8;} if(keystate [ 0]]){yvelocity + = 2; } if(keystate [controls [1]]){yvelocity  -  = 2; } yvelocity = yvelocity * 0.93; yscroll  -  = yvelocity; svg.setAttribute(viewBox,(xscroll ++ yscroll ++ dimensions.width ++ dimensions.height)); centerplayer(); if(checkcollision()){yscroll + = yvelocity; yvelocity = yvelocity * -0.8; } shadowrays(); }},16.666666666666667); var keystate = {}; window.addEventListener(keydown,function(e){if(!((e.keycode || e.which)> 111)& e.keyCode || e.which)<124))){keystate [e.keycode || e.which] = true;}},true); window.addEventListener(keyup,function(e){keystate [e.keycode || e.which] = false;},true); function shadowrays(){var kill = document.getElementsByClassName(shadowray); while(kill [0]){kill [0] .parentNode.removeChild(kill [0]); } var len = level.length,shape = {},points = [],poly = [],p1x,p2x,p1y,p2y,p3x,p3y,p4x,p4y,p5x,p5y,p6x,p6y,cx = player .cx.animVal.value,cy = player.cy.animVal.value,m,i,n; for(i = 1; i  = 0; i- = 1){if(collisions [i] .id ==renclosure|| collisions [i] .id ==cplayer|| collision [i] .id ==rpain|| collisions [i] .id ==rhb|| collisions [i] .className.animVal ==shadowray){collisions.splice(i,1) } else if(collisions [i] .id ==rexit){// winner // DO STUFF}} if(collisions.length> 0){return true; } else {return false; }} level = [{id:l0,name:pretty,// level namedescription:oooooo shadows,// desciptionxspawn:0, yspawn:0,xexit:2200,//其中退出它yexit:2200,bits:50 //级别中的qbits数},{id:enclosure type:rect,// shape type x:0,// top left xy:0,// top left y class:obstacle_box,// style for style width:5760,// width height:2160 // height},{id:1,type:rect,x:150,y:200,class:obstacle_box,width:100,height:100},{id:2 ,x:350,y:200,class:obstacle_box,width:100,height:100},{id:3,type:rect,x:550,y:200,class: ,width:100,height:100},{id:4,type:rect,x:750,y:200,class:obstacle_box,width:100,height:100} 5,类型:rect,x:950,y:200,类:obstacle_box,width:100,height:100},{id:6​​,type:rect,x: y:200,class:obstacle_box,width:100,height:100},{id:7,type:rect,x:1350,y:200,class: height:100},{id:8,type:rect,x:1550,y:200,class:obstacle_box,width:100,height:100} rect,x:1750,y:200,class:obstacle_box,width:100,height:100},{id:10,type:rect,x:1950,y: obstacle_box,width:100,height:100},{id:11,type:rect,x:2150,y:200,class:obstacle_box,width:100,height:100} id:12,type:rect,x:2350,y:200,class:obstacle_box,width:100,height:100},{id:13 2550,y:200,类:obstacle_box,width:100,height:100},{id:14,type:rect,x:2750,y:200,class: 100,height:100},{id:15,type:rect,x:2950,y:200,class:obstacle_box,width:100,height:100}类型:rect,x:3150,y:200,class:obstacle_box,width:100,height:100},{id:17,type:rect,x:3350,y: class:obstacle_box,width:100,height:100},{id:18,type:rect,x:3550,y:200,class:obstacle_box,width:100,height:100} ,{id:19,type:rect,x:3750,y:200,class:obstacle_box,width:100,height:100},{id:20 x:3950,y:200,class:obstacle_box,width:100,height:100}]; draw(level); player = document.getElementById(cplayer); svg.setAttribute(viewBox, ++ yscroll ++ dimensions.width ++ dimensions.height)); centerplayer(); shadowrays();    html,body {/ *所有元素的默认字体* / font-family:Calibri; / *确保页面flush * / margin:0px; width:100%;高度:100%; / *文本的默认位置* / text-align:center; / *摆脱滚动条* / overflow:hidden; / *游标总是正常的指针* / cursor:default;}#canvas {/ *让它与页面齐平* / height:100%; width:100%; padding:0; / * black background * / background-color:#000; / *更多冲洗* /位置:固定; left:0px; top:0px; border:none;}#border {height:100%; width:100%; padding:0; / * black background * / background:none; / *更多冲洗* /位置:固定; left:0px; top:0px; border:1px solid#000;} / *当前播放器* /。st1 {/ *它是黑色的,没有轮廓* / fill:black; stroke:none;} / *可以collidable的级别的主要黑色比特* /。obstacle_box {/ * black fill * / fill:#000; / *黑色轮廓* / stroke:#000; stroke-width:1; / *防止边角卷曲* / stroke-miterlimit:10;} / * hitbox thingy * /。st2 {/ *无填充,但是暗轮廓* / fill:none; stroke:#999; stroke-width:1; stroke-miterlimit:10;} / * exit * /。exit {/ * greenish fill * / fill:#0C3; / *绿色轮廓* / stroke:#00FF40; stroke-width:5; / *让行结束圆* / stroke-linecap:round; / *让它们虚线* / stroke-dasharray:10,10; / *动画:循环中的轮廓* / animation:exit 0.5s linear infinite;} / *退出的轮廓效果* / @ keyframes exit {0%{/ * outline break offset * / stroke-dashoffset:0} {stroke-dashoffset:20}}。shadowray {/ * black * / fill:#000; / * black * / stroke:#000; stroke-width:1; stroke-miterlimit:10; / * visible * / opacity:1;} / * level的边缘* /#renclosure {/ *你实际看到的背景* / fill:#EEE;}  

 < svg id =canvasviewBox =0 0 1920 1080preserveAspectRatio =none> <! - 用于向 - >添加SVG过滤器< defs id =filters>< / defs>< / svg>< div id =border>< / div>   


I am making a game in HTML5 using the the svg tag for the graphics to provide multi-resolution displays. The majority of the game is complete, but in testing I have just come across a major bug which involves the SVG objects being visible, despite being outside of the viewbox on non-native resolutions. I am not sure if this is a flaw in my code, or with the browser itself (Google Chrome 54.0.2840.99 m (64-bit), and 57.0.2950.0 (Official Build) canary (64-bit)). I am having to use Google Chrome because I am using WebSQL in the project (it is not in many major browsers).

The project is a top down scrolling maze game, with shadows that are drawn via raycast filled polygons from shape vertices. The shadows are only drawn if one or more the vertices they are "attached" to are on the screen. The issue is that when I lower my resolution (my default is 1366 x 768) then they do not draw to the top/bottom of the screen as they normally do. It should look like this.

Below is a majorly cut-down version of my code. I would assume that if there were an error, in my code, it would be inside the shadowrays() function. Normally, the program would be run in fullscreen mode (F11) to ensure that it is the same size as the window. To move the screen, use the w, a, s and d keys

window.setInterval(function() {
  if (draw) {
    if (keystate[controls[2]]) {
      xvelocity -= 2;
    }
    if (keystate[controls[3]]) {
      xvelocity += 2;
    }
    xvelocity = xvelocity * 0.93;
    xscroll += xvelocity;
    svg.setAttribute("viewBox", (xscroll + " " + yscroll + " " + dimensions.width + " " + dimensions.height));
    centerplayer();
    if (checkcollision()) {
      xscroll -= xvelocity;
      xvelocity = xvelocity * -0.8;
    }
    if (keystate[controls[0]]) {
      yvelocity += 2;
    }
    if (keystate[controls[1]]) {
      yvelocity -= 2;
    }
    yvelocity = yvelocity * 0.93;
    yscroll -= yvelocity;
    svg.setAttribute("viewBox", (xscroll + " " + yscroll + " " + dimensions.width + " " + dimensions.height));
    centerplayer();
    if (checkcollision()) {
      yscroll += yvelocity;
      yvelocity = yvelocity * -0.8;
    }
    shadowrays();
  }
}, 16.666666666666667);
var keystate = {};
window.addEventListener("keydown", function(e) {
  if (!(((e.keycode || e.which) > 111) && ((e.keyCode || e.which) < 124))) {
    keystate[e.keycode || e.which] = true;
  }
}, true);
window.addEventListener("keyup", function(e) {
  keystate[e.keycode || e.which] = false;
}, true);

function shadowrays() {
  var kill = document.getElementsByClassName("shadowray");
  while (kill[0]) {
    kill[0].parentNode.removeChild(kill[0]);
  }
  var len = level.length,
    shape = {},
    points = [],
    poly = [],
    p1x, p2x, p1y, p2y, p3x, p3y, p4x, p4y, p5x, p5y, p6x, p6y, cx = player.cx.animVal.value,
    cy = player.cy.animVal.value,
    m, i, n;
  for (i = 1; i < len; i += 1) {
    shape = level[i];
    points = [shape.x, shape.y, shape.x, shape.y + shape.height, shape.x + shape.width, shape.y + shape.height, shape.x + shape.width, shape.y];
    for (n = 0; n < 4; n += 1) {
      p1x = points[(n * 2) % 8];
      p2x = points[(n * 2 + 2) % 8];
      p1y = points[(n * 2 + 1) % 8];
      p2y = points[(n * 2 + 3) % 8];
      if ((((Math.abs(p1x - cx) <= dimensions.width / 2) || (Math.abs(p2x - cx) <= dimensions.width / 2)) && ((Math.abs(p1y - cy) <= dimensions.height / 2) || (Math.abs(p2y - cy) <= dimensions.height / 2))) && shape.id != "enclosure") {
        m = (p1y - cy) / (p1x - cx);
        p6y = m * (cx + dimensions.width / 2 * (Math.abs(p1x - cx) / (p1x - cx))) - m * cx + cy;
        if (Math.abs(p6y - cy) <= dimensions.height / 2) {
          p6x = (p6y - cy) / m + cx;
          p5x = p6x;
          p5y = cy + dimensions.height / 2 * (Math.abs(p6y - cy) / (p6y - cy));
        } else {
          p6y = cy + dimensions.height / 2 * (Math.abs(p6y - cy) / (p6y - cy));
          p6x = (p6y - cy) / m + cx;
          p5x = cx + dimensions.width / 2 * (Math.abs(p6x - cx) / (p6x - cx));
          p5y = p6y;
        }
        m = (p2y - cy) / (p2x - cx);
        p3y = m * (cx + dimensions.width / 2 * (Math.abs(p2x - cx) / (p2x - cx))) - m * cx + cy;
        if (Math.abs(p3y - cy) <= dimensions.height / 2) {
          p3x = (p3y - cy) / m + cx;
          p4x = p3x;
          p4y = cy + dimensions.height / 2 * (Math.abs(p3y - cy) / (p3y - cy));
        } else {
          p3y = cy + dimensions.height / 2 * (Math.abs(p3y - cy) / (p3y - cy));
          p3x = (p3y - cy) / m + cx;
          p4x = Number(cx) + Number(dimensions.width) / 2 * (Math.abs(p3x - cx) / (p3x - cx));
          p4y = p3y;
        }
        poly = [];
        poly.push(p1x + ',' + p1y, p2x + ',' + p2y, p3x + ',' + p3y, p4x + ',' + p4y, p5x + ',' + p5y, p6x + ',' + p6y);
        createpolygon(poly, "", ("s" + i + n), "shadowray");
      }
    }
  }
}

function createpolygon(points, filter, id, classt) {
  var polygon = document.createElementNS(svgns, "polygon"),
    data_points = "",
    max = points.length,
    z;
  polygon.setAttributeNS(null, "id", "p" + id);
  for (z = 0; z < max; z += 1) {
    data_points += points[z] + " ";
  }
  polygon.setAttributeNS(null, "points", data_points);
  if (filter !== "") {
    polygon.setAttributeNS(null, "filter", filter);
  }
  polygon.setAttributeNS(null, "class", classt);
  svg.appendChild(polygon);
}

function centerplayer() {
  player.setAttributeNS(null, "cx", (xscroll + dimensions.width / 2));
  player.setAttributeNS(null, "cy", (yscroll + dimensions.height / 2));
  var hitbox = document.getElementById("rhb");
  hitbox.setAttributeNS(null, "width", player.r.animVal.value * 2);
  hitbox.setAttributeNS(null, "height", player.r.animVal.value * 2);
  //            var hitboxbbox = hitbox.getBBox();
  hitbox.setAttributeNS(null, "transform", ("translate(" + (xscroll + dimensions.width / 2 - player.r.animVal.value) + ", " + (yscroll + dimensions.height / 2 - player.r.animVal.value) + ")"));
}

function draw(lvl) {
  var objects = lvl.length,
    i;
  xscroll = Number(lvl[0].xspawn);
  yscroll = Number(lvl[0].yspawn);
  xvelocity = 0;
  yvelocity = 0;
  for (i = 1; i < objects; i += 1) {
    var object = lvl[i];
    if (object.type == "rect") {
      createrectangle(object.x, object.y, object.width, object.height, "", object.id, object.class);
    } else if (object.type == "circle") {
      createcircle(object.x, object.y, object.r, "", object.id, object.class);
    } else if (object.type == "polygon") {
      createpolygon(object.points, "", object.id, object.class);
    }
  }
  createcircle("7680", "4320", "50", "", "player", "st1");
  createrectangle("0", "0", "100", "100", "", "hb", "st2");
  createrectangle(lvl[0].xexit - 50, lvl[0].yexit - 50, "100", "100", "", "exit", "exit");
  drawn = true;
}

function createcircle(posx, posy, radius, filter, id, classt) {
  var circle = document.createElementNS(svgns, "circle");
  circle.setAttributeNS(null, "id", "c" + id);
  circle.setAttributeNS(null, "cx", posx);
  circle.setAttributeNS(null, "cy", posy);
  circle.setAttributeNS(null, "r", radius);
  if (filter !== "") {
    circle.setAttributeNS(null, "filter", filter);
  }
  circle.setAttributeNS(null, "class", classt);
  svg.appendChild(circle);
}

function createrectangle(posx, posy, width, height, filter, id, classt) {
  var rectangle = document.createElementNS(svgns, "rect");
  rectangle.setAttributeNS(null, "id", "r" + id);
  rectangle.setAttributeNS(null, "x", posx);
  rectangle.setAttributeNS(null, "y", posy);
  rectangle.setAttributeNS(null, "width", width);
  rectangle.setAttributeNS(null, "height", height);
  if (filter !== "") {
    rectangle.setAttributeNS(null, "filter", filter);
  }
  rectangle.setAttributeNS(null, "class", classt);
  svg.appendChild(rectangle);
}

var svg = document.getElementById("canvas"), //the svg element
  dimensions = {
    width: 1920,
    height: 1080
  }, //view dimensions
  svgns = "http://www.w3.org/2000/svg", //the SVG name space address
  player, //player is used later in game
  level, xvelocity, yvelocity, xscroll, yscroll, //current level, speeds and positions
  controls = ["87", "83", "65", "68", "32"],
  drawn = false;

function checkcollision() {
  var r = player.r.animVal.value,
    frame = document.getElementById("renclosure").getBBox(),
    i;
  if ((player.cx.animVal.value < r) || (player.cy.animVal.value < r) || (player.cx.animVal.value > frame.width - r) || (player.cy.animVal.value > frame.height - r)) {
    return true;
  }
  var collisions = [],
    len, r0 = document.getElementById("rhb").getBoundingClientRect(),
    r1 = svg.createSVGRect();
  r1.x = r0.left;
  r1.y = r0.top;
  r1.width = r0.width;
  r1.height = r0.height;
  var collisions_node = svg.getIntersectionList(r1, null);
  len = collisions_node.length;
  for (i = 0; i < len; i += 1) {
    collisions.push(collisions_node[i]);
  }
  for (i = len - 1; i >= 0; i -= 1) {
    if (collisions[i].id == "renclosure" || collisions[i].id == "cplayer" || collisions[i].id == "rpain" || collisions[i].id == "rhb" || collisions[i].className.animVal == "shadowray") {

      collisions.splice(i, 1);
    } else if (collisions[i].id == "rexit") { //winner
      //DO STUFF
    }
  }
  if (collisions.length > 0) {
    return true;
  } else {
    return false;
  }
}

level = [{
  "id": "l0",
  "name": "pretty", //level name
  "description": "oooooo shadows", //desciption
  "xspawn": 0, //where the player starts
  "yspawn": 0,
  "xexit": 2200, //where the exit it
  "yexit": 2200,
  "bits": 50 //umber of qbits in the level
}, {
  id: "enclosure", //shape id
  type: "rect", //shape type
  x: 0, //top left x
  y: 0, //top left y
  class: "obstacle_box", //class for style
  width: 5760, //width
  height: 2160 //height
}, {
  id: "1",
  type: "rect",
  x: 150,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "2",
  type: "rect",
  x: 350,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "3",
  type: "rect",
  x: 550,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "4",
  type: "rect",
  x: 750,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "5",
  type: "rect",
  x: 950,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "6",
  type: "rect",
  x: 1150,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "7",
  type: "rect",
  x: 1350,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "8",
  type: "rect",
  x: 1550,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "9",
  type: "rect",
  x: 1750,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "10",
  type: "rect",
  x: 1950,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "11",
  type: "rect",
  x: 2150,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "12",
  type: "rect",
  x: 2350,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "13",
  type: "rect",
  x: 2550,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "14",
  type: "rect",
  x: 2750,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "15",
  type: "rect",
  x: 2950,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "16",
  type: "rect",
  x: 3150,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "17",
  type: "rect",
  x: 3350,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "18",
  type: "rect",
  x: 3550,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "19",
  type: "rect",
  x: 3750,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "20",
  type: "rect",
  x: 3950,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}];

draw(level);
player = document.getElementById("cplayer");
svg.setAttribute("viewBox", (xscroll + " " + yscroll + " " + dimensions.width + " " + dimensions.height));
centerplayer();
shadowrays();

html,
body {
  /*default font for all elements*/
  font-family: Calibri;
  /*ensures page is flush*/
  margin: 0px;
  width: 100%;
  height: 100%;
  /*default position of text*/
  text-align: center;
  /*gets rid of scrollbars*/
  overflow: hidden;
  /*cursor is always the normal pointer*/
  cursor: default;
}
#canvas {
  /*makes it flush with the page*/
  height: 100%;
  width: 100%;
  padding: 0;
  /*black background*/
  background-color: #000;
  /*more flushing*/
  position: fixed;
  left: 0px;
  top: 0px;
  border: none;
}
#border {
  height: 100%;
  width: 100%;
  padding: 0;
  /*black background*/
  background: none;
  /*more flushing*/
  position: fixed;
  left: 0px;
  top: 0px;
  border: 1px solid #000;
}
/*currently the player*/

.st1 {
  /*it's black and no outline*/
  fill: black;
  stroke: none;
}
/*the main black bits of the levels that are collidable*/

.obstacle_box {
  /*black fill*/
  fill: #000;
  /*black outline*/
  stroke: #000;
  stroke-width: 1;
  /*prevents corner curling*/
  stroke-miterlimit: 10;
}
/*the hitbox thingy*/

.st2 {
  /*no fill but darkish outline*/
  fill: none;
  stroke: #999;
  stroke-width: 1;
  stroke-miterlimit: 10;
}
/*the exit*/

.exit {
  /*greenish fill*/
  fill: #0C3;
  /*greener outline*/
  stroke: #00FF40;
  stroke-width: 5;
  /*makes the line ends round*/
  stroke-linecap: round;
  /*makes them dashed*/
  stroke-dasharray: 10, 10;
  /*animates in a loop the outline*/
  animation: exit 0.5s linear infinite;
}
/*outline effect for the exit*/

@keyframes exit {
  0% {
    /*outline breaks offset*/
    stroke-dashoffset: 0
  }
  100% {
    stroke-dashoffset: 20
  }
}
.shadowray {
  /*black*/
  fill: #000;
  /*black*/
  stroke: #000;
  stroke-width: 1;
  stroke-miterlimit: 10;
  /*visible*/
  opacity: 1;
}
/*the edge of the level*/

#renclosure {
  /*the background you actually see*/
  fill: #EEE;
}

<svg id="canvas" viewBox="0 0 1920 1080">
  <!--for adding SVG filters to-->
  <defs id="filters"></defs>
</svg>
<div id="border"></div>

解决方案

Turns out there was a really simple solution, all I had to do was add a preserveAspectRatio="none" into the svg tag and this would make it stretch to fill all windows.

window.setInterval(function() {
  if (draw) {
    if (keystate[controls[2]]) {
      xvelocity -= 2;
    }
    if (keystate[controls[3]]) {
      xvelocity += 2;
    }
    xvelocity = xvelocity * 0.93;
    xscroll += xvelocity;
    svg.setAttribute("viewBox", (xscroll + " " + yscroll + " " + dimensions.width + " " + dimensions.height));
    centerplayer();
    if (checkcollision()) {
      xscroll -= xvelocity;
      xvelocity = xvelocity * -0.8;
    }
    if (keystate[controls[0]]) {
      yvelocity += 2;
    }
    if (keystate[controls[1]]) {
      yvelocity -= 2;
    }
    yvelocity = yvelocity * 0.93;
    yscroll -= yvelocity;
    svg.setAttribute("viewBox", (xscroll + " " + yscroll + " " + dimensions.width + " " + dimensions.height));
    centerplayer();
    if (checkcollision()) {
      yscroll += yvelocity;
      yvelocity = yvelocity * -0.8;
    }
    shadowrays();
  }
}, 16.666666666666667);
var keystate = {};
window.addEventListener("keydown", function(e) {
  if (!(((e.keycode || e.which) > 111) && ((e.keyCode || e.which) < 124))) {
    keystate[e.keycode || e.which] = true;
  }
}, true);
window.addEventListener("keyup", function(e) {
  keystate[e.keycode || e.which] = false;
}, true);

function shadowrays() {
  var kill = document.getElementsByClassName("shadowray");
  while (kill[0]) {
    kill[0].parentNode.removeChild(kill[0]);
  }
  var len = level.length,
    shape = {},
    points = [],
    poly = [],
    p1x, p2x, p1y, p2y, p3x, p3y, p4x, p4y, p5x, p5y, p6x, p6y, cx = player.cx.animVal.value,
    cy = player.cy.animVal.value,
    m, i, n;
  for (i = 1; i < len; i += 1) {
    shape = level[i];
    points = [shape.x, shape.y, shape.x, shape.y + shape.height, shape.x + shape.width, shape.y + shape.height, shape.x + shape.width, shape.y];
    for (n = 0; n < 4; n += 1) {
      p1x = points[(n * 2) % 8];
      p2x = points[(n * 2 + 2) % 8];
      p1y = points[(n * 2 + 1) % 8];
      p2y = points[(n * 2 + 3) % 8];
      if ((((Math.abs(p1x - cx) <= dimensions.width / 2) || (Math.abs(p2x - cx) <= dimensions.width / 2)) && ((Math.abs(p1y - cy) <= dimensions.height / 2) || (Math.abs(p2y - cy) <= dimensions.height / 2))) && shape.id != "enclosure") {
        m = (p1y - cy) / (p1x - cx);
        p6y = m * (cx + dimensions.width / 2 * (Math.abs(p1x - cx) / (p1x - cx))) - m * cx + cy;
        if (Math.abs(p6y - cy) <= dimensions.height / 2) {
          p6x = (p6y - cy) / m + cx;
          p5x = p6x;
          p5y = cy + dimensions.height / 2 * (Math.abs(p6y - cy) / (p6y - cy));
        } else {
          p6y = cy + dimensions.height / 2 * (Math.abs(p6y - cy) / (p6y - cy));
          p6x = (p6y - cy) / m + cx;
          p5x = cx + dimensions.width / 2 * (Math.abs(p6x - cx) / (p6x - cx));
          p5y = p6y;
        }
        m = (p2y - cy) / (p2x - cx);
        p3y = m * (cx + dimensions.width / 2 * (Math.abs(p2x - cx) / (p2x - cx))) - m * cx + cy;
        if (Math.abs(p3y - cy) <= dimensions.height / 2) {
          p3x = (p3y - cy) / m + cx;
          p4x = p3x;
          p4y = cy + dimensions.height / 2 * (Math.abs(p3y - cy) / (p3y - cy));
        } else {
          p3y = cy + dimensions.height / 2 * (Math.abs(p3y - cy) / (p3y - cy));
          p3x = (p3y - cy) / m + cx;
          p4x = Number(cx) + Number(dimensions.width) / 2 * (Math.abs(p3x - cx) / (p3x - cx));
          p4y = p3y;
        }
        poly = [];
        poly.push(p1x + ',' + p1y, p2x + ',' + p2y, p3x + ',' + p3y, p4x + ',' + p4y, p5x + ',' + p5y, p6x + ',' + p6y);
        createpolygon(poly, "", ("s" + i + n), "shadowray");
      }
    }
  }
}

function createpolygon(points, filter, id, classt) {
  var polygon = document.createElementNS(svgns, "polygon"),
    data_points = "",
    max = points.length,
    z;
  polygon.setAttributeNS(null, "id", "p" + id);
  for (z = 0; z < max; z += 1) {
    data_points += points[z] + " ";
  }
  polygon.setAttributeNS(null, "points", data_points);
  if (filter !== "") {
    polygon.setAttributeNS(null, "filter", filter);
  }
  polygon.setAttributeNS(null, "class", classt);
  svg.appendChild(polygon);
}

function centerplayer() {
  player.setAttributeNS(null, "cx", (xscroll + dimensions.width / 2));
  player.setAttributeNS(null, "cy", (yscroll + dimensions.height / 2));
  var hitbox = document.getElementById("rhb");
  hitbox.setAttributeNS(null, "width", player.r.animVal.value * 2);
  hitbox.setAttributeNS(null, "height", player.r.animVal.value * 2);
  //            var hitboxbbox = hitbox.getBBox();
  hitbox.setAttributeNS(null, "transform", ("translate(" + (xscroll + dimensions.width / 2 - player.r.animVal.value) + ", " + (yscroll + dimensions.height / 2 - player.r.animVal.value) + ")"));
}

function draw(lvl) {
  var objects = lvl.length,
    i;
  xscroll = Number(lvl[0].xspawn);
  yscroll = Number(lvl[0].yspawn);
  xvelocity = 0;
  yvelocity = 0;
  for (i = 1; i < objects; i += 1) {
    var object = lvl[i];
    if (object.type == "rect") {
      createrectangle(object.x, object.y, object.width, object.height, "", object.id, object.class);
    } else if (object.type == "circle") {
      createcircle(object.x, object.y, object.r, "", object.id, object.class);
    } else if (object.type == "polygon") {
      createpolygon(object.points, "", object.id, object.class);
    }
  }
  createcircle("7680", "4320", "50", "", "player", "st1");
  createrectangle("0", "0", "100", "100", "", "hb", "st2");
  createrectangle(lvl[0].xexit - 50, lvl[0].yexit - 50, "100", "100", "", "exit", "exit");
  drawn = true;
}

function createcircle(posx, posy, radius, filter, id, classt) {
  var circle = document.createElementNS(svgns, "circle");
  circle.setAttributeNS(null, "id", "c" + id);
  circle.setAttributeNS(null, "cx", posx);
  circle.setAttributeNS(null, "cy", posy);
  circle.setAttributeNS(null, "r", radius);
  if (filter !== "") {
    circle.setAttributeNS(null, "filter", filter);
  }
  circle.setAttributeNS(null, "class", classt);
  svg.appendChild(circle);
}

function createrectangle(posx, posy, width, height, filter, id, classt) {
  var rectangle = document.createElementNS(svgns, "rect");
  rectangle.setAttributeNS(null, "id", "r" + id);
  rectangle.setAttributeNS(null, "x", posx);
  rectangle.setAttributeNS(null, "y", posy);
  rectangle.setAttributeNS(null, "width", width);
  rectangle.setAttributeNS(null, "height", height);
  if (filter !== "") {
    rectangle.setAttributeNS(null, "filter", filter);
  }
  rectangle.setAttributeNS(null, "class", classt);
  svg.appendChild(rectangle);
}

var svg = document.getElementById("canvas"), //the svg element
  dimensions = {
    width: 1920,
    height: 1080
  }, //view dimensions
  svgns = "http://www.w3.org/2000/svg", //the SVG name space address
  player, //player is used later in game
  level, xvelocity, yvelocity, xscroll, yscroll, //current level, speeds and positions
  controls = ["87", "83", "65", "68", "32"],
  drawn = false;

function checkcollision() {
  var r = player.r.animVal.value,
    frame = document.getElementById("renclosure").getBBox(),
    i;
  if ((player.cx.animVal.value < r) || (player.cy.animVal.value < r) || (player.cx.animVal.value > frame.width - r) || (player.cy.animVal.value > frame.height - r)) {
    return true;
  }
  var collisions = [],
    len, r0 = document.getElementById("rhb").getBoundingClientRect(),
    r1 = svg.createSVGRect();
  r1.x = r0.left;
  r1.y = r0.top;
  r1.width = r0.width;
  r1.height = r0.height;
  var collisions_node = svg.getIntersectionList(r1, null);
  len = collisions_node.length;
  for (i = 0; i < len; i += 1) {
    collisions.push(collisions_node[i]);
  }
  for (i = len - 1; i >= 0; i -= 1) {
    if (collisions[i].id == "renclosure" || collisions[i].id == "cplayer" || collisions[i].id == "rpain" || collisions[i].id == "rhb" || collisions[i].className.animVal == "shadowray") {

      collisions.splice(i, 1);
    } else if (collisions[i].id == "rexit") { //winner
      //DO STUFF
    }
  }
  if (collisions.length > 0) {
    return true;
  } else {
    return false;
  }
}

level = [{
  "id": "l0",
  "name": "pretty", //level name
  "description": "oooooo shadows", //desciption
  "xspawn": 0, //where the player starts
  "yspawn": 0,
  "xexit": 2200, //where the exit it
  "yexit": 2200,
  "bits": 50 //umber of qbits in the level
}, {
  id: "enclosure", //shape id
  type: "rect", //shape type
  x: 0, //top left x
  y: 0, //top left y
  class: "obstacle_box", //class for style
  width: 5760, //width
  height: 2160 //height
}, {
  id: "1",
  type: "rect",
  x: 150,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "2",
  type: "rect",
  x: 350,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "3",
  type: "rect",
  x: 550,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "4",
  type: "rect",
  x: 750,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "5",
  type: "rect",
  x: 950,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "6",
  type: "rect",
  x: 1150,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "7",
  type: "rect",
  x: 1350,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "8",
  type: "rect",
  x: 1550,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "9",
  type: "rect",
  x: 1750,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "10",
  type: "rect",
  x: 1950,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "11",
  type: "rect",
  x: 2150,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "12",
  type: "rect",
  x: 2350,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "13",
  type: "rect",
  x: 2550,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "14",
  type: "rect",
  x: 2750,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "15",
  type: "rect",
  x: 2950,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "16",
  type: "rect",
  x: 3150,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "17",
  type: "rect",
  x: 3350,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "18",
  type: "rect",
  x: 3550,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "19",
  type: "rect",
  x: 3750,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}, {
  id: "20",
  type: "rect",
  x: 3950,
  y: 200,
  class: "obstacle_box",
  width: 100,
  height: 100
}];

draw(level);
player = document.getElementById("cplayer");
svg.setAttribute("viewBox", (xscroll + " " + yscroll + " " + dimensions.width + " " + dimensions.height));
centerplayer();
shadowrays();

html,
body {
  /*default font for all elements*/
  font-family: Calibri;
  /*ensures page is flush*/
  margin: 0px;
  width: 100%;
  height: 100%;
  /*default position of text*/
  text-align: center;
  /*gets rid of scrollbars*/
  overflow: hidden;
  /*cursor is always the normal pointer*/
  cursor: default;
}
#canvas {
  /*makes it flush with the page*/
  height: 100%;
  width: 100%;
  padding: 0;
  /*black background*/
  background-color: #000;
  /*more flushing*/
  position: fixed;
  left: 0px;
  top: 0px;
  border: none;
}
#border {
  height: 100%;
  width: 100%;
  padding: 0;
  /*black background*/
  background: none;
  /*more flushing*/
  position: fixed;
  left: 0px;
  top: 0px;
  border: 1px solid #000;
}
/*currently the player*/

.st1 {
  /*it's black and no outline*/
  fill: black;
  stroke: none;
}
/*the main black bits of the levels that are collidable*/

.obstacle_box {
  /*black fill*/
  fill: #000;
  /*black outline*/
  stroke: #000;
  stroke-width: 1;
  /*prevents corner curling*/
  stroke-miterlimit: 10;
}
/*the hitbox thingy*/

.st2 {
  /*no fill but darkish outline*/
  fill: none;
  stroke: #999;
  stroke-width: 1;
  stroke-miterlimit: 10;
}
/*the exit*/

.exit {
  /*greenish fill*/
  fill: #0C3;
  /*greener outline*/
  stroke: #00FF40;
  stroke-width: 5;
  /*makes the line ends round*/
  stroke-linecap: round;
  /*makes them dashed*/
  stroke-dasharray: 10, 10;
  /*animates in a loop the outline*/
  animation: exit 0.5s linear infinite;
}
/*outline effect for the exit*/

@keyframes exit {
  0% {
    /*outline breaks offset*/
    stroke-dashoffset: 0
  }
  100% {
    stroke-dashoffset: 20
  }
}
.shadowray {
  /*black*/
  fill: #000;
  /*black*/
  stroke: #000;
  stroke-width: 1;
  stroke-miterlimit: 10;
  /*visible*/
  opacity: 1;
}
/*the edge of the level*/

#renclosure {
  /*the background you actually see*/
  fill: #EEE;
}

<svg id="canvas" viewBox="0 0 1920 1080" preserveAspectRatio="none">
  <!--for adding SVG filters to-->
  <defs id="filters"></defs>
</svg>
<div id="border"></div>

这篇关于SVG viewbox显示显示屏幕项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆