Not getting the src of the image in sencha image gallery - image-gallery

Hi i am working on an image gallery project in Sencha Touch 2 whereby when i click an image it should show up the image in the gallery carousel.
But the problem i am facing here is that when i click on the image the carousal shows but it doesn't get the src of the image i tried many things regarding it but nothing is working on i am posting the code below
Ext.define('ImageViewer.view.Gallery', {
extend: 'Ext.Container',
xtype: 'gallery',
config:{
xtype: 'container',
scrollable: 'vertical',
floatingCloseBtn : true,
style: 'margin: auto !important; text-align: center;',
defaults: {
style: "float: left; margin: 10px; box-shadow: "+
"#999 0px 0px 6px 2px; border: 1px solid #888; "+
"overflow: hidden;",
height: 170,
width: 110
},
items: [
{
html: '<img class="image-wrap" src="http://content6.flixster.com/movie/11/13/43/11134356_pro.jpg" />'
},{
html: '<img class="image-wrap" src="http://content9.flixster.com/movie/11/16/11/11161107_pro.jpg" />'
},{
html: '<img class="image-wrap" src="http://content8.flixster.com/movie/11/16/10/11161098_pro.jpg" />'
},{
html: '<img class="image-wrap" src="http://content9.flixster.com/movie/11/15/90/11159075_pro.jpg" />'
}]
},
initialize : function(){
var me = this;
// Add tap event on the images to open the carousel
me.element.on('tap', function(e, el){
me.showGalleryCarousel(el);
}, me, {
delegate : 'img'
});
//me.loadImages();
//me.callParent(arguments);
},
/**
* Show the gallery carousel with all the images
*/
showGalleryCarousel : function(clickedImage){
var me = this,
clickedImgIndex = 0,
// Create the Gallery Carousel
galleryCarousel = Ext.Viewport.add({
xtype : 'gallerycarousel',
totalCount : me.items.length
});
// Query all the images and save in an array
me.images = me.images || me.element.query('img');
// On clicking close icon, hide the carousel
// and destroy it after a certain perdiod
galleryCarousel.element.on('tap', function(e, el){
galleryCarousel.hide(true);
Ext.defer(function(){
Ext.Viewport.remove(galleryCarousel);
}, 300);
}, this, {
delegate : 'div[data-action="close_carousel"]'
});
// Get the image index which is clicked
while( (clickedImage = clickedImage.previousSibling) != null ) {
clickedImgIndex++;
}
// Add the images as separate containers in the carousel
for(var i=0; i<me.images.length; i++){
galleryCarousel.add({
xtype : 'container',
html : '<img class="gallery-item" src=""' + Ext.get(me.images[i]).getAttribute('data-fullimage') + '" />',
index : i + 1
});
}
// Set the clicked image container as the active item of the carousel
galleryCarousel.setActiveItem(clickedImgIndex);
// Show the carousel
galleryCarousel.show();
}
});
I have the GalleryCarousal.js file which i have not included here
the problem that i am getting is that the src is not being able to get the path of the image links of the items html in the for loop section's src "" i.e
html : '<img class="gallery-item" src=""' + Ext.get(me.images[i]).getAttribute('data-fullimage') + '" />',
in the image viewer i want the same src to be called when i tap an image

Why are you using HTML's img tag instead of image xtype in Sencha? Sencha component will give you easy way to handle tap event on images and getting image related data like src using this image object in handler.

Related

Empty Div Preventing Interaction with amCharts5 MapChart on Vue3

