How to make a preview of DIV in another DIV? - javascript

I am making an application or a site in html/css/javascript that will allow me to create slides, add some text, image maybe change color and styles to every slide and than launch it as a whole presentation.
So far I have managed to make a really easy layout :
http://sandbox.padsbanger.pl/ss/
My question is:
How can I make a dynamic preview of a div on sidebar and a full view of slide on the right ? This would allow me to switch between the diffrent slides and make changes to them.
Thanks in advance :)
EDIT: For this project I am not allowed to use PHP.
EDIT 2:
I am not bothering about storing the data about slides somewhere in db. The idea of this app it to make a presentation consistig of a few slides and then launch it full screen view as a presentation.

Well, you could do something like this:
.slajd * {
zoom: 0.25;
-moz-transform: scale(0.25);
-moz-transform-origin: 0 0;
-o-transform: scale(0.25);
-o-transform-origin: 0 0;
-webkit-transform: scale(0.25);
-webkit-transform-origin: 0 0;
}
That would shrink all the content in the left 'preview' panes to 1/4 size. Then, when you click one just copy the innerHTML to the right pane and since it won't have the zoom/scale styles it will be full size.
As for the connecting - this will make all slides clickable. I suggest you add this to a document.ready block somewhere in the HEAD.
$('#leftcolumn').on('click', '.slajd', function() {
$('#rightcolumn').html($(this).html());
});

If you want to show the exact contents of the left sidebar in the main content area you can read the contents of the current sidebar using $this then use .html to read the content.
Take a look at Google Docs, slide/presentation as an example.
They basically size everything tiny in the left box which is just what's in the right.

First, you need to save all of the design parameters in a data structure, for example:
var design =
[
{
type : "background-image",
params :
{
url: "/images/snow.png"
}
},
{
type : "image",
params :
{
x : 100,
y : 300,
width : 100,
height : 100,
url: "/images/tree.png"
}
},
{
type : "text",
params :
{
x : 100,
y : 300,
text : "Happy XMAS!",
font :
{
size : 20
family: arial;
}
}
},
];
Here you have a background image, some text and a regular image.
The size parameters will be used normally on the regular sized slide but you will have to divide those parameters by the size ratio of the large slide & the small one for example:
if the large slide is 400x400 and the small one is 100x100 do this:
largeWidth = 400;
largeHeight = 400;
smallWidth = 100;
smallHeight = 100;
xRatio = Math.round( largeWidth / smallWidth );
yRatio = Math.round( largeHeight / smallHeight );
Now, when you draw the thumbnail slide you need to divide the coordinates of the large one (which are specified in the data structure by the x & y ratios).

Related

Full screen background image minus flexible top-nav bar

