How do i create svg box opening animation? - svg

It looks "broken". Transform origin of the right element is out of place. I am trying to make this box "solid", but it scatters.
http://codepen.io/HappyHarlequin/pen/bZWQro
svg:hover #right{
animation: open_right 1s linear infinite;
animation-direction: alternate;
}
svg:hover #left{
transform-origin: 0% 50%;
animation: open_left 1s linear infinite;
animation-direction: alternate;
}
#keyframes open_right{
0% {
}
100% {
transform-origin:100% 50%;
transform: rotate(230deg) rotateX(-230deg)
}
}
#keyframes open_left{
0% {
}
100% {
transform-origin: 0% 50%;
transform: rotate(-230deg) rotateX(230deg)
}
}

rotateX() is a 3D rotation and you can't do 3D transformations on elements inside an SVG. You can only apply two dimensional transforms to them (rotate, scale, translate etc in X and Y only)
Even if you could do 3D transforms, you are trying to apply a 3D transform to something that is a two dimensional shape drawn to look like it is 3D. So it would not work anyway.
Possible approaches
You could:
Stick with 2D and use keyframe animation to animate your box flaps. Draw a series of keyframes of your flaps as they open. Then step, or morph, between those shapes.
Change your flaps to be HTML elements, such as a <div>. Then position them so that they line up with your fake 3D box and have the right amount of perspective. Then you can apply a 3D rotation to those.
Switch to a proper 3D box and animate that. There are various JS libraries that can help you with that, such as three.js.

Related

piechart using svg and react

I created a pie chart in React using the svg pattern from this tutorial https://www.smashingmagazine.com/2015/07/designing-simple-pie-charts-with-css/
With four pieces I have
For all four pieces:
stroke-dasharray: 25, 100;
For each piece I also have:
stroke-dashoffset: 0;,
stroke-dashoffset: -25;,
stroke-dashoffset: -50; and
stroke-dashoffset: -75;
Problem is I get a gap between the first and the last piece so the pieces does not fully fill the circle.
I managed to figure out the answer by looking at this similar thread SVG circle has a gap
It turned out I had a radius of 16 the full circle was more than 100%. Setting stroke-dasharray: 100,53and dividing my radius by 1.0053 helped.

Susy maths adjustment to particular layout

Working on a Drupal site with a Zen sub theme, I ditched zen-grids for susy. I have been playing around with Susy and it works nicely. But here is my question.
I have a layout with two main columns: #content (holding the main content; a grid of three rows of four images with a width of 181px) and div.region-sidebar-second (holding the main navigation).
My designer came up with a 960px layout, where the #content container’s width is 750px then there is a 8px right-margin and div.region-sidebar-second has a width of 202px.
In my responsive.scss I put:
.sidebar-second {
#content {
#include span-columns(9, 12);
}
.region-sidebar-second {
#include span-columns(3 omega, 12);
}
}
So #content uses the first 9 columns and .region-sidebar-second uses the last 3 columns. But this does not translate to 750px/8px/202px.
The percentages that susy calculates are correct, of course, but for my layout I would need Susy to calculate different percentages.
E.g. Susy calculates for #content
.sidebar-second #content {
float: left;
margin-right: 1.40845%;
width: 74.6479%;
}
and for
.sidebar-second .region-sidebar-second {
float: right;
margin-right: 0;
width: 23.9437%;
}
In order to meet the design requirements I would need a width: 78.125% for #content, .833333% for margin-right and a width: 21.0416666% for .region-sidebar-second
Not sure whether this can be achieved with Susy span-columns. If you have a quick idea this would be very much appreciated. Thanks.

Adding padding to the inside of a container

I have designed a layout using 978px as the grid width, with 12px of grid padding. I've never really understood the purpose of grid padding, to be honest, and now I am even more confused, because I thought the grid padding would apply to the inside of my total width so things don't rest right at the edge of the grid.
For example, my header has a background color of #333. I span the logo section 3 columns, but it doesn't look good because it's right at the edge. If I add 12px of padding to the inside of the header, it messes up my column flow, obviously. I tried adding it to the span-columns mixin, like #include span-columns(3, 12, 12px 0px), but the padding is too wide, and I don't think this would be efficient because I would want it on everything that is on the left and right.
So what is the best way to get padding on the inside of the grid?
Here is a little structure:
page-wrapper (container)
#page
header#header
main
footer#footer
I tried adding padding to the #page-wrapper and #page divs, but this didn't work.
/***** UPDATE *****/
Here is a screen shot of what I am trying to achieve:
This is the desktop layout, that I want responsive, so the padding effect I would like to be the same throughout layouts. Basically, the grid in the screen shot is a total width of 1002, with 12px on the side, 12- 54px columns, and 11- 30px gutters.
this is a fireworks template, so my 320 page is 8 columns, 27px wide, with 12px gutters, and 10px gutter width. I am starting to think I am designing wrong, as I mentioned before, I don't really understand the point of grid padding.
As you can see, I would like there to be padding on the sides of the container which by default everything rests on the edges.
Here is a code snippet of my set up:
$total-columns : 8;
$column-width : 27px;
$gutter-width : 12px;
$grid-padding : 10px;
$container-style: fluid;
$full: 747px 12;
$tablet: 747px 12 977px;
$desktop: 978px 12;
#page-wrapper{
#include container;
#include susy-grid-background;
#include at-breakpoint(747px 12 977px){
#include set-container-width;
max-width: 747px;
#include susy-grid-background;
}
#include at-breakpoint(978px 12){
#include set-container-width;
max-width: 1002px;
#include susy-grid-background;
}
Now here is something I did by checking on that other post, and it seems to work, but I am not sure if it is the right way to do it:
#header{
margin-left: -$grid-padding;
margin-right: -$grid-padding;
padding: 0 $grid-padding;
margin-bottom: 1em;
}
Your screenshot link is broken, but if I understand right you simply want your outer grid elements to span the grid padding. For that, I use the technique you mentioned, although doing it by hand can be a pain if you want it too many places on the site. Here's a mixin that I've created to handle this kind of "bleed" in a flexible way:
#mixin bleed($padding: $grid-padding, $sides: left right) {
#if $sides == 'all' {
margin: - $padding;
padding: $padding;
} #else {
#each $side in $sides {
margin-#{$side}: - $padding;
padding-#{$side}: $padding;
}
}
}
The default setting there is to add $grid-padding bleed to the left and right. You can change the size of the bleed, and also the sides that it should apply to. You can apply it like this:
#header { #include bleed; }
#nav { #include bleed($sides: left); }
#main { #include bleed($sides: right); }
You have a few other strange bits of code. By default, Susy build what I call a magic grid: fluid with a max width. Instead of allowing that to happen by default, you are forcing your grids fully-fluid ($container-style: fluid;), including set-container-width (which would set the max-width if you hadn't turned it off, but is now doing nothing useful for you) and then adding a max-width by hand.
You also mention wanting different column and gutter widths at your different sizes. For that you will want to use with-grid-settings inside your breakpoints. e.g:
#include at-breakpoint($desktop){
#include with-grid-settings(12,54px,30px,12px) {
#include set-container-width;
#include susy-grid-background;
}
}