I decided to dip my toes in Vue and have had an idea for a website for a while which I'd like to use amCharts5 for.
I had some issues initially as all the info I could find was related to Vue2, but I think I've somewhat wrapped my head around Vue3 and its composition API.
The MapChart is created, however there is always a div slapped on top of it which prevent any interaction. If I delete this element via DevTools, the MapChart becomes interactive.
I've tried debugging this and commenting sections of the code out, regardless this div is always created. And I simply can't figure out if it's injected by Vue or if amCharts 5 is the culprit.
The highlighted element is the one I must delete for it to become interactive.
Here's how the component is setup;
<template>
<div class="testClass" ref="chartdiv">
</div>
</template>
<script setup lang="ts">
import * as am5 from "#amcharts/amcharts5";
import * as am5map from "#amcharts/amcharts5/map";
import am5geodata_worldLow from "#amcharts/amcharts5-geodata/worldLow";
import am5themes_Animated from '#amcharts/amcharts5/themes/Animated';
import { ref, onMounted, onUnmounted } from "vue";
const chartdiv = ref<HTMLElement | null>()
var root!: am5.Root;
onMounted(() => {
if (chartdiv.value) {
// Create the Root
var root = am5.Root.new(chartdiv.value);
// Setup the MapChart
var chart = root.container.children.push(
am5map.MapChart.new(root, {
panX: "rotateX",
panY: "rotateY",
projection: am5map.geoOrthographic(),
centerMapOnZoomOut: false
})
);
// Setup Animations
root.setThemes([
am5themes_Animated.new(root)
]);
// Create MapPolygons
var polygonSeries = chart.series.push(
am5map.MapPolygonSeries.new(root, {
geoJSON: am5geodata_worldLow
})
);
// Setup MapPolygon Styling
polygonSeries.mapPolygons.template.setAll({
tooltipText: "{name}",
fill: am5.color("#909090")
});
// Setup MapPolygon Hover Styling
polygonSeries.mapPolygons.template.states.create("hover", {
fill: am5.color("#FF0000"),
stroke: am5.color("#00FF00"),
strokeWidth: 2
});
polygonSeries.mapPolygons.template.events.on("click", function(event) {
//console.log("Clicked: {0}", event.target);
});
// Setup Background
var backgroundSeries = chart.series.unshift(
am5map.MapPolygonSeries.new(root, {})
);
backgroundSeries.mapPolygons.template.setAll({
fill: am5.color(0x2c84d0),
stroke: am5.color(0x2c84d0)
});
backgroundSeries.data.push({
geometry: am5map.getGeoRectangle(90, 180, -90, -180)
});
}
});
onUnmounted(() => {
if (root) {
root.dispose();
}
});
</script>
<style scoped>
.testClass {
width: 50vw;
height: 50vh;
}
</style>
When you create a Vite-powered Vue project, it automatically creates a bunch of CSS files for you. One of those is base.css.
Inside this file, you'll find these lines which causes all the headache;
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
position: relative;
font-weight: normal;
}
Removing those lines will fix the issue.

Phaser 3: Spritesheet doesn't load correctly

