How can I stop a CSS animation using JavaScript? - css-animations

CSS file
I am trying to toggle the class pause, but to pause the animation, the class is adding and roving from the tag. But the animation doesn't stop. Is there anything I am missing?
.pause{ /* Pause class which I will toggle in JavaScript */
-webkit-animation-play-state: paused;
-moz-animation-play-state: paused;
-o-animation-play-state: paused;
animation-play-state: paused;
}
JavaScript file
window.onload = getready;
function getready(){
var button = document.getElementById("button");
button.onclick = toggleplay;
function toggleplay(){
/* alert("button clicked"); */
var element = document.querySelector("#sun");
var toggle2 = document.querySelector("#stage");
element.classList.toggle("pause");
toggle2.classList.toggle("pause");
}
}

Related

How to capture keyboard events in wxWebView?

I want to handle keyboard events for wxWebView but it seems that the rendering engine, in my case WebView2 (edge backend) eats all the events and does not allow them to propagate to the parents.
I have bound a handler for key down events but it does not work.
ctrl_->Bind( wxEVT_KEY_DOWN, &WxHtml::onKeyDown, this );
void onKeyDown( wxKeyEvent& evt )
{
fs::out << evt.GetKeyCode() << std::endl;
}
How should we get the events?
wx version: 3.2.1
OS: win 10
wxWebView backend: WebView2
As Igor said, some native windows, such as wxWebview, will consume all low level events such as key presses and mouse clicks so that they can't be handled with wxWidgets events.
In the case of wxWebview, you can use JavaScript to handle key presses on the window and then try to navigate to an anchor with the key code. If you then handle the navigating event for the wxWebview window, you can retrieve the key code from the url for that event. Here is an example:
#include <wx/wx.h>
#include <wx/webview.h>
#include <wx/uri.h>
#ifdef __WXMSW__
#include <wx/msw/webview_ie.h>
#endif
class MyFrame: public wxFrame
{
public:
MyFrame();
private:
void OnWebViewNavigating(wxWebViewEvent& event);
void OnKeyUp(wxKeyEvent&);
wxWebView* m_webView;
};
MyFrame::MyFrame()
:wxFrame(NULL, wxID_ANY, "Test Frame", wxDefaultPosition,
wxSize(600, 400))
{
#ifdef __WXMSW__
wxWebViewIE::MSWSetEmulationLevel(wxWEBVIEWIE_EMU_IE11);
#endif
m_webView = wxWebView::New(this, wxID_ANY);
wxString s =R"(<!DOCTYPE html>
<html lang="en">
<body>
<p>Hello</p>
<script>
document.onkeyup = function(e) {
let key_press = e.key;
let key_code = key_press.charCodeAt(0);
location.hash = "#" + key_code;
}
</script>
</body>
</html>
)";
m_webView->SetPage(s,"");
Bind(wxEVT_WEBVIEW_NAVIGATING,&MyFrame::OnWebViewNavigating, this);
m_webView->Bind(wxEVT_KEY_UP, &MyFrame::OnKeyUp, this);
}
void MyFrame::OnKeyUp(wxKeyEvent& event)
{
// Escape has keycode 69, so to check if it was pressed:
if ( event.GetKeyCode() == 69 )
{
// Change this to how you want to handle the escape key press.
SetTitle("Escape was pressed");
}
else
{
// Handle any other key presses here.
}
}
void MyFrame::OnWebViewNavigating(wxWebViewEvent& event)
{
wxKeyEvent keyEvent(wxEVT_KEY_UP);
keyEvent.SetEventObject(event.GetEventObject());
wxURI uri(event.GetURL());
uri.GetFragment().ToLong(&keyEvent.m_keyCode);
m_webView->ProcessWindowEvent(keyEvent);
// Veto the action since we don't actually want to navigate.
event.Veto();
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
It's a bit of a pain, but it's the best way we can connect the Java Script and wxWidgets worlds unless you want to run a webserver locally.

How to draw some text when click a button in wxWidgets?

I want to draw some text when click a button. My code is:
#include <wx/wx.h>
enum
{
BUTTON_Hello = wxID_HIGHEST + 1
};
class myFrame : public wxFrame {
public:
wxButton* HelloWorld;
wxPanel* panel;
void OnPaint(wxCommandEvent& event) {
wxClientDC bdc =wxClientDC(this);
bdc.DrawText(wxString("Draw some text when button clicked."), wxPoint(300, 300));
Refresh();
};
myFrame(wxWindow* parent,
wxWindowID id,
const wxString& title,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize) :
wxFrame(parent,id,title, pos, size) {
panel =new wxPanel(this, wxID_ANY, wxPoint(0,0),wxSize(100,100));
//Connect(wxEVT_PAINT, wxPaintEventHandler(myFrame::OnPaint));
HelloWorld = new wxButton(panel, BUTTON_Hello, _T("Hello World"),
wxPoint(5,5), wxSize(100, 100));
HelloWorld->Bind(wxEVT_BUTTON, &myFrame::OnPaint, this);
};
};
class MyApp : public wxApp
{
bool OnInit() {
frame = new myFrame((wxFrame*)NULL, -1, wxT("Hello wxDC"),
wxPoint(50, 50), wxSize(800, 600));
frame->Show();
return true;
};
wxFrame* frame;
public:
};
IMPLEMENT_APP(MyApp)
I define the drawing function in a wxFrame and bind it to a wxButton using Bind(). The drawing function uses a wxClientDC. I have added Refersh() to force updating wxFrame. The wxButton belongs to a wxPanel which is a child of wxFrame.
However, when I click the button, nothing happens and no text is shown.
You must use wxPaintDC when drawing in your wxEVT_PAINT handler, not wxClientDC. While wxClientDC also "works", at least for now and at least under some platforms, this is definitely not the right way to do it.
When using wxPaintDC, Refresh() would work as expected and will result in a call to your paint handler during the next event loop iteration. Normally you don't need to call Update(), which immediately calls your handler, at all.
I solved this problem by myself.
As wxPanel is the only child of wxFrame, it will automatically cover the whole area of wxFrame. Now drawing on wxFrame is necessarily having no effect. So I have to draw on wxPanel:
void paintNow(wxCommandEvent& event) {
wxClientDC bdc =wxClientDC(panel);
bdc.DrawText(wxString("Draw some texts when button clicked."),
wxPoint(300, 300));
//panel->Refresh();
panel->Update();
};
Also I find that if I use Refresh() and Update() simultaneously, no text will be shown.
If I only use Refresh(), no text will be shown.

Is it possible to programatically create a xaml page?

I might write no sense on the next lines:
I tried to derive a struct named mainpage from winrt::Windows::UI::Xaml::Controls::Page and pass it to winrt::xaml_typename<>(), in "<>" is mainpage.
It will be understandable when you look at the code:
Point number 1 "(1)" is the mainpage.h file, is very short.
Point number 2 "(2)" is the App.cpp file, it only has the necessary.
//(1) mainpage.h
#pragma once
#include "pch.h"
struct mainpage : winrt::Windows::UI::Xaml::Controls::Page
{
mainpage() {
winrt::Windows::UI::Xaml::Controls::Button thebutton = winrt::Windows::UI::Xaml::Controls::Button();
thebutton.Click([&](const IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& event_arg)
{
thebutton.Content(winrt::box_value(L"Clicked"));
});
}
};
//(2) App.cpp
#include "pch.h"
#include "mainpage.h"
struct App : winrt::Windows::UI::Xaml::ApplicationT<App>
{
void OnLaunched(const winrt::Windows::ApplicationModel::Activation::LaunchActivatedEventArgs& event_arg)
{
winrt::Windows::UI::Xaml::Controls::Frame root_frame{ nullptr };
winrt::Windows::UI::Xaml::UIElement content = winrt::Windows::UI::Xaml::Window::Current().Content();
if (content)
{
root_frame = content.try_as<winrt::Windows::UI::Xaml::Controls::Frame>();
}
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (root_frame == nullptr)
{
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
root_frame = winrt::Windows::UI::Xaml::Controls::Frame();
root_frame.NavigationFailed({ this, &App::OnNavigationFailed });
if (event_arg.PreviousExecutionState() == winrt::Windows::ApplicationModel::Activation::ApplicationExecutionState::Terminated)
{
// Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete
}
if (event_arg.PrelaunchActivated() == false)
{
if (root_frame.Content() == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
root_frame.Navigate(winrt::xaml_typename<mainpage>(), box_value(event_arg.Arguments()));
}
// Place the frame in the current Window
winrt::Windows::UI::Xaml::Window::Current().Content(root_frame);
// Ensure the current window is active
winrt::Windows::UI::Xaml::Window::Current().Activate();
}
}
else
{
if (event_arg.PrelaunchActivated() == false)
{
if (root_frame.Content() == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
root_frame.Navigate(winrt::xaml_typename<mainpage>(), box_value(event_arg.Arguments()));
}
// Ensure the current window is active
winrt::Windows::UI::Xaml::Window::Current().Activate();
}
}
}
void App::OnNavigationFailed(const IInspectable&, const winrt::Windows::UI::Xaml::Navigation::NavigationFailedEventArgs& event_arg)
{
throw winrt::hresult_error(E_FAIL, winrt::hstring(L"Failed to load Page ") + event_arg.SourcePageType().Name);
}
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) {
winrt::Windows::UI::Xaml::Application::Start([](auto &&) { winrt::make<App>(); });
}
If it is not possible, how can I properly create a page?
It is simple if you have installed the CppWinRT VSIX. Then create a "View model" and edit the files. You shouldn't derive the struct from the winrt::Windows::UI::Xaml::Controls::Page class because winrt::xaml_typename<> needs a WinRT class in <>.

How to use CharmFlyoutLibrary with master page?

I have a Windows 8 app, and recently I refactored it to use a 'master page'. This means that there is one 'layout' that has a few generic components such as the header and footer. In that layout, I have a Frame. Every time I want to show a different view, I load it in the frame.
This means that my startup screen is no longer of type Frame but of type Layout, which is a LayoutAwarePage. This is how I initialize it in App.xaml.cs OnLaunched:
Layout rootFrame = Window.Current.Content as Layout;
if (rootFrame == null)
{
rootFrame = new Layout();
Here comes the problem: I have a charms flyout that contains a few items like Settings. I made a nice view (Flayouts.xaml) that contains the layout of these flyouts. The code behind for that view looks like this:
public Flyouts()
{
InitializeComponent();
SettingsPane.GetForCurrentView().CommandsRequested += Flyouts_CommandsRequested;
}
void Flyouts_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{
// add some commands
}
And this is how you'd get this to work in your app:
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new CharmFlyoutLibrary.CharmFrame { CharmContent = new Flyouts() };
What they're doing here is assigning a Frame to 'rootFrame'. However, since I switched to a master page, I no longer have a Frame but a Layout/LayoutAwarePage type, so I can't assign the CharmFrame to it. How do I overcome this problem?
Anyone?
When navigating inside a frame the page that you navigate to is placed inside the navigate the Content property.
So if you navigate to you Layout first, then the content will be filled with your page and you can navigate to your child page's. I've placed a example below
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null) {
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
//Associate the frame with a SuspensionManager key
SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) {
// Restore the saved session state only when appropriate
try {
await SuspensionManager.RestoreAsync();
} catch (SuspensionManagerException) {
//Something went wrong restoring state.
//Assume there is no state and continue
}
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null) {
if (rootFrame.Navigate(typeof(Layout))) {
var secondFrame = rootFrame.Content as Layout;
if (!secondFrame.ContentFrame.Navigate(typeof(YourPage)) {
throw new Exception("Failed to create initial page");
}
}
}

WebView title is sometimes null when it shouldn't be

I'm writing a simple browser in Vala and WebKitGTK+.
One of the things I need to do is set the window's title to that of the webpage title, so I monitor title changes with web_view.notify["title"].connect. However, sometimes the value of title is null, when it obviously shouldn't be.
Some examples I remember:
Search anything in Google. Going to the next results page sets the title to null.
Click on an anchor link (e.g. http://example.com/page.html#section)
In any case, using the Web Inspector shows that the pages do have a title set.
Is this a bug I should report? Or maybe I'm doing something wrong? Here's the code I'm using:
//valac --thread --pkg webkitgtk-3.0 --pkg gtk+-3.0 --vapidir=./ test.vala
//The vapidir folder should have webkitgtk-3.0.vapi and webkitgtk-3.0.deps
using WebKit;
using Gtk;
public class Test : Gtk.Window {
public WebView webview;
public Test () {
this.title = "Test";
this.window_position = Gtk.WindowPosition.CENTER;
this.set_default_size (800, 600);
this.hide_titlebar_when_maximized = false;
this.destroy.connect (() => {
Gtk.main_quit ();
});
var scroll = new ScrolledWindow (null, null);
this.webview = new WebView ();
this.add (scroll);
scroll.add (webview);
webview.settings.enable_developer_extras = true;
webview.notify["title"].connect ((sender, property) => {
if (webview.title != null) {
this.title = webview.title;
stdout.printf (webview.title + "\n");
} else {
stdout.printf ("(null)\n");
}
});
webview.web_inspector.inspect_web_view.connect ((p0) => {
var w = new Window ();
w.window_position = WindowPosition.CENTER;
w.title = "Inspector";
w.set_default_size (800,600);
WebView view = new WebView ();
unowned WebView view2 = view;
w.add (view2);
w.show_all ();
return view2;
});
}
public static int main (string[] args) {
Gtk.init (ref args);
Test app = new Test ();
app.webview.load_uri ("http://google.com");
app.show_all ();
Gtk.main ();
return 0;
}
}
There is a signal called title_changed for that purpose and you should always use the signals provided by webkitgtk instead of the GLib notify feature.
(GLib notify is emitted each time a value changes, even if the change is just for the purpose of clearing the old value, such as in your case.)