Anchor and rotation for DOM marker - here-api

I can set the rotation to the css of the DOM marker in here map api. However, I can't set the anchor. That would lead to the origin of the spin deviate from the coordination of the marker. See the picture below:
How to resolve it?
The relevant code is like the following:
import { renderToStaticMarkup } from 'react-dom/server';
import { PositionToLatLng } from './utils';
export class DomMarker {
constructor(map, options) {
const { position, children, angle, ...others } = options;
this.marker = new H.map.DomMarker(PositionToLatLng(position), {
icon: new H.map.DomIcon(renderToStaticMarkup(
<div>
<div
style={{
transform: `rotate(${angle}deg)`,
cursor: 'pointer'
}}
>
{children}
</div>
</div>
)),
});
this.map = map;
this.map.addObject(this.marker);
}
remove() {
this.map.removeObject(this.marker);
}
}
It works with "renderToStaticMarkup". But it renders nothing if I use "renderToDiv".
import ReactDOM from 'react-dom';
export function renderToDiv(element) {
const content = document.createElement('div');
ReactDOM.render(element, content);
return content;
}
I print the return value of "renderToDiv", it looks like the following:

The anchor parameters only works for H.map.Icon. Use CSS styles to center an H.map.DomIcon.
Assuming your icon is 24px width and height:
<div style="left: -12px; top: -12px;">
// icon content
</div>

Related

Position one image over another on react in a specific location and animate

I Want to reply a behavior I saw on a page the map below the section "How It works" title (I wanted to embed a video but it seems stack overflow don't allow it) i.e place one image over another in a specific location, the page I linked shows a map and a pointer that points to the emirates but I can't figure how to do this I achieve this in React, by using position CSS property to position the second image (pointer) relative to the first image (map) and then use the top, left, right, and bottom properties to position the pointer on the desired location on the map but I am having problems with the animation, this is rendering when the parent is rendered and not when the page is scrolled down, I am using the IntersectionObserver
my code is the following:
import React from 'react';
import React, {useEffect, useRef, useState} from 'react';
function MapWithPointer() {
const mapRef = useRef(null);
const pointerRef = useRef(null);
const [isPointerVisible, setIsPointerVisible] = useState(false);
useEffect(() => {
if(!isPointerVisible) return;
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
setIsPointerVisible(true);
}
});
if(mapRef.current) observer.observe(mapRef.current);
return () => observer.disconnect();
}, [isPointerVisible, mapRef]);
return (
<div ref={mapRef} style={{ position: "relative" }}>
<img src="https://emiride.com/wp-content/uploads/2022/11/map-1024x594.png" alt="map" />
<img
ref={pointerRef}
src="https://emiride.com/wp-content/uploads/2022/11/piont.png"
alt="pointer"
width={'30wh'}
className={`pointer ${isPointerVisible ? "is-visible" : ""}`}
style={{ position: "absolute", top: "310px", left: "640px" }}
/>
</div>
);
}
css:
#keyframes pointer-animation {
from {
transform: translateY(1000%);
}
to {
transform: translateY(0);
}
}
.pointer {
animation: pointer-animation 1s ease-in-out;
transform: translateY(100%);
}
.pointer.is-visible {
transform: translateY(0);
animation: pointer-animation 1s ease-in-out;
}
and int the parent ins rendering like this:
<MapComponent/> , the parent does not have useEffect hook.
how can I achieve my purpose?

Nuxt 3 with Vuetify 3 and SSR reactivity

I am trying to use Nuxt 3 together with Vuetify 3 in SSR mode. I face a problem using display's breakpoints. What is more, this functionality works with Nuxt 2 and Vuetify 2.
The code below shows only div element with red background instead of green, although the screen size is large. The reason is that the initial DOM rendering, which happens on the server side, assumes that the screen's size is small. The hydration on the client side somehow doesn't take into account, that the real size is large, although you can see in the browser's web inspector a log information result green.
<template>
<div>
<div :class="divClass">Reactivity</div>
</div>
</template>
<script setup>
import { computed, ref } from 'vue'
import { useDisplay } from 'vuetify'
const counter = ref(1)
const { lgAndUp } = useDisplay()
const divClass = computed(() => {
const result = lgAndUp.value ? 'green' : 'red'
console.log('result', result)
return result
})
</script>
<style>
.green {
background-color: green;
}
.red {
background-color: red;
}
</style>
This seems like a bug, but maybe I've done some silly mistake here. Could you look at this and verify? Thanks in advance :)
The project sources can be found on GitHub
You could use ref property and watch the lgAndUp value to update it :
<template>
<div>
<div :class="divClass">Reactivity</div>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
import { useDisplay } from 'vuetify';
const { lgAndUp } = useDisplay();
const divClass = ref('');
watch(lgAndUp, (val) => {
console.log(val);
divClass.value = val ? 'green' : 'red';
},{immediate:true});
</script>
<style>
.green {
background-color: green;
}
.red {
background-color: red;
}
</style>
DEMO

Vue lazyloading, remove spinner when image loads

