I have a React/Electron app, where I'm trying to use the new CSS Houdini paint() function (as demonstrated in this page). In my project's index.html file I have added a script tag with the paintWorklet addModule() function as shown:
<script>
CSS.paintWorklet.addModule('../src/ResultDisplay/DefaultResultDisplay/testPaint.js');
</script>
Then in that testPaint.js file I have essentially a copy of what's shown in that blog post:
registerPaint(
"testPaint",
class {
paint(ctx, geom) {
console.log("painting!!!");
const circleSize = 10;
const bodyWidth = geom.width;
const bodyHeight = geom.height;
const maxX = Math.floor(bodyWidth / circleSize);
const maxY = Math.floor(bodyHeight / circleSize);
for (let y = 0; y < maxY; y++) {
for (let x = 0; x < maxX; x++) {
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.arc(
x * circleSize * 2 + circleSize,
y * circleSize * 2 + circleSize,
circleSize,
0,
2 * Math.PI,
true
);
ctx.closePath();
ctx.fill();
}
}
}
}
);
And finally my css file:
.container {
background-image: paint(testPaint);
display: flex;
margin: 4px;
border-radius: 12px;
height: 75px;
}
I should point out I am using CSS Modules, so this file is defaultResultStyles.module.scss; not sure if that affects anything. When I bring up the component that's meant to have these styles in my app, it has no styles, though inspecting it, it does display background-image: paint(testPaint). The console.log that I added to the testPaint.js` file is never shown.
I have tried multiple variations of the filepath for addModule; I've tried just testPaint.js, starting it with ./src and src both, but nothing seems to work; is this possible in an Electron/React app?
The addModule function will not work through webpack or other bundlers, it instead works through the native module system of browsers. You have to put the testPaint.js file in the public directory, otherwise it would get bundled with everything else.
Here's what I added to the index.html to get it to run from the public directory on a local Create React App project:
<script>
CSS.paintWorklet.addModule('%PUBLIC_URL%/testPaint.js');
</script>
I didn't actuallly set up any of the markup and just added the container class to test it out:
If you want to use this without going through the public folder (at all, because normally you'd have to add the paint module in the index.html which is changing the public directory), then I'd suggest using React Helmet to set up the script tags. As a note with this, the hot-reload features of CRA seems to prevent the scripts from updating, so every time you change the script tags, you'll need to refresh the page manually.
import React from 'react';
import { render } from 'react-dom';
import { Helmet } from 'react-helmet';
import styled from 'styled-components';
// Render these styled components like normal react components.
// They will pass on all props and work
// like normal react components – except they're styled!
const Demo = styled.div`
background: #1108a0;
padding: 50px 0;
`;
const Test = styled.div`
--color: cyan;
--multiplier: 0.24;
--pad: 30;
--slant: 20;
background: paint(background-canvas);
transition: --multiplier 0.4s;
font: bold 6em sans-serif;
color: yellow;
text-shadow: 0 3px 1px cyan;
line-height: 1.5em;
width: max-content;
padding-left: 30px;
padding-right: 50px;
isolation: isolate;
&:hover {
--multiplier: 1;
}
& span {
mix-blend-mode: exclusion;
}
`;
export const App = () => (
<Demo>
<Test className="el" right={'right'}>
<span>JS-in-CSS</span>
</Test>
</Demo>
);
export const Helm = () => (
<Helmet>
<script language="javascript+paint">{`
registerPaint('background-canvas', class {
static get inputProperties() {
return ['--multiplier', '--color', '--pad', '--slant'];
}
paint(ctx, geom, properties) {
let multiplier = +properties.get('--multiplier').toString();
let c = properties.get('--color').toString();
let pad = +properties.get('--pad').toString();
let slant = +properties.get('--slant').toString();
ctx.moveTo(0, 0);
ctx.lineTo(pad + (geom.width - slant - pad) * multiplier, 0);
ctx.lineTo(pad + (geom.width - slant - pad) * multiplier + slant, geom.height);
ctx.lineTo(0, geom.height);
ctx.fillStyle = c;
ctx.fill();
}
})
`}</script>
<script>{`
if ("paintWorklet" in CSS) {
const src = document.querySelector('script[language$="paint"]').innerHTML;
const blob = new Blob([src], {
type: 'text/javascript'
});
CSS.paintWorklet.addModule(URL.createObjectURL(blob));
}
`}</script>
</Helmet>
);
render(
<div>
<Helm />
<App />
</div>,
document.getElementById('root')
);
If you're looking to avoid using /public, you can use a monorepo manager like Yarn Workspaces to keep your worklet in a dedicated package. Then, you can import it into your client app like you would any other package dependency.
Step by step (using Yarn Workspaces):
create dedicated packages for your app (package.json name is #packages/myapp) and worklet (#packages/myworklet)
add your worklet as a dependency to your app -- from #packages/myapp run yarn add #packages/myworklet
import your worklet from #packages/myworklet and add it -- see https://houdini.how/usage/
Related
I'm using FullCalendar in angular and I would like to change the specific day grid background I have tried some options but it didn't work.
HTML
<full-calendar #calendar [options]="calendarOptions"></full-calendar>
TS
export class CalendarComponent implements OnInit{
calendarData: CalendarData[] = [];
calendarVisible = false;
calendarOptions: CalendarOptions = {
headerToolbar: {
right: 'title,prev,next',
center: '',
left: 'timeGridDay,timeGridWeek,dayGridMonth'
},
initialView: 'dayGridMonth',
eventColor: '#F4C584',
};
#ViewChild('calendar') calendarComponent!: FullCalendarComponent;
isData = false;
calendarPlugins = [listPlugin,dayGridPlugin,timeGridPlugin]
getCalendar(): void{
this.calendarService.getCalendar(2022).subscribe((res) => {
this.calendarOptions.events = [];
const data = Object.entries(res.data).map((val: any) => {
return val;
});
for(let i = 0; i < data.length; i++){
console.log(data[i][0]);
for(let j = 0; j < data[i][1].length; j++){
this.calendarOptions.events.push( //here I'm pushing into event options array my data
{
title : data[i][1][j].date.split(' ')[0],
date: data[i][0]
background: '#000000' //I tried to give a color like this but it didn't work
});
}
}
});
}
link to the full calendar
Had the same problem and I discovered that FullCalendar styles for Angular just work after the page is rendered, meaning, if you apply the style into your styles.scss it will work :)
For example, i did this:
.fc .fc-daygrid-day.fc-day-today {
background-color: rgb(229, 248, 225, 0.5) !important;
}
Hope that it helps :)
If you use bootstrap in your project, then u must use ": host ::ng-deep" before the property u want to modify in the CSS file. This works I have applied it.
e.g. :- : host:: ng-deep color: '#ffffff'
How to decrease the size of the mouse pointer in testcafe.. Below is code which I wrote but not working...
import { ClientFunction } from 'testcafe';
import { Selector } from 'testcafe';
fixture test
.page http://example.com
.beforeEach(async t => {
await disableCursor();
})
const disableCursor = ClientFunction(() => {
var styleElement = document.createElement('style');
styleElement.innerHTML = '.cursor-hammerhead-shadow-ui {width:10px; height:40px }';
document.head.appendChild(styleElement);
});
test('test', async t => {
await t.click(Selector('body > div > p:nth-child(3) > a'))
await t.click(Selector('#header > div.navigation > ul > li:nth-child(1) > a'))
});
To decrease the mouse pointer size, do the following:
Specify cursor selector: #root-hammerhead-shadow-ui.root-hammerhead-shadow-ui .cursor-hammerhead-shadow-ui.
Use the !important flag in CSS properties.
As a result, the code below replaces the default cursor with a red square:
const resizeCursor = ClientFunction(() => {
var styleElement = document.createElement('style');
styleElement.innerHTML = '#root-hammerhead-shadow-ui.root-hammerhead-shadow-ui .cursor-hammerhead-shadow-ui { background: red !important; width:40px !important; height:40px !important }';
document.head.appendChild(styleElement);
});
If you want to change the cursor to your own image, try this CSS property: background-image.
Note, since in a general case, it is hard to predict what unexpected results adding this CSS may produce, I suggest that you carefully check this prior to integrating this solution into your project.
See also: ClientFunction
I'm trying to change the opacity of my ion-backdrop from 0.08 to 0.33.
I've tried:
ion-backdrop {
opacity: 0.33 !important;
}
and setting $popover-ios-background: rgba(0, 0, 0, 0.33);.
Setting the value on ion-backdrop does work but since it's important, it doesn't animate the fade out.
How can I change the opacity of the backdrop?
I know I am a bit late to this party, but now with Ionic 5, you have a CSS selector that will do the job for you. That is mentioned in their documentation as well.
So basically all you could do is, initialize the modal and style it in your SCSS file.
This is my component.ts file:
import { Component } from '#angular/core';
import { ModalController } from '#ionic/angular';
// ModalComponent is just a normal angular component, your path may vary
import { ModalComponent } from '../../modals/modal.component';
#Component({
selector: 'some-component',
templateUrl: './some-component.component.html',
styleUrls: ['./some-component.component.scss']
})
export class SomeComponentComponent {
constructor(
private modalController: ModalController,
) { }
async presentModal() {
const modal = await this.modalController.create({
component: ModalComponent,
cssClass: 'modal-class'
});
return await modal.present();
}
}
and my component.scss file:
.modal-class {
ion-backdrop {
--backdrop-opacity: 0.33;
}
}
I’ve do it using the cssClass property in alertController (Ionic 4)
async alertError(message: string) {
const alert = await this.alertController.create({
cssClass: 'alertClass',
animated: true,
header: 'Error',
message,
buttons: ['OK']
});
await alert.present();
}
ion-alert {
&.alertClass{
background: rgb(0,0,0,.8);
}
}
I am guessing that this ion-backdrop question it's related with the Ionic Alert Controller. If that is the case than you need to apply CSS inside the global.scss (Ionic 3) file or theme\variable.scss (Ionic 4/5). This is required because ion-backdrop lives in the app as an Ionic Global Component.
Therefore find the mentioned file inside your Ionic project. It's usually in this directory app > src > global.scss.
Now let's suppose that we have this Alert Controller instanciated in some page class.
...
async serviceErrorAlert() {
const alert = await this.alertController.create({
cssClass: 'try-again-alert',
...
});
await alert.present();
}
...
As you can see this Alert Controller haves a CSS class of try-again-alert.
So to add all custom CSS that you want just go the style file and add your own style.
global.scss (Ionic 3):
.try-again-alert {
--background: rgba(55, 67, 77, 0.9);
}
theme\variable.scss (Ionic 4/5):
I strongly recommend you to use CSS background attribute and rgba() property. With this approach you can now choose the color that you want (first three numbers) and the opacity of the color (fourth number).
There is currently an open issue about this in Ionic's GitHub. The only workaround listed there that doesn't break the animation is long and complex - too much to list here. A direct link to the solution: https://github.com/ionic-team/ionic/issues/9105#issuecomment-375010398
I only managed to do it in Ionic 5 by using background: rgba() property with a desired alpha value.
Page where modal is called
openModal(): Promise<void> {
return this.modalCtrl.create({
component: ModalPage,
backdropDismiss: true,
cssClass: 'custom-class'
}).then(modal => {
modal.present();
});
}
app/theme/variable.css
.custom-class {
background: rgba(0,0,0,0.8); /*black with 0.8 opacity*/
}
I am trying to test this code but I am encountering problems. I have netbeans with default JavaFX platform.
This example is from this web site: http://onjava.com/pub/a/onjava/2007/07/27/introduction-to-javafx-script.html?page=4
package captureexample1;
import java.io.*;
import javafx.ui.*;
import javafx.ui.canvas.*;
import javafx.ui.filter.*;
import java.awt.Robot;
import java.awt.Rectangle;
import java.awt.image.RenderedImage;
import javax.imageio.ImageIO;
import java.lang.System;
class CaptureExample extends CompositeNode{
attribute lx: Integer;
attribute ly: Integer;
operation CaptureExample();
}
attribute CaptureExample.lx = 0;
attribute CaptureExample.ly = 0;
operation saveCapture(lx_copy:Integer, ly_copy:Integer) {
var robot = new Robot();
var rect = new Rectangle (lx_copy, ly_copy, 50, 50);
var BI=robot.createScreenCapture(rect);
var file = new File(".//capture.jpg");
ImageIO.write((RenderedImage)BI, "jpg", file);
}
function CaptureExample.composeNode() =
Group{
transform: []
content:[ImageView {
transform: []
image: Image { url: ".//app//Sunset.gif" }
cursor: DEFAULT
onMouseClicked: operation(e:CanvasMouseEvent) {
saveCapture(e.source.XOnScreen,e.source.YOnScreen);
}
onMouseMoved: operation(e:CanvasMouseEvent) {
lx = e.x;
ly = e.y;
}
},
Rect{
x: bind lx
y: bind ly
width: 50
height:50
strokeWidth: 1
stroke: black
}]
};
Frame {
centerOnScreen: true
visible: true
height: 230
width: 300
title: "Capture the screen..."
onClose: operation() {System.exit(0);}
content: ScrollPane {
background: white
view: Canvas {
background: black
cursor: DEFAULT
content: CaptureExample
}
}
}
It seems you are mixing JavaFX script and JavaFX2.
JavaFX script (aka JavaFX 1.3) is obsolete, not supported and old.
modern JavaFX 2 uses Java as language instead of FX script. You can see examples here: http://docs.oracle.com/javafx/2/get_started/jfxpub-get_started.htm
If you really want to use JavaFX 1.3:
get older NetBeans, like 6.1
rename you .java file to .fx
But if you just trying to learn JavaFX I really advise you to try JavaFX 2.
I have a standalone Swing application and I'm using Groovy as programing language.
Trying to apply styles using CSS and searching for some tool for this purpose, I've found CSSBuilder.
The problem is that CSSBuilder comes integrated with Griffon framework, so I cannot use all of its features isolated from Griffon, such as 'cssClass' selector.
Therefore my question is simply: has anyone managed to do something like this?
Just wrote a quick test, and this seems to work:
#GrabResolver( name='codehaus', root='http://repository.codehaus.org' )
#Grab( 'org.codehaus.griffon:cssbuilder:0.4' )
import griffon.builder.css.*
import groovy.swing.SwingBuilder
import java.awt.BorderLayout as BL
def style = '''* {
background-color: red;
}
jbutton {
background-color: blue;
}
.active {
color: green ;
font-size: 50%;
}
jlabel {
color: pink ;
font-size: 200% ;
}'''
Class klass = javax.swing.JComponent
if( !AbstractSyntheticMetaMethods.hasBeenEnhanced(klass) ) {
AbstractSyntheticMetaMethods.enhance(klass,[
"getCssClass": {-> delegate.getClientProperty(ClarityConstants.CLIENT_PROPERTY_CLASS_KEY) },
"setCssClass": { String cssClass -> delegate.putClientProperty(ClarityConstants.CLIENT_PROPERTY_CLASS_KEY, cssClass) }
])
}
new SwingBuilder().edt {
int count = 0
def frame = frame( title:'CSS Test', size:[ 300, 300 ], show: true ) {
borderLayout()
textlabel = label(text:"Click the button!", constraints: BL.NORTH)
button(text:'Click Me',
cssClass: 'active',
actionPerformed: {count++; textlabel.text = "Clicked ${count} time(s)."; println "clicked"},
constraints:BL.SOUTH)
}
CSSDecorator.applyStyle( style, frame )
}
The meta-class enhancing code I took from the source of CSSBuilder