首页 > 其他分享 >前端色环制作的方式

前端色环制作的方式

时间:2023-07-11 17:13:45浏览次数:43  
标签:style document linear gradient 前端 green background 色环 制作

需求背景

最近有个项目中有个功能需要在浏览器上实现图片颜色任意变化,并且不会出现卡顿,要向德芙一样的丝滑

思路

最开始的思路

使用canvas+js的方式实现

github地址:https://github.com/miniflycn/JsCV
这个方式好处就是canvase绘制的图片不会失真,缺点就是图像越精细,变动越大,canvase渲染就越慢

优化思路



发现b站的视频饱和度,亮度,对比度是可以手动变化的,很丝滑,所以又研究了半天这玩意儿,然后我就找到了filter属性。
既然视频都可以这样,那么就搜索一样这个css属性看看它的介绍
关于filter的介绍链接:
http://www.ecomcn.com/Website/show_id465.html
https://www.runoob.com/cssref/css3-pr-filter.html
https://codepen.io/qwguo88/pen/XWbNLmx

其中的filter的hue-rotate(色环)属性可以完美解决jpg等图片的变色问题,因为有这个属性存在,所以不用把图片转换成svg图片格式即可改变颜色
实验代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>3D Canvas Example</title>
    <style>
      #img1 {
        filter:hue-rotate(0deg) brightness(100%) saturate(100%) contrast(100%) grayscale(0%);
      }
    </style>
  </head>
  <body>
    <img id="img1" src="./imges/3.jpeg" alt="" width="800px" height="800px">
    <img id="img2" src="./imges/3.jpeg" alt="" width="800px" height="800px">
  </body>
</html>

以上代码中,filter属性分别为:色环,明度,饱和度,对比度,灰度
具体的可以实验去尝试更改,效果如下图所示

关于色环的操作的方式的额外衍生思路

以上我们已经知道怎么更改图片颜色了,在使用canvas+js方式更改图片颜色的时候,我是通过rgb调整的方式更改的。最开始我本想把rgb保留,然后根据rgb值计算出色环角度值(如上图那个如同时钟一样的东西)
但是如果做成时钟一样的东西,那么我需要实现一个真的色环,思路方式先是生成一个直线形式的过渡的颜色,如下代码:

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        [class|=linear] {
            width: 300px;
            height: 50px;
            margin: 20px auto;
            font-size: 2rem;
            color: #fff;
        }
 
        .linear-1 {
            background-image: linear-gradient(red, blue, green);
            background-image: -webkit-linear-gradient(red, blue, green);
            background-image: -ms-linear-gradient(red, blue, green);
            background-image: -o-linear-gradient(red, blue, green);
            background-image: -moz-linear-gradient(red, blue, green);
        }
 
        .linear-2 {
            background-image: linear-gradient(90deg, green, blue, red);
        }
 
        .linear-3 {
            background-image: linear-gradient(to bottom, red 25%, green 25%, green 50%, green 50%, green 75%, hotpink 75%, hotpink 100%);
        }
    </style>
</head>
 
<body>
    <div class="linear-1"></div>
    <div class="linear-2"></div>
    <div class="linear-3"></div>
</body>
 
</html>

效果如图所示:

中间那种是比较复合要求的,但是我应该如何把这个直线型的弄成圆环形的呢?后面我朋友告诉我background: conic-gradient属性可以做到
实现代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .circle1{
            position: relative;
            width: 80px;
            height: 80px;
            margin: 20px auto;
            border-radius: 50%;
            background: white;
            text-align: center;
        }
        .circle1::after {
            position: absolute;
            content: '';
            /*  linear-gradient:线性渲染,conic-gradient:环形渲染*/
            /* background: linear-gradient(180deg, red 0%, green 34%, blue 100%);*/
            background: conic-gradient(red, green, blue, red);
            bottom: 0;
            right: 0;
            left: 0;
            top: 0;
            z-index: -1;
            transform: scale(1.3);
            border-radius: 50%;
        }
        
    </style>
</head>
<body>
    <div class="circle1"></div>
</body>
</html>

效果如图所示:

好了,现在环结构有了,那么指针咋搞呢?算了好麻烦啊,还是用直线型的吧→_→,记录到此结束,拜拜了您嘞