I have a vue Nuxt project where I explore lazyloading with lazysizes package.
I created a spinner component (html css only) who should be visible only while the image is loading.
I also created an ImageItem component who includes the spinner component and it looks like this:
< script >
import spinner from '~/components/spinner.vue'
export default {
components: {
spinner,
},
props: {
source: {
type: String,
required: true,
}
},
} <
/script>
<style lang="scss" scoped>.imageItem {
position: relative;
.image {
z-index: 2;
&.lazyload,
&.lazyloading {
opacity: 0;
}
&.lazyloaded {
opacity: 1;
transition: all 1s linear 0.35s;
}
}
}
</style>
<template>
<div class="imageItem">
<spinner />
<img class="image lazyload" :data-srcset="source" />
</div>
</template>
To explain my code, I have props: source where In parent component i pass the image i want to lazyload. Also in the CSS while the image is loading, the image has .lazyloading class and when is loaded .lazyloaded class. Right now when Image is loaded i put it on top of the spinner.
My problem is, when I load the image I want to hide or destroy the spinner element since I think just putting the image on top is not the best way to do it. Can someone give me direction how should I properly hide the spinner when the image is loaded ?
Lazysizes fires an event when loading the image is finished : lazyloaded event, So you can do this :
<template>
<div class="imageItem">
<spinner v-if="lazyloading"/>
<img class="image lazyload" :data-srcset="source" />
</div>
</template>
<script>
import spinner from '~/components/spinner.vue'
export default {
data(){
return {
lazyloading
}
},
mounted(){
document.addEventListener('lazyloaded', (e) => {
this.lazyloading = false;
}
});
}
}
</script>

React Modals visible for a split-second on page load

I am rendering modals in React.
My index.html looks like this:
<div id="root"></div>
<div id="modal"></div>
And all my modals are rendered (through a portal) as a child of .modal.
Each modal element has the following form:
<div class="modal-background open">
<!-- children -->
</div>
Where the class can be modal-background open or modal-background closed. The entire component is:
interface OwnProps {
children: React.ReactNode
isOpen: boolean
onExit: () => void
}
export class Modal extends React.Component<OwnProps, any> {
_exit = () => this.props.onExit();
_renderModal = () => (
<div className={`modal-background ${this.props.isOpen ? "open" : "closed"}`} onClick={this._exit}>
{this.props.children}
</div>
);
render() {
if (this.props.isOpen) {
document.body.className += " no-scroll";
} else {
document.body.classList.remove("no-scroll");
}
let elem = document.querySelector("#modal");
if (elem == null) {
console.log("Could not render modal.");
return null;
}
return ReactDOM.createPortal(this._renderModal(), elem);
}
}
And the CSS looks like:
.modal-background {
/* Other styling - this a dark backdrop for a modal child */
background-color: rgba(0,0,0,0.2);
transition: opacity 150ms ease-out;
&.closed {
opacity: 0;
pointer-events: none;
}
&.open {
pointer-events: all;
opacity: 1;
&:hover {
cursor: pointer;
}
}
}
So my modal is used like <Modal><CustomModalElement/></Modal>.
When I load the page, my modal elements briefly flash, indicating that they are not hidden on load (but a split-second afterwards).
I can fix this by adding display: none and display: inherit into the css, but then I miss the nice transitions.
Is there a better way to do this?
Not sure you need to do anything else inside your index.html file except
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="modal"></div>
And for your Modal.js, you could try something along these lines:
import React from "react";
import ReactDOM from "react-dom";
const Modal = props => {
return ReactDOM.createPortal(
<div className="ui dimmer modals visible active">
<div className="ui standard modal visible active">
<div className="header">Delete Object</div>
<div className="content">
Are you sure you want to delete this?
</div>
<div className="actions">
<button className="ui primary button">Delete</button>
<button className="ui button">Cancel</button>
</div>
</div>
</div>,
document.querySelector("#modal")
);
};
export default Modal;
and then inside your other component where the user will execute the modal:
import React from "react";
import Modal from "../Modal"; // or wherever your Modal is in the file tree
const ObjectDelete = () => {
return (
<div>
ObjectDelete
<Modal />
</div>
);
};
export default ObjectDelete;
Keep in mind that the example of modal I offer here is not a reusable component.

gatsby-image: how to import the processed image into css and use it with background-image property

I sucessfully implemented the gatsby-image into my project and replace lots of img tag that are used in my components. But now im trying to optimized the background image for some of my component but i dont know how since using gatsby-image would generate a new img tag, and i cant use that to style as a background for say a div element. can s1 show me how i can use the generated images with css. Here's my code:
const HeaderlineSection = ({headerOne}) => {
return(
<div className="header-back" ></div>
)
}
export const query = graphql`
query IndexPageQuery {
headerOne: imageSharp(id: { regex: "/header_one.jpg/" }) {
sizes(maxWidth: 1200 ) {
...GatsbyImageSharpSizes
}
}
}
previously, in my css i use a non optimized image for backgroud-image:
.header-back {
background: url(../images/header_one.jpg) 50% 0 no-repeat;
height: 470px;
width: 100%;
}
I am using gatsby-background-image plugin for that. Here is one exemple of how you can use it :
import React from 'react'
import { graphql, StaticQuery } from 'gatsby'
import styled from 'styled-components'
import BackgroundImage from 'gatsby-background-image'
const BackgroundSection = ({ className }) => (
<StaticQuery query={graphql`
query {
desktop: file(relativePath: { eq: "seamless-bg-desktop.jpg" }) {
childImageSharp {
fluid(quality: 100, maxWidth: 4160) {
...GatsbyImageSharpFluid_withWebp
}
}
}
}
`}
render={data => {
const imageData = data.desktop.childImageSharp.fluid
return (
<BackgroundImage Tag="section"
className={className}
fluid={imageData}
backgroundColor={`#040e18`}
>
<h1>Hello gatsby-background-image</h1>
</BackgroundImage>
)
}
}
/>
)
const StyledBackgroundSection = styled(BackgroundSection)`
width: 100%;
background-repeat: repeat-y;
`
export default StyledBackgroundSection
The code is self-explanatory, but basically, element will be replaced with the element that you select in the Tag attribute and will have the background image set to the one selected with the graphql imageSharp query.

Resources