How do you rotate SVG images in processing.js

I am just staring with processing.js and I have been having trouble because every time I rotate an image it also changes its location on the screen. So what processing seems to do is, rotate my image around the point I told it to place it, instead of rotating it first around its own axis and then placing it where I told it to (which I figured cannot be done in that way/order).
This is the code
PShape s;
float angle = 0.1; //rads
s = loadShape("sensor.svg");
s.rotate(angle);
//I change this angle manually or with my clickMouse function which isnt shown.
void setup(){
size(400,350);
frameRate(30); //30 frames per seconds
}
void draw(){ //shape( shape, x, y, width, height);
smooth();
fill(153);
ellipse(200, 350/2, 100, 100);
shape(s, 200, 350/2, 20, 20);
ellipse(200, 350/2, 2, 2);
}
What I am basically trying to do is make this "sensor" image rotate in the correct orientation around the circle (ellipse) that I drew. Thats the idea. Its doing neither. Maybe having a click function that rotates the SVG image around the circle. But instead it rotates around the coordinates of the shape(image, x_coord, y_coord, width, height) function. If anyone has any suggestions, I would be so happy! Hope my question makes sense, if it doesnt I would be more than happy to clarify any part of it.
Thanks! :)
It's much easier not to rotate your shape, but to rotate the coordinate system.
void draw() {
translate(s.width/2,s.height/2);
rotate(PI/4);
shape(s);
resetMatrix();
// keep on drawing here
}
This first moves the coordinate system so that (0,0) is on top of the center of your shape, then rotates the entire coordinate system by 45 degrees, then draws your shape. Then you reset the coordinate system and keep drawing as usual.

Scaling SVG objects defined in pixels to physical units?

I have an SVG element defined with a width and height of "297mm" and "210mm", and no viewbox. I do this because I want to work inside an A4 viewport, but I want to create elements in pixels.
At some point, I need to scale up an object defined in pixels so that it fits into part of the A4 page. For example, I might have an object which is 100 px wide, that I want to scale to 30mm horizontally.
Is this possible? I think I need a second container with a new co-ordinate system, but I can't find any way to do this.
EDIT
It seems that I (or SVG) has misunderstood what a pixel is. I realised that I could size a line to 100%, and then get it's pixel size with getBBox to find the scaling required. I wrote this code and ran it on 2 clients, one with a 1280x1024 monitor (80dpi), and one with a 1680x1050 LCD (90dpi):
function getDotsPerInch() {
var hgroup, vgroup, hdpi, vdpi;
hgroup = svgDocument.createElementNS(svgNS, "g");
vgroup = svgDocument.createElementNS(svgNS, "g");
svgRoot.appendChild(hgroup);
svgRoot.appendChild(vgroup);
drawLine(hgroup, 0, 100, "100%", 100, "#202020", 1, 1);
drawLine(vgroup, 100, 0, 100, "100%", "#202020", 1, 1);
hdpi = hgroup.getBBox().width * 25.4 / WIDTH;
vdpi = vgroup.getBBox().height * 25.4 / HEIGHT;
drawText(hgroup, "DPI, horizontal: " + hdpi.toFixed(2), 100, 100);
drawText(hgroup, "DPI, vertical: " + vdpi.toFixed(2), 100, 120);
}
IE9, FF, Opera, and Chrome all agree that both monitors are 96 dpi horizontally and vertically (although Opera's slightly inaccurate), and Safari reports 0 dpi on both monitors. So svg just appears to have defined "pixels" as "96dpi". some quick Googling appears to confirm this, though I haven't found anything definitive, and most hits give 90dpi, with 96dpi as the FF variant.
You can nest <svg> elements and use the viewBox attribute on the child element to get a new coordinate system. Give the child <svg> element x, y, width and height attributes of where you want it to appear on the parent in the parent's co-ordinate system.

Resources