I followed the documentation and Github I did the following steps:
install vue-konva and konva and canvas using npm install vue-konva konva --save and npm install canvas --save.
Created vuekonva.js under plugins folder with below content:
import Vue from 'vue'
import VueKonva from 'vue-konva'
Vue.use(VueKonva)
Added plugins: [ "~/plugins/vuekonva"], under nuxt.config.js
I tried adding under nuxt-config.js but still no luck:
build: {
standalone: true
},
Created a page under pages folder and added code from documenation:
<template>
<div>
<v-stage ref="stage" :config="stageSize">
<v-layer>
<v-text :config="{ text: 'Some text on canvas', fontSize: 15 }" />
<v-rect
:config="{
x: 20,
y: 50,
width: 100,
height: 100,
fill: 'red',
shadowBlur: 10,
}"
/>
<v-circle
:config="{
x: 200,
y: 100,
radius: 50,
fill: 'green',
}"
/>
<v-line
:config="{
x: 20,
y: 200,
points: [0, 0, 100, 0, 100, 100],
tension: 0.5,
closed: true,
stroke: 'black',
fillLinearGradientStartPoint: { x: -50, y: -50 },
fillLinearGradientEndPoint: { x: 50, y: 50 },
fillLinearGradientColorStops: [0, 'red', 1, 'yellow'],
}"
/>
</v-layer>
<v-layer ref="dragLayer" />
</v-stage>
</div>
</template>
<script>
export default {
data () {
return {
stageSize: {
width,
height
}
}
},
mounted () {
if (process.browser) {
this.stageSize.width = window.innerWidth
this.stageSize.height = window.innerHeight
}
}
}
</script>
I get the error:
Must use import to load ES Module:
I tried without plugins and it is throwing the error:
vue.runtime.esm.js:620 [Vue warn]: Unknown custom element: <v-stage> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
Not understanding whats the issue please help.
According to Nuxt documentation some plugins export an ES6 module. I think this is the case for konva node module. I followed the steps you mentioned above. But in the nuxt.config.js file I configured the plugin as follow:
plugins: [
{ src: "~/plugins/vuekonva", mode: 'client' }
],
build: {
transpile: ['konva']
},
After that I replaced the code of your page with the code of konvajs as follows:
<template>
<v-stage :config="configKonva">
<v-layer>
<v-circle :config="configCircle"></v-circle>
</v-layer>
</v-stage>
</template>
<script>
export default {
data() {
return {
configKonva: {
width: 200,
height: 200
},
configCircle: {
x: 100,
y: 100,
radius: 70,
fill: "red",
stroke: "black",
strokeWidth: 4
}
};
}
};
</script>
That is working for me when I link to the page with nuxt-link. but if I refresh the page I get some errors that is maybe for SSR. I am not sure but if you read this documentation you maybe could solve the problem for SSR.
Related
Trying to load an image in the center of a QR Code on a Vue3 project. Been reading through the API documentation online and it appears I'm supposed to load it as a string through the "image" parameter, but every time I try to load the image by QR Code disappears entirely.
The page I'm specifically working through is here: https://www.npmjs.com/package/qrcode-vue3
Below is the current working of the code:
<QRCodeVue3
:width="200"
:height="200"
value="HelloWorld"
:qrOptions="{ typeNumber: 0, mode: 'Byte', errorCorrectionLevel: 'H' }"
image="https://cryptologos.cc/logos/ravencoin-rvn-logo.png"
:imageOptions="{ hideBackgroundDots: true, imageSize: 0.4, margin: 0 }"
backgroundColor="white"
:dotsOptions="{
type: 'dots',
color: '#26249a',
gradient: {
type: 'linear',
rotation: 0,
colorStops: [
{ offset: 0, color: '#26249a' },
{ offset: 1, color: '#26249a' },
],
},
}"
:backgroundOptions="{ color: '#ffffff' }"
:cornersSquareOptions="{ type: 'dot', color: '#000000' }"
:cornersDotOptions="{ type: undefined, color: '#000000' }"
/>
End goal I would prefer to load the image from my assets folder but I can't even get a simple image that works to load. I know it's possible because I see the examples QR codes on the npm page but no example code to demonstrate it.
Realized I needed to add the crossOrigin = 'Anonymous' as well as I implemented a v-bind to a url of my local image. Final working solution is as follows:
New component:
<QRCodeVue3
:width="200"
:height="200"
value="HelloWorld"
:qrOptions="{ typeNumber: 0, mode: 'Byte', errorCorrectionLevel: 'H' }"
v-bind:image="iconUrl"
:imageOptions="{ hideBackgroundDots: true, imageSize: 0.4, margin: 3, crossOrigin: 'Anonymous' }"
backgroundColor="white"
:dotsOptions="{
type: 'dots',
color: '#26249a',
gradient: {
type: 'linear',
rotation: 0,
colorStops: [
{ offset: 0, color: '#26249a' },
{ offset: 1, color: '#26249a' },
],
},
}"
:backgroundOptions="{ color: '#ffffff' }"
:cornersSquareOptions="{ type: 'dot', color: '#000000' }"
:cornersDotOptions="{ type: undefined, color: '#000000' }"
/>
Loading image:
export default {
name: "HomeView",
components: {
QRCodeVue3,
},
data() {
return {
iconUrl: require('../assets/ravencoin-rvn-logo.png')
};
},
working with vue-konva (svg based canvas library) right now. I'm trying to animate all shapes which are defined by a v-loop. While trying to use the Konva Animation library functions, I'm getting "Cannot read property 'getNode' of undefined" error. I'm assuming this is due to the fact that a ref has to have one specific element and not be adressed inside a v-for loop. How can I simultaneaously animate all the polygons?
SVG / canvas element:
<v-regular-polygon
v-for="el in results"
ref="hexagon"
:key="el.index"
:config="{
x: 200 * Math.abs(el.land),
y: 200,
sides: 6,
radius: 20,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
}"
/>
function responsible for animation
mounted() {
this.fetchTemperature()
const vm = this
const amplitude = 100
const period = 5000
// in ms
const centerX = vm.$refs.stage.getNode().getWidth() / 2
const hexagon = this.$refs.hexagon.getNode()
// example of Konva.Animation
const anim = new Konva.Animation(function (frame) {
hexagon.setX(amplitude * Math.sin((frame.time * 2 * Math.PI) / period) + centerX)
}, hexagon.getLayer())
anim.start()
},
You can set a unique ref to every polygon by adding an index.
<v-regular-polygon
v-for="(el, i) in results"
:ref="`hexagon_${i}`"
...
Here's an example:
<template>
<div id="app">
<v-stage :config="configKonva">
<v-layer>
<v-circle
v-for="(item, i) in items"
:config="item"
:key="i"
:ref="`circle_${i}`"
></v-circle>
</v-layer>
</v-stage>
</div>
</template>
<script>
import Konva from "konva";
export default {
name: "App",
data() {
return {
items: [
{
x: 30,
y: 100,
radius: 20,
fill: "red",
stroke: "black",
strokeWidth: 2,
},
{
x: 100,
y: 100,
radius: 20,
fill: "red",
stroke: "black",
strokeWidth: 2,
},
],
configKonva: {
width: 200,
height: 200,
},
};
},
mounted() {
for (let i = 0; i < this.items.length; i++) {
const node = this.$refs[`circle_${i}`][0].getNode();
const period = 1000;
const amplitude = 10;
const anim = new Konva.Animation((frame) => {
node.setX(
amplitude * Math.sin((frame.time * 2 * Math.PI) / period) +
this.items[i].x
);
}, node.getLayer());
anim.start();
}
},
};
</script>
Codesandbox
Currently I'm using Vue-Konva.js to help me build a 2d editor for panorama.
Does konva.js support GLSL code for apply image effect (ex: stereographic projection)?
Maybe like this format.
KonvaScens.vue
<template>
<v-stage :config="configKonva">
<v-layer>
<v-image :config="configImage"></v-image>
</v-layer>
</v-stage>
</template>
<script>
import {myVertexShader, myFragmentShader} from 'imageShader'
export default {
data () {
return {
testImg: new Image(100, 100),
configKonva: {
width: 500,
height: 500
}
}
},
computed: {
configImage () {
return {
x: 20,
y: 20,
image: this.testImg,
width: 500,
height: 500,
vertexShader: myVertexShader,
fragmentShader: myFragmentShader
}
}
},
mounted () {
this.testImg.src = "https://konvajs.github.io/assets/lion.png"
}
}
</script>
No, vue-konva doesn't support GLSL. GLSL can be used in webgl canvas context. But Konva uses only 2d context.
I want to set the height of a vue component (to be specific it is this -> https://github.com/jbaysolutions/vue-grid-layout).
The height of which (in vue-grid-layout -> grid-item) should be same as of its parent.
And this also should be only in page load time. So how this can be achieved in vue js?
I don't want to do this using CSS. I need height in pixels. as to vue-grid-layout -> item height needs in pixel initially. as it is resizable, it can be changed afterwards.
it would be easier to provide an accurate answer with some example html (your actual code), but the following should work in general.
export default {
...
data() {
return {
parentHeight: 0
}
},
mounted() {
this.parentHeight = this.$parent.$el.offsetHeight;
}
...
}
So in the mounted lifecycle hook you can read the height of the parent and then set it where ever you need it.
No need for advanced javascript to calculate the height, just use styling:
height: 100%;
Demo:
.parent {
resize: both;
overflow: auto;
height: 100px;
display: block;
width: 100px;
border: 1px solid black;
}
.child {
height: 100%;
background: pink;
}
<div class="parent">
</div>
<div class="parent">
<div class="child">
I'm a child!
</div>
</div>
I found a solution to fix the grid-layout height depending on available space. For that I have used folowing props: max-rows, row-height, margins, autoSize=false
And ResizeObserver which will adjust grid-layout row-height according to available height after window resize. Also be aware that I used some Bootstrap classes for styling
<template>
<div class="flex-grow-1 w-100">
<grid-layout
:layout="layout"
:col-num="colCount"
:maxRows="rowCount"
:row-height="rowHeight"
:autoSize="false"
:is-draggable="true"
:is-resizable="true"
:is-mirrored="false"
:preventCollision="true"
:vertical-compact="false"
:margin="margin"
:use-css-transforms="true"
>
<grid-item
v-for="item in layout"
class="bg-primary"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
>
<span class="remove" #click="removeItem(item.i)">x</span>
</grid-item>
</grid-layout>
</div>
</template>
<script lang="ts">
import { defineComponent } from '#vue/runtime-core';
interface GridItem {
x: number;
y: number;
w: number;
h: number;
i: string;
}
interface State {
layout: GridItem[];
index: number;
colCount: number;
rowCount: number;
rowHeight: number;
observer: null | ResizeObserver;
margin: number[];
}
export default defineComponent({
name: 'VideoWall',
data(): State {
return {
layout: [
{ x: 0, y: 0, w: 2, h: 2, i: '0' },
{ x: 2, y: 0, w: 2, h: 4, i: '1' },
{ x: 4, y: 0, w: 2, h: 5, i: '2' },
{ x: 6, y: 0, w: 2, h: 3, i: '3' },
{ x: 8, y: 0, w: 2, h: 3, i: '4' },
],
index: 0,
colCount: 36,
rowCount: 36,
rowHeight: 40,
margin: [5, 5],
observer: null,
};
},
mounted() {
this.observer = new ResizeObserver(this.onResize);
if (this.$el instanceof Element) {
this.observer.observe(this.$el);
} else {
console.log('VideoWall: Failed to bind observer');
}
},
unmounted() {
if (this.observer) {
this.observer.disconnect();
}
},
methods: {
onResize(entries: ResizeObserverEntry[]): void {
this.rowHeight =
Math.floor(entries[0].contentRect.height / this.rowCount) -
this.margin[1];
},
},
});
</script>
I am new to Aurelia and have some background in javascript. I am using CLI to build and run my project. Dwayne Charrington has guided me on the integration of sigmajs into Aurelia. Thanks, Dwayne!
I have installed sigma into the project through
npm install sigma --save
I have prepended the sigma.min.js to aurelia_project/aurelia.json.
"prepend": [
"node_modules/bluebird/js/browser/bluebird.core.js",
"node_modules/requirejs/require.js",
"node_modules/sigma/build/sigma.min.js"
]
I am using the attached() lifecycle method to get the ts and html to work together for integrating sigmajs as suggested by Dwayne.
-- sigmajs.html
<template>
<require from="./sigmajs.css"></require>
<section>
<div class="col-lg-4 col-lg-offset-4">
<h1> An </h1>
<div id="container1"></div>
</div>
<div class="col-lg-4 col-lg-offset-4">
<button click.delegate="refreshUI()"> Refresh UI </button>
</div>
</section>
</template>
--sigmajs.ts
export class Sigmajs {
s;
refreshUI() {
this.s.refresh();
this.s.graph.nodes().forEach(function(n) {
console.log(n);
});
}
attached() {
this.s = new sigma({
container: 'container1'
});
this.s.graph.addNode({
id: 'n0',
label: 'Hello',
x: 10,
y: 10,
size: 1,
color: '#f00'
}).addNode({
id: 'n1',
label: 'World !',
x: 100,
y: 10,
size: 1,
color: '#00f'
}).addEdge({
id: 'e0',
source: 'n0',
target: 'n1'
});
}
}
-- sigmajs.css
<style>
#container1 {
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
}
</style>
I am unable to see the graph on the HTML page; even when I click the Refresh UI button. When I click the Refresh UI button, I do see the debug statements in the console corresponding to console.log(n) as
Object { label: "Hello", x: 10, y: 10, size: 1, color: "#f00", id: "n0", read_cam0:size: 8, read_cam0:x: -2.8125, read_cam0:y: 0, cam0:x: 195.1875, 2 more… } app-bundle.js:396:17
Object { label: "World !", x: 100, y: 10, size: 1, color: "#00f", id: "n1", read_cam0:size: 8, read_cam0:x: 2.8125, read_cam0:y: 0, cam0:x: 200.8125, 2 more… } app-bundle.js:396:17
thereby leading me to conclude that I am initializing sigmajs correctly; just not seeing the output (of a graph) on HTML
Thank you in advance for your advice.
Answering my own question
The issue was with the css NOT specifying the appropriate height, width with bootstrap also in picture. The following declaration in sigmajs.css shows the rather simple graph (2 nodes, one edge).
<style type="text/css">
body {
margin: 0;
}
#container2 {
position: absolute;
width: 100%;
height: 100%;
}
</style>
I am not a CSS guy; so this answer, while it works, may need some nuances for the graph to look better.
#LStarky It does not seem necessary to do sigma import. I believe that vendor-bundle.js also has sigma due to prepend