How do I make a QML rectangle spawn? - javascript

I'm currently making a game called Snowflake to learn how to program QML with Javascript.
I have my sourcecode here: https://gist.github.com/4510190.
The only files i got besides that is a default qmlproject file and a png file.
I have made this timer(Timer) and a rectangle(skullflake) which it should spawn for every interval it has finished.
Timer { //spawnrate
interval: 2000; running: true; repeat: true
onTriggered: Qt.createQmlObject(skullflake)
}
But when I try to run it, it gives me the error:
file:///where/the/project/is/saved/Snowflake/Snowflake.qml:21: Error: Qt.createQmlObject(): Invalid arguments
I have tried with both these elements but I can't seem to make it work
Qt.createComponent(skullflake)
Qt.createQmlObject(skullflake)

You were using wrong Qt.createQmlComponent().
It requires 3 parameters:
Qt::createQmlObject ( string qml, object parent, string filepath )
So it should look like something like this (parent should be id of element which should contain skullflake):
Timer { //spawnrate
interval: 2000; running: true; repeat: true
onTriggered: Qt.createQmlObject("YOUR skullflake QML CODE (NOT FILE PATH)", parent, "skullflake")
}

I solved it by using the Qt.createComponents() which requires you to use a QML file on the side or use the Component element.
Item {
id: container
width: 300; height: 300
function skullFlake() {
var component = Qt.createComponent("Skullflake.qml");
if (component.status == Component.Ready) {
var flake = component.createObject(container);
flake.color = "purple";
}
}
Component.onCompleted: loadButton()
}
Timer { //spawnrate
interval: 2000; running: true; repeat: true
onTriggered: skullFlake();
}

Related

Closing toastr in webdriver

UI automation testing
I have toast message all around my app, sometimes I get multiple toasts, which blocks clicking on other parts of the app. meaning I have to close them before I can interact with other buttons.
I wrote an if else statement to close them. when there is only one it works. when there are more than 2 toasts it fails.
I am using JS and Node js
Using Webdriverio and Mocha
This is the toastr library https://github.com/CodeSeven/toastr
Can someone tell me what am I missing?
closeToastMessage() {
let close_toast = $$('.toast-close-button');
const closeToasts = $$('.toast-close-button');
let toast_exist = browser.waitForExist('.toast', 5000);
if (close_toast.value) {
close_toast.click();
browser.waitUntil(function() {
return close_toast.waitForExist(5000, true);
}, 5000, 'expecte toast to disappear');
} else if (closeToasts.length) {
for (let i = 0; i < closeToasts.length; i++) {
closeToasts[i].click();
browser.waitUntil(() => {
return !closeToasts[i].isVisible();
}, 5000, `Close toast ${i} still visible after 5 s`, 1000);
} else {
throw new Error('Oops! toast did NOT disappear');
}
}
}
There is a preventDuplicates option. Try setting it to true.
Other options to check out.
toastr.options = {
"closeButton": true, // Allow force-closing
"newestOnTop": false, // Keep the oldest one up-front
"preventDuplicates": true, // Do not allow duplicates to appear
"showDuration": 300, // Time it take to show up, 0.3 sec default
"hideDuration": 1000, // Time it take to hide, 1 sec default
"timeOut": 5000, // Duration it is displayed, 5 sec default
"extendedTimeOut": 1000 // Time it takes to hide if hovered, 1 sec default
}
Checkout their demo.

quaggaJS: how to "pause" the decoder

I'm using quaggaJS (https://github.com/serratus/quaggaJS) to read barcodes in a web application. It works very well, and this is my initialization code:
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
constraints: {
width: 1280,
height: 720,
facingMode: "environment"
}
},
decoder: {
readers: ["code_39_reader"],
debug: {
drawBoundingBox: true,
showFrequency: false,
drawScanline: true,
showPattern: true
},
multiple: false
},
locator: {
halfSample: true,
patchSize: "medium"
}
}, function (err) {
if (err) {
alert(err);
return;
}
Quagga.registerResultCollector(resultCollector);
Quagga.start();
});
here the handling of the onDetected event:
Quagga.onDetected(function (data) {
Quagga.stop(); // <-- I want to "pause"
// dialog to ask the user to accept or reject
});
What does that mean?
When it recognize a barcode I need to ask the user if he wants to accept or reject the decoded value - and therefore repeat the process.
It would be nice to leave the captured image so he can actually see what he just captured.
Quagga.stop() works in most cases but it's not reliable because sometimes the canvas will turn black. I guess this is due the behavior of the stop() method:
the decoder does not process any more images. Additionally, if a camera-stream was requested upon initialization, this operation also disconnects the camera.
For this reason I'm looking for a way to pause the decoding, so the last frame is still there and the camera has not disconnected yet.
Any suggestion how to achieve this?
A better way to do it would be to first pause the video and then call Quagga.stop() so that the video element that Quagga creates for you will be paused and you don't see the blacked out image. Additionally, you can also have a restart/re-scan button to resume or rather restart the scanning process.
To get the view element you can do something like below:
Quagga.onDetected(function (result) {
var cameraFeed = document.getElementById("cameraFeedContainer")
cameraFeed.getElementsByTagName("video")[0].pause();
return;
});
You can get the image frame via Quagga.canvas.dom.image.
With that, you can overlay the videostream.
HTML
<div class="scanArea">
<div id="interactive" class="viewport"></div>
<div class="scanArea__freezedFrame"></div>
</div>
CSS
.scanArea {
position: relative;
}
.scanArea__freezedFrame {
position: absolute;
left: 0;
top: 0;
}
JavaScript
Quagga.onDetected(function(result) {
var canvas = Quagga.canvas.dom.image;
var $img = $('<img/>');
$img.attr("src", canvas.toDataURL());
$('.scanArea__freezedFrame').html($img);
});

