Vue Konva。使用动画提高渲染多个圆的性能

问题描述 投票:1回答:2

我正在尝试提高下面代码的性能。我正在寻找每X秒在屏幕上的鼠标光标位置渲染多个圆圈。 gif很好地显示了它。

这是当我按住鼠标并拖动时的当前外观,但是我想提高性能,因此至少我没有使用那么多图层。请参阅Google开发工具中的警告。GIF demonstrating the current effects and issues

这是我的组件代码,它是用Vue和Typescript编写的。Vue with Typescript和Vue Konva对我来说都是新手,因此,如果您发现我的代码有任何捷径,也请告诉我。

我不喜欢解决问题的方法,我觉得有更好的解决方法,但是我没有在文档中或通过Google搜索找到任何真正的例子,所以我设法做到了开始工作。

谢谢。

<template>
  <v-stage ref="stage" :config="stageSize" class="konva-stage" @mousemove="throttledMethod" :onMouseDown="onMouseDownHandler" :onMouseUp="onMouseUpHandler">
    <v-layer ref="layer" />
  </v-stage>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { ITool } from '../types/canvas'
import Konva from 'konva'
import _ from 'lodash'

@Component({
  name: 'MapCanvas',
  data () {
    return {
      stageSize: {
        width: window.innerWidth,
        height: window.innerHeight
      },
      showPing: false
    }
  },
  methods: {
    throttledMethod: _.throttle(function (e) {
      this.onMouseMoveHandler(e)
    }, 100),
    onMouseUpHandler (e: any) : void {
      this.$data.showPing = false
    },
    onMouseDownHandler (e: any) : void {
      this.$data.showPing = true
    },
    addPing (e, stage) {
      const layer = new Konva.Layer()
      const amplitude = 25
      const period = 500

      let item = new Konva.Circle({
        x: e.evt.x,
        y: e.evt.y,
        radius: 0,
        stroke: 'red',
        strokeWidth: 5
      })
      layer.add(item)
      stage.add(layer)

      const anim = new Konva.Animation((frame: any) => {
        item.radius(amplitude * Math.sin((frame.time * Math.PI) / 1000))
      }, layer)
      anim.start()

      setTimeout(() => {
        layer.remove()
        anim.stop()
      }, period)
    },
    onMouseMoveHandler (e:any) : void {
      if (this.$data.showPing) {
          const stage = this.$refs.stage.getStage()
          this.addPing(e, stage)
        }
      }
    }
  }
})
export default class MapButtons extends Vue {
  @Prop() private id!: string;
}
</script>
<style scoped lang="scss">
.konva-stage {
  background-color: white;
  width: 100%;
  height: 100%;
  position: absolute;
}
</style>

typescript performance vue.js animation konvajs
2个回答
2
投票

您可以只使用已经在模板中创建的图层:

    addPing(e, stage) {
      const layer = this.$refs.layer.getNode();
      const amplitude = 25;
      const period = 500;

      let item = new Konva.Circle({
        x: e.evt.x,
        y: e.evt.y,
        radius: 0,
        stroke: "red",
        strokeWidth: 5
      });
      layer.add(item);

      const anim = new Konva.Animation(frame => {
        item.radius(amplitude * Math.sin((frame.time * Math.PI) / 1000));
      }, layer);
      anim.start();

      setTimeout(() => {
        item.destroy();
        anim.stop();
        layer.batchDraw();
      }, period);
    },

0
投票

[只是为了好玩,这是@lavrton用普通JS给出的答案。运行该代码段,并将鼠标移到白色画布上。随后出现红色圆圈。

function addPing(e) {

  var amplitude = 25,
      period = 500;

  var item = new Konva.Circle({
          x: e.evt.x,
          y: e.evt.y,
          radius: 0,
          stroke: "red",
          strokeWidth: 5
        });

  layer.add(item);

  var anim = new Konva.Animation(
    function(frame) {
      item.radius(amplitude * Math.sin((frame.time * Math.PI) / 1000));
    }, layer);

  anim.start();

  setTimeout(function(){
      item.destroy();
      anim.stop();
      layer.batchDraw();
    }, period);

}

function setup() {

// Set up a stage and a shape
stage = new Konva.Stage({
  container: 'konva-stage',
  width: 800,
  height: 500
});


layer = new Konva.Layer();
stage.add(layer);

stage.draw()

stage.on('mousemove', function(e){
          addPing(e)
  })
}

var stage, layer;

setup()
.konva-stage {
  width: 100%;
  height: 100%;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/4.0.13/konva.js"></script>

<div id="konva-stage"></div>
© www.soinside.com 2019 - 2024. All rights reserved.