CSS in GTK+ doesn't work - css

GtkCssProvider *provider;
GdkDisplay *display;
GdkScreen *screen;
provider = gtk_css_provider_new ();
display = gdk_display_get_default ();
screen = gdk_display_get_default_screen (display);
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
const gchar *myCssFile = "style.css";
GError *error = 0;
gtk_css_provider_load_from_file(provider, g_file_new_for_path(myCssFile), &error);
g_object_unref (provider);
This doesn't work, but when I change "style.css" to the full path, everything works great. What am I doing wrong?

Please, do the bare minimum: check your error codes, and process them.
const gchar *css_relpath = "style.css";
GError *error = NULL;
GFile *css_file = g_file_new_for_path(css_relpath);
gtk_css_provider_load_from_file(provider, css_file, &error);
if (error)
{
// Display a warning if the stylesheet is not loaded
g_warning ("%s", error->message);
// Free the memory allocated for the error
// and acknowledge the error has been processed
g_clear_error (&error);
}
g_object_unref (css_file);

window {
background-image: image(Peru);
}
button {
background-image: image(Tan);
background-color: Tan;
}
button:active {
background-image: image(#C69F6C);
background-color: #C69F6C;
}
#unpressed {
background-image: image(Sienna);
background-color: Sienna;
}
#button_black {
background-image: image(Black);
background-color: Black;
}
#button_white {
background-image: image(White);
background-color: White;
}
"style.css:2:19Not a valid image"
My .css file above

Related

Variable frequency PWM on ESP32

