Positioning a div in js - javascript

Wonder if anyone could give me some guidance. I'm trying to reposition a div based on:
if fpd-actions-wrapper has a class of fpd-pos-outside then position in body.
else position (as below) in main wrapper.
//set action button to specific position
var _setActionButtons = function(pos) {
fpdInstance.$mainWrapper.append('<div class="fpd-actions-wrapper fpd-pos-'+pos+'"></div>');
var posActions = instance.currentActions[pos];
for(var i=0; i < posActions.length; ++i) {
var actionName = posActions[i],
$action = $actions.children('[data-action="'+actionName+'"]');
fpdInstance.$mainWrapper.children('.fpd-actions-wrapper.fpd-pos-'+pos).append($action.clone());
}
};
I've tried below and it does get .fpd-actions-wrapper out of the main wrapper but it's empty - can't work out the last line.
//set action button to specific position
var _setActionButtons = function(pos) {
$body = $('body');
$body.append('<div class="fpd-actions-wrapper fpd-pos-'+pos+'"></div>');
var posActions = instance.currentActions[pos];
for(var i=0; i < posActions.length; ++i) {
var actionName = posActions[i],
$action = $actions.children('[data-action="'+actionName+'"]');
fpdInstance.$mainWrapper.children('.fpd-actions-wrapper.fpd-pos-
'+pos).append($action.clone());
}
};

You need to add position:aboslute; top:10px; left:10px to you div tag. Only divisions with fixed or absolute positions can be moved pro-grammatically. You must define x (distance to left side) and y (distance to top of screen) motion independently. I only defined the 'top' position. You need to add a 'left' point of reference as well. It may not be a simple 'left:'+pos+'px;', so I did not add that code for you except in the div tag.Notice that the actual commands to change position are very much 'css' like. The div tag uses css syntax, so must your code.
//set action button to specific position
var _setActionButtons = function(pos) {
fpdInstance.$mainWrapper.append('<div class="fpd-actions-wrapper fpd-pos-'top:'+pos+'px; fpd-pos-'left:'+pos+'px;"></div>');
var posActions = instance.currentActions['top':+pos+"px;"];
for(var i=0; i < posActions.length; ++i) {
var actionName = posActions[i],
$action = $actions.children('[data-action="'+actionName+'"]');
fpdInstance.$mainWrapper.children('.fpd-actions-wrapper.fpd-pos-':'+pos'px;').append($action.clone());
}
};

Related

InDesign script, resize images after word import

Sometimes we have big images in word file and after importing this word file inside InDesign, the image goes inside the overflow text and the text flow stops at this point.
We couldn't resize these images or can't get hold of this image for applying any scripting logic.
Basically, I will search for figure parastyle, then check for rectangles inside the para, and do resize logic. Sample jsx code here:
app.findTextPreferences.appliedParagraphStyle= 'figure';
var founds = app.findText();
// find 92% text width area
var pageWidth = this.props.textAreaWidth * 92 /100;
for(var i=0, len=founds.length; i<len; i++){
// find the rectangles inside the para
var rect = founds[i].rectangles;
if(rect.length == 0) continue;
var vb = rect[0].visibleBounds;
var imgWidth = vb[3] - vb[1];
// image resize logic
if(imgWidth > pageWidth){
vb[3] = pageWidth;
rect[0].visibleBounds = vb;
rect[0].fit(FitOptions.PROPORTIONALLY);
rect[0].fit(FitOptions.FRAME_TO_CONTENT);
}
How to apply some logic to the images which are in the overflow text? how to resize the image which is in overflow text?
We can just import the below word file into any InDesign template
Sample word file
You could iterate through all the graphics and resize the big ones.
var images = app.activeDocument.allGraphics;
var max = {};
max.w = 100; // max width
max.h = 100; // max height
for (var i=0; i<images.length; i++) {
var gb = images[i].geometricBounds;
var size = {};
size.w = -gb[1] + gb[3];
size.h = -gb[0] + gb[2];
if (size.w > max.w || size.h > max.h) {
var scale = (size.w > size.h) ? max.w/size.w : max.h/size.h;
images[i].horizontalScale *= scale;
images[i].verticalScale *= scale;
images[i].parent.fit(FitOptions.FRAME_TO_CONTENT);
}
}

Why does .matchMedia not work in these certain conditions?

I am making a page that uses buttons to display the content when the creen is wider than 500px, and then it moves to an 'accordion' style layout when the screen is smaller than 500px.
I am using event listeners and match media along with an if/else statement to determine which code to run.
However, when the code is run with a window of size less than 500px, then dragged out to make it bigger than 500px, the buttons are not responding to the 'onclick' when pressed and nothing happens.
Could somebody please advise where I am going wrong here?
Please see JSfiddle here
//Start listing variables for use in array.
var art1 = document.getElementById("article1");
var button1 = document.getElementById("list1");
var art2 = document.getElementById("article2");
var button2 = document.getElementById("list2");
var art3 = document.getElementById("article3");
var button3 = document.getElementById("list3");
var articleArray = [art1, art2, art3];
var buttonArray = [button1, button2, button3];
function mediaQuery(x) {
//If window is under 500px in width.
if (x.matches) {
//Begin accordion code
var initAccordion = function(accordionElement) {
function handlePanelClick(event) {
showPanel(event.currentTarget);
}
function showPanel(panel) {
var expandedPanel = accordionElement.querySelector(".active");
if (expandedPanel) {
expandedPanel.classList.remove("active");
}
panel.classList.add("active");
}
var allPanelElements = accordionElement.querySelectorAll(".panel");
for (var y = 0; len = allPanelElements.length; y++ ) {
allPanelElements[y].addEventListener("click", handlePanelClick);
}
showPanel(allPanelElements[0]);
}
initAccordion(document.getElementById("contentWrapper"));
}
else //If window if is over 500px in width.
{
//Begin button code.
var createfunc = function (i) {
return function() { document.getElementById("fillMe").innerHTML = articleArray[i].innerHTML;};
}
for (let i=0; i < articleArray.length; i++) {
let button = buttonArray[i];
button.addEventListener("click", createfunc(i));
}
}
}
//Declare media query and add listener.
var x = window.matchMedia("(max-width: 500px)")
mediaQuery(x) // Call listener function at run time
x.addListener(mediaQuery) // Attach listener function on state changes

How to dynamically shift a DIV down based on predecessor

I've got a series of DIVs, all with the same class (.ms-acal-item). What I'm trying to do is get the position of each one, compare it to the one above it, and shift it down if needed. This is to correct an issue on a SharePoint 2013 calendar where event tiles are overlapping. Here's my code so far:
$(function() {
$('.ms-acal-item').each(function(i, obj) {
var tile = jQuery(this);
var prev = tile.prev();
var prevPos = prev.position();
var tilePOs = tile.position();
var curTop = parseInt(tilePos.top);
var newTop = parseInt(prevPos.top) + 30;
if(curtop !== newTop){
tile.css('top', newTop);
}
});
});
And here's an example of what the SharePoint-generated content looks like:
Each tile is 20px high and positioned absolutely in-line. What I need to do is compare the position of each tile to its predecessor and then move it down 30px if it isn't already there (20px for the tile and 10px between them). So far it's not working - my code seems to have no effect on the tile positions.
What am I doing wrong?
There is a problem in the logic, while processing the first element we do not have any previous element, so we need to ignore it and few typo(variable case issues) mistakes in your code. Below is the revamp code.(To see the changes effect i changed style from top to margin-left, correct it afterwards)
$(function() {
$('.ms-acal-item').each(function(i, obj) {
var tile = $(this);
var prev = tile.prev();
if (typeof prev.position() !== "undefined") {
var prevPos = JSON.parse(JSON.stringify(prev.position()));
var tilePos = JSON.parse(JSON.stringify(tile.position()));
var curTop = parseInt(tilePos.top);
var newTop = parseInt(prevPos.top) + 30;
if(curTop !== newTop){
tile.css('margin-left', newTop);
}
}
});
});

how to check whether crop div covers rotated image?

I want to check whether cropping div covers images in it.Everything works fine when image is not rotated but after rotating image crop does not shows error msg...
Here is fiddle : Fiddle
function isCropValid(){
var $selector = $("#resizeDiv"); // cropping Div
var $img = $("#rotateDiv"); // image div
var $selectorW = $selector.width();
var $selectorH = $selector.height();
var $selectorX = $selector.offset().left ;
var $selectorY = $selector.offset().top ;
var $imgW = $img.width();
var $imgH = $img.height();
var $imgX = $img.offset().left;
var $imgY = $img.offset().top;
var diff_X = $selectorX - $imgX;
var diff_Y = $selectorY - $imgY;
if(diff_X+$selectorW > $imgW){
return false;
} else if(diff_Y+$selectorH > $imgH){
return false;
} else if($selectorX<$imgX){
return false;
} else if($selectorY<$imgY){
return false;
}
else {
return true;
}
}
or another function
function isCropValid(){
var el1 = document.getElementById("resizeDiv"); // cropDiv
var el2 = document.getElementById("rotateDiv"); // imageDiv
var cropdiv = el1.getBoundingClientRect();
var imgdiv = el2.getBoundingClientRect();
return (
((imgdiv.top <= cropdiv.top) && (cropdiv.top <= imgdiv.bottom)) &&
((imgdiv.top <= cropdiv.bottom) && (cropdiv.bottom <= imgdiv.bottom)) &&
((imgdiv.left <= cropdiv.left) && (cropdiv.left <= imgdiv.right)) &&
((imgdiv.left <= cropdiv.right) && (cropdiv.right <= imgdiv.right))
);
}
I above code i have one image inside div.if crop div gets out of this div i m showing label bg color red meaning crop is not correct otherwise i m showing label color green means crop is correct..
I think what you'll have to do is to calculate the positions of each of the 4 points of the image top-left top-right bottom-right and bottom-left, then do the same thing for the crop div something like this:
var $topLeftX=$selectorX-($selectorW/2)-($selectorH/2);
var $topLeftY=$selectorY-($selectorH/2)-($selectorW/2);
var $bottomLeftX=$selectorX-($selectorW/2)+($selectorH/2);
var $bottomLeftY=$selectorY+($selectorH/2)-($selectorW/2);
var $topRightX=$selectorX+($selectorW/2)-($selectorH/2);
var $topRightY=$selectorY-($selectorH/2)+($selectorW/2);
var $bottomRightX=$selectorX+($selectorW/2)+($selectorH/2);
var $bottomRightY=$selectorY+($selectorH/2)+($selectorW/2);
Then compare the corner points.
now the issue is with the corners of the image, as after rotation this will need some sine/cosine calculations.
you might want to take a look at this post: Find the coordinates of the corners of a rotated object in fabricjs
I think it will make your life much easier
So this is gonna be a big hack, but hey :-) The idea is to put the cut out behind the image, and then see whether the image overlaps the cut out on all four corners.
function cutoutIsOK() {
// Grab the cutout element and position it behind the image
var cutout = document.querySelector('#resizeDiv');
cutout.style.zIndex = -1;
// Grab the image
var image = document.querySelector('#rotateDiv img');
// Take the four corners of the cutout element
var cutoutRect = cutout.getBoundingClientRect();
var pos = [
[cutoutRect.left, cutoutRect.top],
[cutoutRect.right - 1, cutoutRect.top],
[cutoutRect.left, cutoutRect.bottom - 1],
[cutoutRect.right - 1, cutoutRect.bottom - 1]
];
// And verify that the image overlaps all four corners
var ok = pos.every(function(p) {
return document.elementFromPoint(p[0], p[1]) === image;
});
// Reset the cutout's z-index to make it visible again
cutout.style.zIndex = 0;
return ok;
}

webGL story sphere popups

I am trying to adapt the really cool looking WebGL Story Sphere, source code and css here. There's one big problem: once you click on a news article, the text of the article in the popup is always the same. I want to modify the code so that when you click on an article, the right text appears in the popup.
I'm working from a set of article texts that I specify in the code, e.g. var captions = ["good","better","best"]. Though the article titles and images populate correctly in the popup, I can't get the text to do so. Can you help me?? Here's what I've got:
// function code
var passvar = null; // failed attempt to store texts for later
function initialize() {
math = tdl.math;
fast = tdl.fast;
canvas = document.getElementById("canvas");
g_fpsTimer = new tdl.fps.FPSTimer();
hack();
canvas.addEventListener("mousedown", handleMouseDown, false);
canvas.addEventListener("mousemove", handleMouseMove, false);
canvas.addEventListener("mouseup", handleMouseUp, false);
// Create a canvas 2d for making textures with text.
g_canvas2d = document.createElement('canvas');
window.two2w = window.two2h = g_tilesize;
g_canvas2d.width = two2w;
g_canvas2d.height = two2h;
g_ctx2d = g_canvas2d.getContext("2d");
window.gl = wu.create3DContext(canvas);
if (g_debug) {
gl = wd.makeDebugContext(gl, undefined, LogGLCall);
}
//gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, gl.TRUE);
// Here is where I specify article titles, images, captions
// Titles and images populate the popup correctly, captions don't...
var titles = ["a","b","c"];
var captions = ["good","better","best"];
var images = ['imagesphere/assets/1.jpg',
'imagesphere/assets/bp/2.png',
'imagesphere/assets/bp/3.png'
];
var headlines = titles.concat( titles);
var blurbs = captions.concat( captions);
var tmpImages = [];
var tmpHeadlines = [];
var tmpCaptions = [];
// make a bunch of textures.
for (var ii = 0; ii < g_imagesDownGrid; ++ii) {
var textures = [];
for (var jj = 0; jj < g_imagesAcrossGrid; ++jj) {
var imgTexture = new ImgTexture();
textures.push(imgTexture);
if (tmpImages.length == 0) {
tmpImages = images.slice();
}
if (tmpHeadlines.length == 0) {
tmpHeadlines = headlines.slice();
}
if (tmpCaptions.length == 0) {
tmpCaptions = blurbs.slice();
}
var rando = math.randomInt(tmpImages.length);
var img = tmpImages.splice(rando, 1)[0];
var headline = tmpHeadlines.splice(rando, 1)[0];
var caption = tmpCaptions.splice(rando, 1)[0];
passvar = caption;
if (img.indexOf('videoplay.jpg') > -1){
window.vidtexture = imgTexture;
images = images.slice(1); // dont use that thumb again.
headlines = 'WebGL Brings Video To the Party as Well'
}
imgTexture.load(img, /* "[" + jj + "/" + ii + "]" + */ headline);
}
g_textures.push(textures);
}
// And here's where I try to put this in a popup, finally
// But passvar, the stored article text, never refreshes!!!
<div id="story" class="prettybox" style="display:none">
<img class="close" src="imagesphere/assets/close.png">
<div id="storyinner">
<input id = "mytext">
<script>document.getElementById("mytext").value = passvar;</script>
</div>
</div>
And here is my click handler code:
function sphereClick(e){
window.console && console.log('click!', e, e.timeStamp);
var selected = g_textures[sel.y][sel.x];
window.selected = selected;
animateGL('eyeRadius', glProp('eyeRadius'), 4, 500);
var wwidth = $(window).width(),
wheight = $(window).height(),
story = $('#story').width( ~~(wwidth / 7 * 4) ).height( ~~(wheight / 6 * 5) ),
width = story.width(),
height = story.height(),
miniwidth = 30;
story.detach()
.find('#storyinner').find('h3,img,caption').remove().end().end()
.show();
story.css({
left : e.pageX,
top : e.pageY,
marginLeft : - width / 2,
marginTop : - height / 2
}).appendTo($body); // we remove and put back on the DOM to reset it to the correct position.
$('style.anim.story').remove();
$('<style class="anim story">')
.text( '.storyopen #story { left : ' + (wwidth / 3 * 2) + 'px !important; top : ' + wheight / 2 + 'px !important; }' )
.appendTo($body);
$(selected.img).prependTo('#storyinner').parent();
$('<h3>').text(selected.msg.replace(/\(.*/,'')).prependTo('#storyinner');
$body.addClass('storyopen');
} // eo sphereClick()
There's a lot wrong here, but here's a start. It won't solve your problem, but it will help you avoid issues like this.
var passvar = null; is a global variable.
Your loop for (var ii = 0; ... sets that global variable to a new value on every iteration.
Later, you click something and the global variable passvar is never changed.
If you want to use this pattern, you need to set passvar from your click handler so it has the value that was clicked. Since you didn't actually post your click handlers, it's hard to advise more.
But this is also a bad pattern, functions take arguments for a good reason. Since you have to find your clicked item in the click handler anyway, why not pass it directly which does involve a shared global variable at all?
var handleMouseUp = function(event) {
var story = findClickedThing(event);
if (obj) {
showPopup(story.texture, story.caption);
}
}
Which brings me to this:
var titles = ["a","b","c"];
var captions = ["good","better","best"];
var images = ['imagesphere/assets/1.jpg',
'imagesphere/assets/bp/2.png',
'imagesphere/assets/bp/3.png'
];
When you have 3 arrays, all of the same length, each array describing a different property of an object, you are doing it wrong. What you want, is one array of objects instead.
var stories = [
{
title: "a",
caption: "good",
image: "imagesphere/assets/1.jpg"
}, {
title: "b",
caption: "better",
image: "imagesphere/assets/bp/2.jpg"
}, {
title: "c",
caption: "best",
image: "imagesphere/assets/bp/3.jpg"
},
];
console.log(stories[1].caption); // "better"
Now once you find the clicked object, you can just ask it what it's caption is. And you can pass the whole object to the popup maker. And no field is handled differently or passed around in a different manner, because you are not passing around the fields. You are passsing the entire object.

Categories

Resources