How to Properly Use +cache function in Stylus - mixins

I am trying to create a mixin using variables and the cache function. It works fine, except for one problem. See sample code below and then I'll explain the problem.
First, here is the mixin (simplified for reasons of space, but in essence this is how it works):
mixin($type = apples,
$color = blue,
$font-size = 12px,
$margin = 10px,
$padding = 20px,
$border-radius = 30px
)
if $type == apples
$color = red
if $type == oranges
// code
if $type == peas
// code
+cache('color' + $color)
color $color
+cache('font-size' + $font-size)
font-size $font-size
+cache('margin' + $margin)
margin: $margin
+cache('padding' + $padding)
padding: $padding
+cache('border-radius' + $border-radius)
border-radius: $border-radius
.one
mixin($font-size: 13px)
.two
mixin($type: oranges)
.three
mixin($type: peas)
This outputs the following code:
.one {
color: #f00;
}
.one {
font-size: 13px;
}
.one,
.two,
.three {
margin: 10px;
}
.one,
.two,
.three {
padding: 20px;
}
.one,
.two,
.three {
border-radius: 30px;
}
.two,
.three {
color: #00f;
}
.two,
.three {
font-size: 12px;
}
The problem with this method is that the selectors are being unnecessarily repeated. We could easily combine classes one, two and three together for margin, padding and border-radius and classes two and three together for color and font-size.
So let's try another tact for +cache:
+cache(
'color' + $color,
'font-size' + $font-size,
'margin' + $margin,
'padding' + $padding,
'border-radius' + $border-radius
)
color $color
font-size $font-size
margin: $margin
padding: $padding
border-radius: $border-radius
This outputs the following code:
.one {
color: #f00;
font-size: 13px;
margin: 10px;
padding: 20px;
border-radius: 30px;
}
.two,
.three {
color: #00f;
font-size: 12px;
margin: 10px;
padding: 20px;
border-radius: 30px;
}
Now we are unnecessarily outputting properties. margin, padding and border-radius are each mentioned twice.
What I want is a method that will produce the following result:
.one,
.two,
.three {
margin: 10px;
padding: 20px;
border-radius: 30px;
}
.one {
color: #f00;
font-size: 13px
}
.two,
color: #00f;
font-size: 12px;
}

Unfortunately, no. As it stands this is the best you will get with +cache. Although, to make things a bit more readable you can use +cache(arguments) like I have done bellow.
mixin($type = apples,
$color = blue,
$font-size = 12px,
$margin = 10px,
$padding = 20px,
$border-radius = 30px
)
+cache(arguments)
if $type == apples
$color = red
if $type == oranges
// code
if $type == peas
// code
color $color
font-size $font-size
margin: $margin
padding: $padding
border-radius: $border-radius

A CSS minifier should do what you want. For example, cssnano reduces your original, verbose CSS down to the following (I added whitespace for readability):
.one{
color:red;
font-size:13px
}
.one,.three,.two{
margin:10px;
padding:20px;
border-radius:30px
}
.three,.two{
color:#00f;
font-size:12px
}
Here is the code in action.

Related

How can I use #property in #emotion/styled?

Hello I want to customize my css property using the below method (#property).
https://css-tricks.com/using-property-for-css-custom-properties/
How can I use in emotion?
I want to use this inside code below.
export const Typography = styled("h4", {
label: "Typography"
})<{}>(() => {
return {
fontSize: 36,
fontWeight: 400,
marginBottom: 40,
color: palette.grey.default,
width: 300,
letterSpacing: -1
};
});
And make increasing number animation like below.
#property --num1 {
syntax: "<integer>";
initial-value: 0;
inherits: false;
}
#property --num2 {
syntax: "<integer>";
initial-value: 0;
inherits: false;
}
#property --num3 {
syntax: "<integer>";
initial-value: 0;
inherits: false;
}
div {
counter-reset: num1 var(--num1) num2 var(--num2) num3 var(--num3);
font-size: 40px;
font-weight: bold;
animation: animate 2s forwards ease;
}
div:before {
content: counter(num1) counter(num2) counter(num3);
}
#keyframes animate {
to {
--num1: 3;
--num2: 8;
--num3: 999999;
}
}

QML Change Size of Dropitem on Drop