I have been working on the following project that was created by Rui Santos and wanted to make some modifications.
ESP32 Web Server Slider
In the code the frequency is set constant and the duty cycle is adjustable with a slider. I would like to add a slide that also adjusts the frequency from 100Hz to 10kHz.
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-web-server-slider-pwm/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
// Import required libraries
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const int output = 2;
String sliderValue = "0";
// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
const char* PARAM_INPUT = "value";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP Web Server</title>
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 2.3rem;}
p {font-size: 1.9rem;}
body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
.slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
outline: none; -webkit-transition: .2s; transition: opacity .2s;}
.slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
.slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; }
</style>
</head>
<body>
<h2>ESP Web Server</h2>
<p><span id="textSliderValue">%SLIDERVALUE%</span></p>
<p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="255" value="%SLIDERVALUE%" step="1" class="slider"></p>
<script>
function updateSliderPWM(element) {
var sliderValue = document.getElementById("pwmSlider").value;
document.getElementById("textSliderValue").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if (var == "SLIDERVALUE"){
return sliderValue;
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
// configure LED PWM functionalitites
ledcSetup(ledChannel, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(output, ledChannel);
ledcWrite(ledChannel, sliderValue.toInt());
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
ledcWrite(ledChannel, sliderValue.toInt());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
// Start server
server.begin();
}
void loop() {
}
It seems the Arduino interface to ESP32 PWM is not really documented, but if you look at the relevant header and source then you'll find a function ledcChangeFrequency() which seems to do the trick.
const double newFreq = ledcChangeFrequency(ledChannel, freq, resolution);
serial.println(newFreq);
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-web-server-slider-pwm/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
// Import required libraries
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const int output = 2;
String sliderValue = "0";
// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
const char* PARAM_INPUT = "value";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP Web Server</title>
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 2.3rem;}
p {font-size: 1.9rem;}
body {max-width: 400px; margin:0px auto; padding-bottom: 25px;}
.slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C;
outline: none; -webkit-transition: .2s; transition: opacity .2s;}
.slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;}
.slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; }
</style>
</head>
<body>
<h2>ESP Web Server</h2>
<p><span id="textSliderValue">%SLIDERVALUE%</span></p>
<p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="255" value="%SLIDERVALUE%" step="1" class="slider"></p>
<p><span id="textSliderValue2">%SLIDERFREQ</span></p>
<p><input type="range" onchange="updateSliderFREQ(this)" id="freqSlider" min="0" max="255" value="%SLIDERVALUE%" step="1" class="slider"></p>
<script>
function updateSliderPWM(element) {
var sliderValue = document.getElementById("pwmSlider").value;
document.getElementById("textSliderValue").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/slider?value="+sliderValue, true);
xhr.send();
}
function updateSliderFREQ(element) {
var sliderValue = document.getElementById("freqSlider").value;
document.getElementById("textSliderValue2").innerHTML = sliderValue;
console.log(sliderValue);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/freq?value="+sliderValue, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if (var == "SLIDERVALUE"){
return sliderValue;
}
return String();
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
// configure LED PWM functionalitites
ledcSetup(ledChannel, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(output, ledChannel);
ledcWrite(ledChannel, sliderValue.toInt());
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
ledcWrite(ledChannel, sliderValue.toInt());
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
server.on("/freq", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input1 value on <ESP_IP>/slider?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
sliderValue = inputMessage;
freq = sliderValue.toInt();
}
else {
inputMessage = "No message sent";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
// Start server
server.begin();
}
void loop() {
}

Can't do JS-in-CSS for css-houdini paint?

I'm trying to copy this example; I have a scss file that I'm using with modular CSS in a React/Electron project. I want to define the function to be used by paint in the same file, as in the example:
.container {
--background-canvas: (ctx, geom) => {
// left blank for minimal example
};
background-image: paint(background-canvas);
display: flex;
margin: 4px;
border-radius: 12px;
height: 75px;
}
However, this fails to compile with CssSyntax error: Expected a pseudo-class or pseudo-element. (2:23). What am I not doing that the demo is?
Alright, I got it mostly working. The only part that isn't working is the transition which I'm not sure why it isn't.
-- Edit: I got that working via: https://css-houdini.rocks/animating-gradient
CSS.registerProperty({
name: '--multiplier',
syntax: '<number>',
inherits: false,
initialValue: 0
})
I couldn't find a way to get the CSS in JS parser to treat { } as a part of a string rather than special characters, so I used an array to allow me to run the relevant function calls in the background-canvas function.
--background-canvas: (ctx, geom) => [ ctx.moveTo(0, 0),
ctx.lineTo(
var(--pad) + (geom.width - var(--slant) - var(--pad)) * var(--multiplier),
0
),
ctx.lineTo(
var(--pad) + (geom.width - var(--slant) - var(--pad)) * var(--multiplier) +
var(--slant),
geom.height
),
ctx.lineTo(0, geom.height), ctx.fillStyle = \`var(--color)\`, ctx.fill() ];
The real fun part about this solution is that you still need to actually register the paint function.
I did that in a similar way as a previous answer I have: https://stackoverflow.com/a/61966697/13175138 which uses this https://twitter.com/DasSurma/status/983305990731894785
As a note, this solution from that example uses eval as part of it's registerPaint function, so this could be problematic from a security standpoint, though the paint code should theoretically be sandboxed from the main runtime.
const Demo = styled.div`
background: #1108a0;
padding: 50px 0;
`;
const Test = styled.div`
--color: cyan;
--multiplier: 0.24;
--pad: 30;
--slant: 20;
--background-canvas: (ctx, geom) => [ ctx.moveTo(0, 0),
ctx.lineTo(
var(--pad) + (geom.width - var(--slant) - var(--pad)) * var(--multiplier),
0
),
ctx.lineTo(
var(--pad) + (geom.width - var(--slant) - var(--pad)) * var(--multiplier) +
var(--slant),
geom.height
),
ctx.lineTo(0, geom.height), ctx.fillStyle = \`var(--color)\`, ctx.fill() ];
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;
}
`;
const App = () => (
<Demo>
<Test className="el" right={'right'}>
<span>JS-in-CSS</span>
</Test>
</Demo>
);
ReactDOM.render(<App />, document.getElementById('root'));
/*if ("paintWorklet" in CSS) {
console.log('here')
const src = document.querySelector('script[language$="paint"]').innerHTML;
const blob = new Blob([src], {
type: 'text/javascript'
});
CSS.paintWorklet.addModule(URL.createObjectURL(blob));
}*/
#media (max-width: 900px) {
.el {
font-size: 4em;
}
}
#media (max-width: 500px) {
.el {
font-size: 2.4em;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react-is#17.0.1/umd/react-is.production.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id="root"/>
<script language="javascript+paint">
registerPaint('background-canvas', class {
static get inputProperties() {
return ['--background-canvas'];
}
paint(ctx, geom, properties) {
eval(properties.get('--background-canvas').toString())(ctx, geom, properties);
}
})
</script>
<script>
// Register the property so it become animatable
CSS.registerProperty({
name: '--multiplier',
syntax: '<number>',
inherits: false,
initialValue: 0
})
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>

LESS fails on missing value from a list in Map/List

The idea is to add a 'default' value to the list and if one exists, output a class. If the 'default' doesn't exists, the compiler fails. How can this be achieved?
I tried a few variations of Less Guards and couldn't figure out a way to solve the problem.
I also attempted to add a 'default' list for these situations but they aren't merging.
Current Less I'm testing:
// Map / List
#borderRadius: {
//default: .25rem;
none: 0;
small: .3rem;
medium: .5rem;
large: 1rem;
round: 9999px;
}
// Extract
.getKeyFromList(#list, #key, #fallback...) {
.-(length(#list));
.-(#i) when (#i > 0) {.-((#i - 1))}
.-(#i) when (#key = extract(extract(#list, #i), 1)) {
#value: extract(#list, #i);
}
.--() {#value: #fallback} .--;
}
// Generate the CSS
& when not (#borderRadius) {
.getKeyFromList(#borderRadius[default], #borderRadius[default]);
&radius {
border-radius: #value;
}
}
EDIT:
Here is my real-world example.
I'm trying to extract the 'responsive' key from each ##component to generate responsive modifier classes dynamically
for individual components/variants. I was able to get the :hover and :focus variants to work, but can't figure out a
good way to do it for media queries (responsive modifier classes)
#responsiveModifiers: true;
#breakpointOffset: 1;
#screens: {
small: 768px;
medium: 960px;
large: 1440px;
};
#opacity: {
0: 0;
25: .25;
50: .5;
75: .75;
100: 1;
}
#borderRadius: {
none: 0;
small: .3rem;
medium: .5rem;
large: 1rem;
round: 9999px;
}
#components: {
#opacity: {
enabled: false;
responsive: false;
hover: true;
focus: false;
}
#borderRadius: {
enabled: true;
responsive: false;
hover: true;
focus: false;
}
}
.config() {
// Create generators here
& when (#components[#opacity][enabled]) {
#component: opacity;
.generate(opacity, opacity, #opacity);
}
& when (#components[#borderRadius][enabled]) {
#component: opacity;
.generate(radius, border-radius, #borderRadius);
}
}
// Call the mixin for default, non media-query classes
// and prefix it with a period (.)
.groundwork-utility-classes() {
#period: .;
#{period} {
.config();
}
}
// Dynamically generate CSS responsive modifiers, per breakpoint,
// via the #screens list array
.groundwork-media-queries() when (#responsiveModifiers = true) {
each(#screens, {
#media screen and (min-width: (#value + #breakpointOffset)) {
.#{key}&\: {
.config();
}
}
})
}
// Main mixin to generate all CSS utility classes
.generate(#className; #property; #list) {
// Generate CSS classes from a #list array
// e.g `.generate(p, padding, #padding);`
each(#list, {
& when not (#key > 0) {
&#{className} {
#{property}: #value;
}
&hover\:#{className}:hover when (#components[##component][hover] = true) {
#{property}: #value;
}
&focus\:#{className}:focus when (#components[##component][focus] = true) {
#{property}: #value;
}
}
});
}
// Render non media-query classes together
.groundwork-utility-classes();
// Group and render media queries together,
.groundwork-media-queries();

