Created
January 15, 2026 18:25
-
-
Save albfan/e3803767c0c2b6682be520d390d7bccb to your computer and use it in GitHub Desktop.
Gtk Webkit with interaction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| import gi | |
| gi.require_version("Gtk", "3.0") | |
| gi.require_version("WebKit2", "4.1") | |
| from gi.repository import Gtk, WebKit2 | |
| from os.path import abspath, dirname, join | |
| WHERE_AM_I = abspath(dirname(__file__)) | |
| class WebBrowser(object): | |
| def __init__(self): | |
| self.builder = Gtk.Builder() | |
| self.builder.add_from_file(join(WHERE_AM_I, 'layout.ui')) | |
| go = self.builder.get_object | |
| self.window = go('window') | |
| self.scrolled = go('scrolled') | |
| user_content_manager = WebKit2.UserContentManager() | |
| user_content_manager.register_script_message_handler("external") | |
| user_content_manager.connect("script-message-received::external", self.on_message_received) | |
| self.webview = WebKit2.WebView.new_with_user_content_manager(user_content_manager) | |
| self.scrolled.add_with_viewport(self.webview) | |
| self.builder.connect_signals(self) | |
| self.window.connect('delete-event', Gtk.main_quit) | |
| file_uri = f"file://{abspath(dirname(__file__))}/carousel.html" | |
| self.load_uri(file_uri) | |
| self.window.show_all() | |
| def load_uri(self, uri): | |
| self.webview.load_uri(uri) | |
| return | |
| def on_message_received(self, user_content_manager, message): | |
| js_value = message.get_js_value() | |
| clicked_id = js_value.object_get_property("id").to_string() | |
| clicked_text = js_value.object_get_property("text").to_string() | |
| print(f"Clicked div with ID: {clicked_id}, Text: {clicked_text}") | |
| if __name__ == '__main__': | |
| gui = WebBrowser() | |
| Gtk.main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>3D Carousel/Slider (CSS 3D & Vanilla JS)</title> | |
| <link rel='stylesheet' href='https://static.fontawesome.com/css/fontawesome-app.css'> | |
| <link rel='stylesheet' href='https://pro.fontawesome.com/releases/v5.9.0/css/all.css'> | |
| <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400&display=swap'><link rel="stylesheet" href="./style.css"> | |
| </head> | |
| <body> | |
| <p>3D Carousel/Slider!</p> | |
| <div class="carousel"> | |
| <div class="carousel__body"> | |
| <div class="carousel__prev"><i class="far fa-angle-left"></i></div> | |
| <div class="carousel__next"><i class="far fa-angle-right"></i></div> | |
| <div class="carousel__slider"> | |
| <div class="carousel__slider__item" data-id="1"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>1</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="2"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>2</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="3"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>3</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="4"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>4</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="5"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>5</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="6"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>6</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="7"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>7</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="8"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>8</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="9"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>9</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| <div class="carousel__slider__item" data-id="10"> | |
| <div class="item__3d-frame"> | |
| <div class="item__3d-frame__box item__3d-frame__box--front"> | |
| <h1>10</h1> | |
| </div> | |
| <div class="item__3d-frame__box item__3d-frame__box--left"></div> | |
| <div class="item__3d-frame__box item__3d-frame__box--right"> </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="script.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?xml version="1.0" encoding="UTF-8"?> | |
| <interface> | |
| <!-- interface-requires gtk+ 3.0 --> | |
| <object class="GtkWindow" id="window"> | |
| <property name="can_focus">False</property> | |
| <property name="border_width">5</property> | |
| <property name="title" translatable="yes">WebBrowser</property> | |
| <property name="window_position">center-always</property> | |
| <property name="default_width">800</property> | |
| <property name="default_height">600</property> | |
| <child> | |
| <object class="GtkBox" id="box"> | |
| <property name="visible">True</property> | |
| <property name="can_focus">False</property> | |
| <property name="orientation">vertical</property> | |
| <child> | |
| <object class="GtkScrolledWindow" id="scrolled"> | |
| <property name="visible">True</property> | |
| <property name="can_focus">False</property> | |
| <property name="shadow_type">in</property> | |
| <child> | |
| <placeholder/> | |
| </child> | |
| </object> | |
| <packing> | |
| <property name="expand">True</property> | |
| <property name="fill">True</property> | |
| <property name="position">1</property> | |
| </packing> | |
| </child> | |
| </object> | |
| </child> | |
| </object> | |
| </interface> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function() { | |
| "use strict"; | |
| var carousel = document.getElementsByClassName('carousel')[0], | |
| slider = carousel.getElementsByClassName('carousel__slider')[0], | |
| items = carousel.getElementsByClassName('carousel__slider__item'), | |
| prevBtn = carousel.getElementsByClassName('carousel__prev')[0], | |
| nextBtn = carousel.getElementsByClassName('carousel__next')[0]; | |
| var width, height, totalWidth, margin = 20, | |
| currIndex = 0, | |
| interval, intervalTime = 4000; | |
| function init() { | |
| resize(); | |
| move(Math.floor(items.length / 2)); | |
| bindEvents(); | |
| timer(); | |
| } | |
| function resize() { | |
| width = Math.max(window.innerWidth * .25, 275), | |
| height = window.innerHeight * .5, | |
| totalWidth = width * items.length; | |
| slider.style.width = totalWidth + "px"; | |
| for(var i = 0; i < items.length; i++) { | |
| let item = items[i]; | |
| item.style.width = (width - (margin * 2)) + "px"; | |
| item.style.height = height + "px"; | |
| } | |
| } | |
| function move(index) { | |
| if(index < 1) index = items.length; | |
| if(index > items.length) index = 1; | |
| currIndex = index; | |
| for(var i = 0; i < items.length; i++) { | |
| let item = items[i], | |
| box = item.getElementsByClassName('item__3d-frame')[0]; | |
| if(i == (index - 1)) { | |
| item.classList.add('carousel__slider__item--active'); | |
| box.style.transform = "perspective(1200px)"; | |
| } else { | |
| item.classList.remove('carousel__slider__item--active'); | |
| box.style.transform = "perspective(1200px) rotateY(" + (i < (index - 1) ? 40 : -40) + "deg)"; | |
| } | |
| } | |
| slider.style.transform = "translate3d(" + ((index * -width) + (width / 2) + window.innerWidth / 2) + "px, 0, 0)"; | |
| } | |
| function timer() { | |
| /* | |
| clearInterval(interval); | |
| interval = setInterval(() => { | |
| move(++currIndex); | |
| }, intervalTime); | |
| */ | |
| } | |
| function prev() { | |
| move(--currIndex); | |
| timer(); | |
| } | |
| function next() { | |
| move(++currIndex); | |
| timer(); | |
| } | |
| function bindEvents() { | |
| window.onresize = resize; | |
| prevBtn.addEventListener('click', () => { prev(); }); | |
| nextBtn.addEventListener('click', () => { next(); }); | |
| } | |
| init(); | |
| document.querySelectorAll('.carousel__slider__item').forEach((element) => { | |
| element.addEventListener('click', (event) => { | |
| window.webkit.messageHandlers.external.postMessage({ | |
| id: element.getAttribute('data-id'), | |
| text: element.innerText, | |
| }); | |
| }); | |
| }); | |
| })(); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Grabacion.de.pantalla.desde.2026-01-15.19-29-32.mp4