I want to change the size of a Rectangle in the QML drag and drop example on drop to the size of the drop area. But somehow the Rectangle will not render to the new size although it takes the width and height values.
DragTile.qml
import QtQuick 2.0
Item
{
id: rootItem
property int boxWidth: 0
property int boxHeight: 0
property Item dragParent
width: boxWidth
height: boxHeight
MouseArea
{
id: mouseArea
width: rootItem.boxWidth
height: rootItem.boxHeight
drag.target: msgTile
onReleased:
{
parent = msgTile.Drag.target !== null ? msgTile.Drag.target : rootItem
rootItem.boxHeight = parent.boxHeight
rootItem.boxWidth = parent.boxWidth
}
Rectangle
{
id: msgTile
color: "cyan"
width: mouseArea.width
height: mouseArea.height
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
Drag.active: mouseArea.drag.active
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
//draging
states: State
{
when: mouseArea.drag.active
ParentChange { target: msgTile; parent: dragParent } // draw on top while draging
AnchorChanges { target: msgTile; anchors.verticalCenter: undefined; anchors.horizontalCenter: undefined }
}
}
}
}
The dragsource as well as the droparea take the size of a parent rectangle
in Main.qml
Rectangle
{
x: 100
y: 100
width: 100
height: 300
border.width: 1
DragSource
{
msgCount: 2
msgCapacity: 10
dragParent: topItem
}
}
Rectangle
{
x: 400
y: 100
width: 150
height: 300
border.width: 1
MsgDrop
{
msgCapacity: 12
}
}
The size of the droparea is a little bit larger, than the size of the dragtiles
Is there any order of rendering that I am missing?
I would be very happy for some advice.
Best regards

Add text on the circle created by the leaflet L.circle() function

I use the following function to create a series of circles around a clicked point on a leaflet map. I would like to label each circle by placing the distance (r or radius) on the circle line itself. But I can't find any option or function to do this. Can someone tell me how?
function circleKoords(e) {
var myJSON = JSON.stringify(e.latlng);
//alert("myJSON "+myJSON);
// myJSON {"lat":39.257778150283364,"lng":-94.41925048828126}
// myJSON {"lat":39.39587712612034,"lng":-93.54583740234376}
var LatLng = e.latlng;
var lat = e.latlng["lat"]; //alert(lat); // 39.172658670429946
var lng = e.latlng["lng"]; //lert(lng);
var i;
var r = 1609.34; // in meters = 1 mile, 4,828.03 meters in 3 miles
//https://jsfiddle.net/3u09g2mf/2/
//https://gis.stackexchange.com/questions/240169/leaflet-onclick-add-remove-circles
var group1 = L.featureGroup(); // Allows us to group the circles for easy removal
var circleOptions = {
color: 'blue',
fillColor: '#69e',
fillOpacity: 0.1
}
var milesbetween = 0; var numberofrings = 0;
var milesbetween = prompt("How many miles between circles?");
if (milesbetween <= 0) {milesbetween = 1;}
var numberofrings = prompt("How many circles do you want to see?");
if (numberofrings <= 0) {numberofrings = 5;}
// The actual circles are created here at the var Cname =
for (i=0 ; i < numberofrings; i++ ) {
var Cname = 'circle'+i; //alert(Cname); // circle0, circle1, circle2, etc.
r = (r * i) + r; r=r*milesbetween;
//alert(lat+", "+lng); // lat and lng of clicked point.
//alert('r= '+r); // r= 1609.34, r= 3218.68, r= 4828.0199999999995, etc. up to the number of rings
var Cname = L.circle([lat, lng], r, circleOptions);
Cname.addTo(group1);
// r = 1609.34; // reset r so r calculation above works for each 1 mile step
map.addLayer(group1);
r = 1609.34;
}
alert("All "+numberofrings+" rings are "+milesbetween+" mile apart.");
// This part allows us to delete the circles by simply clicking anywhere in the circles.
group1.on('click', function() {
if(map.hasLayer(group1)) {map.removeLayer(group1);}
//else {map.addLayer(group1);}
});
}
Can you try putting this after "var Cname = L.circle([lat, lng], r, circleOptions);"? This attempts to add a label to the same coordinates with the text "radius" followed by the computed radius value.
var label = L.marker([lat, lng], {
icon: L.divIcon({
className: 'label',
html: `radius ${r}`,
iconSize: [0, 0]
})
});
label.addTo(group1);
Add the L.GeometryUtil library:
<script src="https://cdn.jsdelivr.net/npm/leaflet-geometryutil#0.9.1/src/leaflet.geometryutil.min.js"></script>
Update your circle loop to:
// The actual circles are created here at the var Cname =
for (i=0 ; i < numberofrings; i++ ) {
var Cname = 'circle'+i; //alert(Cname); // circle0, circle1, circle2, etc.
r = (r * i) + r; r=r*milesbetween;
//alert(lat+", "+lng); // lat and lng of clicked point.
//alert('r= '+r); // r= 1609.34, r= 3218.68, r= 4828.0199999999995, etc. up to the number of rings
var Cname = L.circle([lat, lng], r, circleOptions);
Cname.addTo(group1);
mymap.addLayer(group1);
//180° from top
var p_c = L.GeometryUtil.destination(L.latLng([lat, lng]),180,r);
var icon = L.divIcon({ className: 'dist-marker', html: r.toFixed(0)+';iles', iconSize: [null, 16] });
var marker = L.marker(p_c, { title: r.toFixed(0)+'Miles', icon: icon});
marker.addTo(mymap);
// r = 1609.34; // reset r so r calculation above works for each 1 mile step
r = 1609.34;
}
CSS:
.dist-marker {
margin-left: -8px !important;
font-size: 9px;
border: 1px solid #777;
border-radius: 10px;
text-align: center;
color: #000;
background: #fff;
padding: 0 3px;
}
https://jsfiddle.net/falkedesign/3aukgm7t/

