Vue Konva。提高用动画渲染多个圆的性能
Vue Konva. Improve performance of rendering multiple circles with animation
我正在尝试提高下面代码的性能。我希望每隔 X 秒在鼠标光标位置的屏幕上渲染多个圆圈。 gif 显示得很好。
这是我按住鼠标并拖动时的当前外观,但我想提高性能,所以至少我没有使用那么多图层。请参阅 google 开发工具中的警告。
这是我的组件代码,它是用 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>
您可以只使用您已经在模板中创建的图层:
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);
},
为了好玩,这里是@lavrton 的简单 JS 回答。 运行 片段并将鼠标悬停在白色 canvas 上。随之而来的是红色圆圈。
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>
我正在尝试提高下面代码的性能。我希望每隔 X 秒在鼠标光标位置的屏幕上渲染多个圆圈。 gif 显示得很好。
这是我按住鼠标并拖动时的当前外观,但我想提高性能,所以至少我没有使用那么多图层。请参阅 google 开发工具中的警告。
这是我的组件代码,它是用 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>
您可以只使用您已经在模板中创建的图层:
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);
},
为了好玩,这里是@lavrton 的简单 JS 回答。 运行 片段并将鼠标悬停在白色 canvas 上。随之而来的是红色圆圈。
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>