This is my first post here and I haven't been able to find the answer to my question.
I am building a page and I want a picture to fill the entire screen, from the bottom of the top-nav bar (menu etc..) to the bottom of the screen. Only issue I have... the bar is responsive : it's taller on very large screen and much smaller on mobiles, which of course impacts my background image differently on different screens.
Here's my css :
.backgroundimage{
background-image: url(https://file...);
background-repeat: no-repeat;
background-size: cover;
width: 100%;
min-height: 100vh;
background-position: center center;
position: relative;
}
</style>
So I've tried multiples things for hours, playing around with the "vh" property.
For example :
min-height:calc(100vh - 17vh)
That gives decent result on my laptop, but not on a larger screen. So I've been trying to find the fonction or class that represents the navHeight, but I can't find a proper way to do it and nothing is working so far. I've tried stuff like :
min-height:calc(100vh - $headerHeight)
And so on... This is a shopify store and I have no knowledge in js, which may explain why I'm struggling. Here's some js code that revolves around the header, but nowhere can I find a way to remove the height of the header. Any idea or direction to give me ? Thanks.
JS code (not in proper order):
theme.headerNav = (function() {
var selectors = {
siteNav: '#SiteNav',
siteNavCompressed: '#SiteNavCompressed',
siteNavParent: '#SiteNavParent',
siteNavItem: '.site-nav__item',
stickyNavWrapper: '#StickNavWrapper',
stickyNav: '#StickyNav'
};
function init() {
sizeNav();
initMegaNavs();
initHeaderSearch();
$(window).on('resize.headernav', $.debounce(250, sizeNav));
}
window.Meganav = (function() {
var Meganav = function(options) {
this.cache = {
$document: $(document),
$page: $('.page-element')
};
var defaults = {
$meganavs: $('.meganav'),
$megaNav: $('.meganav__nav'),
$meganavToggle: $('.meganav-toggle'),
$meganavDropdownContainers: $('.site-nav__dropdown-container'),
$meganavToggleThirdLevel: $('.meganav__link-toggle'),
$meganavLinkSecondLevel: $('.meganav__link--second-level'),
$meganavLinkThirdLevel: $('.meganav__link--third-level'),
$meganavDropdownThirdLevel: $('.site-nav__dropdown--third-level'),
isOpen: false,
preventDuplicates: false,
closeOnPageClick: false,
closeThirdLevelOnBlur: false,
activeClass: 'meganav--active',
drawerClass: 'meganav--drawer',
meganavDropdown: '.site-nav__dropdown',
meganavLinkClass: 'meganav__link',
drawerToggleClass: 'drawer__nav-toggle-btn',
drawerNavItem: '.drawer__nav-item',
navCollectionClass: 'meganav__nav--collection',
secondLevelClass: 'meganav__link--second-level',
thirdLevelClass: 'meganav__link-toggle',
thirdLevelContainerClass: 'site-nav__dropdown--third-level',
noAnimationClass: 'meganav--no-animation'
};
theme.HeaderSection = (function() {
function Header() {
theme.stickyHeader.init();
theme.headerNav.init();
theme.Notify = new window.Notify();
theme.NavDrawer = new window.Drawers('NavDrawer', 'left');
drawerSearch();
}

jQuery panzoom fit and center

There's a fixed container that serves as the viewport to my content. The content is a <div> element of a fixed size. The viewport size is bound to the window and may change if the user resizes the window. I'm using the jQuery.panzoom library to handle panning and zooming to let the user view the parts of the content they want. Now I need the following features and can't find them:
The content must never be smaller than required to be completely visible within the viewport. This seems to be done with the minScale option. I just need to wire up the resize events to update the minscale value then.
The content must never be dragged out to one edge if there would be an empty space on the opposite edge. That means, if the content is small enough to be completely visible, it must be completely visible. This must be centered so that the content is always at the same position when zoomed out.
It's like a picture viewer that initially zooms the image to fit and centers it. The user can zoom in, but not zoom out further than the initial view. Only that my content is not an image but a more complex HTML element.
Here's what I've done so far:
<div id="room-wrapper" style="position: fixed; top: 0; left: 150px; right: 0; bottom: 0;">
<div id="room" style="width: 800px; height: 600px;">
Content here.
</div>
</div>
<script>
var roomWrapper = $("#room-wrapper");
// Set up options
var minScaleX = roomWrapper.innerWidth() / 800;
var minScaleY = roomWrapper.innerHeight() / 600;
var minScale = Math.min(minScaleX, minScaleY);
var panzoom = $("#room").panzoom({
startTransform: "scale(" + minScale + ")",
minScale: minScale,
//contain: "invert",
increment: 0.1
});
// Compensate strange offset, doesn't work
panzoom.panzoom("pan", 150, 0, {
animate: false,
silent: true
});
// Mouse wheel zooming
panzoom.parent().on("mousewheel.focal", function (e) {
e.preventDefault();
var delta = e.delta || e.originalEvent.wheelDelta;
var zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0;
panzoom.panzoom("zoom", zoomOut, {
animate: true,
focal: e
});
});
</script>
The content is initially zoomed correctly, but offset somewhere to the top and left. I have no idea where that offset comes from. Also, there's no panning contraint yet. The commented out contain may be related but I don't understand any of its documentation.
What do I need to fix in my code to make it meet the above requirements? I guess these are pretty basic and many people would need them but there's no example for that.

CesiumJS Rectangle Entity Overlap and Size Issue

My team and I are attempting to develop an application on Cesium that requires circle and rectangle points. We are using the native PointGraphics to make the circles, but are creating entities for the rectangles. The code is shown below:
var entity = {
id: point.id,
box: {
dimensions: new Cesium.Cartesian3(20000,
20000,
0),
outline: true,
material: Cesium.Color.fromHsl(hue, 1, 0.5)
},
position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat)
};
We are getting the boxes to draw but with some issues. First, when two boxes overlap, the graphic distorts as shown below:
I'm not sure if it's a code or browser issue. This screenshot is from Chrome, but we have tried it on Chrome and Firefox on two different machines.
Second, there is no automated zoom scaling. When we zoom out, the boxes stay the absolute size instead of relative to the zoom number like the PointGraphics. Compare the example below to the image above:
We may try multiplying the dimensions (not sure what unit they are in) by the zoom level as soon as we figure out how to get the zoom from Cesium, but I'm not sure if that will work since the entity creation may be static?
As a side note, we are using an angular version of Cesium, but I don't think that will prevent us from implementing a solution even if it's solved in regular JS.
The artifacts you're seeing are called "z-fighting", which is a common problem in 3D rendering when multiple polygons are rendered at the same depth and the depth buffer can't distinguish them.
But let's try a different approach: If you want these boxes to stay the same size regardless of zoom level, then you should probably switch to using Billboards to render the boxes. This will fix the z-fighting artifacts in the process. Run this code snippet and see if it's closer to your desired result.
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationHelpButton: false, animation: false, timeline: false
});
var boxImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wwDFRU4/aN5pAAAACNJREFUKM9jYCARMDIwMPz//59Y1YyMTKTaMKphVAO1NJAMALu5AxxK3JB5AAAAAElFTkSuQmCC';
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
billboard : {
image : boxImage,
color : Cesium.Color.LIME
}
});
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-75.2, 39.8),
billboard : {
image : boxImage,
color : new Cesium.Color(0, 0.5, 1.0, 1.0)
}
});
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-70.0, 41.0),
billboard : {
image : boxImage,
color : new Cesium.Color(0.5, 0.9, 1.0, 1.0)
}
});
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-73.0, 37.0),
billboard : {
image : boxImage,
color : Cesium.Color.RED
}
});
viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-89.0, 35.0),
billboard : {
image : boxImage,
color : Cesium.Color.YELLOW,
scale : 2.0
}
});
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
font-family: sans-serif;
}
<link href="http://cesiumjs.org/releases/1.15/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.15/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>

