I have an alpha premultiplied image that requires changing the opacity of it. The opacity change applied to the image can be from 0.0 to 1.0.
This process is easy to achieve using the following formula:
Cn = C*alpha;
An = A*alpha;
However, I'm trying to avoid writing this code my self and allow the highly optimized library pixman do the job. They provide various blending options but I'm not too sure how to use mask for or which blend option to utilize. I have tried using MULTIPLY but that just made the image darker as expected I guess...
Any ideas which potential blend option I should use?
{ "CLEAR", PIXMAN_OP_CLEAR },
{ "SRC", PIXMAN_OP_SRC },
{ "DST", PIXMAN_OP_DST },
{ "OVER", PIXMAN_OP_OVER },
{ "OVER_REVERSE", PIXMAN_OP_OVER_REVERSE },
{ "IN", PIXMAN_OP_IN },
{ "IN_REVERSE", PIXMAN_OP_IN_REVERSE },
{ "OUT", PIXMAN_OP_OUT },
{ "OUT_REVERSE", PIXMAN_OP_OUT_REVERSE },
{ "ATOP", PIXMAN_OP_ATOP },
{ "ATOP_REVERSE", PIXMAN_OP_ATOP_REVERSE },
{ "XOR", PIXMAN_OP_XOR },
{ "ADD", PIXMAN_OP_ADD },
{ "SATURATE", PIXMAN_OP_SATURATE },
{ "MULTIPLY", PIXMAN_OP_MULTIPLY },
{ "SCREEN", PIXMAN_OP_SCREEN },
{ "OVERLAY", PIXMAN_OP_OVERLAY },
{ "DARKEN", PIXMAN_OP_DARKEN },
{ "LIGHTEN", PIXMAN_OP_LIGHTEN },
{ "COLOR_DODGE", PIXMAN_OP_COLOR_DODGE },
{ "COLOR_BURN", PIXMAN_OP_COLOR_BURN },
{ "HARD_LIGHT", PIXMAN_OP_HARD_LIGHT },
{ "SOFT_LIGHT", PIXMAN_OP_SOFT_LIGHT },
{ "DIFFERENCE", PIXMAN_OP_DIFFERENCE },
{ "EXCLUSION", PIXMAN_OP_EXCLUSION },
{ "HSL_HUE", PIXMAN_OP_HSL_HUE },
{ "HSL_SATURATION", PIXMAN_OP_HSL_SATURATION },
{ "HSL_COLOR", PIXMAN_OP_HSL_COLOR },
{ "HSL_LUMINOSITY", PIXMAN_OP_HSL_LUMINOSITY },
This is the actual composite function:
void pixman_image_composite(pixman_op_t op,
pixman_image_t *src,
pixman_image_t *mask,
pixman_image_t *dest,
int16_t src_x,
int16_t src_y,
int16_t mask_x,
int16_t mask_y,
int16_t dest_x,
int16_t dest_y,
uint16_t width,
uint16_t height);
The solution was actually fairly easy. At the beginning I didn't think too much of the mask. Then I realized ah a mask of course just like photoshop uses.
So applying a mask with the correct alpha value will cause the image to change it's opacity.
So changing the image opacity to 50% we would use a mask with white color and alpha value at 50%.
Related
I'm trying to customize the Tailwind Typography plugin, as follows:
typography (theme) {
return {
DEFAULT: {
css: {
'code::before': {
content: 'none', // don’t generate the pseudo-element
//content: '""', // this is an alternative: generate pseudo element using an empty string
},
'code::after': {
content: 'none'
},
code: {
color: theme('colors.slate.700'),
fontWeight: "400",
backgroundColor: theme('colors.stone.100/30'),
borderRadius: theme('borderRadius.DEFAULT'),
borderWidth: '1px',
paddingLeft: theme('spacing[1.5]'),
paddingRight: theme('spacing[1.5]'),
paddingTop: theme('spacing[0.5]'),
paddingBottom: theme('spacing[0.5]'),
},
}
},
invert: {
css: {
code: {
color: theme('colors.slate.100'),
backgroundColor: theme('colors.slate.800'),
borderColor: theme('colors.slate.600'),
}
}
}
}
},
How can I apply a color value to backgroundColor - based on one of the built in colors, with with opacity applied? For example colors.slate.800 / 50 (which doesn't work)
This is a tricky one. The problem is theme function will return HEX value for colors - it simply gets value from resolved configuration in dot notation. So theme('colors.red.500/300') is not valid (at least for now. I think it worth to open PR or Discussion)
All you need to solve the problem is to convert HEX to RGB. There are two Tailwind's ways I know but of course you're free to use any similar approach
First one - convert using Tailwind's withAlphaVariable function. It accepts an object with CSS property, color name and variable name.
const withAlphaVariable = require('tailwindcss/lib/util/withAlphaVariable')
module.exports = {
theme: {
extend: {
typography: ({theme}) => {
// This will create CSS-like object
// you should destruct and override CSS-variable with desired opacity
const proseCodeBgColor = withAlphaVariable({
color: theme('colors.red.500'), // get color from theme config
property: 'background-color',
variable: '--tw-my-custom-bg-opacity', // could be any
})
return {
DEFAULT: {
css: {
code: {
...proseCodeBgColor,
'--tw-my-custom-bg-opacity': '.3', // opacity
},
}
},
}
}
},
},
plugins: [
require('#tailwindcss/typography')
],
}
Second one much simplier - use #apply directive. Pass desired Tailwind's utilities as a key and empty object as a value
module.exports = {
theme: {
extend: {
typography: ({theme}) => {
return {
DEFAULT: {
css: {
code: {
// you may pass as much utilities as you need eg `#apply bg-red-500/30 text-lg font-bold`: {}
'#apply bg-red-500/30': {},
},
}
},
}
}
},
},
plugins: [
require('#tailwindcss/typography')
],
}
Worth to mention you can customize code background as utility prose-code:bg-blue-500/50
<div class="prose prose-code:bg-blue-500/50">
<code>
npm install tailwindcss
</code>
</div>
DEMO
This may have been asked numerous times, but I can't get a clear "newbie" plan of action.
Building Aframe experiences to showcase some interiors for numerous client presentations—this will be show on a desktop browser only, and I need to be able to control pan/rotate/turn-around camera movement with left and right arrow keys instead of relying on the mouse, as many clients have found this cumbersome. I just need to control this like an old first-person shooter with four arrow buttons.
Is there a simple way to do this? I've seen various permutations of this question but no simple solution so far. Thanks!
A simple keyboard input look component:
AFRAME.registerComponent('kbd-look-controls', {
schema: {
speed: {type: 'number', default: 2}
},
init: function () {
this.bindFunctions();
this.addEventListeners();
this.keyPressed = {
'ArrowUp': false,
'ArrowDown': false,
'ArrowLeft': false,
'ArrowRight': false
}
},
remove: function () {
this.removeEventListeners();
},
tick: function(time, delta) {
var data = this.data;
var object3D = this.el.object3D;
const angleDelta = 0.01 * data.speed * (delta / 16);
if (this.keyPressed['ArrowUp']) {
object3D.rotation.x = object3D.rotation.x + angleDelta;
}
if (this.keyPressed['ArrowDown']) {
object3D.rotation.x = object3D.rotation.x - angleDelta;
}
if (this.keyPressed['ArrowLeft']) {
object3D.rotation.y = object3D.rotation.y + angleDelta;
}
if (this.keyPressed['ArrowRight']) {
object3D.rotation.y = object3D.rotation.y - angleDelta;
}
},
bindFunctions() {
this.onKeyUp = this.onKeyUp.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
},
addEventListeners() {
window.addEventListener('keydown', this.onKeyDown);
window.addEventListener('keyup', this.onKeyUp);
},
removeEventListeners() {
window.removeEventListener('keydown', this.onKeyDown);
window.removeEventListener('keyup', this.onKeyUp);
},
onKeyUp: function (evt) {
this.keyPressed[evt.code] = false;
},
onKeyDown: function (evt) {
this.keyPressed[evt.code] = true;
}
})
Sample usage:
<a-entity camera kbd-look-controls="speed: 2.5" position="0 1 0"></a-entity>
This is one approach to getting to achieve your functionality.
Using wasd-controls component as well can be undesirable, since the wasd-controls also listens to the arrow keys.
Doesn't work with the look-controls component since it's also adjusting the rotation.
I want to separate the style from color schemes in a Cytoscape.js 3.1 graph. According to http://js.cytoscape.org/#cy.style, I initialize and then add to cy.style():
var mystyle = [
{
"selector": "node",
"css":
{
"border-opacity": 1.0,
'label': function(ele)
{
if(ele.data('Labels_EN')) {return ele.data('Labels_EN')[0];}
...
}, ...
];
var bright = [
{
"selector": "node",
"css":
{"background-color": "white";}
}];
cy = cytoscape(
{
container: mycontainer,
style: mystyle
});
cy.style().fromJson(bright).update();
Unfortunately, the call to cy.style().fromJson() seems to automatically invoke cy.style().resetToDefault(), as it removes the existing style.
How can I prevent Cytoscape.js from deleting my existing style and instead add to it using JSON? I need this functionality so that I don't have to put the complete style information in all my color scheme files, which makes it harder to maintain.
P.S.: As a workaround, I merged two style files like this:
function mergeJsonArraysByKey(a1,a2)
{
let map1 = new Map();
let map2 = new Map();
for(i=0;i<a1.length;i++) {if(a1[i].selector) {map1.set(a1[i].selector,a1[i]);}}
for(i=0;i<a2.length;i++) {if(a2[i].selector) {map2.set(a2[i].selector,a2[i]);}}
let merged = [];
map1.forEach((value,key,map) =>
{
if(map2.has(key))
{
merged.push($.extend(true,{},value,map2.get(key)));
} else
{
merged.push(value);
}
});
map2.forEach((value,key,map) =>
{
if(!map1.has(key))
{
merged.push(value);
}
});
return merged;
}
function initGraph(container, graph)
{
let merged = mergeJsonArraysByKey(mystyle,bright);
cy = cytoscape(
{
container: container,
style: merged
});
}
Merge the json rather than appending to the stylesheet. You can do whatever you want with the json, whereas cy.style() can be modified in only particular ways to prevent issues.
cy.style().fromJson( sheetA.concat( sheetB ) )
I have a Highcharts pie chart here: http://jsfiddle.net/6PbbR/52/
$(function () {
var chart;
$(document).ready(function() {
// Radialize the colors
Highcharts.getOptions().colors = Highcharts.map(Highcharts.getOptions().colors, function(color) {
return {
radialGradient: { cx: 0.5, cy: 0.3, r: 0.7 },
stops: [
[0, color]
]
};
});
// Build the chart
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
shadow: true,
},
tooltip: {
enabled: false
},
title: {
text: ""
},
plotOptions: {
pie: {
allowPointSelect: true,
size:'68%',
cursor: 'pointer',
shadow: true,
dataLabels: {
enabled: true,
distance: -40,
style: {
width: '100px'
},
color: '#fff',
connectorColor: '#000000',
formatter: function() {
return '<b style="font-family:arial;font-size:10px;font-weight:bold">'+ this.point.name +'</b> ';
}
}
}
},
series: [{
type: 'pie',
name: 'Income Investments',
data: [
['FLOATING RATE FUNDS', 16.667],
{
name: 'Corporate Capital Trust',
y: 16.667,
sliced: true,
selected: true
},
['BONDS', 16.667],
['ANNUITIES', 16.667],
['REITs', 16.667],
['CDs', 16.667]
]
}],
colors: [
'#83a3c6',
'#98012e',
'#19699b',
'#ae9e8e',
'#5283b0',
'#958370'
],
});
});
});
Two questions:
1) I'm not happy with how I inserted inline style in plotOptions{pie{formatter. Where is a better place to do this using the API, instead of brute-forcing inline style?
2) I would like to change the font-family for the red wedge (and possibly tweak fix its positioning/margins). What's the best way of doing this?
Edit: Ideally, I can accomplish my needs without needing to go outside the above function. Is it possible to attach style to just one data point using the API?
It's a simple html, so you can add a class or id and then style using css.
js
formatter: function() {
return '<b id="myTooltipId">'+ this.point.name +'</b> ';
}
css
#myTooltipId {
font-family: arial;
font-size: 10px;
font-weight:bold
}
Update:
Inside formatter you can get the slice properties using this.
So you just have to check if the slice is the one you want.
formatter: function() {
// key is the slice name
if (this.key == 'CDs') {
return '<b id="myTooltipId">'+ this.point.name +'</b> ';
} else {
return this.value;
}
}
I'm a c# programmer, my JS skills are weak. I've been trying all manners and syntax to get a custom icon image to appear based on query parameters from a Fusion table. I always get a default red dot icon. I'm using SetOptions as follows:
Note that the other markers do work, just not the custom image.
Many thanks for any help.
layerl0.setOptions({
query:
{
select: 'col3',
from: '1RqmLYAIdL9mvV3zAMVdnEjncXiiX0ZXJAwL92PY'
},
styles: [
{ where: "'Category' = 'Hotel'", markerOptions: { iconName: "rec_lodging" } },
{ where: "'Category' = 'Restaurant'", markerOptions: { iconName: "dining" } },
{ where: "'Category' = 'Do'", markerOptions: { icon: new google.maps.MarkerImage("http://m.inbocas.com/Content/icons/surfing.png")} },
{ where: "'Category' = 'Shop'", markerOptions: { iconName: "grocery" } },
{ where: "'Category' = 'Party'", markerOptions: { iconName: "bars" } },
]
});
Do you have the constructor for your MarkerImage?
MarkerImage(url:string, size?:Size, origin?:Point, anchor?:Point, scaledSize?:Size)