Does anyone know how to use html-gl library ?
I tried to implement rendering HTML/CSS via WebGL. I've tried to do some WebGL postprocessing, but it started to get really slow once I created a lot of Text Geometry. I did all that with react-three-fiber framework. So I tried another alternative to achieve what I want, I tried CSS Custom Filter, but unfortunately it doesn't work yet in modern browser. And then I found html-gl library. It was really hard for me to implement that because it has a very minimal docs.
Problems:
1. I've tried to use html-gl in my project, but nothing seems to be working
2. There is also one more issue, if I click the box, the css coloring doesn't work, but if I don't wrap it with <html-gl> tag, it works as it should
here is the codesandbox:
https://codesandbox.io/s/html-gl-project-lhk2fp
Dependencies:
npm i html-gl
npm i pixi.js
Here is my code:
main.js
import './style.css';
import * as PIXI from 'pixi.js';
const redbox = document.querySelector('.box');
redbox.addEventListener('click', () => {
redbox.classList.toggle('blue');
});
// get html gl element
const htmlgl = document.getElementsByTagName('html-gl')[0];
// set up pixi stage
const stage = new PIXI.Container();
// set up renderer
const renderer = window.HTMLGL.renderer;
const displaceContainer = htmlgl.sprite; // --> this line is undefined
// displacement filter
const displacementTexture = PIXI.Texture.from('images/blur.JPG');
const displacementFilter = new PIXI.DisplacementFilter(displacementTexture);
displacementFilter.scale.x = 50;
displacementFilter.scale.y = 50;
displaceContainer.filters = displacementFilter; // --> error here
// render loop
function animate() {
renderer.render(stage);
requestAnimationFrame(animate);
}
renderer.render(stage);
requestAnimationFrame(animate);
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<!-- this is the html-gl DOM -->
<html-gl>
<div id="app">
<div class="layout-flex">
<div class="box red">click me !</div>
</div>
</div>
</html-gl>
<!-- this is the html-gl DOM -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/html-gl/0.3.1/htmlgl.min.js"
integrity="sha512-MffjPWwAY9ra9a7OXYEo1j9JiYD8IHJ6Pr1hjxSKk7gNzpYk6YRFB0QOQNg7EvxBosNclFOjl7Fe+1cMGI3rEA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script type="module" src="/main.js"></script>
</body>
</html>
Any idea what goes wrong here?
Related
Webpage is empty, main.js file is not being linked despite them being in the same folder. Npt is used & Vite is used for 3d effects, cameras, etc.
index.html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> Abd </title>
</head>
<body>
hello
<canvas id="bg"></canvas>
<script type="module" src="/main.js"></script>
</body>
</html>
style.css code:
canvas {
position: fixed;
top: 0;
left: 0;
}
main.js code:
import './style.css'
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth /
window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#bg'),
});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
camera.position.setZ(30);
renderer.render( scene,camera );
const geometry = new THREE.TorusGeometry( 10,3,16,100)
const material = new THREE.MeshBasicMaterial( {color:
0xFF6347,wireframe:true});
const torus=new THREE.Mesh( geometry,material);
scene.add(torus)
function animate() {
requestAnimationFrame( animate );
renderer.render(scene,camera);
}
animate()
Empty webpage- javascript not being linked
Are these files in the root folder of your site? Using a / in your URL tells HTML that your file is found there. If that's your issue, you should be able to fix this just by changing /main.js to main.js.
Try to put:
<script src=".js-path"> </script>
to your <head> section
if the script file is in another directory you can access this by putting "./" before the script path
there are a couple of things you need to look at.
First of all, JavaScript modules allow a program to be divided into multiple sequences of statements and declarations. <script type=module> is used to load JavaScript modules inside web pages.
To link a Javascript file to your HTML file, you have to use the <script> tag with a scr attribute. Since the javascript file is in the same folder as the HTML file, you can write the tag like this: <script src="main.js"> .
Good luck my friend.
At the begining I want to say that I'm aware that the question is similar to:
How to let imported css font / icons have effects on elements in the shadow dom?
It's not the case and it does not help.
Issue:
I've recently decided to use the ShadowDOM to encapsulate the styles in my project. At the very begining it I thought it worked as expected but I've noticed that some of the icons coming from the external CSS files were gone.
It's important to notice that those styles are external and possibilities of making changes are limited.
I've prepared the code to demonstrate the issue (look at the snippet below).
Everything seems to be working fine except the #font-face
As You can see, HTML containing the external CSS file with icons works as expected outside the ShadowDOM. I'd like to use it inside the shadowDOM as well.
How can I achieve that ?
NOTE: If you check the dev tools, there is a problem with the CSS path in network tab but it's the SO snippet issue. If You run the snippet locally, everything is ok in network.
const body = document.getElementsByTagName('body')[0];
const wrapper = document.querySelector('.wrapper')
const handleAddToShadowClick = (param) => {
const host = document.querySelector('#shadowHost');
if(param === 'insideShadow') {
const shadowRoot = host.attachShadow({mode: 'open'});
shadowRoot.innerHTML = firstComponent
} else {
const shadowRoot = host;
wrapper !== null ? body.removeChild(wrapper): ''
shadowRoot.innerHTML = firstComponent
}
}
const firstComponent = `
<div class="wrapper">
<div class="icon login">Bla bla</div>
<div style="font-family: testFont;">Sample String od text</div>
<link rel="stylesheet" href="./style.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css" integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V" crossorigin="anonymous">
</div>
`
.wrapper {
font-family: agGridBalham;
background-color: aquamarine;
color: black;
}
.balham:before {
content: "\F11F";
}
.login::before {
font-family: "Font Awesome 5 Free";
font-weight: 900;
content: "\f007";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
Refresh the page after each button click
</p>
<button onclick="handleAddToShadowClick('outside')">Add outside shadow</button>
<button onclick="handleAddToShadowClick('insideShadow')">Add inside shadow</button>
<div>
<div id="shadowHost"> </div>
</div>
<script src="./script.js"></script>
</body>
</html>
The behavior mentioned in the question is a bug which has been there in chromium(It was also there in Gecko too not sure if it has been fixed or not).
Here is the link for the bug reported at chromium related
to this issue, which still not resolved by them. At, present i feel
this is the only workaround which will work.
The issue is mainly related to scoping of #font-face. Currently you cannot use the fonts awesome fonts when they are only included inside the shadow DOM. So inorder to use the fonts the fonts css must be present inside both light DOM and shadow DOM. So you need to import the font css both inside the shadow dom and the light dom.
Here is a Working Plunker which solves your problem.
<html>
<head>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css" integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V" crossorigin="anonymous">
</head>
<body>
Refresh the page after each button click
</p>
<button onclick="handleAddToShadowClick('outside')">Add outside shadow</button>
<button onclick="handleAddToShadowClick('insideShadow')">Add inside shadow</button>
<div>
<div id="shadowHost"> </div>
</div>
<script src="lib/script.js"></script>
</body>
</html>
As you can see the plunker above, we have included the font-awesome css both in light DOM and Shadow Dom. And it is working fine as intended.
I want to display chess from chessboardjs.com. But I can't whereas I follow documentation. And whereas the ID is same.
<html>
<head>
<!--
UTF-8 (U from Universal Character Set + Transformation Format—8-bit[1]) is a character encoding capable of encoding all possible characters
-->
<meta charset="UTF-8">
<link rel="stylesheet" href="css/chessboard-0.2.0.css"/>
<script type="text/javascript" src="js/chessboard-0.2.0.js" > </script>
<script type="text/javascript">
var board1 = new ChessBoard('board1', 'start');
</script>
</head>
<body>
<div id="board1" style="width: 400px"></div>
</body>
The id is same. It is 'board1'. I follow the rules from the documentation...
link
But, I get error. The error is chessboard error 1002: element with id "board1" does not exist in the DOM.
Then, I read documentation about error 1002. It says..
ChessBoard could not find your element with document.getElementById. Please note that if you pass a string as the first argument to the ChessBoard() constructor it should be the value of a DOM id, not a CSS selector (ie: "board", not "#board").
link
You don't need the entire jQuery library to get this to work, though you may find it helpful for other things. If you don't foresee using jQuery for anything else all you need is setTimeout
setTimeout(function() {
var board1 = new ChessBoard('board1', 'start');
}, 0);
I accidentally discovered this trick 6 years ago and posted a question that got this informative answer. He did point out that it may not work in IE though perhaps that has changed in the meantime.
You need jquery to make this work.
<html>
<head>
<!--
UTF-8 (U from Universal Character Set + Transformation Format—8-bit[1]) is a character encoding capable of encoding all possible characters
-->
<meta charset="UTF-8">
<link rel="stylesheet" href="css/chessboard-0.3.0.css"/>
<script type="text/javascript" src="js/chessboard-0.3.0.js" > </script>
<script src="https://code.jquery.com/jquery-1.10.1.js"></script>
</head>
<body >
<div id="board1" style="width: 400px"></div>
</body>
<script type="text/javascript">
var init = function() {
//--- start example JS ---
var board = new ChessBoard('board1');
//--- end example JS ---
}; // end init()
$(document).ready(init);
</script>
</html>
I am trying to modify sample-google-maps to work inside a polymer element. On running following code I don't see anything except the title and there are no errors.Please advise how can I make this work.
In longer run I want to define additional components using google-chart api and Polymer dart. Can someone point me to a worked out example.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DEMO</title>
<script type="text/javascript" src="packages/web_components/platform.js"></script>
<link rel="import" href="lib_elements/googlemapcanvas/googlemapcanvas.html">
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?sensor=false">
</script>
</head>
<body>
<h1> Trial for Charted Library</h1>
<google-map-canvas></google-map-canvas>
<!-- bootstrap polymer -->
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
<script src="packages/browser/interop.js"></script>
</body>
</html>
googlemapcanvas.html
<!-- import polymer-element's definition -->
<link rel="import" href="packages/polymer/polymer.html">
<polymer-element name="google-map-canvas" attributes="title">
<template>
<style>
#google-map-canvas {
height:100%
}
</style>
<h1>{{title}}</h1>
<div id="google-map-canvas"></div>
</template>
<script type="application/dart" src="googlemapcanvas.dart"></script>
</polymer-element>
googlemapcanvas.dart
import 'package:polymer/polymer.dart';
import 'dart:js' as js;
import 'dart:html';
/**
* A Polymer click counter element.
*/
#CustomTag('google-map-canvas')
class GoogleMapCanvas extends PolymerElement{
#published String title = "Google Map Canvas";
DivElement googlemapcanvas;
GoogleMapCanvas.created(): super.created(){
}
#override
void attached(){
googlemapcanvas = $['google-map-canvas'];
draw();
}
draw(){
final google_maps = js.context['google']['maps'];
var center = new js.JsObject(google_maps['LatLng'], [-34.397, 150.644]);
var mapTypeId = google_maps['MapTypeId']['ROADMAP'];
var mapOptions = new js.JsObject.jsify({
"center": center,
"zoom": 8,
"mapTypeId": mapTypeId
});
new js.JsObject(google_maps['Map'],[googlemapcanvas, mapOptions]);
}
}
This is a CSS problem, maybe specific to Polymer, but a CSS problem all the same. There are several things you can do. The simplest one is to add fullbleed as an attribute to <body>.
<body unresolved fullbleed>
</body>
And your map will show up, taking up the rest of the space available. Or you can specify the height of your google-map-canvas element to have a height in pixels like so
<polymer-element ...>
<template>
<style>
:host {
height: 500px;
}
...
</style>
...
</template>
</polymer-element>
And the map will fill the space left after the title you put just before it. But it will not go beyond the 500px that you gave the element. There are other tricks you could do. I'd look at this site for more ways to layout polymer elements
https://www.polymer-project.org/docs/polymer/layout-attrs.html
And a guide to style polymer elements
https://www.polymer-project.org/docs/polymer/styling.html
Hope that answers your questions.
By the way, you do know the is a port of Google maps API to Dart?
https://pub.dartlang.org/packages/google_maps
I'm trying to implement the features from this site. But my code isn't alerting anything when I click on the x-foo element. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>
Test
</title>
</head>
<body>
<script type="text/javascript">
var xFoo = document.createElement('x-foo');
var xFoo = new XFoo();
document.body.appendChild(xFoo);
xFoo.onclick=function(){alert("It works!")};
</script>
<x-foo>
Test
</x-foo>
</body>
</html>
Any suggestions? (I'm on Chrome)
It looks like you're trying to create a Custom Element but you haven't registered it yet. To create your own XFoo element would look something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Custom Element</title>
</head>
<body>
<!-- Create a template for the content inside your element -->
<template>
<h1>Hello from XFoo</h1>
</template>
<!-- Register your new element -->
<script>
var tmpl = document.querySelector('template');
var XFooProto = Object.create(HTMLElement.prototype);
XFooProto.createdCallback = function() {
var root = this.createShadowRoot();
root.appendChild(document.importNode(tmpl.content, true));
};
var XFoo = document.registerElement('x-foo', {
prototype: XFooProto
});
</script>
<!-- Use the element you've just registered as a tag -->
<x-foo></x-foo>
<!-- OR, create an instance using JavaScript -->
<script>
var el = document.createElement('x-foo');
document.body.appendChild(el);
</script>
</body>
</html>
Unfortunately this approach depends on native APIs which currently only ship in Chrome 34. As someone else mentioned, a much easier approach to creating your own custom element would be to use Polymer. Polymer is a library that adds support for Web Components (essentially what you're trying to build) to all modern browsers. That includes IE 10+, Safari 6+, Mobile Safari, current Chrome and current Firefox.
I've put together a jsbin which shows how to create your own x-foo element using Polymer.
You should try viewing the following article:
http://www.polymer-project.org/
It's an open source Github project. I actually tried that article, but don't recommend it. Instead, use the link given above. It uses Ajax and JSON.