Set border to the grid (Vaadin 7.4.9)

I need to add border to the columns in grid.
In my webapp I have addons.scss, mytheme.scss, styles.scss and styles.css. How i can add this new borders into my grid?
My grid code -
#Override
protected void init(VaadinRequest vaadinRequest) {
Grid grid = new Grid();
IndexedContainer container = new IndexedContainer();
grid.setContainerDataSource(container);
container.addContainerProperty("September", String.class, null);
container.addContainerProperty("Person1", Integer.class, 0);
container.addContainerProperty("Person2", Integer.class, 0);
container.addContainerProperty("Person3", Integer.class, 0);
container.addContainerProperty("Person4", Integer.class, 0);
container.addContainerProperty("Person5", Integer.class, 0);
container.addContainerProperty("Person6", Integer.class, 0);
container.addContainerProperty("Person7", Integer.class, 0);
container.addContainerProperty("Person8", Integer.class, 0);
Grid.HeaderRow row = grid.addHeaderRowAt(0);
Grid.HeaderRow row2 = grid.addHeaderRowAt(1);
String[] Group1 = {"Person3", "Person4", "Person1", "Person2"};
String[] Group2 = {"Person7", "Person8", "Person5", "Person6"};
String[] Group3 = {"Person3", "Person4"};
String[] Group4 = {"Person1", "Person2"};
String[] Group5 = {"Person7", "Person8"};
String[] Group6 = {"Person5", "Person6"};
row.join(Group1).setText("Čerpacia stanica");
row.join(Group2).setText("Panos");
row2.join(Group3).setText("TPP");
row2.join(Group4).setText("Brigada");
row2.join(Group5).setText("TPP");
row2.join(Group6).setText("Brigada");
container.addItem(1);
Item item = container.getItem(1);
item.getItemProperty("September").setValue("1.9.2017 Piatok");
...
//This is from your post
grid.setCellStyleGenerator(new Grid.CellStyleGenerator() {
#Override
public String getStyle(Grid.CellReference cellReference) {
if ("TPP".equals(cellReference.getPropertyId()) ||
"Brigáda".equals(cellReference.getPropertyId())) {
return "right-and-left-border";
else {
return null;
}
}
});
}
There is class that i have in my webapp folder.
Mytheme.scss
// If you edit this file you need to compile the theme. See README.md for details.
// Global variable overrides. Must be declared before importing Valo.
// Defines the plaintext font size, weight and family. Font size affects general component sizing.
//$v-font-size: 16px;
//$v-font-weight: 300;
//$v-font-family: "Open Sans", sans-serif;
// Defines the border used by all components.
//$v-border: 1px solid (v-shade 0.7);
//$v-border-radius: 4px;
// Affects the color of some component elements, e.g Button, Panel title, etc
//$v-background-color: hsl(210, 0%, 98%);
// Affects the color of content areas, e.g Panel and Window content, TextField input etc
//$v-app-background-color: $v-background-color;
// Affects the visual appearance of all components
//$v-gradient: v-linear 8%;
//$v-bevel-depth: 30%;
//$v-shadow-opacity: 5%;
// Defines colors for indicating status (focus, success, failure)
//$v-focus-color: valo-focus-color(); // Calculates a suitable color automatically
//$v-friendly-color: #2c9720;
//$v-error-indicator-color: #ed473b;
// For more information, see: https://vaadin.com/book/-/page/themes.valo.html
// Example variants can be copy/pasted from https://vaadin.com/wiki/-/wiki/Main/Valo+Examples
#import "../valo/valo.scss";
#mixin mytheme {
#include valo;
.mytheme .v-grid-cell
{
font-size: 5px;
overflow: visible;
}
//I insert this code here
.v-grid-cell.right-and-left-border {
border-left: solid 2px black;
border-right: solid 2px black;
}
// Insert your own theme rules here
}
There is code from styles.scss
#import "mytheme.scss";
#import "addons.scss";
// This file prefixes all rules with the theme name to avoid causing conflicts with other themes.
// The actual styles should be defined in mytheme.scss
.mytheme {
#include addons;
#include mytheme;
}
This is class addons.scss
/* This file is automatically managed and will be overwritten from time to time. */
/* Do not manually edit this file. */
/* Import and include this mixin into your project theme to include the addon themes */
#mixin addons {
}
And styles.css have 13000 lines ...
After insert your code into mytheme.scss and grid set style method into my java code, then i recompiled the project. But when i refresh the page, all is the same.
--
Now I want update some styles in my theme. E.G
.mytheme .v-grid-row > td, .mytheme .v-grid-editor-cells > div {
font-size: 15px;
border-left: 1px solid #d4d4d4;
border-bottom: 1px solid #d4d4d4;
}
and i want have some new styles
.mytheme .v-grid-row > td, .mytheme .v-grid-editor-cells > div {
text-align: center;
font-weight: bold;
font-size: 10px;
border-left: 1px solid #d4d4d4;
border-bottom: 1px solid #d4d4d4;
}
Where do I save it? Thanks again :)