How to get a JS function to execute itself

I have a background image (width = 2000px, height = 400px) sitting behind a div with width and height equal to 400px. My image is split into 5 blocks, all with width and height equal to 400px. I want my image to shift by 400px each time the function is called to emulate a GIF image.
var imageWidth = $("#imageScroll").width();
console.log(imageWidth);
var timer = setInterval(function(){ shiftImage() }, 250);
function shiftImage(){
$("#imageScroll").mouseover (function(){
$("#imageScroll").css({"background-position-x": (imageWidth)});
});
};
});
This is my jQuery code, and I have tried and failed on a lot of different code. imageScroll is the ID of the div that I want the image to be pushed through.
you have to define css of the image so that it repeats itself on the x-axis.
<style>
#imageScroll{
height: 400px;
width: 500px;
background-image: url('./background.jpg');
background-repeat: repeat-x;
}
</style>
then, at the bottom of the page, or in body onload, you should execute the following instructions.
intervalFunc = setInterval(shiftImage, 250);
function shiftImage(){
var currentBackgroundX = $('#imageScroll').css('background-position-x');
split = currentBackgroundX.split("%");
currentBackgroundX = split[0];
currentBackgroundX = parseInt(currentBackgroundX);
$('#imageScroll').css({"background-position-x": (currentBackgroundX + 25) + '%'});
}
I didn't give too much though about the positioning part actually, since that is a completely different subject. But what i'm trying to do here is, change the background-position-x by 25% every 250 miliseconds. You can change the inner workings of the shiftImage function.
If you want to stop the animation at any point, just run
clearInterval(intervalFunc);
Hope this helps
Edit: jsFiddle
Edit 2: edited fiddle link
Edit 3: edited fiddle link

Creating masks across browsers

