RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1306806
Accepted
Leonid
Leonid
Asked:2022-07-20 00:45:55 +0000 UTC2022-07-20 00:45:55 +0000 UTC 2022-07-20 00:45:55 +0000 UTC

如何在 SVG 和 JavaScript 中同时引入和使用变量?

  • 772

我试图用 JS 控制的 SVG 制作一个小游戏。但是,我遇到了一个问题:如何在 SVG 代码中引入和重用变量?这里要定义宽度和高度<svg>,火球的起始位置(<circle>),边界框的宽度<rect>。那么如何在 JS 中优雅地获取它们呢?

我也欢迎任何关于 SVG 和 JS 的评论。谢谢你。

let svg = document.getElementById('_svg');
let circle = svg.querySelector('circle');
let text = svg.querySelector('text');

let position = [+circle.getAttribute('cx'), +circle.getAttribute('cy')];

let attractionX = 0;
let attractionY = 0;

let score = 0;

let anim;

svg.addEventListener('mousemove', e => {
    attractionX = position[0] < e.clientX ? 1 : -1;
    attractionY = position[1] < e.clientY ? 1 : -1;
})

function animateCircle() {
    position[0] += Math.floor(Math.random()*11) - 5 + attractionX;
    position[1] += Math.floor(Math.random()*11) - 5 + attractionY;
    score++;
    
    circle.setAttribute('cx', position[0]);
    circle.setAttribute('cy', position[1]);
    text.innerHTML = score;
    
    anim = requestAnimationFrame(animateCircle);
    
    if(position[0]<=20 || position[0]>=580 || position[1]<=20 || position[1]>=140){
        cancelAnimationFrame(anim);
        text.style.fill = 'red';
        text.style.fontSize = '20px';
        text.innerHTML = 'GAMEOVER. Your score: ' + score;
    }   
}

animateCircle();
<svg viewbox="0 0 600 160" id="_svg" width="600px" height="160px">
    <circle cx="300" cy="80" r="20" fill="yellow" stroke="black" />
    <rect x="0" y="0" width="600" height="160" stroke="red" fill="none"/>
    <text x="10" y="20">0</text>
</svg>

javascript
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    user347472
    2022-07-23T05:25:19Z2022-07-23T05:25:19Z

    SVG 中没有变量,就像 HTML 中一样。您可以在 JS 中创建它们并从那里设置 SVG 元素的属性。因此,您不必阅读它们,因为变量已经在 J​​S 中。

    也许您想从 SVG 开始,因为它看起来更直观。但是你可以将 SVG 仅用作显示组件,而不是数据源,并将所有实体保留在 JS 中。所以数据方向总是从 JS 到 SVG。这就是在 SVG 上构建图形、在线构造函数和其他动态事物的方式。他们的数据总是在 JS 或 JSON 或某些数据库中,但不在 SVG 中。

    在个别变量上,你只能做一些基本的事情,然后你不必考虑优雅。

    并且可以使用类(组件)来制作优雅的解决方案。显示元素的所有逻辑都包含在类中。然后你只使用这些类的副本进行操作。事实证明,这种抽象在开发速度方面具有优势。这是一个示例,不是试图重复您的情况,而只是为了说明它通常是如何工作的:

    class Game {
      
      svg;
      
      constructor(){
        this.svg = new Svg();
        
        // Просто куча кругов для примера удобства использования
        for( let i = 0; i < 10; i++ ){
          let circle = new Circle(
            Math.random() * this.svg.width,
            Math.random() * this.svg.height,
            Math.random() * 20
          );
          this.svg.append(circle);
        }
        
        // А этот круг за мышкой следует
        let circleForMouse = new Circle( 0, 0, 50 );
        this.svg.append(circleForMouse);
        
        this.svg.element.addEventListener( 'mousemove', event => {
          circleForMouse.x = event.clientX;
          circleForMouse.y = event.clientY;
        })
      }
    
    }
    
    class Svg {
      
      static xmlns = "http://www.w3.org/2000/svg";
      
      element;
      
      constructor(){
        this.element = Svg.createElement('svg');
        document.body.append(this.element);
        this.updateSize();
      }
      
      static createElement( tagName ){
        return document.createElementNS( Svg.xmlns, tagName );
      }
      
      updateSize(){
        let width = document.body.clientWidth;
        let height = document.body.clientHeight;
        this.viewbox = `0 0 ${width} ${height}`;
        this.width = width;
        this.height = height;
      }
      
      get viewbox(){
        return this.element.getAttribute('viewbox');
      }
      
      set viewbox( value ){
        this.element.setAttribute( 'viewbox', value );
      }
      
      get width(){
        return +this.element.getAttribute('width');
      }
      
      get height(){
        return +this.element.getAttribute('height');
      }
      
      set width( value ){
        this.element.setAttribute( 'width', value );
      }
      
      set height( value ){
        this.element.setAttribute( 'height', value );
      }
      
      append( childInstance ){
        this.element.append( childInstance.element );
      }
      
    }
    
    class Circle {
      
      element;
      
      constructor( x, y, radius ){
        this.element = Svg.createElement('circle');
        this.x = x;
        this.y = y;
        this.radius = radius;
      }
      
      get x(){
        return +this.element.getAttribute('cx');
      }
      
      get y(){
        return +this.element.getAttribute('cy');
      }
      
      set x( value ){
        this.element.setAttribute( 'cx', value );
      }
      
      set y( value ){
        this.element.setAttribute( 'cy', value );
      }
      
      get radius(){
        return +this.element.getAttribute('r');
      }
      
      set radius( value ){
        this.element.setAttribute( 'r', value );
      }
      
    }
    
    let game = new Game();
    svg {
      border: 1px solid black;
    }
    <!-- заметьте, что в HTML ничего нет, всё в JS -->

    • 2

相关问题

  • 第二个 Instagram 按钮的 CSS 属性

  • 由于模糊,内容不可见

  • 弹出队列。消息显示不正确

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5