WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2024-05-16 2c8603596c79d104e4189a06eb796a8699e25140
forms/imagePicker/CImagePreview.vue
@@ -4,26 +4,73 @@
 */
<template>
    <view class="c-image-preview"></view>
    <view class="c-image-preview">
        <image
            class="c-image-preview-img"
            :class="imgClass"
            mode="aspectFit"
            :lazyLoad="true"
            v-for="(img, index) of imgList"
            :src="loadFail[index] ? img.org : img.thumb"
            :key="index"
            @tap="evt => $preview({ current: img.org, urls: imgs })"
            @error="evt => handleLoadError(index)"
        />
    </view>
</template>
<script>
import Taro from '@tarojs/taro';
import { $ } from '@tarojs/extend';
import './cImagePreview.scss';
// 直线方程,点斜式参数
const createLineEquation = (p1, p2) => ({
    k: (p1.y - p2.y) / (p1.x - p2.x),
    b: p1.y - k * p1.x,
});
const createLineEquation = (p1, p2) => {
    const k = (p1.y - p2.y) / (p1.x - p2.x);
    const b = p1.y - k * p1.x;
    return { k, b };
};
const winWidth = window.innerWidth;
export default {
    name: 'CImagePreview',
    props: {
        // 图片样式名
        imgClass: String,
        // 图片地址
        imgs: {
            type: Array,
            default: () => [],
        },
        // 开启缩略图地址转换
        useThumb: {
            typeof: Boolean,
            default: false,
        },
    },
    data() {
        return {};
        return {
            loadFail: [],
        };
    },
    computed: {
        imgList() {
            return this.imgs.map((img, index) => ({
                org: img,
                thumb: this.useThumb
                    ? img.replace(/(.*?)(\.(png|jpg|jpeg|gif))$/, '$1_thumb$2')
                    : img,
            }));
        },
    },
    methods: {
        handleLoadError(index) {
            while (this.loadFail.length - 1 < index) {
                this.loadFail.push(false);
            }
            this.loadFail.splice(index, 1, true);
        },
        // option { current, urls }
        $preview(option) {
            // 网页模式下,增加缩放操作
            if (process.env.TARO_ENV === 'h5') {
@@ -38,8 +85,8 @@
            // 小程序模式,直接支持缩放
            else {
                Taro.previewImage({
                    current: file.url, // 当前显示图片的http链接
                    urls, // 需要预览的图片http链接列表
                    current: option.current, // 当前显示图片的http链接
                    urls: option.urls, // 需要预览的图片http链接列表
                });
            }
        },
@@ -67,8 +114,8 @@
                    let equationY = {};
                    $img.on({
                        touchstart: evt => {
                            startOffsetX = parseInt($img.css('left'));
                            startOffsetY = parseInt($img.css('top'));
                            startOffsetX = parseInt($img.css('left')) || 0;
                            startOffsetY = parseInt($img.css('top')) || 0;
                            startWidth = parseInt($img.css('width')) * scale;
                            if (evt.touches.length == 1) {
                                const { clientX, clientY } = evt.touches[0];
@@ -85,14 +132,14 @@
                                if (scale - 1 > 0.1) {
                                    equationX = createLineEquation(
                                        { x: 1, y: 0 },
                                        { x: scale, y: startOffsetX }
                                        { x: scale, y: startOffsetX },
                                    );
                                    equationY = createLineEquation(
                                        { x: 1, y: 0 },
                                        { x: scale, y: startOffsetY }
                                        { x: scale, y: startOffsetY },
                                    );
                                }
                                // 初始状态,不线性计算
                                // 初始状态,不计算
                                else {
                                    equationX = equationY = { k: 0, b: 0 };
                                }
@@ -126,7 +173,7 @@
                                const yMove =
                                    evt.touches[1].clientY - evt.touches[0].clientY;
                                const newDistance = Math.sqrt(
                                    xMove * xMove + yMove * yMove
                                    xMove * xMove + yMove * yMove,
                                );
                                const distanceDiff = newDistance - distance;
                                const newScale = scale + 0.01 * distanceDiff;
@@ -142,8 +189,8 @@
                                    }
                                }
                                // 修正位置
                                const left = equationX.a * scale + equationX.b;
                                const top = equationY.a * scale + equationY.b;
                                const left = equationX.k * scale + equationX.b;
                                const top = equationY.k * scale + equationY.b;
                                // 渲染
                                $img.css({
                                    transform: 'scale(' + scale + ')',