Chrome App - webview.cleardata, reload and periodic refresh

I'm working on a kiosk app with a webview to display a Google Slides presentation. Basic mechanics are all working fine, but I need for the webview to refresh periodically to reflect changes made to the Slides.
Watched Chromium bug 406437 to clear webview cache (yay!), and am attempting to implement the webview.cleardata and webview.reload, but doesn't seem to work. Console log shows "Cannot read property 'reload' of null"
Am I on the right track? Is there something simple I'm overlooking, or is there a design flaw in my logic?
Contents of my browser.js (at least the first part)...
// NOTE: Refresh timing is on line 26 - in milliseconds
// 5 min: 5 x 60 (sec) x 1000 (ms)
window.onresize = doLayout;
var isLoading = false;
// Define the function
function refreshWebView() {
var webview = document.querySelector('webview');
// https://github.com/GoogleChrome/chrome-app-samples/blob/master/samples/webview-samples/browser/browser.js
// Set up the clear data variable
var clearDataType = {
appcache: true,
cookies: true,
fileSystems: true,
indexedDB: true,
localStorage: true,
webSQL: true,
cache: true
}
webview.clearData({since: 0}, clearDataType, function() { webview.reload(true); });
webview.reload(true);
setTimeout(function() { refreshWebView(); }, 60*1000);
}
// Kick off the refresh (with the delay defined above)
console.log('starting refreshWebView...');
refreshWebView();
onload = function() {
var webview = document.querySelector('webview');
doLayout();
document.querySelector('#back').onclick = function() {
webview.back();
};
... remaining code removed for brevity...

Paper undefined in JS function using Raphael

Alright, so I am having a bit of trouble with Raphael and automatic updating of elements.
I've got a file called objects.js which looks something like this:
window.onload = function() {
paper = Raphael(document.getElementById('ikoner'), 600, 200);
pump = paper.circle(50,100,50);
pump.data("id","pump");
pump.data("tag",':="output".tag5:');
}
function objectFill (table) {
paper.forEach(function(e){
var tagValue = e.tag.innerHTML;
var tagId = e.id.innerHTML.trim();
if (tagValue == 0) {
paper.getById(tagId).attr({fill:"white"});
}
}
}
On my main page I've got a script which then calls objectFill on a certain interval, and updates the fill color of my objects.
Now to the problem; when I run the page I get the error that paper is undefined in objectFill. How do I make sure that objectFill will be able to find the paper? I've also tried declaring it outside like:
var paper;
window.onload = function() {
paper = Raphael(document.getElementById('ikoner'), 600, 200);
}
But I do not get that to work either. Anyone know what the problem might be?

Easeljs sprite animation stuck on frame

I'm learning javascript by using the easeljs library to make a simple game, for school lessons.
I want to make a crosshair give some feedback to the player by showing a small animation while you are pointing at your target, using a hittest I made.
However, when the crosshair touches the target, the animation (should be two little triangles pointing to the middle of the crosshair) seems to be stuck on it's first frame.
Here is a bit of my code, I put both of these functions inside a ticker function. The functions do what they're supposed to do (I checked by sending a message to the console.log), but I think the animation is reset as soon as the variable "hitTestControle" is set to true, at every tick.
If you want to check out all of the code, here is a link to the "game":
http://athena.fhict.nl/users/i279907/achtergrond/achtergrond.html
function hitTest() {
if(distance(crossHair, block) < 60) {
hitTestControle = true;
} else {
hitTestControle = false;
console.log(hitTestControle);
}
}
function hitTestControl() {
if(hitTestControle == true) {
crossHair.gotoAndPlay("move");
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
}
}
PS: There also seems to be something wrong with this hittest I used.
function distance() {
var difx = blok.x - crossHair.x;
var dify = blok.y - crossHair.y;
return Math.sqrt( (difx * difx) + (dify * dify) );
}
It looks like you're starting the animation... setting it to the first frame and starting it... every time hitTestControle is true. Since hitTestControle will be true as long as you're hovering over the target, the animation will never reach the second frame.
What you need to do is start the animation when you transition from hitTestControle = false to hitTestControle = true, but once that happens you just let it play automatically.
Try changing your hitTestControl() function to something like this:
function hitTestControl() {
if(hitTestControle == true && alreadyOverHit == false) {
crossHair.gotoAndPlay("move");
alreadyOverHit = true;
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
alreadyOverHit = false;
}
}
In other words, only start the animation once, during the first frame you're detecting a hit, and then don't touch it unless you move off the target and back on.

Categories

Resources