mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 02:10:08 +00:00
sorking on virtual blocks...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
6bb4232086
commit
12c5ac8693
@ -524,8 +524,6 @@ body {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* DEBUG stuff... */
|
||||
.container-center {
|
||||
position: absolute;
|
||||
|
||||
@ -695,8 +695,10 @@ stretching in width... */
|
||||
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
|
||||
text-shadow: black 0.1em 0.1em 0.4em, black 0.1em 0.1em;
|
||||
/* XXX do we need this???
|
||||
text-shadow:
|
||||
black 0.1em 0.1em 0.4em,
|
||||
black 0.1em 0.1em; */
|
||||
|
||||
/* NOTE: we can't set the bg color here because it will get
|
||||
affected by filters... */
|
||||
@ -705,6 +707,28 @@ stretching in width... */
|
||||
border: solid @image-border transparent;
|
||||
}
|
||||
|
||||
.image {
|
||||
padding: @single-image-indicator-size;
|
||||
}
|
||||
.image div {
|
||||
display: block;
|
||||
position: absolute;
|
||||
|
||||
max-width: @image-tile-size;
|
||||
width: auto;
|
||||
max-height: @image-tile-size;
|
||||
height: auto;
|
||||
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
/*font-size: 2vh;*/
|
||||
}
|
||||
|
||||
.crisp-resize .image {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
@ -2042,7 +2066,10 @@ progress:not(value)::-webkit-progress-bar {
|
||||
/* XXX this is by no means final... */
|
||||
/*@import "theme-light";*/
|
||||
|
||||
.viewer,
|
||||
.light.single-image-mode.viewer .image,
|
||||
.light.transparent-ribbon.viewer .image {
|
||||
color: black;
|
||||
}
|
||||
.light.viewer,
|
||||
.light.viewer .overlay-block .background {
|
||||
background: white;
|
||||
|
||||
@ -48,6 +48,9 @@ require('features/external-editor')
|
||||
require('features/metadata')
|
||||
require('features/meta')
|
||||
|
||||
// XXX EXPERIMENTAL...
|
||||
require('features/virtual-images')
|
||||
|
||||
require('features/experimental')
|
||||
require('features/tests')
|
||||
require('features/demo')
|
||||
|
||||
@ -122,71 +122,6 @@ var ExperimentActions = actions.Actions({
|
||||
function(){
|
||||
}],
|
||||
|
||||
|
||||
|
||||
// construction of new "virtual images"...
|
||||
//
|
||||
// XXX should this be restricted to collections???
|
||||
// XXX should these be importable???
|
||||
// i.e. exported as json to <title>.virt and imported back...
|
||||
// ...might be a good idea to add custom import/export handlers...
|
||||
//
|
||||
// XXX do better arg processing -- handle metadata correctly...
|
||||
// XXX add export support for this type of stuff...
|
||||
// XXX add default named templates...
|
||||
// XXX add svg templates...
|
||||
// - blank (white/black/gray/...)
|
||||
// - title
|
||||
// - text
|
||||
// XXX move to 'virtual-images' feature...
|
||||
makeVirtualImage: ['Experimental/',
|
||||
function(ref, offset, metadata){
|
||||
ref = ref || 'current'
|
||||
offset = offset || 'after'
|
||||
offset = offset == 'after' ?
|
||||
1
|
||||
: offset == 'before' ?
|
||||
0
|
||||
: typeof(offset) == typeof(123) ?
|
||||
offset
|
||||
: 0
|
||||
// XXX revise...
|
||||
metadata = arguments[arguments.length-1] instanceof Object ?
|
||||
arguments[arguments.length-1]
|
||||
: null
|
||||
|
||||
var data = this.data
|
||||
|
||||
ref = data.getImage(ref)
|
||||
var r = data.getRibbon(ref)
|
||||
|
||||
var gid = data.newGID()
|
||||
|
||||
// place image into data...
|
||||
var order = data.order
|
||||
order.splice(order.indexOf(ref)+offset,0, gid)
|
||||
var ribbon = data.ribbons[r]
|
||||
ribbon.splice(ribbon.indexOf(ref)+offset,0, gid)
|
||||
|
||||
// update data...
|
||||
data.updateImagePositions()
|
||||
|
||||
// update metadata...
|
||||
metadata
|
||||
&& (this.images[gid] = metadata)
|
||||
|
||||
// focus new image...
|
||||
// NOTE: this should update the view too...
|
||||
this.focusImage(gid)
|
||||
}],
|
||||
// XXX
|
||||
makeVirtualBlank: ['Experimental/',
|
||||
function(){
|
||||
}],
|
||||
// XXX
|
||||
makeVirtualText: ['Experimental/',
|
||||
function(){
|
||||
}],
|
||||
})
|
||||
|
||||
var ExperimentFeature =
|
||||
|
||||
@ -163,6 +163,7 @@ core.ImageGridFeatures.Feature('imagegrid-testing', [
|
||||
'ui-preview-filters',
|
||||
'url-history',
|
||||
'external-editor',
|
||||
'virtual-images',
|
||||
|
||||
// experimental features...
|
||||
//'ui-range',
|
||||
|
||||
187
ui (gen4)/features/virtual-images.js
Normal file
187
ui (gen4)/features/virtual-images.js
Normal file
@ -0,0 +1,187 @@
|
||||
/**********************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
**********************************************************************/
|
||||
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
||||
(function(require){ var module={} // make module AMD/node compatible...
|
||||
/*********************************************************************/
|
||||
|
||||
var actions = require('lib/actions')
|
||||
var features = require('lib/features')
|
||||
|
||||
var core = require('features/core')
|
||||
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
// XXX revise menu placement...
|
||||
var VirtualImagesActions = actions.Actions({
|
||||
// construction of new "virtual images"...
|
||||
//
|
||||
// XXX should this be restricted to collections???
|
||||
// XXX should these be importable from fs???
|
||||
// i.e. exported as json to <title>.virt and imported back...
|
||||
// ...might be a good idea to add custom import/export handlers...
|
||||
//
|
||||
// XXX do better arg processing -- handle metadata correctly...
|
||||
// XXX add export support for this type of stuff...
|
||||
// XXX add default named templates...
|
||||
// XXX add svg templates???
|
||||
makeVirtualBlock: ['- Virtual/',
|
||||
function(ref, offset, metadata){
|
||||
ref = ref || 'current'
|
||||
offset = offset || 'after'
|
||||
offset = offset == 'after' ?
|
||||
1
|
||||
: offset == 'before' ?
|
||||
0
|
||||
: typeof(offset) == typeof(123) ?
|
||||
offset
|
||||
: 0
|
||||
// XXX revise...
|
||||
metadata = arguments[arguments.length-1] instanceof Object ?
|
||||
arguments[arguments.length-1]
|
||||
: null
|
||||
|
||||
var data = this.data
|
||||
|
||||
ref = data.getImage(ref)
|
||||
var r = data.getRibbon(ref)
|
||||
|
||||
var gid = data.newGID()
|
||||
|
||||
// place image into data...
|
||||
var order = data.order
|
||||
order.splice(order.indexOf(ref)+offset,0, gid)
|
||||
var ribbon = data.ribbons[r]
|
||||
ribbon.splice(ribbon.indexOf(ref)+offset,0, gid)
|
||||
|
||||
// update data...
|
||||
data.updateImagePositions()
|
||||
|
||||
// update metadata...
|
||||
metadata
|
||||
&& (this.images[gid] = metadata)
|
||||
|
||||
// focus new image...
|
||||
// NOTE: this should update the view too...
|
||||
this.focusImage(gid)
|
||||
}],
|
||||
|
||||
// XXX
|
||||
makeVirtualBlank: ['Virtual/Add blank after',
|
||||
core.doc``,
|
||||
//{ browseMode: function(){ return !this.collection && 'disabled' }, },
|
||||
function(ref, offset){
|
||||
this.makeVirtualBlock(ref, offset, {
|
||||
type: 'virtual',
|
||||
path: null,
|
||||
}) }],
|
||||
makeVirtualText: ['Virtual/Add text block after',
|
||||
core.doc`
|
||||
|
||||
NOTE: this was not designed for complex HTML, only use simple
|
||||
formatted text.`,
|
||||
//{ browseMode: function(){ return !this.collection && 'disabled' }, },
|
||||
function(text, ref, offset){
|
||||
this.makeVirtualBlock(ref, offset, {
|
||||
type: 'virtual',
|
||||
path: null,
|
||||
text: text || '',
|
||||
}) }],
|
||||
|
||||
// XXX virtual block editor UI...
|
||||
// XXX
|
||||
|
||||
|
||||
// XXX export...
|
||||
})
|
||||
|
||||
var VirtualImages =
|
||||
module.VirtualImages = core.ImageGridFeatures.Feature({
|
||||
title: '',
|
||||
doc: '',
|
||||
|
||||
tag: 'virtual-images',
|
||||
depends: [
|
||||
'edit',
|
||||
// XXX
|
||||
],
|
||||
suggested: [
|
||||
'ui-virtual-images',
|
||||
],
|
||||
|
||||
actions: VirtualImagesActions,
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
var VirtualImagesUIActions = actions.Actions({
|
||||
// XXX
|
||||
})
|
||||
|
||||
var VirtualImagesUI =
|
||||
module.VirtualImagesUI = core.ImageGridFeatures.Feature({
|
||||
title: '',
|
||||
doc: '',
|
||||
|
||||
tag: 'ui-virtual-images',
|
||||
depends: [
|
||||
'ui',
|
||||
'virtual-images'
|
||||
],
|
||||
|
||||
actions: VirtualImagesUIActions,
|
||||
|
||||
handlers: [
|
||||
['updateImage',
|
||||
function(res, gid, img){
|
||||
var image = this.images[gid] || {}
|
||||
|
||||
// set image content...
|
||||
if(image.type == 'virtual' && image.text){
|
||||
var text = document.createElement('div')
|
||||
text.innerHTML = image.text
|
||||
img[0].innerHTML = ''
|
||||
img[0].appendChild(text)
|
||||
|
||||
// threshold after which we try to fill the volume...
|
||||
var C = 100
|
||||
|
||||
// scale the text if it is small...
|
||||
var R = img[0].offsetHeight * 0.8
|
||||
var r = image.text.length > C ?
|
||||
Math.max(
|
||||
text.offsetWidth,
|
||||
text.offsetHeight,
|
||||
// keep large text blocks roughly square-ish...
|
||||
Math.sqrt(text.scrollHeight * text.scrollWidth))
|
||||
: Math.max(
|
||||
text.offsetWidth,
|
||||
text.offsetHeight,
|
||||
text.scrollHeight,
|
||||
text.scrollWidth)
|
||||
var s = R/r
|
||||
text.style.fontSize = `${ 100*s }%`
|
||||
// prioritize width...
|
||||
text.style.width = '100%'
|
||||
|
||||
// clear reused image content...
|
||||
} else if(img[0].innerHTML != ''){
|
||||
img[0].innerHTML = ''
|
||||
}
|
||||
}],
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* vim:set ts=4 sw=4 : */ return module })
|
||||
@ -495,6 +495,12 @@ module.ImagesPrototype = {
|
||||
//gid = gid == null ? getImageGID(): gid
|
||||
//size = size == null ? getVisibleImageSize('max') : size
|
||||
img_data = img_data == null ? this[gid] : img_data
|
||||
img_data = img_data || IMAGE_DATA
|
||||
|
||||
// if path is explicitly null there are no previews...
|
||||
if(img_data.path === null){
|
||||
return undefined
|
||||
}
|
||||
|
||||
// if no usable images are available use STUB data...
|
||||
if(!img_data
|
||||
|
||||
@ -1514,126 +1514,12 @@ var RibbonsPrototype = {
|
||||
// .correctImageProportionsForRotation(..)
|
||||
//
|
||||
// .updateImageIndicators(..)
|
||||
_updateImage: function(image, gid, size, sync){
|
||||
image = (image == '*' ? this.viewer.find(IMAGE)
|
||||
: image == null
|
||||
|| typeof(image) == typeof('str') ? this.getImage(image)
|
||||
: $(image))
|
||||
sync = sync == null ? this.load_img_sync : sync
|
||||
size = size == null ? this.getVisibleImageSize('max') : size
|
||||
|
||||
var that = this
|
||||
return $(image.map(function(){
|
||||
var image = this instanceof String
|
||||
|| typeof(this) == typeof('str')
|
||||
? that.getImage(this+'')
|
||||
: $(this)
|
||||
if(image.length == 0){
|
||||
return
|
||||
}
|
||||
var old_gid = that.elemGID(image)
|
||||
|
||||
// same image -- update...
|
||||
if(old_gid == gid || gid == null){
|
||||
var gid = old_gid
|
||||
|
||||
// reuse for different image -- reconstruct...
|
||||
} else {
|
||||
// remove old marks...
|
||||
if(typeof(old_gid) == typeof('str')){
|
||||
that.getImageMarks(old_gid).remove()
|
||||
}
|
||||
// reset gid...
|
||||
image
|
||||
.attr('gid', JSON.stringify(gid)
|
||||
// this removes the extra quots...
|
||||
.replace(/^"(.*)"$/g, '$1'))
|
||||
.css({
|
||||
// clear the old preview...
|
||||
'background-image': '',
|
||||
})
|
||||
}
|
||||
|
||||
// if no images data defined drop out...
|
||||
if(that.images == null){
|
||||
return image[0]
|
||||
}
|
||||
|
||||
// get the image data...
|
||||
var img_data = that.images[gid]
|
||||
if(img_data == null){
|
||||
img_data = images.IMAGE_DATA
|
||||
}
|
||||
|
||||
// if we are a group, get the cover...
|
||||
// NOTE: groups can be nested...
|
||||
var seen = []
|
||||
while(img_data.type == 'group'){
|
||||
// error, recursive group...
|
||||
if(seen.indexOf(img_data.id) >= 0){
|
||||
img_data = images.IMAGE_DATA
|
||||
console.error('Recursive group:', gid)
|
||||
break
|
||||
}
|
||||
seen.push(img_data.id)
|
||||
|
||||
img_data = that.images[img_data.cover]
|
||||
}
|
||||
|
||||
// image state...
|
||||
//that.rotateImage(image, img_data.orientation == null ? 0 : img_data.orientation)
|
||||
//that.flipImage(image, img_data.flipped == null ? [] : img_data.flipped)
|
||||
image.attr({
|
||||
orientation: img_data.orientation == null ? '' : img_data.orientation*1,
|
||||
flipped: (img_data.flipped == null ? [] : img_data.flipped).join(', '),
|
||||
})
|
||||
|
||||
// preview...
|
||||
var p_url = that.images.getBestPreview(img_data.id, size, img_data, true).url
|
||||
|
||||
// update the preview if it's a new image or...
|
||||
// XXX this should be pushed as far back as possible...
|
||||
if(old_gid != gid
|
||||
// the new preview (p_url) is different to current...
|
||||
// NOTE: this may not work correctly for relative urls...
|
||||
|| image.css('background-image').indexOf(util.path2url(p_url)) < 0){
|
||||
// sync load...
|
||||
if(sync){
|
||||
that._loadImagePreviewURL(image, p_url)
|
||||
|
||||
// async load...
|
||||
} else {
|
||||
// NOTE: storing the url in .data() makes the image load the
|
||||
// last requested preview and in a case when we manage to
|
||||
// call updateImage(...) on the same element multiple times
|
||||
// before the previews get loaded...
|
||||
// ...setting the data().loading is sync while loading an
|
||||
// image is not, and if several loads are done in sequence
|
||||
// there is no guarantee that they will happen in the same
|
||||
// order as requested...
|
||||
image.data().loading = p_url
|
||||
setTimeout(function(){
|
||||
that._loadImagePreviewURL(image, image.data().loading)
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: this only has effect on non-square image blocks...
|
||||
// XXX this needs the loaded image, thus should be done right
|
||||
// after preview loading...
|
||||
// XXX preview loading is async, is this the right
|
||||
// place for this??
|
||||
// ...this is also done in .rotateImage(..) above...
|
||||
that.correctImageProportionsForRotation(image)
|
||||
|
||||
// marks and other indicators...
|
||||
that.updateImageIndicators(gid, image)
|
||||
|
||||
return image[0]
|
||||
}))
|
||||
},
|
||||
//
|
||||
// XXX add options for images to preload and only then do the update...
|
||||
// XXX really slow for very large numbers of input images/gids...
|
||||
// XXX add support for basic image templating here...
|
||||
// ...templates for blank images, text blocks and other stuff,
|
||||
// this would best be done by simply filling in SVG templates...
|
||||
updateImage: function(image, gid, size, sync, callback){
|
||||
var that = this
|
||||
var imgs = this.viewer.find(IMAGE)
|
||||
@ -1729,8 +1615,13 @@ var RibbonsPrototype = {
|
||||
//will_change.push('transform')
|
||||
|
||||
// stage background image update...
|
||||
var p_url = that.images.getBestPreview(img_data.id, size, img_data, true).url
|
||||
if(old_gid != gid
|
||||
// XXX add support for basic templating here...
|
||||
var p_url = (that.images.getBestPreview(img_data.id, size, img_data, true) || {}).url
|
||||
// no preview -> reset bg...
|
||||
if(p_url == null){
|
||||
image[0].style.backgroundImage = ''
|
||||
|
||||
} else if(old_gid != gid
|
||||
// the new preview (p_url) is different to current...
|
||||
// NOTE: this may not work correctly for relative urls...
|
||||
|| image.css('background-image').indexOf(util.path2url(p_url)) < 0){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user