I see that there are ways to do this in webkit browsers, but I don't see ways to do it in others. Is this simply a feature that hasn't been implemented in all the browsers?
I don't have standard images, so clip won't work. I may have to render everything ahead of time, which will make my work exponential, but you deal with what you have, right?
I'd also want to be able to activate this stuff from javascript. :/
Thanks if you can provide support.
Just off the top of my head - and without an actual problem from you for us to solve - here's a possible way to accomplish what you want...
HTML
<div class="myImage">
<img src="path_to_image" title="Lorem ipsum" alt="Dolar sit amet" />
<div class="myMask">
</div><!-- /myMask -->
</div><!-- /myImage -->
CSS
.myImage {
position: relative;
}
.myMask {
position:absolute;
top: 0;
left: 0;
background-color: transparent;
background-image: url('path_to_masking_image');
}
Alternatively, use an <img /> inside the myMask div, and remove the background-image property from the CSS.
The way it's currently laid out, you would need two images: the image itself in all its glory, and the mask.
The way you would accomplish the 'masking effect' is to have the mask image be a static solid color that matches background of the container its in - ie white, black, whatever.
Kapeesh? This would work in all browsers, which is what you asked for. The background-clip property has -webkit and -moz selectors, but is not supported in browsers like IE or (to my knowledge) Opera.
Here are my 2 cents, if it is indeed CSS Sprites you are after.
<head>
<style type="text/css"><!--
#imagemask {
background-image: url(image.png);
background-repeat: no-repeat;
background-color: transparent;
height: 40px;
width: 40px;
}
.mask1 { background-position: top left; }
.mask2 { background-position: 0 40px; }
.mask3 { background-position: 0 80px; }/* And so on, however your image file is 'layed out' */
--></style>
<script type="text/javascript">
function mask1(){ document.getElementById("imagemask").setAttribute("class", "mask1"); }
function mask2(){ document.getElementById("imagemask").setAttribute("class", "mask1"); }
function mask3(){ document.getElementById("imagemask").setAttribute("class", "mask1"); }
</script>
</head>
<body>
mask 1
mask 2
mask 3
<div id="imagemask" class="mask1"></div>
</body>
We define the div#imagemask to contain 1 image file as a background and set it to not repeat around, as that would sort of defy the point.
We define how to "move around" the image inside the "mask" (div) with fixed width and height.
As a reference, I've then added the javascript you need to switch between the masks on the fly. I wrote that in about 10 seconds, you could probably write something a little more elegant if you want.
Add the links with onclick= events
Finally, add the div#imagemask to the body.
Given that I don't know the width or height of your image file or it's target masking, you'll have to do some substantial edits to this code. But you get the idea :)
I'm just going to skip the CSS variant in favor of this:
Example of a working mask: http://gumonshoe.net/NewCard/MaskTest.html
I acquired a javascript class from another website tutorial:
http://gumonshoe.net/js/canvasMask.js
It reads the image data and applies the alpha pixels from the mask to the target image:
function applyCanvasMask(image, mask, width, height, asBase64) {
// check we have Canvas, and return the unmasked image if not
if (!document.createElement('canvas').getContext) return image;
var bufferCanvas = document.createElement('canvas'),
buffer = bufferCanvas.getContext('2d'),
outputCanvas = document.createElement('canvas'),
output = outputCanvas.getContext('2d'),
contents = null,
imageData = null,
alphaData = null;
// set sizes to ensure all pixels are drawn to Canvas
bufferCanvas.width = width;
bufferCanvas.height = height * 2;
outputCanvas.width = width;
outputCanvas.height = height;
// draw the base image
buffer.drawImage(image, 0, 0);
// draw the mask directly below
buffer.drawImage(mask, 0, height);
// grab the pixel data for base image
contents = buffer.getImageData(0, 0, width, height);
// store pixel data array seperately so we can manipulate
imageData = contents.data;
// store mask data
alphaData = buffer.getImageData(0, height, width, height).data;
// loop through alpha mask and apply alpha values to base image
for (var i = 3, len = imageData.length; i < len; i = i + 4) {
imageData[i] = alphaData[i];
}
// return the pixel data with alpha values applied
if (asBase64) {
output.clearRect(0, 0, width, height);
output.putImageData(contents, 0, 0);
return outputCanvas.toDataURL();
}
else {
return contents;
}
}

Categories