Output a single base css class to specify background-image

I am using grunt-spritesmith and it generates a css file such as this:
.icon-admin {
background-image: url(../sprites/spritesheet.png);
background-position: -288px -856px;
width: 37px;
height: 32px;
}
.icon-report {
background-image: url(../sprites/spritesheet.png);
background-position: -256px -888px;
width: 26px;
height: 28px;
}
This works fine. What I want to do is to use a base css class for icons for specifying the background-image (like what Compass does), so the output is like this:
.icon {
background-image: url(../sprites/spritesheet.png);
}
.icon-admin {
background-position: -288px -856px;
width: 32px;
height: 32px;
}
.icon-report {
background-position: -256px -888px;
width: 24px;
height: 24px;
}
I wonder if this is possible?
You need to use the cssTemplate function (example).
A quick (and dirty) implementation would be (based on this):
cssTemplate: function(params) {
var fs = require('fs'),
mustache = require('mustache'),
tmpl = fs.readFileSync(__dirname + '/template/css.template.mustache', 'utf8'),
items = params.items,
options = params.options;
// Fallback class naming function
var classFn = options.cssClass || function defaultCssClass (item) {
return '.icon-' + item.name;
};
// Add class to each of the options
items.forEach(function saveClass (item) {
item['class'] = classFn(item);
});
// Set the default class
options.cssClass = options.cssClass || '.icon';
// Render and return CSS
var css = mustache.render(tmpl, params);
return css;
}
Also, you need this template (placed inside a template directory, based on this):
{{options.cssClass}} {
background-image: url({{{spritesheet.escaped_image}}});
}
{{#items}}
{{class}} {
background-position: {{px.offset_x}} {{px.offset_y}};
width: {{px.width}};
height: {{px.height}};
}
{{/items}}
This should do the trick.

Resources