I tried to add a spritesheet to my Phaser game the same way I've done it a few times before, however this time it seems to not load the images correctly, causing it to display a black & green square instead and causing it to throw an error when trying to play an animation.
Can anyone tell what is causing this issue?
(Warning: Playing the Code here seems to freeze up your browser for a few seconds, alternatively view on JSFiddle: https://jsfiddle.net/cak3goru/4/ )
// Configs and Constants
const gameState = {
gameWidth: 800,
gameHeight: 800,
textStyle: {
fontFamily: "'Comic Sans MS'",
fill: "#fff",
align: "center",
boundsAlignH: "left",
boundsAlignV: "top"
},
mouseDown: false,
menu: {
options: [
"Feed", "Clean", "Play"
],
barColor: "0x123456",
items: [],
itemText: [],
itemColor: "0x654321",
}
};
function preload() {
// Clean Tools
this.load.atlas('clean', 'https://gaylie.neocities.org/game/assets/clean.png', 'https://gaylie.neocities.org/game/assets/clean.json');
}
function create () {
this.anims.create({
key: "shower_cursor",
framerate: 12,
frames: this.anims.generateFrameNumbers("clean", {
prefix: "showerhead_000",
start: 0,
end: 7}),
repeat: -1
});
gameState.shower_cursor = this.add.sprite(400,400,'shower_cursor');
console.log(gameState.shower_cursor.frame);
//gameState.shower_cursor.playAfterDelay('shower_cursor', 100);
//gameState.shower_cursor.alpha = 0;
}
var config = {
backgroundColor: "0xf0f0f0",
scale: {
width: gameState.gameWidth,
height: gameState.gameHeight,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: {
preload, create
}
};
var game = new Phaser.Game(config);
<head>
<title>Pet Simulator</title>
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.min.js"></script>
</head>
<body style="height: 100%; width: 100%; margin: 0;">
</body>
The problem is, that you are using the wrong function, you should use this.anims.generateFrameNames, and not this.anims.generateFrameNumbers.
And set the correct key clean for the sprite.
the line should be:
gameState.shower_cursor = this.add.sprite(200, 100, 'clean');
because shower_cursor, is only the key of the animation, not the key of the sprite.
P.s.: the posted code doesn't run on jsfiddler or Stackoverflow due to CORS-Error, but if all assets are on the same server, it should not be a problem.

What's the real meaning of randomize=false using cose-bilkent layout

What the real meaning of randomize=false using cose-bilkent layout ?
I can only read such a simple comment to describe this feature in this extension wiki page.
// Whether to enable incremental mode
randomize: true,
I also find another description for randomize in cytoscape.js-expand-collapse wiki page.
// recommended usage: use cose-bilkent layout with randomize: false to preserve mental map upon expand/collapse
So I have learned that randomize: false is to preserve mental map. But what is the real behavior ?
Suppose that I have run a topology graph using cose-bilkent layout, then call the following snippet to append new nodes and edges to the graph with randomize: false. What will be the expected result on incremental mode ? Should the old nodes and edges keep the relative position as so called mental map , while new nodes and edges should be positioned to a resonable coordinate?
var demoId = 10000;
document.getElementById("append").addEventListener("click", function() {
var tid = cy.nodes()[Math.floor(Math.random()*cy.nodes().length)].data().id;
var sid = ++demoId;
var data = {
nodes : [
{data:{"id":"id"+source, "name":"name"+source}}
],
edges :[
{data:{"id":"id"+source+"-"+target, "source":"id"+source, "target":target}}
]
};
cy.add(data);
cy.layout({
name: 'cose-bilkent',
animate: false,
randomize : false,
fit : false
}).run();
});
See my demo. My test result is that all nodes and edges will be relayout. You could watch some nodes and their neighborhood. The neighborhood will be changed after each layout. I can't get a clear mental map. So could the experts explain how incremental layout task effect here.
document.addEventListener("DOMContentLoaded", function() {
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
ready: function() {
this.layout({
name: "cose-bilkent",
animationDuration: 1000
}).run();
},
style: [{
selector: "node",
style: {
'content': 'data(id)',
'text-valign': 'center',
'text-halign': 'center',
'background-color': 'blue',
'color':'red',
'width':'10px',
'height':'10px'
}
},
{
selector: ":parent",
style: {
"background-opacity": 0.333
}
},
{
selector: "edge",
style: {
width: 3,
"line-color": "#ad1a66"
}
}
],
elements: [{"group":"nodes","data":{"id":"p_1","parent":"n_72"}},{"group":"nodes","data":{"id":"p_298","parent":"n_72"}},{"group":"nodes","data":{"id":"p_4","parent":"n_72"}},{"group":"nodes","data":{"id":"p_5","parent":"n_72"}},{"group":"nodes","data":{"id":"p_9","parent":"n_72"}},{"group":"nodes","data":{"id":"p_32","parent":"n_72"}},{"group":"nodes","data":{"id":"p_607","parent":"n_72"}},{"group":"nodes","data":{"id":"p_57","parent":"n_72"}},{"group":"nodes","data":{"id":"p_242","parent":"n_72"}},{"group":"nodes","data":{"id":"p_64","parent":"n_72"}},{"group":"nodes","data":{"id":"p_77","parent":"n_72"}},{"group":"nodes","data":{"id":"p_81","parent":"n_72"}},{"group":"nodes","data":{"id":"p_82","parent":"n_72"}},{"group":"nodes","data":{"id":"p_289","parent":"n_72"}},{"group":"nodes","data":{"id":"p_803","parent":"n_72"}},{"group":"nodes","data":{"id":"n_0"}},{"group":"nodes","data":{"id":"n_72"}},{"group":"edges","data":{"source":"n_0","target":"n_0","id":"n_0-n_0"}},{"group":"edges","data":{"source":"n_0","target":"p_81","id":"n_0-p_81"}},{"group":"edges","data":{"source":"n_0","target":"p_4","id":"n_0-p_4"}},{"group":"edges","data":{"source":"n_0","target":"p_298","id":"n_0-p_298"}},{"group":"edges","data":{"source":"n_0","target":"p_803","id":"n_0-p_803"}},{"group":"edges","data":{"source":"n_0","target":"p_607","id":"n_0-p_607"}},{"group":"edges","data":{"source":"n_0","target":"p_1","id":"n_0-p_1"}},{"group":"edges","data":{"source":"n_0","target":"p_289","id":"n_0-p_289"}},{"group":"edges","data":{"source":"n_0","target":"p_57","id":"n_0-p_57"}},{"group":"edges","data":{"source":"n_0","target":"p_82","id":"n_0-p_82"}},{"group":"edges","data":{"source":"n_0","target":"p_32","id":"n_0-p_32"}},{"group":"edges","data":{"source":"p_77","target":"n_0","id":"p_77-n_0"}},{"group":"edges","data":{"source":"p_64","target":"n_0","id":"p_64-n_0"}},{"group":"edges","data":{"source":"p_607","target":"n_0","id":"p_607-n_0"}},{"group":"edges","data":{"source":"p_5","target":"n_0","id":"p_5-n_0"}},{"group":"edges","data":{"source":"p_9","target":"n_0","id":"p_9-n_0"}},{"group":"edges","data":{"source":"p_9","target":"p_803","id":"p_9-p_803"}},{"group":"edges","data":{"source":"p_242","target":"n_0","id":"p_242-n_0"}}],
}));
var demoId = 10000;
document.getElementById("append").addEventListener("click", function() {
var tid = cy.nodes()[Math.floor(Math.random()*cy.nodes().length)].data().id;
var sid = ++demoId;
var data = {
nodes : [
{data:{"id":sid}}
],
edges :[
{data:{"id":sid+"-"+tid, "source":sid, "target":tid}}
]
};
cy.add(data);
cy.layout({
name: 'cose-bilkent',
animate: false,
randomize : false,
fit : true
}).run();
});
});
body {
font-family: helvetica;
font-size: 14px;
}
#cy {
height: 100%;
width: 90%;
position: absolute;
}
h1 {
opacity: 0.5;
font-size: 1em;
}
button {
margin-right: 10px;
}
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<!--polyfills are needed for this extension for old browsers like IE -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/shim.min.js"></script>
<script src="https://unpkg.com/layout-base/layout-base.js"></script>
<script src="https://unpkg.com/cose-base/cose-base.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-cose-bilkent#4.1.0/cytoscape-cose-bilkent.min.js"></script>
<body>
<button id="append" class="button">Append</button>
<div id="cy"></div>
</body>

