<template>
<img v-if="isBrowser()" ref="imageRef" />
<img v-else :src="getSsrSrc()" />
</template>
<script lang="ts">
/**
* @mixin VueSDK
* @description The Cloudinary Vue SDK contains components like \<AdvancedImage\> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional JS plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness.
*
* @example
* <caption>
* Please note that the order of the plugins is important. See {@link https://cloudinary.com/documentation/sdks/js/frontend-frameworks/index.html#plugin-order|Plugin Order} for more details.
* </caption>
* // AdvancedImage
* <template>
* <div>
* <AdvancedImage :cldImg="cldImg" :plugins="plugins" />
* </div>
* </template>
*
* <script lang="ts">
* import { defineComponent } from 'vue';
* import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
* import { AdvancedImage, responsive } from '@cloudinary/vue';
*
* export default defineComponent({
* name: 'App',
* components: {
* AdvancedImage,
* },
* setup(props) {
* const cldImg = new CloudinaryImage(
* 'sample',
* { cloudName: 'demo' },
* { analytics: false }
* );
*
* const plugins = [responsive({ steps: 100 })];
*
* return {
* cldImg,
* plugins,
* };
* },
* });
* </ script>
*
* @example
* <caption>
* Using `AdvancedVideo` custom defined resources.
* </caption>
*
* // AdvancedVideo
* <template>
* <AdvancedVideo :cldVid="cldVid" :sources="sources" controls width="600" />
* </template>
*
* <script lang="ts">
* import { defineComponent } from "vue";
* import { auto } from "@cloudinary/url-gen/qualifiers/videoCodec";
* import { videoCodec } from "@cloudinary/url-gen/actions/transcode";
* import { AdvancedVideo } from "../dist";
* import { CloudinaryVideo } from "@cloudinary/url-gen/assets/CloudinaryVideo";
*
* export default defineComponent({
* name: "App",
* components: {
* AdvancedVideo,
* },
* setup(props) {
* const cldVid = new CloudinaryVideo(
* "dog",
* { cloudName: "demo" },
* { analytics: false }
* );
*
* const sources = [
* {
* type: "mp4",
* transcode: videoCodec(auto()),
* },
* {
* type: "webm",
* transcode: videoCodec(auto()),
* },
* ];
*
* return {
* cldVid,
* sources,
* };
* },
* });
* </ script>
*/
/**
* @memberOf VueSDK
* @module AdvancedImage
* @description The Cloudinary image component.
* @vue-prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @vue-prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
</script>
<script setup lang="ts">
import { ref, onMounted, onUpdated, onUnmounted } from "vue";
import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import {
HtmlImageLayer,
isBrowser,
serverSideSrc,
cancelCurrentlyRunningPlugins,
Plugins,
} from "@cloudinary/html";
import { SDKAnalyticsConstants } from "../internal/SDKAnalyticsConstants";
interface ImgProps {
cldImg: CloudinaryImage;
plugins?: Plugins;
[x: string]: any;
}
// Disabled linting due to [@vue/compiler-sfc] `defineProps` is a compiler macro and no longer needs to be imported.
// eslint-disable-next-line no-undef
const props = defineProps<ImgProps>();
const imageRef = ref(null);
let htmlLayerInstance;
const getSsrSrc = () => serverSideSrc(props.plugins, props.cldImg, SDKAnalyticsConstants);
/**
* On mount, creates a new HTMLLayer instance and initializes with ref to img element,
* user generated cloudinaryImage and the plugins to be used.
*/
onMounted(() => {
htmlLayerInstance = new HtmlImageLayer(
imageRef.value,
props.cldImg,
props.plugins,
SDKAnalyticsConstants
);
});
/**
* On update, we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins.
*/
onUpdated(() => {
cancelCurrentlyRunningPlugins(htmlLayerInstance.htmlPluginState);
// call html layer to update the dom again with plugins and reset toBeCanceled
htmlLayerInstance.update(props.cldImg, props.plugins, SDKAnalyticsConstants);
});
/**
* On unmount, we cancel the currently running plugins.
*/
onUnmounted(() => {
// Safely cancel running events on unmount.
cancelCurrentlyRunningPlugins(htmlLayerInstance.htmlPluginState);
});
</script>