对了,这里顺带记录一个图片拖拽,放大缩小的功能代码,别误会,我只是为了方便我以后使用:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style type="text/css">

        body{
        
            margin: 0;
            
            background: pink;
        
        }
        
        .imgWrap{
            width: 500px;
            margin: 50px auto;
            
        }
        
        .imgWrap img{
            width:100%;
        
        }
        
        #mask{
            display: block;
            position: absolute;
            top:0;
            bottom:0;
            left:0;
            right:0;
            background-color:rgba(0,0,0,.9);
        
        }

        #box_tk{
            width: 500px;
            height: 500px;
            margin:50px auto;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%,-50%);
            overflow: hidden;
        }
        
        #tk{
            width: 500px;
            height: 500px;
            box-shadow: 0 0 20px #ffffff;
            position: relative;
        }

        #tkImg{
            position: absolute;
            left: 0;
            top: 0;
        }
        
    </style>
    <script>
        window.onload = function(){

            let mask = document.getElementById("mask");
            
            let tk = document.getElementById("tk");
            
            let tkImg = document.getElementById("tkImg");
            
            let boxTk = document.getElementById("box_tk");
            
            
            tkImg.style.zoom = 20+'%';
            
            tkImg.setAttribute("src",tkImg.src);

            dragTool(tkImg);
            
        
            function dragTool(node) {
                console.log("移动函数触发")

                node.onmousedown = function (ev) {
                    console.log("onmousedown事件监听成功")
                    tkImg.style.cursor="move"                
                    
                    // 去除h5的默认事件,不然可能会造成onmouseup方法失效
                    document.ondragstart = function(ev) {
                        ev.preventDefault();
                      };
                      document.ondragend = function(ev) {
                        ev.preventDefault();
                      };

                    // 浏览器兼容处理
                    var e = ev || window.event;
                    // 鼠标按下记录相对位置
                    // 水平方向都距离 = 当前鼠标左边的距离 - 被拖拽元素距离左边的距离
                    var offsetX = e.clientX;
                    // 垂直方向都距离 = 当前鼠标都上边的距离 - 被拖拽元素距离距离的距离
                    var offsetY = e.clientY;
                    // 鼠标移动和被拖拽的元素是相对的 这里是鼠标拖拽的物体在整个页面上移动 所以
                    // move加在document上
                    document.onmousemove = function (ev) {
                        console.log("onmousemove事件监听成功")
                        // 当前鼠标的事件对象
                        var e = ev || window.event;
                        // 定义 currentLeft  = 当前鼠标位置 - 距离左边的距离
                        var currentLeft = e.clientX - offsetX;
                        // 定义 currentTop = 当前鼠标上边位置 - 距离上边的距离
                        var currentTop = e.clientY - offsetY
                        // 限制左出界 最左是 0 
                        /*
                        if (currentLeft <= 0) {
                            currentLeft = 0;
                        }
                        */
                        // 当前窗口的宽 浏览器兼容
                        // var windowWidth = document.documentElement.clientWidth || document.body.clientWidth;
                        // 限制右边出界 如果大于当前窗口的宽 那么就让它等于当前窗口的宽减去当前元素的offsetWidth 也就是留在原地
                        if (currentLeft >= boxTk.width) {
                            currentLeft = boxTk.width;
                        }
                        // 设置上出界 最上边是 0 
                        /*
                        if (currentTop <= 0) {
                            currentTop = 0;
                        }
                        */
                        // 当前窗口的高 浏览器兼容
                        // var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
                        // 限制下边出界 如果大于当前窗口的高 减去 本身的高 那么就让它等于 当前窗口的高减去本身的高
                        if (currentTop >= boxTk.height) {
                            currentTop = boxTk.height;
                        }
                        // 当前被拖拽元素的 left 值 等于上面计算出的 currentLeft
                        node.style.left = currentLeft + 'px';
                        // 当前被拖拽元素的 top 值 等于上面计算出的 currentTop
                        node.style.top = currentTop + 'px';
                    }
                }
                // 鼠标弹起取消拖拽 这里添加到 node 元素对象也可以的
                document.onmouseup = function () {
                    document.onmousemove = null;
                    console.log("onmouseup事件监听成功")
                    tkImg.style.cursor="default"    
                }
            }
        
            
        }
        
        function zoomImg(obj){
        
            var zoom = parseInt(obj.style.zoom, 10) || 100;//zoom属性用于设置或检索对象的缩放比例
        
            zoom += event.wheelDelta/12;
        
            if(zoom>0){
                obj.style.zoom = zoom + '%';
        
                document.body.style.position = "fixed";
            }
        
            document.body.style.height=100+"%";
            
            document.body.style.width=100+"%";
        
        }
        
        function tkImgClick(){
            event.stopPropagation();
        
        }
    </script>