KnockoutJS: components binding, working with objects as data type

I'm new to Knockout JS and I find this library very powerful, but quite hard to understand sometimes. The documentation is hudge, but it's always (too) small code snippets, so it's difficult to have the big picture, unless your coding style & philosophy paradigm are the same as KO developers.
I come from angular world, and I'm used to have an array where each item is an object with properties (id, name, etc). When I click a button, I "send" this object to a new component that will render it in a form.
I'm sure I'm missing something obvious, but I don't understand how to make things work, even with plugins like ko.mapping and ko.postbox.
Does anyone can help me to find the solution? In the working code above, I've posted my 3 very specific questions in the javascript area.
EDIT: I answered to them, but I don't know if it's a best practice or not.
var
// User class to give to each property the observable capacity
User = function (rawData) {
var self = this,
data = rawData || {};
self.id = ko.observable(data.id);
self.name = ko.observable(data.name);
},
// List component. initially in a separate file
// (small modifs so all can be in the same file for this demo)
cmplist = {
viewModel: function () {
var self = this;
self.users = ko.observableArray([
new User({id: 1, name: 'John'}),
new User({id: 2, name: 'Jack'}),
new User({id: 3, name: 'Smith'})
]);
// #ANSWER 1: initialize postbox event
self.user = ko.observable(new User()).publishOn('userEdit');
self.showEdit = function (user) {
// #QUESTION 1: how do I send this object to the
// users-form component. ko.postbox?
// #ANSWER 1: change the observable
self.user(user);
console.log('show', user);
};
},
template: ''
+ '<ul data-bind="foreach: users">'
+ '<li>'
+ '<button data-bind="click: $parent.showEdit">Edit</button>'
+ ' <span data-bind="text: name"></span>'
+ '</li>'
+ '</ul>'
},
// Form component, initially in a separate file
// (small modifs so all can be in the same file for this demo)
cmpform = {
viewModel: function () {
var self = this;
// #QUESTION 2: how do I recept the object sent by the
// list?
// #ANSWER 2: make the observable subscribe to event
self.user = ko.observable(new User()).subscribeTo('userEdit');
self.save = function () {
// #QUESTION 3: how do I notify the users-list cmp
// that object has changed? ko.postbox?
window.alert('save ' + ko.toJSON(self.user()));
console.log('save');
};
},
// #ANSWER 2: call user() with parenthesis to access properties
template: ''
+ '<form>'
+ '<p>Edit user <span data-bind="text: user().name"></span> '
+ 'with id <span data-bind="text: user().id"></span></p>'
+ '<input data-bind="textInput: user().name" />'
+ '<button data-bind="click: save">Save</button>'
+ '</form>'
};
// KO bootstrap, initially in a 3rd file
// (small modifs so all can be in the same file for this demo)
ko.components.register('users-list', cmplist);
ko.components.register('users-form', cmpform);
ko.applyBindings({});
ul {
border: 1px solid blue;
list-style: none;
float: left;
}
li {
border: 1px solid green;
}
form {
border: 1px solid red;
float: right;
margin-top: 20px;
}
ul, li, form {
padding: 5px;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-postbox/0.5.2/knockout-postbox.min.js"></script>
</head>
<body>
<users-list></users-list>
<users-form></users-form>
</body>
</html>

Prevent Fancybox text from wrapping

I'm using Fancybox 2.1.3 to display some text when the page loads. The problem is that it's wrapping it onto two lines when I want it to all be on one line. I've tried the width, autoSize, and fitToView properties, and none of them are doing anything.
I'd prefer not to modify the fancybox css files, since I'm also using fancybox to display some images, and those are working properly.
Javascript
<script type='text/javascript'>
$(document).ready(function(){
// Activate fancyBox
$('.text').fancybox({
padding : 0,
closeBtn : false,
topRatio : 0.75,
helpers : {
overlay: {
css: {'background' : 'rgba(0, 0, 0, 0.0)'}
} // overlay
} // helpers
});
// Launch fancyBox on first element
$('.text').eq(0).trigger('click');
// Close automatically
setTimeout('parent.$.fancybox.close();', 10000);
});
HTML
<a href='#textid' class='text'></a>
<div style='display: none'>
<div id='textid'>The display text goes here.</div>
</div>
CSS
#textid
{
font-size: 40px;
color: red;
}
#textid {
font-size: 40px;
color: red;
white-space: nowrap;
}

Resources