Particle system does not get updated in aframe - aframe

I'm trying to create a simulation for an X-Ray Tube, where you can change the current or voltage and see the effects on the electrones and photons.
I've setup the electrones as a particle system with the aframe-particle-system-component. (https://www.npmjs.com/package/aframe-particle-system-component/v/1.1.3) Now I'm trying to change the particle system with a slider.
The problem is that the input of the slider gets registered, but it has no effect on the particle system in the scene.
The weird thing for me is, that the particle system will get changed, when I call the setAttribute() function outside of the EventListener. But than it changes only once at the beginning obviously, which does not help me.
The DOM of the entity does get updated and shows the new value of the size, when i inspect it in the console. Even the aframe inspector shows the updated size. But the actual particle system in the scene still shows the size, that i set in the html file.
Here is the js code that I'm using for this:
var elektron = document.querySelector('#ParticleSystem');
var scene = document.querySelector('a-scene');
//Var for the two sliders
var rangeCurrent = document.querySelector('#rangeCurrent');
var rangeVoltage = document.querySelector('#rangeVoltage');
var current = rangeCurrent.value;
var voltage = rangeVoltage.value;
//EventListener for the slider
rangeCurrent.addEventListener('change', function(){
current = rangeCurrent.value;
elektron.setAttribute('particle-system', {size: current});
});
There are no error messages.
I've been stuck with this problem the whole day and would be really thankful if someone could help me out!

I finally got it to work!!
In the update() function of the particle-system-component script they don't initiate the new ParticleSystem with the new data you define with setAttribute. I tried to fix it by myself for a while but couldn't get it to work. So then I used the earlier version 1.12 of the particle-system-component and now it works.

Related

Hi, I need an algorithm to tell a sprite to change the image when the in-game text finishes appearing (in GameMaker studio 1.4)

I need an algorithm to tell a sprite to end as soon as the text finishes appearing, basically I need to make a cutscene which describes the beginning of a story within the game, but since I'm using gamemaker, I don't know how to do it, can someone help me?
For cutscenes and automated image sequences you usually have some sort of variables, that handle the states and counters for displaying sprite's sub-images.
But firstly I like to use mainly two main time-related variables in my controller object usually named sys (counter and counterTime):
c = 0; // and for stepEvent: c += 1; // so it goes +1 per step
ct = 0; // and for stepEvent: ct+= 1 / room_speed; // so it goes +1 per second
During the cutscene you might want to stop everything else that moves:
is_cutscene = false; // objects might not be able to move when this is true
// you still have to implement that by yourself
// player can't move if is_cutscene, nothing happens!!
(except cutscene buttons etc...)
So now when the player gets to a 'cutscene'y object and triggers some cutscene_1 = true eg. you can have the image/text/sound/animation object come to life/create/active... That object might have in the create event:
duration = 6; // 6 seconds the scene lasts
start_time = sys.ct // and in Step: if sys.ct > (start_time + duration)
// then -> cutscene advance/destroy
Ofcourse - this is super simple and now you could only say implement:
walk close to a pop-up object
show an image for 6 seconds
it dissappears
And it might not be big trouble to implement it... BUT THIS may also be the foundation for more advanced multi-step sequence and cuts.

Awesomewm update watch widget on keypress