How to change column count in listing page Magento2?

I want to make product listing page to use 3 columns instead of 4 default columns.
I've got some categories on my Magento2 Web, and some products on each category. I want them to show as 3 columns count, but it always shows as 4 default columns count, how can i change plz help me for this.
Magento 2 don't have an option to set a column count as Magento 1.
To change from 4 to 3 (for theme based on Luma) you will need to change CSS and to reset image size.
CSS code that you need to change is inside Magento_Catalog module, file:
_listings.less
and it is like this:
.media-width(#extremum, #break) when (#extremum = 'min') and (#break = #screen__l) {
.products-grid .product-item { width: 100%/5 }
.page-layout-1column .products-grid .product-item { width: 100%/6 }
.page-layout-3columns .products-grid .product-item { width: 100%/4 }
.page-products .products-grid .product-items { margin: 0; }
.page-products .products-grid .product-item {
width: 24.439%;
margin-left: calc(~"(100% - 4 * 32.439%) / 3");
padding: 0;
&:nth-child(3n+1) {
margin-left: 0;
}
}
.page-products.page-layout-1column .products-grid .product-item { width: 100%/5 }
.page-products.page-layout-3columns .products-grid .product-item { width: 100%/4 }
}
to have 3 columns, change it to (I recommend add this code to _theme.less):
.media-width(#extremum, #break) when (#extremum = 'min') and (#break = #screen__l) {
.products-grid .product-item { width: 100%/4 }
.page-layout-1column .products-grid .product-item { width: 100%/5 }
.page-layout-3columns .products-grid .product-item { width: 100%/3 }
.page-products .products-grid .product-items { margin: 0; }
.page-products .products-grid .product-item {
width: 32.439%;
margin-left: calc(~"(100% - 3 * 32.439%) / 2");
padding: 0;
&:nth-child(3n+1) {
margin-left: 0;
}
}
.page-products.page-layout-1column .products-grid .product-item { width: 100%/4 }
.page-products.page-layout-3columns .products-grid .product-item { width: 100%/3 }
}
after this in
/your_theme/etc/view.xml
change small image width and height. Now is 240 and 300, change it to something like 300 and 330.
Refresh and that is it.

D3 Axis transition

The visualization is a bar chart in which the range of the bar heights is great (several orders of magnitude). I have built a transition triggered by a click that increases the heights of all the bars by a multiplicative amount. I would also like the y-axis ticks and labels to transition to the new scale of the bars. I have altered the domain of the y-axis scale. The bar height transition works fine. The axis transition does nothing.I cannot seem to get the axis transition correct. Can anyone help?
The code is a simple example of what I am trying to do - data is fixed.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="../static/js/d3.js"></script>
<style type="text/css">
.axis, .axis text {
font: 10px sans-serif;
}
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.tick text {
font-family: sans-serif;
fill: black;
}
</style>
</head>
<body>
<script type="text/javascript">
var xSize = 900,
ySize = 500;
var data = [10000, 3000, 100, 40, 10, 5, 1];
var margin = {top:40, right: 40, bottom:60, left: 60};
var width = xSize - margin.left - margin.right;
var height = ySize - margin.top - margin.bottom;
var barwidth = width / data.length;
var xscale = d3.scale.linear().domain([0, data.length]).range([0, width]);
var maxData = d3.max(data);
var yscale = d3.scale.linear().domain([0, maxData]).range([height, 0]);
var xAxis = d3.svg.axis().scale(xscale).orient("bottom");
var yAxis = d3.svg.axis().scale(yscale).orient("left");
var fieldView = d3.select("body")
.append("svg")
.attr("width", xSize)
.attr("height", ySize)
.on("click", update)
;
var chart = fieldView
.append("g")
.attr("id", "clip")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
;
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("rect")
.attr("x", function(d, i) {return xscale(i);})
.attr("y", function(d) { return yscale(d);})
.attr("height", function(d) { return height - yscale(d);})
.attr("width", barwidth)
.attr("fill", "steelblue")
.attr("clip-path", "url(#clip)")
;
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
;
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
;
var transitionScale = 1;
var transitionMultiplier = 5;
var transitionYscale = d3.scale.linear().domain([0, maxData])
.range([height, 0]);
function update() {
// new multiplier for data
transitionScale *= transitionMultiplier;
// update to y axis domain
yscale.domain([0, maxData / transitionScale]);
// transition the bars
bar
.transition()
.attr("y", function(d) {return yscale(d);})
.attr("height", function(d) {return height - yscale(d);})
.duration(2000)
.ease("linear")
;
// transition the y-axis
chart
.selectAll(".y axis")
.transition()
.call(yAxis)
;
}
</script>
</body>
</html>
Changing the axis transition selection from:
chart.selectAll(".y axis")
to:
chart.selectAll(".y.axis")
causes the axis to transition correctly. I don't know why, however.