</head>
<body>
        
    <div id="mask">
        <div id="box_tk">
            <div id="tk" onclick="tkImgClick()">
                <img id="tkImg" src="./imges/3.jpeg" alt="" onm ousewheel="zoomImg(tkImg)"/>
            </div>
        </div>
        
    </div>
</body>
</html>

好啦,别看下去了,这里真的是最后一个了,溜了

标签:style,document,linear,gradient,前端,green,background,色环,制作
From: https://www.cnblogs.com/YMWH/p/17545155.html

相关文章

  • 如何制作一个超低功耗的高保真的数字录音机
    前记 您是否曾经想过购买一台小型录音机来录制环境中的声音并将其存储在内存中?其实这只需执行几个简单的步骤即可轻松制作自己的录音机。该项目主要是用来指导学生做一个课题,也可以将其用做商业用途。该模块的使用两颗超低功耗的芯片做主体,一个做音频采集并将所记录的语音存储......
  • web前端 第四天总结
    案例1:盒子模型<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</ti......
  • 前端框架及项目面试-聚焦Vue、React、Webpack
    第1章课程导学介绍课程制作的背景和课程主要内容。第2章课程介绍先出几道面试真题,引导思考。带着问题来继续学习,效果更好。第3章Vue使用Vue是前端面试必考内容,首先要保证自己要会使用Vue。本章讲解Vue基本使用、组件使用、高级特性和VuexVue-router,这些部分的知识点和......
  • 前端编程开发 --- vue3 监听属性
    监听变量的变化并触发函数 <divid="app"><pstyle="font-size:25px;">计数器:{{counter}}</p><button@click="counter++"style="font-size:25px;">点我</button>//counter++表示变量自增......
  • web前端 第三天总结
    案例1:伪类选择器<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>伪类选择器</titl......
  • API管理不好做?来试试Apipost,前端、后端、测试,一个平台全搞定
    API是什么&API管理存在哪些问题API(ApplicationProgrammingInterface,应用程序接口)作为一系列预先定义的规则和约定,用于不同软件应用之间的通信,促进了系统间的互动和数据共享。在企业数字化转型的推进中,API管理变得越来越重要。然而,API管理过程中存在着一些困境,以下是其中的四个......
  • 黑马程序员前端JS基础视频课程(pink老师)
    共计76个视频,20小时时长课程分为三大块1.JavaScript基础2.webAPIs3.JS进阶之前看过pink老师的css+html讲的那是扛扛,刚刚在其他社区找到这套课程特意分享给大家! download:黑马程序员前端JS基础视频课程(pink老师) ......
  • AE 制作简单动态壁纸
    成品B站链接WallpaperEngine可用:搜索Alice_StarCried简述参考了B站的两个自学教程,都是直接搜能搜到的。PS、AE零基础。因为需要渲染所用电脑配置有一定需求,额外用了数位板。AE使用了现成脚本。从学习到制作完成总用时不过四天。所需技能为PS基本使用,包括抠图、补图等,......
  • 前端解决跨域问题
    1.JSONP 缺点是只能解决get请求不支持postJSONP原理就是通过script标签的src属性请求跨域的数据接口并通过函数调用的方法来接受跨域接口响应回来的数据<scriptsrc="./js/yanshi.js?callback=name"></script>回调函数callback关键字找到想要调用的形参在jq中发起jsonp......
  • 助教工作总结(前端开发技术)
    一、助教工作的具体职责和任务(1)和老师配合的方面理论课(1) 老师会在每一块内容授课结束后发布相应云班课的作业,在理论课进行时,我主要的工作是负责的作业批改,和提醒同学们修改,解答同学们在实操时遇到的一些问题。(2) 定期收集课程的评价,同学们对课程某些方......