I am a new user to awesomewm (but have used other WMs before: i3, bspwm, xmonad, etc). I like to have some shell scripts that I have written in my wibar (I think that's what its called, the bar at the top of the screen with the taglist) to display stuff like battery, audio, etc (as I know is common). Currently I am using the "wibar.widget.watch" to do this, as shown below.
-- Right widgets
layout = wibox.layout.fixed.horizontal,
awful.widget.watch('musicbar', 5),
wibox.widget.textbox(' | '),
awful.widget.watch('wifibar', 5),
wibox.widget.textbox(' | '),
awful.widget.watch('audiobar', 0.5),
wibox.widget.textbox(' | '),
awful.widget.watch('batbar', 5),
In the code above stuff like "audiobar" are scripts that return information as standard output. It all works perfectly, even displays the emojis well :). I have one problem (maybe just an optimization).
Currently I have the audiobar running twice a second, this is because that is the only one which directly changes based on my input (changing volume) and so I want it to change immediately (obviously this still has a <= 0.5 second delay, which is annoying). This means that most of the time it is updating twice a second unnecesarily.
So, I'm wondering if there is a way to have it update when I change the volume, which I've bound to the XF86 audio keys in rc.lua, instead of changing based on a timer. Based on my reading of the documentation, there is no way to do this with the watch widget, but as I said I am new to awesome.
Below is how I bound the keys (shouldn't make a difference, but I imagine that this is where the change would be made).
awful.key(
{},
"XF86AudioLowerVolume",
function()
awful.spawn("amixer -q set Master 5%-")
end,
{description = "lower volume", group = "control"}
),
I know that I can use some of the pre-made widgets on github to display volume and stuff but I like the shell scripts because they let me easily move between WMs and are simpler than those widgets (which I like because it means that I can more easily address problems with them and make them display exactly what I want, as well as learn).
edit: I am willing to learn to do this with lua, I just first want to see if I can easily do it with shell scripts.
You need to keep a reference to the timer around that awful.widget.watch creates internally. To do this, you need to do something like this in global context (i.e. outside of the definitions of the widgets or keybindings):
local musicbar_widget, musicbar_timer = awful.widget.watch('musicbar', 5)
You now add musicbar_widget to your wibox (instead of calling awful.widget.watch there). Now, you can "force-update" the widget via musicbar_timer:emit_signal("timeout"). This "pretends" to the widget that the timeout happened again.
In your keybinding (yes, I am mixing up your widgets here, most likely musicbar has nothing to do with the volume):
awful.key(
{},
"XF86AudioLowerVolume",
function()
awful.spawn("amixer -q set Master 5%-")
musicbar_timer:emit_signal("timeout")
end,
{description = "lower volume", group = "control"}
),
Note that this might or might not work. awful.spawn only starts the command, but does not wait for it to finish. So now you are changing the volume at the same time that your are querying it. If querying finishes faster than changing the volume, then the update does not actually occur.
To only update the widget after changing the volume is done, do something like the following:
awful.spawn.with_line_callback(
"amixer -q set Master 5%-", {
exit = function()
musicbar_timer:emit_signal("timeout")
end
})
I ran into a similar problem with streetturtle's volumearc widget. By default, it runs an update command:
Everytime the volume is modified through the widget.
Every second to catch any external volume changes (like with key bindings defined in rc.lua).
watch(get_volume_cmd, 1, update_graphic, volumearc)
Of course this has the following disadvantages:
A slight delay in the volume update (one second in still very perceptible).
On my machine, a constant 1% CPU load just for this task. A trifle I know, but little things add up.
Using a returned update function
A possible solution is to return an update function, available in the context of rc.lua and call this update along the volume modifications.
In volumearc.lua, in the worker function, we put the widget update into a dedicated function:
local ext_update = function()
spawn.easy_async(get_volume_cmd,
function(stdout, stderr, exitreason, exitcode)
update_graphic(volumearc, stdout, stderr, exitreason, exitcode) end)
end
And we return it both from the worker function:
return volumearc, ext_update
and from the widget itself:
volumearc, ext_update = { __call = function(_, ...) return worker(...) end }
return setmetatable(widget, volumearc), ext_update
Now we can use it in rc.lua:
local volumearc_widget = require("widgets.volume-widget.volumearc")
-- ...
local GET_VOLUME = "amixer sget Master"
local INC_VOLUME = "amixer sset Master 3%+"
local DEC_VOLUME = "amixer sset Master 3%-"
local TOG_VOLUME = "amixer sset Master toggle"
myvolume, volume_update = volumearc_widget({get_volume_cmd=GET_VOLUME,
inc_volume_cmd=INC_VOLUME,
dec_volume_cmd=DEC_VOLUME,
tog_volume_cmd=TOG_VOLUME})
-- `myvolume` is the widget that can be added as usual in the wibox.
-- `volume_update` is the function to call in order to trigger an update.
-- ...
-- In the key bindings:
awful.key({}, "XF86AudioMute",
function () awful.spawn(TOG_VOLUME) volume_update() end,
{description="mute", group = "media"}),
awful.key({}, "XF86AudioRaiseVolume",
function () awful.spawn(INC_VOLUME) volume_update() end,
{description="raise volume", group = "media"}),
awful.key({}, "XF86AudioLowerVolume",
function () awful.spawn(DEC_VOLUME) volume_update() end,
{description="lower volume", group="media"}),
Now the volume will be updated both when changed from the widget or from the media keys, instantly and without the need for polling.
Caveat
This does not catch changes made through other interfaces, such as alsamixer for example. To catch these changes, you might want to run the watch function with a very low time frequency (say once per minute).
The code given here is specific to streetturtle's widget, but the concept of returning an internal update function applies for any widget.

JXBrowser - What is globalX, globalY, windowX, windowY in relation to x, y for forwarding mouse events?

I can find no explanation on what these are actually supposed to do.
There are examples on:
https://jxbrowser.support.teamdev.com/support/solutions/articles/9000102480-forwarding-mouse-events
but 629 and 373 ? I can't figure out what those values are for. I can get the same behaviour with any value for those.
What if you one also sets windowX and windowY ?
What would they do to the result click?
I am looking to be able to click and move on a google map. Is that possible?
The x and y values define the mouse event coordinate inside the browser content area.
The globalX and globalY values define the screen coordinate of the mouse event.
The windowX and windowY are deprecated. If you set them, this doesn't affect anything.
For more detailed information about working with Google Maps, please take a look at the article.
Your browserView must be active/focused first!
Then, let's do this way:
public static void simulateMouseClickOnElement(Browser browser, BrowserView browserView, DOMElement element){
Rectangle rect = element.getBoundingClientRect();
Point ptOnScreen = new Point(rect.x , rect.y );
SwingUtilities.convertPointToScreen(ptOnScreen, browserView);
forwardMouseClickEvent(browser,MouseButtonType.PRIMARY,rect.x,rect.y, ptOnScreen.x, ptOnScreen.y);
}
JxBrowser is the BEST automation or crawling/hacking tool! Selenium is a best alternative choice due to the TCO.

Selenium and wordpress: New post test

I've been looking a bit at Selenium, and I'm beginning to like it, since I know some Java programming and find both Java and C# pretty straight-forward for simple things like this.
However, I'm struggling with a test that creates a new post in Wordpress, from the Dashboard page:
This is the Selenium code (in C#):
(The Driver instance is, obviously, a driver class I've created - for starting the browser and connecting to the wordpress site.)
1: Driver.Instance.FindElement(By.Id("title)).SendKeys(title);
2: Thread.Sleep(1000);
3:
4: Instance.SwitchTo().Frame("content_ifr");
5: Thread.Sleep(1000);
6:
7: Driver.Instance.SwitchTo().ActiveElement().SendKeys("something");
Now, what happens is that the title is easily found (by ID, so I wouldn't expect problems there), and I can easily insert the title text (line 1).
But the inline frame for the post body is causing problems. When running the test, after the topic is filled in, the cursor changes to the body area (line 4) - as planned. However, nothing more happens. The SendKeys("string") method (ine 7) doesn't seem to work there.
Any ideas?
EDIT: Of course - an important piece of information is that the iframe in Wordpress simply loads a TinyMCE editor. So, in the page source, there's only a body tag with the javascript loading of the editor.
EDIT2: Of course, something suddenly changed. Without ANY change to the wordpress page, the "content_ifr" is now suddenly missing (?!!!!!?) The Selenium test fails with "unable to locate frame...", and it's also suddenly missing from the page source.
EDIT3: I also noticed something:
Driver.Instance.SwitchTo().Frame(iframe);
Driver.Instance.FindElement(By.Id("tinymce")).SendKeys("message body");
It's the SECOND line that makes the cursor switch to the mce field, not the line with the .SwitchTo(). However, I need the first line - the second line does nothing on its own. This is approaching something really stupid. I've been looking for a solution to this for a week - this doesn't exactly bode well for Selenium. The Selenium user group doesn't even want to answer when I ask them.
Also - if I skip the SendKeys() method in the second line, nothing happens. So, it seems that the two lines does ALLMOST what it should, right up to and including placing the cursor in the correct spot. But it never sends any text.
EDIT4 (last): After actually figuring out how to use IJavaScriptExecutor, it works using the solution(s) below.
Java method to handle TinyMCE editor would look like:
public void entersTopicOfBody(String textToBeTyped, WebDriver driver) {
driver.switchTo().frame("content_ifr");
WebElement body = driver.findElement(By.xpath("//body"));
body.click();
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].innerHTML = '"+ textToBeTyped+"'", body);
driver.switchTo().defaultContent();
}
Below is some C# code that publishes a post. I think the main issues you have are due to timing issues.
I've done a bit of Selenium recently and I favour implicit waits: it waits for a maximum time period for the item to be available, but returns as soon as possible. So you can specify a max wait of 100 seconds, but if it finds it in 1 second, it will only wait 1 second. Much more efficient vs sleeping for an arbitrary length of time. See this post about Implicit and Explicit waits
But even with implicit waits, it may not solve all issues. When coding the sample below, I ran into the issue where the "Publish" button was disabled and re-enabled after some time. And that's when you have to look at the code to see what it is doing as well. It's times such as these where sleeps can help you fix the problem for a quick fix if you do not wish to debug too much: just be sure to set a large enough sleep time and be wary that it could be inconsistent in the future.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Support.Events;
namespace SeleniumTest
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver = new OpenQA.Selenium.Firefox.FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
// enter your configurations here
driver.Navigate().GoToUrl("http://localhost/wordpress/wp-admin/post-new.php");
driver.FindElement(By.Id("user_login")).SendKeys("admin");
driver.FindElement(By.Id("user_pass")).SendKeys("yourpassword");
driver.FindElement(By.Id("wp-submit")).Click();
driver.FindElement(By.Id("title")).SendKeys("the title");
var iframe = driver.FindElement(By.Id("content_ifr"));
driver.SwitchTo().Frame(iframe);
// your solution which works in my instance
//driver.SwitchTo().ActiveElement().SendKeys("hello tiny mce from selenium");
// send keys with exact element
//driver.FindElement(By.Id("tinymce")).SendKeys("hello tiny mce from selenium");
// javascript - 1
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
var tinymce = driver.FindElement(By.Id("tinymce"));
IJavaScriptExecutor executor = (IJavaScriptExecutor)driver;
executor.ExecuteScript("arguments[0].innerHTML = 'hello tiny mce via javascript'", tinymce);
// javascript - 0
driver.SwitchTo().DefaultContent();
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(11));
wait.Until((d) => { return !d.FindElement(By.Id("publish")).GetAttribute("class").Contains("disabled"); }); // wait for publish button to be enabled
driver.FindElement(By.Id("publish")).Click();
driver.FindElement(By.Id("message")); // wait for message on next page to verify it is posted
driver.Close();
}
}
}
A PHP version of olyv solution:
$content = 'my text';
$this->frame( 'content_ifr' );
$body = $this->byXPath( '//body' );
$body->click();
$script = 'arguments[0].innerHTML = "" + arguments[1] + ""; ';
$this->execute( [
'script' => $script,
'args' => [ $body->toWebDriverObject(), $content ],
]
);
$this->frame( null );
I know that I am a bit late to the party, but I just found a solution that is (I believe) much simpler than the answers given so far. So I decided to post it here in case it could help someone else.
There is no need to switch frames here. What you wanna do is 'click' on the button in the top right corner of the text editor that says "Text", which has id = "content-html". Now, you can 'send keys" to the textarea, which has id = "content".
Here is some Python code that does just this:
driver.find_element_by_id("content-html").click()
driver.find_element_by_id("content").send_keys("Some text...")
Hope it helps

Yahoo Maps API - Same code ok in Firefox, not IE7

I've implemented a simple yahoo mapping example using JQUERY.
My problem is i'm developing using my localhost, my intended target platform is to be within an Intranet environment. My thinking is that my localhost will to some extent mimic this.
I have an update, made some progress. See the code snippet below, all ok in Firefox but in IE (my target browser) it fails on the line:
var currentGeoPoint = new YGeoPoint($('#txtLatitude').val(), $('#txtLongitude').val());
What I cannot understand is why will IE allow the MAP API Code to run and manipulate the MAP object and fail on this one line.
Could this all be to do with Tools/Intranet Options/Security and trusted sites etc? My URL locally is "http://localhost:4724/LMS/Site.mvc/Details/77" if thats any help.
$(document).ready(function() {
jQuery("textarea[class*=expand]").TextAreaExpander(); // initialize all expanding textareas, new code, john s 10/08/2010
var geoPoint;
// Create a map object
var map = new YMap(document.getElementById('map'));
// Add map type control
map.addTypeControl();
// Set map type to either of: YAHOO_MAP_SAT, YAHOO_MAP_HYB, YAHOO_MAP_REG
map.setMapType(YAHOO_MAP_REG);
// Display the map centered on a geocoded location
map.drawZoomAndCenter("United Kingdom", 12);
// Add map type control
map.addTypeControl();
// Add map zoom (long) control
map.addZoomLong();
// Add the Pan Control
map.addPanControl();
// Set map type to either of: YAHOO_MAP_SAT, YAHOO_MAP_HYB, YAHOO_MAP_REG
map.setMapType(YAHOO_MAP_REG);
// Display the map centered on a geocoded location
map.drawZoomAndCenter("United Kingdom", 12);
var currentGeoPoint = new YGeoPoint($('#txtLatitude').val(), $('#txtLongitude').val()); // FAILS IN IE ON THIS LINE!! Unspecified Error popup dialogue box
map.addMarker(currentGeoPoint);
});
John
Have this working now, reverted back to original javascript, i'd hand rolled my own code and although neater was not working in IE. Glad to be out of the woods, cheers, J

Resources